import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { FormattedMessage as Message } from 'react-intl'; import Helmet from 'react-helmet'; import { SlideMotion } from 'app/components/ui/motion'; import { ScrollIntoView } from 'app/components/ui/scroll'; import { Input, Button, Form, FormModel, FormError, } from 'app/components/ui/form'; import { BackButton } from 'app/components/profile/ProfileForm'; import styles from 'app/components/profile/profileForm.scss'; import helpLinks from 'app/components/auth/helpLinks.scss'; import Stepper from 'app/components/ui/stepper'; import changeEmail from './changeEmail.scss'; import messages from './ChangeEmail.intl.json'; const STEPS_TOTAL = 3; export default class ChangeEmail extends Component { static propTypes = { onChangeStep: PropTypes.func, lang: PropTypes.string.isRequired, email: PropTypes.string.isRequired, stepForms: PropTypes.arrayOf( (propValue, key, componentName, location, propFullName) => { if (propValue.length !== 3) { return new Error( `\`${propFullName}\` must be an array of 3 FormModel instances. Validation failed.`, ); } if (!(propValue[key] instanceof FormModel)) { return new Error( `Invalid prop \`${propFullName}\` supplied to \ \`${componentName}\`. Validation failed.`, ); } return null; }, ), onSubmit: PropTypes.func.isRequired, step: PropTypes.oneOf([0, 1, 2]), code: PropTypes.string, }; static get defaultProps() { return { stepForms: [new FormModel(), new FormModel(), new FormModel()], onChangeStep() {}, step: 0, }; } state = { activeStep: this.props.step, code: this.props.code || '', }; componentWillReceiveProps(nextProps) { this.setState({ activeStep: typeof nextProps.step === 'number' ? nextProps.step : this.state.activeStep, code: nextProps.code || '', }); } render() { const { activeStep } = this.state; const form = this.props.stepForms[activeStep]; return (
this.forceUpdate()} >
{pageTitle => (

{pageTitle}

)}

{activeStep > 0 ? : null} {this.renderStepForms()}
{this.isLastStep() ? null : ( )}
); } renderStepForms() { const { email } = this.props; const { activeStep, code } = this.state; const isCodeSpecified = !!this.props.code; return ( {new Array(STEPS_TOTAL).fill(0).map((_, step) => { const form = this.props.stepForms[step]; return this[`renderStep${step}`]({ email, code, isCodeSpecified, form, isActiveStep: step === activeStep, }); })} ); } renderStep0({ email, form }) { return (

{email}

); } renderStep1({ email, form, code, isCodeSpecified, isActiveStep }) { return (

{email}, }} />

); } renderStep2({ form, code, isCodeSpecified, isActiveStep }) { const { newEmail } = this.state; return (

{newEmail ? ( {newEmail}, }} />{' '} ) : null}

); } onStepMeasure(step) { return height => this.setState({ [`step${step}Height`]: height, }); } nextStep() { const { activeStep } = this.state; const nextStep = activeStep + 1; let newEmail = null; if (activeStep === 1) { newEmail = this.props.stepForms[1].value('email'); } if (nextStep < STEPS_TOTAL) { this.setState({ activeStep: nextStep, newEmail, }); this.props.onChangeStep(nextStep); } } isLastStep() { return this.state.activeStep + 1 === STEPS_TOTAL; } onSwitchStep = event => { event.preventDefault(); this.nextStep(); }; onCodeInput = event => { const { value } = event.target; this.setState({ code: this.props.code || value, }); }; onFormSubmit = () => { const { activeStep } = this.state; const form = this.props.stepForms[activeStep]; const promise = this.props.onSubmit(activeStep, form); if (!promise || !promise.then) { throw new Error('Expecting promise from onSubmit'); } promise.then( () => this.nextStep(), resp => { if (resp.errors) { form.setErrors(resp.errors); this.forceUpdate(); } else { return Promise.reject(resp); } }, ); }; }