mirror of
https://github.com/scratchfoundation/scratch-www.git
synced 2025-02-17 00:21:20 -05:00
Use formsy-react for validation
Complete validation for username/password form (except for checking if a username exists).
This commit is contained in:
parent
de3151924c
commit
b5c615b1fa
12 changed files with 451 additions and 245 deletions
|
@ -43,6 +43,8 @@
|
|||
"exenv": "1.2.0",
|
||||
"fastly": "1.2.1",
|
||||
"file-loader": "0.8.4",
|
||||
"formsy-react": "0.18.0",
|
||||
"formsy-react-components": "0.7.1",
|
||||
"git-bundle-sha": "0.0.2",
|
||||
"glob": "5.0.15",
|
||||
"json-loader": "0.5.2",
|
||||
|
|
18
src/components/forms/checkbox-group.jsx
Normal file
18
src/components/forms/checkbox-group.jsx
Normal file
|
@ -0,0 +1,18 @@
|
|||
var classNames = require('classnames');
|
||||
var FRCCheckboxGroup = require('formsy-react-components').CheckboxGroup;
|
||||
var React = require('react');
|
||||
|
||||
var CheckboxGroup = React.createClass({
|
||||
type: 'CheckboxGroup',
|
||||
render: function () {
|
||||
var classes = classNames(
|
||||
'checkbox-group',
|
||||
this.props.className
|
||||
);
|
||||
return (
|
||||
<FRCCheckboxGroup {... this.props} className={classes} />
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = CheckboxGroup;
|
18
src/components/forms/checkbox.jsx
Normal file
18
src/components/forms/checkbox.jsx
Normal file
|
@ -0,0 +1,18 @@
|
|||
var classNames = require('classnames');
|
||||
var FRCCheckbox = require('formsy-react-components').Checkbox;
|
||||
var React = require('react');
|
||||
|
||||
var Checkbox = React.createClass({
|
||||
type: 'Checkbox',
|
||||
render: function () {
|
||||
var classes = classNames(
|
||||
'checkbox',
|
||||
this.props.className
|
||||
);
|
||||
return (
|
||||
<FRCCheckbox {... this.props} className={classes} />
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = Checkbox;
|
24
src/components/forms/form.jsx
Normal file
24
src/components/forms/form.jsx
Normal file
|
@ -0,0 +1,24 @@
|
|||
var classNames = require('classnames');
|
||||
var Formsy = require('formsy-react');
|
||||
var React = require('react');
|
||||
var validations = require('./validations');
|
||||
|
||||
for (var validation in validations) {
|
||||
Formsy.addValidationRule(validation, validations[validation]);
|
||||
}
|
||||
|
||||
var Form = React.createClass({
|
||||
render: function () {
|
||||
var classes = classNames(
|
||||
'form',
|
||||
this.props.className
|
||||
);
|
||||
return (
|
||||
<Formsy.Form {... this.props} className={classes}>
|
||||
{this.props.children}
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = Form;
|
|
@ -19,10 +19,6 @@ module.exports = {
|
|||
navigation: null
|
||||
};
|
||||
},
|
||||
onSubmit: function (e) {
|
||||
e.preventDefault();
|
||||
this.props.onNextStep();
|
||||
},
|
||||
render: function () {
|
||||
var classes = classNames(
|
||||
'step',
|
||||
|
@ -33,13 +29,7 @@ module.exports = {
|
|||
<img className="icon" src={this.props.icon} />
|
||||
{this.props.description}
|
||||
{this.props.navigation}
|
||||
{React.Children.map(this.props.children, function (child){
|
||||
if (child.type === 'form') {
|
||||
return React.cloneElement(child, {onSubmit: this.onSubmit});
|
||||
} else {
|
||||
return child;
|
||||
}
|
||||
}, this)}
|
||||
{this.props.children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -85,9 +75,10 @@ module.exports = {
|
|||
<div {... this.props} className={classes}>
|
||||
{React.Children.map(this.props.children, function (child, id) {
|
||||
if (id === this.props.step) {
|
||||
return React.cloneElement(child, {onNextStep: function () {
|
||||
this.props.onSetStep(this.props.step + 1);
|
||||
}.bind(this)});
|
||||
var props = {
|
||||
navigation: navigation
|
||||
};
|
||||
return React.cloneElement(child, props);
|
||||
}
|
||||
}, this)}
|
||||
</div>
|
||||
|
|
|
@ -1,22 +1,25 @@
|
|||
var React = require('react');
|
||||
var classNames = require('classnames');
|
||||
var FRCInput = require('formsy-react-components').Input;
|
||||
var React = require('react');
|
||||
var validateMixin = require('./validateMixin.jsx');
|
||||
|
||||
require('./input.scss');
|
||||
|
||||
var Input = React.createClass({
|
||||
type: 'Input',
|
||||
propTypes: {
|
||||
|
||||
getDefaultProps: function () {
|
||||
return {};
|
||||
},
|
||||
render: function () {
|
||||
var classes = classNames(
|
||||
'input',
|
||||
this.props.className
|
||||
);
|
||||
return (
|
||||
<input {... this.props} className={classes} />
|
||||
return (this.props.type === 'submit' || this.props.noformsy ?
|
||||
<input {... this.props} className={classes} /> :
|
||||
<FRCInput {... this.props} className={classes} />
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = Input;
|
||||
module.exports = validateMixin(Input);
|
||||
|
|
18
src/components/forms/radio-group.jsx
Normal file
18
src/components/forms/radio-group.jsx
Normal file
|
@ -0,0 +1,18 @@
|
|||
var classNames = require('classnames');
|
||||
var FRCRadioGroup = require('formsy-react-components').RadioGroup;
|
||||
var React = require('react');
|
||||
|
||||
var RadioGroup = React.createClass({
|
||||
type: 'RadioGroup',
|
||||
render: function () {
|
||||
var classes = classNames(
|
||||
'radio-group',
|
||||
this.props.className
|
||||
);
|
||||
return (
|
||||
<FRCRadioGroup {... this.props} className={classes} />
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = RadioGroup;
|
|
@ -1,5 +1,6 @@
|
|||
var React = require('react');
|
||||
var classNames = require('classnames');
|
||||
var FRCSelect = require('formsy-react-components').Select;
|
||||
var React = require('react');
|
||||
|
||||
require('./select.scss');
|
||||
|
||||
|
@ -14,9 +15,7 @@ var Select = React.createClass({
|
|||
this.props.className
|
||||
);
|
||||
return (
|
||||
<select {... this.props} className={classes}>
|
||||
{this.props.children}
|
||||
</select>
|
||||
<FRCSelect {... this.props} className={classes} />
|
||||
);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,25 +1,18 @@
|
|||
var React = require('react');
|
||||
var classNames = require('classnames');
|
||||
var FRCTextarea = require('formsy-react-components').Textarea;
|
||||
var React = require('react');
|
||||
|
||||
require('./textarea.scss');
|
||||
|
||||
var TextArea = React.createClass({
|
||||
type: 'TextArea',
|
||||
getDefaultProps: function () {
|
||||
return {
|
||||
rows: 5,
|
||||
cols: 40
|
||||
}
|
||||
},
|
||||
render: function () {
|
||||
var classes = classNames(
|
||||
'textarea',
|
||||
this.props.className
|
||||
);
|
||||
return (
|
||||
<textarea {... this.props} className={classes}>
|
||||
{this.props.children}
|
||||
</textarea>
|
||||
<FRCTextarea {... this.props} className={classes} />
|
||||
);
|
||||
}
|
||||
});
|
||||
|
|
24
src/components/forms/validateMixin.jsx
Normal file
24
src/components/forms/validateMixin.jsx
Normal file
|
@ -0,0 +1,24 @@
|
|||
var defaults = require('lodash.defaultsdeep');
|
||||
var React = require('react');
|
||||
|
||||
var validateMixin = function (Component) {
|
||||
var ValidatedComponent = React.createClass({
|
||||
getDefaultValidationErrors: function () {
|
||||
return {
|
||||
isDefaultRequiredValue: 'This field is required'
|
||||
};
|
||||
},
|
||||
render: function () {
|
||||
var validationErrors = defaults(
|
||||
this.getDefaultValidationErrors(),
|
||||
this.props.validationErrors
|
||||
);
|
||||
return (
|
||||
<Component {...this.props} validationErrors={validationErrors} />
|
||||
);
|
||||
}
|
||||
});
|
||||
return ValidatedComponent;
|
||||
};
|
||||
|
||||
module.exports = validateMixin;
|
10
src/components/forms/validations.js
Normal file
10
src/components/forms/validations.js
Normal file
|
@ -0,0 +1,10 @@
|
|||
var Validations = {
|
||||
notEquals: function (values, value, neq) {
|
||||
return value !== neq;
|
||||
},
|
||||
notEqualsField: function (values, value, field) {
|
||||
return value !== values[field];
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = Validations;
|
|
@ -1,35 +1,337 @@
|
|||
var classNames = require('classnames');
|
||||
var defaults = require('lodash.defaultsdeep');
|
||||
var React = require('react');
|
||||
|
||||
var render = require('../../lib/render.jsx');
|
||||
|
||||
var Button = require('../../components/forms/button.jsx');
|
||||
var Checkbox = require('../../components/forms/checkbox.jsx');
|
||||
var CheckboxGroup = require('../../components/forms/checkbox-group.jsx');
|
||||
var Form = require('../../components/forms/form.jsx');
|
||||
var formset = require('../../components/forms/formset.jsx');
|
||||
var FormSet = formset.FormSet;
|
||||
var FormStep = formset.FormStep;
|
||||
var Input = require('../../components/forms/input.jsx');
|
||||
var Label = require('../../components/forms/label.jsx');
|
||||
var Page = require('../../components/page/www/page.jsx');
|
||||
var RadioGroup = require('../../components/forms/radio-group.jsx');
|
||||
var Select = require('../../components/forms/select.jsx');
|
||||
var TextArea = require('../../components/forms/textarea.jsx');
|
||||
|
||||
var COUNTRIES = require('./countries.json');
|
||||
require('./teacherregistration.scss');
|
||||
|
||||
|
||||
var UsernameStep = React.createClass({
|
||||
render: function () {
|
||||
return (
|
||||
<FormStep title="Create a Teacher Account"
|
||||
description={
|
||||
<p>
|
||||
Creating a Teacher Account requires additional information
|
||||
for review.
|
||||
<strong>The approval process can take up to 24 hours</strong>
|
||||
</p>}>
|
||||
<Form onValidSubmit={this.props.onNextStep} noValidate>
|
||||
<Input label="Username"
|
||||
type="text"
|
||||
name="username"
|
||||
validations={{
|
||||
matchRegexp: /^[\w-]*$/,
|
||||
minLength: 3,
|
||||
maxLength: 20
|
||||
}}
|
||||
validationErrors={{
|
||||
matchRegexp: 'Your username may only contain characters and -',
|
||||
minLength: 'Usernames must be at least three characters',
|
||||
maxLength: 'Usernames must be at most 20 characters'
|
||||
}}
|
||||
required />
|
||||
<Input label="Password"
|
||||
type="password"
|
||||
name="password"
|
||||
validations={{
|
||||
minLength: 6,
|
||||
notEquals: 'password',
|
||||
notEqualsField: 'username'
|
||||
}}
|
||||
validationErrors={{
|
||||
minLength: 'Passwords must be at least six characters',
|
||||
notEquals: 'Your password may not be "password"',
|
||||
notEqualsField: 'Your password may not be your username'
|
||||
}}
|
||||
required />
|
||||
<Input label="Confirm Password"
|
||||
type="password"
|
||||
name="passwordConfirmation"
|
||||
validations="equalsField:password"
|
||||
validationError="The passwords do not match"
|
||||
required/>
|
||||
<Button type="submit">Next Step</Button>
|
||||
</Form>
|
||||
</FormStep>
|
||||
);
|
||||
}
|
||||
});
|
||||
var DemographicsStep = React.createClass({
|
||||
onSubmit: function () {
|
||||
this.props.onNextStep();
|
||||
},
|
||||
render: function () {
|
||||
var countryOptions = Object.keys(COUNTRIES).map(function (code) {
|
||||
return {value: code, label: COUNTRIES[code]};
|
||||
});
|
||||
var monthOptions = [
|
||||
'January', 'February', 'March', 'April', 'May', 'June', 'July',
|
||||
'August', 'September', 'October', 'November', 'December'
|
||||
].map(function (label, id) {
|
||||
return {value: id+1, label: label};
|
||||
});
|
||||
var yearOptions = Array.apply(null, Array(100)).map(function (v, id) {
|
||||
var year = 2016 - id;
|
||||
return {value: year, label: year};
|
||||
});
|
||||
return (
|
||||
<FormStep title="Demographics"
|
||||
description={
|
||||
<p>
|
||||
Your responses to these questions will be kept private.
|
||||
Why do we ask for this information <a onClick={this.handle}>?</a>
|
||||
</p>}>
|
||||
<Form onSubmit={this.onSubmit}>
|
||||
<Select label="Birth Month" name="month" options={monthOptions} />
|
||||
<Select label="Birth Yeah" name="year" options={yearOptions} />
|
||||
<RadioGroup label="Gender"
|
||||
name="gender"
|
||||
options={[
|
||||
{value: 'female', label: 'Female'},
|
||||
{value: 'male', label: 'Male'},
|
||||
{value: 'other', label: 'Other'}
|
||||
]}
|
||||
/>
|
||||
<Input name="genderOther" type="text" />
|
||||
<Select label="Country" name="country" options={countryOptions} />
|
||||
<Button type="submit">Next Step</Button>
|
||||
</Form>
|
||||
</FormStep>
|
||||
);
|
||||
}
|
||||
});
|
||||
var NameStep = React.createClass({
|
||||
onSubmit: function () {
|
||||
this.props.onNextStep();
|
||||
},
|
||||
render: function () {
|
||||
return (
|
||||
<FormStep title="First & Last Name"
|
||||
description={
|
||||
<p>
|
||||
Your responses to these questions will be kept private.
|
||||
Why do we ask for this information <a onClick={this.handle}>?</a>
|
||||
</p>}>
|
||||
<Form onSubmit={this.onSubmit}>
|
||||
<Label htmlFor="first">First Name</Label>
|
||||
<Input type="text" name="first" />
|
||||
<Label htmlFor="last">Last Name</Label>
|
||||
<Input type="text" name="last" />
|
||||
<Button type="submit">Next Step</Button>
|
||||
</Form>
|
||||
</FormStep>
|
||||
);
|
||||
}
|
||||
});
|
||||
var PhoneNumberStep = React.createClass({
|
||||
onSubmit: function () {
|
||||
this.props.onNextStep();
|
||||
},
|
||||
render: function () {
|
||||
return (
|
||||
<FormStep title="Phone Number"
|
||||
description={
|
||||
<p>
|
||||
Your responses to these questions will be kept private.
|
||||
Why do we ask for this information <a onClick={this.handle}>?</a>
|
||||
</p>}>
|
||||
<Form onSubmit={this.onSubmit}>
|
||||
<Label htmlFor="phone">Phone Number</Label>
|
||||
<Input type="tel" name="phone" />
|
||||
<Checkbox name="phoneConsent" />
|
||||
<Label htmlFor="phoneConsent">
|
||||
Yes, I consent to lorem ipsum dolor sit amet,
|
||||
consectetur adipiscing elit.
|
||||
</Label>
|
||||
<Button type="submit">Next Step</Button>
|
||||
</Form>
|
||||
</FormStep>
|
||||
);
|
||||
}
|
||||
});
|
||||
var OrganizationStep = React.createClass({
|
||||
onSubmit: function () {
|
||||
this.props.onNextStep();
|
||||
},
|
||||
render: function () {
|
||||
var organizationOptions = [
|
||||
'Elementary School', 'Middle School', 'High School', 'University / College',
|
||||
'Museum', 'Library', 'Camp'
|
||||
].map(function (type) { return {value: type, label: type}; });
|
||||
return (
|
||||
<FormStep title="Organization"
|
||||
description={
|
||||
<p>
|
||||
Your responses to these questions will be kept private.
|
||||
Why do we ask for this information <a onClick={this.handle}>?</a>
|
||||
</p>}>
|
||||
<Form onSubmit={this.onSubmit}>
|
||||
<Label htmlFor="organization">Organization</Label>
|
||||
<Input type="text" name="organization" />
|
||||
<Label htmlFor="title">Title / Position</Label>
|
||||
<Input type="text" name="title" />
|
||||
<CheckboxGroup label="Type of Organization"
|
||||
options={organizationOptions} />
|
||||
<Checkbox name="organizationType" value="other" />
|
||||
<Input type="text" name="organizationTypeOther" />
|
||||
<Label htmlFor="website">Website URL (not required)</Label>
|
||||
<Input type="url" name="website" />
|
||||
<Button type="submit">Next Step</Button>
|
||||
</Form>
|
||||
</FormStep>
|
||||
);
|
||||
}
|
||||
});
|
||||
var AddressStep = React.createClass({
|
||||
onSubmit: function () {
|
||||
this.props.onNextStep();
|
||||
},
|
||||
render: function () {
|
||||
var countryOptions = Object.keys(COUNTRIES).map(function (code) {
|
||||
return {value: code, label: COUNTRIES[code]};
|
||||
});
|
||||
var stateOptions = ['every','state','in','the','world'].map(function (name) {
|
||||
return {value: name, label: name};
|
||||
});
|
||||
return (
|
||||
<FormStep title="Address"
|
||||
description={
|
||||
<p>
|
||||
Your responses to these questions will be kept private.
|
||||
Why do we ask for this information <a onClick={this.handle}>?</a>
|
||||
</p>}>
|
||||
<Form onSubmit={this.onSubmit}>
|
||||
<Label htmlFor="addressCountry">Country</Label>
|
||||
<Select name="addressCountry" options={countryOptions} />
|
||||
<Label htmlFor="addressLine1">Address Line 1</Label>
|
||||
<Input type="text" name="addressLine1" />
|
||||
<Label htmlFor="addressLine2">Address Line 2</Label>
|
||||
<Input type="text" name="addressLine2" />
|
||||
<Label htmlFor="addressCity">City</Label>
|
||||
<Input type="text" name="addressCity" />
|
||||
<Label htmlFor="addressZip">Zip Code</Label>
|
||||
<Input type="text" name="addressZip" />
|
||||
<Label htmlFor="addressState">State / Province</Label>
|
||||
<Select name="addressState" options={stateOptions} />
|
||||
<Button type="submit">Next Step</Button>
|
||||
</Form>
|
||||
</FormStep>
|
||||
);
|
||||
}
|
||||
});
|
||||
var UseScratchStep = React.createClass({
|
||||
onSubmit: function () {
|
||||
this.props.onNextStep();
|
||||
},
|
||||
render: function () {
|
||||
return (
|
||||
<FormStep title="How do you use Scratch?"
|
||||
description={
|
||||
<p>
|
||||
Tell us a little how you plan to use Scratch.
|
||||
Why do we ask for this information <a onClick={this.handle}>?</a>
|
||||
</p>}>
|
||||
<Form onSubmit={this.onSubmit}>
|
||||
<Label htmlFor="useScratch">How do you use Scratch?</Label>
|
||||
<TextArea name="useScratch" />
|
||||
<Button type="submit">Next Step</Button>
|
||||
</Form>
|
||||
</FormStep>
|
||||
);
|
||||
}
|
||||
});
|
||||
var EmailStep = React.createClass({
|
||||
onSubmit: function () {
|
||||
this.props.onNextStep();
|
||||
},
|
||||
render: function () {
|
||||
return (
|
||||
<FormStep title="Email Address"
|
||||
description={
|
||||
<p>
|
||||
We will send you a <strong>confirmation email</strong> that will
|
||||
allow you to access your Scratch Teacher Account.
|
||||
</p>}>
|
||||
<Form onSubmit={this.onSubmit}>
|
||||
<Label htmlFor="email">Email</Label>
|
||||
<Input type="text" name="email" />
|
||||
<Label htmlFor="confirmEmail">Confirm Email</Label>
|
||||
<Input type="text" name="confirmEmail" />
|
||||
<Button type="submit">Next Step</Button>
|
||||
</Form>
|
||||
</FormStep>
|
||||
);
|
||||
}
|
||||
});
|
||||
var LastStep = React.createClass({
|
||||
render: function () {
|
||||
return (
|
||||
<FormStep title="Almost Done"
|
||||
description={
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet
|
||||
</p>}>
|
||||
<div className="confirm">
|
||||
<h2>Confirm Your Email</h2>
|
||||
<p>
|
||||
Click the link in the confirmation email that we
|
||||
sent to the following address:<br />
|
||||
<strong>{this.state.email}</strong>
|
||||
</p>
|
||||
<div className="box-footer">
|
||||
<a onClick="">Wrong email?</a>
|
||||
<a onClick="">Having trouble?</a>
|
||||
</div>
|
||||
</div>
|
||||
<div className="wait">
|
||||
<h2>Wait for Approval</h2>
|
||||
<p>
|
||||
Your information is being reviewed. Please be
|
||||
patient, the approval process can take up to 24hrs.
|
||||
</p>
|
||||
</div>
|
||||
</FormStep>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
var TeacherRegistration = React.createClass({
|
||||
type: 'TeacherRegistration',
|
||||
getInitialState: function () {
|
||||
return {
|
||||
step: 0
|
||||
step: 0,
|
||||
formData: {}
|
||||
};
|
||||
},
|
||||
setStep: function (step) {
|
||||
this.setState({step: step});
|
||||
},
|
||||
advanceStep: function (formData) {
|
||||
formData = formData || {};
|
||||
this.setState({
|
||||
step: this.state.step + 1,
|
||||
formData: defaults({}, formData, this.state.formData)
|
||||
});
|
||||
},
|
||||
render: function () {
|
||||
var months = [
|
||||
'January', 'February', 'March', 'April', 'May', 'June', 'July',
|
||||
'August', 'September', 'October', 'November', 'December'];
|
||||
var countries = require('./countries.json');
|
||||
var classes = classNames(
|
||||
'teacher-registration',
|
||||
'inner',
|
||||
|
@ -37,212 +339,16 @@ var TeacherRegistration = React.createClass({
|
|||
return (
|
||||
<div {...this.props} className={classes}>
|
||||
<FormSet {... this.props}
|
||||
step={this.state.step}
|
||||
onSetStep={this.setStep}>
|
||||
<FormStep title="Create a Teacher Account"
|
||||
description={
|
||||
<p>
|
||||
Creating a Teacher Account requires additional information
|
||||
for review.
|
||||
<strong>The approval process can take up to 24 hours</strong>
|
||||
</p>}
|
||||
key="step1">
|
||||
<form>
|
||||
<Label htmlFor="username">Username</Label>
|
||||
<Input type="text" name="username" />
|
||||
<Label htmlFor="password">Password</Label>
|
||||
<Input type="password" name="password" />
|
||||
<Label htmlFor="passwordConfirmation">Confirm Password</Label>
|
||||
<Input type="password" name="passwordConfirmation" />
|
||||
<Button type="submit">Next Step</Button>
|
||||
</form>
|
||||
</FormStep>
|
||||
<FormStep title="Demographics"
|
||||
description={
|
||||
<p>
|
||||
Your responses to these questions will be kept private.
|
||||
Why do we ask for this information <a onClick={this.handle}>?</a>
|
||||
</p>}
|
||||
key="step2">
|
||||
<form>
|
||||
<Label htmlFor="month">Birth Month</Label>
|
||||
<Select name="month">
|
||||
{months.map(function (name, id) {
|
||||
return (<option value={id+1} key={id}>{name}</option>);
|
||||
})}
|
||||
</Select>
|
||||
<Label htmlFor="year">Birth Yeah</Label>
|
||||
<Select name="year">
|
||||
{Array.apply(null, Array(100)).map(function (v, id) {
|
||||
return (<option value={2016-id} key={id}>{2016-id}</option>);
|
||||
})}
|
||||
</Select>
|
||||
<Label>Gender</Label>
|
||||
<Input type="radio" name="gender" id="genderFemale" value="female" />
|
||||
<Label htmlFor="genderFemale">Female</Label>
|
||||
<Input type="radio" name="gender" id="genderMale" value="male" />
|
||||
<Label htmlFor="genderMale">Male</Label>
|
||||
<Input type="radio" name="gender" value="genderOther" />
|
||||
<Input name="genderOther" type="text" />
|
||||
<Label htmlFor="country">Country</Label>
|
||||
<Select name="country">
|
||||
{Object.keys(countries).map(function (code, id) {
|
||||
return (<option value={code} key={id}>{countries[code]}</option>);
|
||||
})}
|
||||
</Select>
|
||||
<Button type="submit">Next Step</Button>
|
||||
</form>
|
||||
</FormStep>
|
||||
<FormStep title="First & Last Name"
|
||||
description={
|
||||
<p>
|
||||
Your responses to these questions will be kept private.
|
||||
Why do we ask for this information <a onClick={this.handle}>?</a>
|
||||
</p>}
|
||||
key="step3">
|
||||
<form>
|
||||
<Label htmlFor="first">First Name</Label>
|
||||
<Input type="text" name="first" />
|
||||
<Label htmlFor="last">Last Name</Label>
|
||||
<Input type="text" name="last" />
|
||||
<Button type="submit">Next Step</Button>
|
||||
</form>
|
||||
</FormStep>
|
||||
<FormStep title="Phone Number"
|
||||
description={
|
||||
<p>
|
||||
Your responses to these questions will be kept private.
|
||||
Why do we ask for this information <a onClick={this.handle}>?</a>
|
||||
</p>}
|
||||
key="step4">
|
||||
<form>
|
||||
<Label htmlFor="phone">Phone Number</Label>
|
||||
<Input type="tel" name="phone" />
|
||||
<Input type="checkbox" name="phoneConsent" />
|
||||
<Label htmlFor="phoneConsent">
|
||||
Yes, I consent to lorem ipsum dolor sit amet,
|
||||
consectetur adipiscing elit.
|
||||
</Label>
|
||||
<Button type="submit">Next Step</Button>
|
||||
</form>
|
||||
</FormStep>
|
||||
<FormStep title="Organization"
|
||||
description={
|
||||
<p>
|
||||
Your responses to these questions will be kept private.
|
||||
Why do we ask for this information <a onClick={this.handle}>?</a>
|
||||
</p>}
|
||||
key="step5">
|
||||
<form>
|
||||
<Label htmlFor="organization">Organization</Label>
|
||||
<Input type="text" name="organization" />
|
||||
<Label htmlFor="title">Title / Position</Label>
|
||||
<Input type="text" name="title" />
|
||||
<Label>Type of Organization</Label>
|
||||
{['Elementary School', 'Middle School',
|
||||
'High School', 'University / College',
|
||||
'Museum', 'Library', 'Camp'].map(function (type, id) {
|
||||
var typeId = 'organizationType' + id;
|
||||
return [
|
||||
<Input type="checkbox"
|
||||
name="organizationType"
|
||||
id={typeId}
|
||||
value={type} />,
|
||||
<Label htmlFor={typeId}>{type}</Label>
|
||||
];
|
||||
})}
|
||||
<Input type="checkbox" name="organizationType" value="other" />
|
||||
<Input type="text" name="organizationTypeOther" />
|
||||
<Label htmlFor="website">Website URL (not required)</Label>
|
||||
<Input type="url" name="website" />
|
||||
<Button type="submit">Next Step</Button>
|
||||
</form>
|
||||
</FormStep>
|
||||
<FormStep title="Address"
|
||||
description={
|
||||
<p>
|
||||
Your responses to these questions will be kept private.
|
||||
Why do we ask for this information <a onClick={this.handle}>?</a>
|
||||
</p>}
|
||||
key="step6">
|
||||
<form>
|
||||
<Label htmlFor="addressCountry">Country</Label>
|
||||
<Select name="addressCountry">
|
||||
{Object.keys(countries).map(function (code, id) {
|
||||
return (<option value={code} key={id}>{countries[code]}</option>);
|
||||
})}
|
||||
</Select>
|
||||
<Label htmlFor="addressLine1">Address Line 1</Label>
|
||||
<Input type="text" name="addressLine1" />
|
||||
<Label htmlFor="addressLine2">Address Line 2</Label>
|
||||
<Input type="text" name="addressLine2" />
|
||||
<Label htmlFor="addressCity">City</Label>
|
||||
<Input type="text" name="addressCity" />
|
||||
<Label htmlFor="addressZip">Zip Code</Label>
|
||||
<Input type="text" name="addressZip" />
|
||||
<Label htmlFor="addressState">State / Province</Label>
|
||||
<Select name="addressState">
|
||||
{['every','state','in','the','world'].map(function (name, id) {
|
||||
return <option value={name} key={id}>{name}</option>;
|
||||
})}
|
||||
</Select>
|
||||
<Button type="submit">Next Step</Button>
|
||||
</form>
|
||||
</FormStep>
|
||||
<FormStep title="How do you use Scratch?"
|
||||
description={
|
||||
<p>
|
||||
Tell us a little how you plan to use Scratch.
|
||||
Why do we ask for this information <a onClick={this.handle}>?</a>
|
||||
</p>}
|
||||
key="step7">
|
||||
<form>
|
||||
<Label htmlFor="useScratch">How do you use Scratch?</Label>
|
||||
<TextArea name="useScratch" />
|
||||
<Button type="submit">Next Step</Button>
|
||||
</form>
|
||||
</FormStep>
|
||||
<FormStep title="Email Address"
|
||||
description={
|
||||
<p>
|
||||
We will send you a <strong>confirmation email</strong> that will
|
||||
allow you to access your Scratch Teacher Account.
|
||||
</p>}
|
||||
key="step8">
|
||||
<form>
|
||||
<Label htmlFor="email">Email</Label>
|
||||
<Input type="text" name="email" />
|
||||
<Label htmlFor="confirmEmail">Confirm Email</Label>
|
||||
<Input type="text" name="confirmEmail" />
|
||||
<Button type="submit">Next Step</Button>
|
||||
</form>
|
||||
</FormStep>
|
||||
<FormStep title="Almost Done"
|
||||
description={
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet
|
||||
</p>}
|
||||
key="step8">
|
||||
<div className="confirm">
|
||||
<h2>Confirm Your Email</h2>
|
||||
<p>
|
||||
Click the link in the confirmation email that we
|
||||
sent to the following address:<br />
|
||||
<strong>{this.state.email}</strong>
|
||||
</p>
|
||||
<div className="box-footer">
|
||||
<a onClick="">Wrong email?</a>
|
||||
<a onClick="">Having trouble?</a>
|
||||
</div>
|
||||
</div>
|
||||
<div className="wait">
|
||||
<h2>Wait for Approval</h2>
|
||||
<p>
|
||||
Your information is being reviewed. Please be
|
||||
patient, the approval process can take up to 24hrs.
|
||||
</p>
|
||||
</div>
|
||||
</FormStep>
|
||||
step={this.state.step}>
|
||||
<UsernameStep onNextStep={this.advanceStep} />
|
||||
<DemographicsStep onNextStep={this.advanceStep} />
|
||||
<NameStep onNextStep={this.advanceStep} />
|
||||
<PhoneNumberStep onNextStep={this.advanceStep} />
|
||||
<OrganizationStep onNextStep={this.advanceStep} />
|
||||
<AddressStep onNextStep={this.advanceStep} />
|
||||
<UseScratchStep onNextStep={this.advanceStep} />
|
||||
<EmailStep onNextStep={this.advanceStep} />
|
||||
<LastStep />
|
||||
</FormSet>
|
||||
</div>
|
||||
);
|
||||
|
|
Loading…
Reference in a new issue