Move registration step to main component

Add a placeholder error step
This commit is contained in:
Ray Schamp 2016-06-17 12:22:11 -04:00
parent 8646bd84b3
commit 078463ac25
2 changed files with 124 additions and 72 deletions

View file

@ -43,6 +43,11 @@ var NextStepButton = React.createClass({
module.exports = {
UsernameStep: intl.injectIntl(React.createClass({
getDefaultProps: function () {
return {
waiting: false
};
},
getInitialState: function () {
return {
showPassword: false,
@ -136,7 +141,7 @@ module.exports = {
onChange={this.onChangeShowPassword}
help={null}
name="showPassword" />
<NextStepButton waiting={this.state.waiting}
<NextStepButton waiting={this.props.waiting || this.state.waiting}
text={<intl.FormattedMessage id="teacherRegistration.nextStep" />} />
</Form>
</Card>
@ -147,7 +152,10 @@ module.exports = {
})),
DemographicsStep: intl.injectIntl(React.createClass({
getDefaultProps: function () {
return {defaultCountry: DEFAULT_COUNTRY};
return {
defaultCountry: DEFAULT_COUNTRY,
waiting: false
};
},
getInitialState: function () {
return {otherDisabled: true};
@ -212,7 +220,7 @@ module.exports = {
<Checkbox className="demographics-checkbox-is-robot"
label="I'm a robot!"
name="user.isRobot" />
<NextStepButton waiting={false}
<NextStepButton waiting={this.props.waiting}
text={<intl.FormattedMessage id="teacherRegistration.nextStep" />} />
</Form>
</Card>
@ -222,6 +230,11 @@ module.exports = {
}
})),
NameStep: intl.injectIntl(React.createClass({
getDefaultProps: function () {
return {
waiting: false
};
},
render: function () {
var formatMessage = this.props.intl.formatMessage;
return (
@ -242,7 +255,7 @@ module.exports = {
type="text"
name="user.name.last"
required />
<NextStepButton waiting={false}
<NextStepButton waiting={this.props.waiting}
text={<intl.FormattedMessage id="teacherRegistration.nextStep" />} />
</Form>
</Card>
@ -253,7 +266,10 @@ module.exports = {
})),
PhoneNumberStep: intl.injectIntl(React.createClass({
getDefaultProps: function () {
return {defaultCountry: DEFAULT_COUNTRY};
return {
defaultCountry: DEFAULT_COUNTRY,
waiting: false
};
},
render: function () {
var formatMessage = this.props.intl.formatMessage;
@ -280,7 +296,7 @@ module.exports = {
validationErrors={{
isFalse: formatMessage({id: 'teacherRegistration.validationPhoneConsent'})
}} />
<NextStepButton waiting={false}
<NextStepButton waiting={this.props.waiting}
text={<intl.FormattedMessage id="teacherRegistration.nextStep" />} />
</Form>
</Card>
@ -295,6 +311,11 @@ module.exports = {
otherDisabled: true
};
},
getDefaultProps: function () {
return {
waiting: false
};
},
organizationL10nStems: [
'orgChoiceElementarySchool',
'orgChoiceMiddleSchool',
@ -353,7 +374,7 @@ module.exports = {
<Input label={formatMessage({id: 'general.website'})}
type="url"
name="organization.url" />
<NextStepButton waiting={false}
<NextStepButton waiting={this.props.waiting}
text={<intl.FormattedMessage id="teacherRegistration.nextStep" />} />
</Form>
</Card>
@ -364,7 +385,10 @@ module.exports = {
})),
AddressStep: intl.injectIntl(React.createClass({
getDefaultProps: function () {
return {defaultCountry: DEFAULT_COUNTRY};
return {
defaultCountry: DEFAULT_COUNTRY,
waiting: false
};
},
getInitialState: function () {
return {
@ -460,7 +484,7 @@ module.exports = {
type="text"
name="address.zip"
required />
<NextStepButton waiting={this.state.waiting}
<NextStepButton waiting={this.props.waiting || this.state.waiting}
text={<intl.FormattedMessage id="teacherRegistration.nextStep" />} />
</Form>
</Card>
@ -470,6 +494,11 @@ module.exports = {
}
})),
UseScratchStep: intl.injectIntl(React.createClass({
getDefaultProps: function () {
return {
waiting: false
};
},
render: function () {
var formatMessage = this.props.intl.formatMessage;
return (
@ -485,7 +514,7 @@ module.exports = {
<TextArea label={formatMessage({id: 'teacherRegistration.howUseScratch'})}
name="useScratch"
required />
<NextStepButton waiting={false}
<NextStepButton waiting={this.props.waiting}
text={<intl.FormattedMessage id="teacherRegistration.nextStep" />} />
</Form>
</Card>
@ -495,51 +524,10 @@ module.exports = {
}
})),
EmailStep: intl.injectIntl(React.createClass({
getInitialState: function () {
return {waiting: false};
},
onValidSubmit: function (formData, reset, invalidate) {
this.setState({waiting: true});
api({
host: '',
uri: '/classes/register_educator/',
method: 'post',
useCsrf: true,
formData: {
username: this.props.formData.user.username,
email: formData.user.email,
password: this.props.formData.user.password,
birth_month: this.props.formData.user.birth.month,
birth_year: this.props.formData.user.birth.year,
gender: (
this.props.formData.user.gender === 'other' ?
this.props.formData.user.genderOther :
this.props.formData.user.gender
),
country: this.props.formData.user.country,
is_robot: this.props.formData.user.isRobot,
first_name: this.props.formData.user.name.first,
last_name: this.props.formData.user.name.last,
phone_number: this.props.formData.phone.national_number,
organization_name: this.props.formData.organization.name,
organization_title: this.props.formData.organization.title,
organization_type: this.props.formData.organization.type,
organization_other: this.props.formData.organization.other,
organization_url: this.props.formData.organization.url,
address_country: this.props.formData.address.country,
address_line1: this.props.formData.address.line1,
address_line2: this.props.formData.address.line2,
address_city: this.props.formData.address.city,
address_state: this.props.formData.address.state,
address_zip: this.props.formData.address.zip,
how_use_scratch: this.props.formData.useScratch
}
}, function (err, res) {
this.setState({waiting: false});
if (err) return invalidate({all: err});
if (res[0].success) return this.props.onNextStep(formData);
invalidate({all: res[0].msg});
}.bind(this));
getDefaultProps: function () {
return {
waiting: false
};
},
render: function () {
var formatMessage = this.props.intl.formatMessage;
@ -552,7 +540,7 @@ module.exports = {
<intl.FormattedMessage id="teacherRegistration.emailStepDescription" />
</p>
<Card>
<Form onValidSubmit={this.onValidSubmit}>
<Form onValidSubmit={this.props.onNextStep}>
<Input label={formatMessage({id: 'general.emailAddress'})}
type="text"
name="user.email"
@ -567,7 +555,7 @@ module.exports = {
equalsField: formatMessage({id: 'general.validationEmailMatch'})
}}
required />
<NextStepButton waiting={this.state.waiting}
<NextStepButton waiting={this.props.waiting}
text={<intl.FormattedMessage id="teacherRegistration.nextStep" />} />
</Form>
</Card>
@ -608,5 +596,20 @@ module.exports = {
</Slide>
);
}
})),
RegistrationError: intl.injectIntl(React.createClass({
render: function () {
return (
<Slide>
<h1>Something went wrong</h1>
<Card>
<h2>There was an error while processing your registration</h2>
<p>
{this.props.registrationError}
</p>
</Card>
</Slide>
);
}
}))
};

View file

@ -2,6 +2,8 @@ var defaults = require('lodash.defaultsdeep');
var React = require('react');
var render = require('../../lib/render.jsx');
var api = require('../../lib/api');
var Deck = require('../../components/deck/deck.jsx');
var Progression = require('../../components/progression/progression.jsx');
var Steps = require('./steps.jsx');
@ -13,13 +15,12 @@ var TeacherRegistration = React.createClass({
type: 'TeacherRegistration',
getInitialState: function () {
return {
formData: {},
registrationError: null,
step: 0,
formData: {}
waiting: false
};
},
setStep: function (step) {
this.setState({step: step});
},
advanceStep: function (formData) {
formData = formData || {};
this.setState({
@ -27,20 +28,68 @@ var TeacherRegistration = React.createClass({
formData: defaults({}, formData, this.state.formData)
});
},
register: function (formData) {
this.setState({waiting: true});
api({
host: '',
uri: '/classes/register_educator/',
method: 'post',
useCsrf: true,
formData: {
username: this.state.formData.user.username,
email: formData.user.email,
password: this.state.formData.user.password,
birth_month: this.state.formData.user.birth.month,
birth_year: this.state.formData.user.birth.year,
gender: (
this.state.formData.user.gender === 'other' ?
this.state.formData.user.genderOther :
this.state.formData.user.gender
),
country: this.state.formData.user.country,
is_robot: this.state.formData.user.isRobot,
first_name: this.state.formData.user.name.first,
last_name: this.state.formData.user.name.last,
phone_number: this.state.formData.phone.national_number,
organization_name: this.state.formData.organization.name,
organization_title: this.state.formData.organization.title,
organization_type: this.state.formData.organization.type,
organization_other: this.state.formData.organization.other,
organization_url: this.state.formData.organization.url,
address_country: this.state.formData.address.country,
address_line1: this.state.formData.address.line1,
address_line2: this.state.formData.address.line2,
address_city: this.state.formData.address.city,
address_state: this.state.formData.address.state,
address_zip: this.state.formData.address.zip,
how_use_scratch: this.state.formData.useScratch
}
}, function (err, res) {
this.setState({waiting: false});
if (err) return this.setState({registrationError: err});
if (res[0].success) return this.advanceStep(formData);
this.setState({registrationError: res[0].msg});
}.bind(this));
},
render: function () {
return (
<Deck className="teacher-registration">
<Progression step={this.state.step}>
<Steps.UsernameStep formData={this.state.formData} onNextStep={this.advanceStep} />
<Steps.DemographicsStep formData={this.state.formData} onNextStep={this.advanceStep} />
<Steps.NameStep formData={this.state.formData} onNextStep={this.advanceStep} />
<Steps.PhoneNumberStep formData={this.state.formData} onNextStep={this.advanceStep} />
<Steps.OrganizationStep formData={this.state.formData} onNextStep={this.advanceStep} />
<Steps.AddressStep formData={this.state.formData} onNextStep={this.advanceStep} />
<Steps.UseScratchStep formData={this.state.formData} onNextStep={this.advanceStep} />
<Steps.EmailStep formData={this.state.formData} onNextStep={this.advanceStep} />
<Steps.LastStep formData={this.state.formData} />
{this.state.registrationError ?
<Steps.RegistrationError {... this.state} />
:
<Progression {... this.state}>
<Steps.UsernameStep {... this.state} onNextStep={this.advanceStep} />
<Steps.DemographicsStep {... this.state} onNextStep={this.advanceStep} />
<Steps.NameStep {... this.state} onNextStep={this.advanceStep} />
<Steps.PhoneNumberStep {... this.state} onNextStep={this.advanceStep} />
<Steps.OrganizationStep {... this.state} onNextStep={this.advanceStep} />
<Steps.AddressStep {... this.state} onNextStep={this.advanceStep} />
<Steps.UseScratchStep {... this.state} onNextStep={this.advanceStep} />
<Steps.EmailStep {... this.state} onNextStep={this.register} />
<Steps.LastStep {... this.state} />
</Progression>
}
</Deck>
);
}