var React = require('react'); var api = require('../../lib/api'); var countryData = require('../../lib/country-data'); var intl = require('../../lib/intl.jsx'); var log = require('../../lib/log'); var smartyStreets = require('../../lib/smarty-streets'); var Avatar = require('../../components/avatar/avatar.jsx'); var Button = require('../../components/forms/button.jsx'); var Card = require('../../components/card/card.jsx'); var CharCount = require('../../components/forms/charcount.jsx'); var Checkbox = require('../../components/forms/checkbox.jsx'); var CheckboxGroup = require('../../components/forms/checkbox-group.jsx'); var Form = require('../../components/forms/form.jsx'); var GeneralError = require('../../components/forms/general-error.jsx'); var Input = require('../../components/forms/input.jsx'); var PhoneInput = require('../../components/forms/phone-input.jsx'); var RadioGroup = require('../../components/forms/radio-group.jsx'); var Select = require('../../components/forms/select.jsx'); var Slide = require('../../components/slide/slide.jsx'); var Spinner = require('../../components/spinner/spinner.jsx'); var StepNavigation = require('../../components/stepnavigation/stepnavigation.jsx'); var TextArea = require('../../components/forms/textarea.jsx'); var Tooltip = require('../../components/tooltip/tooltip.jsx'); require('./steps.scss'); var DEFAULT_COUNTRY = 'us'; /** * Return a list of options to give to frc select * @param {Object} intl react-intl, used to localize strings * @param {String} defaultCountry optional string of default country to put at top of list * @return {Object} ordered set of county options formatted for frc select */ var getCountryOptions = function (intl, defaultCountry) { var options = countryData.countryOptions.concat({ label: intl.formatMessage({id: 'registration.selectCountry'}), disabled: true, selected: true }); if (typeof defaultCountry !== 'undefined') { return options.sort(function (a, b) { if (a.disabled) return -1; if (b.disabled) return 1; if (a.value === defaultCountry) return -1; if (b.value === defaultCountry) return 1; return 0; }.bind(this)); } return options; }; var NextStepButton = React.createClass({ getDefaultProps: function () { return { waiting: false, text: 'Next Step' }; }, render: function () { return ( ); } }); module.exports = { UsernameStep: intl.injectIntl(React.createClass({ getDefaultProps: function () { return { showPassword: false, waiting: false }; }, getInitialState: function () { return { showPassword: this.props.showPassword, waiting: false, validUsername: '' }; }, onChangeShowPassword: function (field, value) { this.setState({showPassword: value}); }, validateUsername: function (username, callback) { callback = callback || function () {}; if (!username) { this.refs.form.refs.formsy.updateInputsWithError({ 'user.username': formatMessage({id: 'teacherRegistration.validationRequired'}) }); return callback(false); } api({ host: '', uri: '/accounts/check_username/' + username + '/' }, function (err, body, res) { var formatMessage = this.props.intl.formatMessage; if (err || res.statusCode !== 200) { err = err || formatMessage({id: 'general.error'}); this.refs.form.refs.formsy.updateInputsWithError({all: err}); return callback(false); } body = body[0]; switch (body.msg) { case 'valid username': this.setState({ validUsername: 'pass' }); return callback(true); case 'username exists': this.refs.form.refs.formsy.updateInputsWithError({ 'user.username': formatMessage({id: 'registration.validationUsernameExists'}) }); return callback(false); case 'bad username': this.refs.form.refs.formsy.updateInputsWithError({ 'user.username': formatMessage({id: 'registration.validationUsernameVulgar'}) }); return callback(false); case 'invalid username': default: this.refs.form.refs.formsy.updateInputsWithError({ 'user.username': formatMessage({id: 'registration.validationUsernameInvalid'}) }); return callback(false); } }.bind(this)); }, onUsernameBlur: function (event) { this.validateUsername(event.currentTarget.value); }, onValidSubmit: function (formData) { this.setState({waiting: true}); this.validateUsername(formData.user.username, function (isValid) { this.setState({waiting: false}); if (isValid) return this.props.onNextStep(formData); }.bind(this)); }, render: function () { var formatMessage = this.props.intl.formatMessage; return (

{this.props.title ? ( this.props.title ) : ( )}

{this.props.description ? ( this.props.description ) : ( )} {this.props.tooltip ? ( ) : ( null )}

{formatMessage({id: 'registration.createUsername'})} {this.props.usernameHelp ? (

{this.props.usernameHelp}

):( null )}
} />
); } })), ChoosePasswordStep: intl.injectIntl(React.createClass({ getDefaultProps: function () { return { username: null, showPassword: false, waiting: false }; }, getInitialState: function () { return { showPassword: this.props.showPassword }; }, onChangeShowPassword: function (field, value) { this.setState({showPassword: value}); }, render: function () { var formatMessage = this.props.intl.formatMessage; return (

{formatMessage({id: 'registration.choosePasswordStepTitle'})}

} />
); } })), DemographicsStep: intl.injectIntl(React.createClass({ getDefaultProps: function () { return { waiting: false, description: null }; }, getInitialState: function () { return {otherDisabled: true}; }, getMonthOptions: function () { return [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ].map(function (label, id) { return { value: id + 1, label: this.props.intl.formatMessage({id: 'general.month' + label})}; }.bind(this)); }, getYearOptions: function () { return Array.apply(null, Array(100)).map(function (v, id) { var year = 2016 - id; return {value: year, label: year}; }); }, onChooseGender: function (name, gender) { this.setState({otherDisabled: gender !== 'other'}); }, render: function () { var formatMessage = this.props.intl.formatMessage; return (

{this.props.description ? this.props.description : }

} />
); } })), PhoneNumberStep: intl.injectIntl(React.createClass({ getDefaultProps: function () { return { defaultCountry: DEFAULT_COUNTRY, waiting: false }; }, onValidSubmit: function (formData, reset, invalidate) { if (!formData.phone || formData.phone.national_number === '+') { return invalidate({ 'phone': this.props.intl.formatMessage({id: 'teacherRegistration.validationRequired'}) }); } return this.props.onNextStep(formData); }, render: function () { var formatMessage = this.props.intl.formatMessage; return (

} />
); } })), OrganizationStep: intl.injectIntl(React.createClass({ getInitialState: function () { return { otherDisabled: true }; }, getDefaultProps: function () { return { waiting: false }; }, organizationL10nStems: [ 'orgChoiceElementarySchool', 'orgChoiceMiddleSchool', 'orgChoiceHighSchool', 'orgChoiceUniversity', 'orgChoiceAfterschool', 'orgChoiceMuseum', 'orgChoiceLibrary', 'orgChoiceCamp', 'orgChoiceOther' ], getOrganizationOptions: function () { return this.organizationL10nStems.map(function (choice, id) { return { value: id, label: this.props.intl.formatMessage({ id: 'teacherRegistration.' + choice }) }; }.bind(this)); }, onChooseOrganization: function (name, values) { this.setState({otherDisabled: values.indexOf(this.organizationL10nStems.indexOf('orgChoiceOther')) === -1}); }, render: function () { var formatMessage = this.props.intl.formatMessage; return (

} />
); } })), AddressStep: intl.injectIntl(React.createClass({ getDefaultProps: function () { return { defaultCountry: DEFAULT_COUNTRY, waiting: false }; }, getInitialState: function () { return { countryChoice: this.props.defaultCountry, waiting: false }; }, onChangeCountry: function (field, choice) { this.setState({countryChoice: choice}); }, onValidSubmit: function (formData, reset, invalidate) { if (formData.address.country !== 'us') { return this.props.onNextStep(formData); } this.setState({waiting: true}); var address = { street: formData.address.line1, secondary: formData.address.line2 || '', city: formData.address.city, state: formData.address.state, zipcode: formData.address.zip }; smartyStreets(address, function (err, res) { this.setState({waiting: false}); if (err) { // We don't want to prevent registration because // address validation isn't working. Log it and // move on. log.error(err); return this.props.onNextStep(formData); } if (res && res.length > 0) { return this.props.onNextStep(formData); } else { return invalidate({ 'all': this.props.intl.formatMessage({id: 'teacherRegistration.addressValidationError'}) }); } }.bind(this)); }, render: function () { var formatMessage = this.props.intl.formatMessage; var stateOptions = countryData.subdivisionOptions[this.state.countryChoice]; stateOptions = [{}].concat(stateOptions); return (

{stateOptions.length > 2 ? } />
); } })), UseScratchStep: intl.injectIntl(React.createClass({ getDefaultProps: function () { return { waiting: false, maxCharacters: 300 }; }, getInitialState: function () { return { characterCount: 0 }; }, handleTyping: function (name, value) { this.setState({ characterCount: value.length }); }, render: function () { var formatMessage = this.props.intl.formatMessage; var textAreaClass = (this.state.characterCount > this.props.maxCharacters) ? 'fail' : ''; return (