ilp-core
Version:
ILP core module managing ledger abstraction
236 lines (200 loc) • 7.69 kB
JavaScript
import React, {Component, PropTypes} from 'react'
import {reduxForm} from 'redux-form'
import registerValidation from './RegisterValidation'
import Alert from 'react-bootstrap/lib/Alert'
import { successable } from 'decorators'
import Input from 'components/Input/Input'
import { loadCode } from 'redux/actions/invite'
import classNames from 'classnames/bind'
import styles from './RegisterForm.scss'
const cx = classNames.bind(styles)
// TODO async validation on username
({
form: 'register',
fields: ['username', 'email', 'password', 'inviteCode',
'name', 'phone', 'address1', 'address2', 'city',
'region', 'country', 'zip_code', 'fingerprint'],
validate: registerValidation
}, state => ({
invite: state.invite.invite,
config: state.auth.config
}), {loadCode})
()
export default class RegisterForm extends Component {
static propTypes = {
invite: PropTypes.object,
loadCode: PropTypes.func,
params: PropTypes.object,
config: PropTypes.object,
// Form
fields: PropTypes.object.isRequired,
invalid: PropTypes.bool.isRequired,
pristine: PropTypes.bool.isRequired,
submitting: PropTypes.bool.isRequired,
handleSubmit: PropTypes.func.isRequired,
register: PropTypes.func.isRequired,
// Successable
permSuccess: PropTypes.func,
success: PropTypes.bool,
permFail: PropTypes.func,
fail: PropTypes.any
}
state = {}
componentDidMount() {
// this.refs.fakeuser.style = {display: 'none'}
setTimeout(() => {
this.setState({hideFakes: true})
}, 1)
// Device fingerprint
if (this.props.config.antiFraud) {
let fingerprint = ""
fingerprint += navigator.plugins.length + ","
fingerprint += window.screen.availHeight + ","
fingerprint += window.screen.availWidth + ","
for(let i=0;i<navigator.plugins.length;i++) {
fingerprint += navigator.plugins[i].name + ","
}
fingerprint += navigator.language + "," + navigator.userLanguage + ","
fingerprint += new Date().getTimezoneOffset() + ","
fingerprint += navigator.userAgent
this.props.fields.fingerprint.onChange(fingerprint)
}
this.handleUrlInviteCode()
}
componentWillReceiveProps(nextProps) {
if (this.props.params !== nextProps.params) {
this.handleUrlInviteCode(nextProps)
}
}
handleUrlInviteCode = (props = this.props) => {
const inviteCode = props.params.inviteCode
if (!inviteCode) return
this.props.fields.inviteCode.onChange(inviteCode)
this.handleAddInviteCode(inviteCode)
}
handleAddInviteCodeClick = (e) => {
e.preventDefault()
this.setState({
...this.state,
showInviteInput: true
})
}
// TODO:UX Invite code async validation
handleAddInviteCode = (input) => {
const inviteCode = input.value !== undefined ? input.value : input
// redux-form onChange needs to happen first
// TODO try without a timeout
setTimeout(() => {
if (!this.props.fields.inviteCode.valid || !inviteCode) return
this.props.loadCode(inviteCode)
.then(code => {
if (!code) return
this.setState({
...this.state,
showInviteInput: false
})
})
}, 50)
}
register = (data) => {
return this.props.register(data)
.then(this.props.permSuccess)
.catch(this.props.permFail)
}
render() {
const { invite, handleSubmit, fail,
fields: { username, email, password, inviteCode, name, phone,
address1, address2, city, region, country, zip_code },
pristine, invalid, submitting, config } = this.props
const hideFakes = this.state && this.state.hideFakes
const { showInviteInput } = this.state
return (
<form onSubmit={handleSubmit(this.register)} autoComplete="off">
{fail && fail.id &&
<Alert bsStyle="danger">
{fail.id === 'UsernameTakenError' &&
<div>Username is already taken</div>}
{fail.id === 'EmailTakenError' &&
<div>Email is already taken</div>}
{fail.id === 'InvalidBodyError' &&
<div>{fail.message}</div>}
{fail.id === 'ServerError' &&
<div>Something went wrong</div>}
</Alert>}
<div>
{/* Hey chrome, can you please stop autofilling the register form? */}
{!hideFakes &&
<div className={cx('fakeInputs')}>
<input type="text" name="fakeusernameremembered" ref="fakeuser"/>
<input type="password" name="fakepasswordremembered" ref="fakepass" />
</div>}
<Input object={username} label="Username" size="lg" focus autoCapitalize="off" />
<Input object={email} label="Email" size="lg" autoCapitalize="off" />
<Input object={password} label="Password" size="lg" type="password" />
{config.antiFraud &&
<div>
<div className="row">
<div className="col-sm-6">
<Input object={name} label="Full Name" size="lg" />
</div>
<div className="col-sm-6">
<Input object={phone} label="Phone" size="lg" />
</div>
</div>
<div className="row">
<div className="col-sm-6">
<Input object={address1} label="Address 1" size="lg" />
</div>
<div className="col-sm-6">
<Input object={address2} label="Address 2" size="lg" />
</div>
</div>
<div className="row">
<div className="col-sm-6">
<Input object={city} label="City" size="lg" />
</div>
<div className="col-sm-6">
<Input object={region} label="Region" size="lg" />
</div>
</div>
<div className="row">
<div className="col-sm-6">
<Input object={country} label="Country" size="lg" />
</div>
<div className="col-sm-6">
<Input object={zip_code} label="Zip Code" size="lg" />
</div>
</div>
</div>}
{/* Invite code: Step 1 */}
{!showInviteInput && !invite.code &&
<a href="" className={cx('inviteLink')} onClick={this.handleAddInviteCodeClick}>Have an invite code?</a>}
{/* Invite code: Step 2 */}
{showInviteInput &&
<Input object={inviteCode} label="Invite Code" size="lg" focus
onChange={this.handleAddInviteCode} />}
{/* Invite code: Step 3 */}
{invite.code && !invite.claimed && !showInviteInput &&
<div className={cx('inviteCode', 'row')}>
<span className={cx('text', 'col-sm-9')}>Invite code has been added!</span>
{/* TODO:REFACTOR shouldn't use the global config */}
<span className={cx('balance', 'col-sm-3')}>
<span className={cx('label')}>Balance </span>
<span className={cx('number')}>
{config.currencySymbol}{invite.amount}
</span>
</span>
</div>}
{/* Invite code has already been claimed */}
{invite.claimed &&
<div className={cx('claimed')}>
Provided invite code has already been used. <a href="" onClick={this.handleAddInviteCodeClick}>Try another one</a>
</div>}
</div>
<button type="submit" className="btn btn-success btn-lg" disabled={pristine || invalid || submitting}>
{submitting ? ' Registering...' : ' Register'}
</button>
</form>
)
}
}