UNPKG

appirio-tech-react-components-test10

Version:

Topcoder UI Kit library of components for our React apps.

347 lines (321 loc) 12.1 kB
import React, { Component } from 'react' import Formsy from 'formsy-react' import { find, orderBy, map, range } from 'lodash' import cn from 'classnames' import TextInput from '../Formsy/TextInput' import PhoneInput from '../Formsy/PhoneInput' import TimezoneInput from '../Formsy/TimezoneInput' import PasswordInput from '../Formsy/PasswordInput' import FormsySelect from '../Formsy/FormsySelect' import FormsyDropdowns from '../Formsy/FormsyDropdowns' import Checkbox from '../Formsy/Checkbox' import Loader from '../Loader/Loader' require('./style.scss') const timeOptions = map(range(1, 25), (v) => { const value = v+':00' return { value, label: value } }) class RegistrationScreen extends Component { constructor(props) { super(props) this.submit = this.submit.bind(this) this.enableButton = this.enableButton.bind(this) this.disableButton = this.disableButton.bind(this) this.reRender = this.reRender.bind(this) this.isValidForm = this.isValidForm.bind(this) this.onBusinessPhoneChange = this.onBusinessPhoneChange.bind(this) this.onCountryChange = this.onCountryChange.bind(this) this.hideCountrySelectAlert = this.hideCountrySelectAlert.bind(this) this.hideBusinessPhoneAlert = this.hideBusinessPhoneAlert.bind(this) this.state = { update: true, canSubmit: false, countryList: null, country: null, countrySelectDirty: false, businessPhoneDirty: false } props.vm.reRender = this.reRender } componentDidMount() { if (this.props.vm && this.props.vm.countries) { this.setState({ countryList: orderBy(this.props.vm.countries, ['name'], ['asc']).map(c => ({...c, label: c.name, value: c.name})) }) } } hideCountrySelectAlert() { this.setState({ countrySelectDirty: false }) } hideBusinessPhoneAlert () { this.setState({ businessPhoneDirty: false }) } reRender() { this.setState({ update: true }) } onBusinessPhoneChange({ country, externalChange }) { const { vm } = this.props const { country: previousSelectedCountry } = this.state if (!country || !country.code) { vm.phoneErrorMessage = 'Please enter a valid phone number.' this.reRender() } else { vm.phoneErrorMessage = null // When the business phone's country code changes, we should change the country selection also this.refs.countrySelect.setValue(country.name) this.setState({ update: true, country }) } const countryName = country && country.name const previousCountryName = previousSelectedCountry && previousSelectedCountry.name const countryCodeChanged = countryName && previousCountryName && countryName !== previousCountryName if (!externalChange && countryCodeChanged) { this.setState({ businessPhoneDirty: true }) } } onCountryChange(value) { // when the country selection is changed, we have to change the country code of business phone if (!this.state.country || this.state.country.name !== value) { const country = find(this.props.vm.countries, c => c.name === value) if (country) { this.setState({ country }) } } this.setState({ countrySelectDirty: true }) } enableButton() { this.setState({ canSubmit: true }) } disableButton() { this.setState({ canSubmit: false }) } isValidForm() { const { vm } = this.props const { canSubmit } = this.state return !vm.loading && canSubmit && !vm.usernameErrorMessage && !vm.emailErrorMessage && !vm.phoneErrorMessage && this.state.country } submit(form) { const { vm } = this.props vm.phone = form.phone vm.title = form.title vm.companyName = form.companyName vm.companySize = form.companySize vm.username = form.username vm.password = form.password vm.email = form.email vm.country = find(vm.countries, {name: form.country}) vm.firstName = form.firstName vm.lastName = form.lastName vm.agreeTerm = form.agreeTerm ? form.agreeTerm : false vm.timeZone = form.timeZone vm.workingHourStart = form.workingHour &&form.workingHour[0] vm.workingHourEnd = form.workingHour &&form.workingHour[1] vm.submit() this.setState({ businessPhoneDirty: false, countrySelectDirty: false }) } render() { const { vm } = this.props const { country, countryList, businessPhoneDirty, countrySelectDirty } = this.state const preFillFirstName = vm.firstName const preFillLastName = vm.lastName const preFillEmail = vm.email ? vm.email : null const renderRequired = (label) => <span><span>{label}</span>&nbsp;<sup className="requiredMarker">*</sup></span> const renderTimezoneOptions = ( timezoneOptions, filterFn ) => ( <FormsySelect required name="timeZone" filterOption={filterFn} options={timezoneOptions} wrapperClass={'input-container'} label={renderRequired('Local Timezone')} /> ) return ( <div className="RegistrationScreen flex column middle center"> <div className="container flex column middle center"> <div className="title">Let's start with introductions</div> <div className="sub-title">We're excited to meet you!</div> {vm.errorMessage && (<div className="server-error-message">{vm.errorMessage}</div>)} <Formsy.Form onValidSubmit={this.submit} onValid={this.enableButton} onInvalid={this.disableButton} className="form flex column middle center"> <TextInput wrapperClass={'input-container'} label={renderRequired('First Name')} type="text" name="firstName" validationError="Please enter your first name" required showCheckMark value={preFillFirstName} /> <TextInput wrapperClass={'input-container'} label={renderRequired('Last Name')} type="text" name="lastName" validationError="Please enter your last name" required showCheckMark value={preFillLastName} /> <TextInput wrapperClass={'input-container'} label={renderRequired('Business email')} type="email" name="email" value={preFillEmail} disabled={!!preFillEmail} validations="isEmail" validationError="Invalid business email" required forceErrorMessage={vm.emailErrorMessage} validator={vm.emailIsAvailable} showCheckMark /> <PhoneInput wrapperClass={cn('input-container', {'valid-phone': !vm.phoneErrorMessage})} label={renderRequired('Business phone (include the country code)')} type="phone" name="phone" value="" validationError="Invalid business phone" required listCountry={vm.countries} forceErrorMessage={vm.phoneErrorMessage} onChangeCountry={this.onBusinessPhoneChange} forceCountry={country && country.name} showCheckMark onOutsideClick={this.hideBusinessPhoneAlert} /> { businessPhoneDirty && <div className="warningText">Note: Changing the country code also updates your country selection</div> } <TextInput wrapperClass={'input-container'} label={renderRequired('Your title')} type="text" name="title" validationError="Please enter title" required showCheckMark /> <TextInput wrapperClass={'input-container'} label={renderRequired('Company name')} type="text" name="companyName" validationError="Please enter company name" required showCheckMark /> <FormsySelect ref="countrySelect" wrapperClass={'input-container country-input'} label={renderRequired('Country')} name="country" value="" options={countryList} onChange={this.onCountryChange} required placeholder="- Select country -" showDropdownIndicator setValueOnly onBlur={this.hideCountrySelectAlert} /> {countrySelectDirty && <div className="warningText">Note: Changing the country also updates the country code of business phone.</div> } <TimezoneInput render={renderTimezoneOptions} /> <FormsyDropdowns wrapperClass={'input-container'} name="workingHour" label={<span>normal Working Hours</span>} lProps={{ label:'Start Time', value:'', options: timeOptions, placeholder:'- Select Time -' }} rProps={{ label:'End Time', value:'', options: timeOptions, placeholder:'- Select Time -' }} /> <div className="space" /> <TextInput wrapperClass={'input-container'} label={renderRequired('Create a username (515 characters, AZ, 09)')} type="text" name="username" validationErrors={{ isDefaultRequiredValue: 'Please enter user name', minLength: '515 characters', maxLength: '515 characters', isAlphanumeric: 'Only contains letters or numbers' }} validations={{ minLength: 5, maxLength: 15, isAlphanumeric: true }} required forceErrorMessage={vm.usernameErrorMessage} validator={vm.usernameIsFree} showCheckMark /> { !vm.ssoUser && <PasswordInput wrapperClass={'input-container'} label={renderRequired('Create a password (864 characters, AZ, 09, . _ - ! ? allowed)')} name="password" validationErrors={{ isDefaultRequiredValue: 'Please enter password', minLength: '864 characters', maxLength: '864 characters', matchRegexp: 'The password must contain at least one number or symbol and one character' }} validations={{ minLength: 8, maxLength: 64, matchRegexp: /^((?=.*[a-z])|(?=.*[A-Z]))((?=.*[0-9])|(?=.*[!@#\$%\^&\*]))/ }} required showCheckMark /> } <Checkbox wrapperClass={'input-container'} label="I do not want to receive marketing communications from Topcoder." name="agreeTerm" /> <div className="space" /> <button type="submit" className="tc-btn tc-btn-sm tc-btn-primary flex middle center" disabled={vm.loading || !this.state.canSubmit || !this.state.country}>Continue</button> <div className="by-clicking-continue">By clicking “Continue” you agree to our <a href={vm.termsUrl}>Terms</a> and <a href={vm.privacyUrl}>Privacy Policy</a>. We are never going to sell your data or send you spam messages. Your email is going to be used for communication purposes only.</div> </Formsy.Form> </div> {vm.loading && (<Loader />)} </div> ) } } export default RegistrationScreen