Created
November 26, 2019 13:48
-
-
Save MattBevis/30800ad37bfb6783977a5b9f2027064e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* eslint-disable no-unneeded-ternary */ | |
import React, { Component } from 'react'; | |
import propTypes from 'prop-types'; | |
import { withTheme } from 'styled-components'; | |
import { connect } from 'react-redux'; | |
import { Formik, ErrorMessage } from 'formik'; | |
import Wizard from '../../../components/Wizard'; | |
import { RegistrationContainer } from '../../../components/Containers'; | |
import Headings from '../../../components/Headings'; | |
import Input from '../../../components/Inputs/Text'; | |
import Header from '../../../components/Headers'; | |
import Button from '../../../components/Buttons'; | |
import Label from '../../../components/Inputs/Label'; | |
import Checkbox from '../../../components/Inputs/Checkboxes'; | |
import Notification from '../../../components/Notifications'; | |
import Link from '../../../components/Link'; | |
import { RegistrationAccountDetails } from '../../../utils/formValidation'; | |
import PasswordValidation from '../../../utils/passwordValidation'; | |
import { setHasVisitedAccountDetails } from '../../../redux/actions/registration/plan/hasVisited'; | |
import { setUserInformation } from '../../../redux/actions/registration/plan/settingAccountDetails'; | |
import EmailService from '../../../api/TheChecker-api'; | |
class AccountDetails extends Component { | |
constructor(props) { | |
super(props); | |
this.state = { | |
firstName: '', | |
lastName: '', | |
emailAddress: '', | |
mobileNumber: '', | |
password: '', | |
hasTickedMarketingPreference: false, | |
isShowingPassword: false, | |
emailError: {}, | |
isEmailValid: false | |
}; | |
} | |
componentDidMount() { | |
const { hasVisitedAccountDetails, user } = this.props; | |
if (hasVisitedAccountDetails) { | |
this.setState({ | |
firstName: user.firstName, | |
lastName: user.lastName, | |
emailAddress: user.emailAddress, | |
mobileNumber: user.mobileNumber, | |
password: user.password, | |
hasTickedMarketingPreference: user.hasTickedMarketingPreference | |
}); | |
} | |
} | |
handleScreenChange = () => { | |
const { goForward } = this.props; | |
goForward(); | |
}; | |
render() { | |
const { | |
firstName, | |
lastName, | |
emailAddress, | |
mobileNumber, | |
password, | |
hasTickedMarketingPreference, | |
isShowingPassword, | |
emailError, | |
isEmailValid | |
} = this.state; | |
const initalValue = { | |
firstName, | |
lastName, | |
emailAddress, | |
mobileNumber, | |
password, | |
hasTickedMarketingPreference | |
}; | |
return ( | |
<> | |
<Header type='Register' /> | |
<Wizard /> | |
<div | |
style={{ | |
borderBottom: '1px solid black', | |
display: 'flex', | |
padding: '1.5rem', | |
alignItems: 'center' | |
}} | |
> | |
<div style={{ marginRight: 'auto' }}> | |
<p style={{ margin: 0 }}>Been a member before ?</p> | |
</div> | |
<div> | |
<Button | |
background='lighterPrimary' | |
title='Next steps' | |
onClick={() => this.handleScreenChange()} | |
textAlign='left' | |
icon='ArrowUpRight' | |
hasBorder={false} | |
fullWidth | |
/> | |
</div> | |
</div> | |
{/* | |
Form Notes: | |
https://stackoverflow.com/questions/52834504/react-form-submission-canceled-because-the-form-is-not-connected | |
*/} | |
<Formik | |
initialValues={{ ...initalValue }} | |
validationSchema={RegistrationAccountDetails} | |
onSubmit={(values) => { | |
if (isEmailValid) { | |
const { dispatch } = this.props; | |
dispatch(setHasVisitedAccountDetails()); | |
dispatch(setUserInformation(values)); | |
this.handleScreenChange(); | |
return true; | |
} | |
return false; | |
}} | |
> | |
{({ | |
values, | |
touched, | |
submitCount, | |
errors, | |
handleBlur, | |
handleSubmit, | |
isSubmitting, | |
setFieldValue, | |
setFieldTouched | |
}) => ( | |
<RegistrationContainer> | |
<Headings | |
type='h2' | |
size='1.3rem' | |
height='2' | |
weight='bolder' | |
text='Account details' | |
/> | |
<form onSubmit={handleSubmit}> | |
<div> | |
<Label htmlFor='emailAddress' name='Email Address *' /> | |
<ErrorMessage | |
name='emailAddress' | |
render={(msg) => ( | |
<Notification type='error' message={msg} /> | |
)} | |
/> | |
{!isEmailValid && emailError.isValid === false ? ( | |
<Notification type='error' message={emailError.message} /> | |
) : null} | |
<Input | |
id='emailAddress' | |
placeholder='' | |
background='lighterSecondary' | |
onChange={(e) => { | |
setFieldValue('emailAddress', e.target.value); | |
}} | |
defaultValue={values.emailAddress} | |
name='emailAddress' | |
onBlur={async (e) => { | |
// Manually set the email field to touched | |
setFieldTouched('emailAddress', true); | |
// Validate email | |
const response = await EmailService.validateEmail( | |
e.target.value | |
); | |
if (response.isValid === false) { | |
this.setState({ | |
isEmailValid: false, | |
emailError: response | |
}); | |
} else { | |
this.setState({ | |
isEmailValid: true, | |
emailError: response | |
}); | |
} | |
}} | |
danger={ | |
errors.emailAddress && | |
(touched.emailAddress || submitCount > 0) | |
? true | |
: false | |
} | |
/> | |
</div> | |
<div> | |
<Label htmlFor='firstName' name='First Name *' /> | |
<ErrorMessage | |
name='firstName' | |
render={(msg) => ( | |
<Notification type='error' message={msg} /> | |
)} | |
/> | |
<Input | |
id='firstName' | |
placeholder='' | |
background='lighterSecondary' | |
onChange={(e) => setFieldValue('firstName', e.target.value)} | |
defaultValue={values.firstName} | |
name='firstName' | |
onBlur={handleBlur} | |
danger={ | |
errors.firstName && (touched.firstName || submitCount > 0) | |
? true | |
: false | |
} | |
/> | |
</div> | |
<div> | |
<Label htmlFor='lastName' name='Last Name *' /> | |
<ErrorMessage | |
name='lastName' | |
render={(msg) => ( | |
<Notification type='error' message={msg} /> | |
)} | |
/> | |
<Input | |
id='lastName' | |
placeholder='' | |
background='lighterSecondary' | |
onChange={(e) => setFieldValue('lastName', e.target.value)} | |
defaultValue={values.lastName} | |
name='lastName' | |
onBlur={handleBlur} | |
danger={ | |
errors.lastName && (touched.lastName || submitCount > 0) | |
? true | |
: false | |
} | |
/> | |
</div> | |
<div> | |
<Label htmlFor='mobileNumber' name='Mobile Number *' /> | |
<ErrorMessage | |
name='mobileNumber' | |
render={(msg) => ( | |
<Notification type='error' message={msg} /> | |
)} | |
/> | |
<Input | |
id='mobileNumber' | |
placeholder='' | |
background='lighterSecondary' | |
onChange={(e) => | |
setFieldValue('mobileNumber', e.target.value) | |
} | |
defaultValue={values.mobileNumber} | |
name='mobileNumber' | |
onBlur={handleBlur} | |
danger={ | |
errors.mobileNumber && | |
(touched.mobileNumber || submitCount > 0) | |
? true | |
: false | |
} | |
/> | |
</div> | |
<div> | |
<Label htmlFor='password' name='Password *' /> | |
<ErrorMessage | |
name='password' | |
render={(msg) => ( | |
<Notification type='error' message={msg} /> | |
)} | |
/> | |
<Input | |
id='password' | |
placeholder='' | |
onChange={(e) => setFieldValue('password', e.target.value)} | |
defaultValue={values.password} | |
inputGroupType='withIcon' | |
icon={isShowingPassword ? 'EyeClosed' : 'Eye'} | |
background='lightGrey' | |
name='password' | |
type={isShowingPassword ? 'text' : 'password'} | |
onBlur={handleBlur} | |
danger={ | |
errors.password && (touched.password || submitCount > 0) | |
? true | |
: false | |
} | |
onClick={() => { | |
this.setState({ | |
isShowingPassword: !isShowingPassword | |
}); | |
}} | |
/> | |
<div | |
style={{ | |
display: 'flex', | |
alignItems: 'center', | |
color: 'grey', | |
fontSize: '1rem' | |
}} | |
> | |
<div> | |
<p> | |
Strength:{' '} | |
{values.password.length <= 0 | |
? 'No password' | |
: PasswordValidation(values.password)} | |
</p> | |
</div> | |
</div> | |
</div> | |
<div style={{ marginTop: '1rem' }}> | |
<Headings | |
type='h3' | |
size='1.2rem' | |
height='1' | |
weight='bolder' | |
text='Marketing Preferences' | |
/> | |
<p> | |
To help you on your fitness journey, we'd love to send you | |
tailored offers and information via Email, SMS, Push and | |
Post. <Link text='See our privacy policy' /> | |
</p> | |
</div> | |
<div> | |
<Checkbox | |
name='offers' | |
text='Send me offers and updates' | |
value={values.hasTickedMarketingPreference} | |
checked={values.hasTickedMarketingPreference} | |
onChange={() => | |
setFieldValue( | |
'hasTickedMarketingPreference', | |
!values.hasTickedMarketingPreference | |
) | |
} | |
/> | |
</div> | |
<div style={{ width: '100%', marginTop: '1rem' }}> | |
<Button | |
background='lighterPrimary' | |
title='Next steps' | |
textAlign='left' | |
icon='ArrowUpRight' | |
hasBorder={false} | |
buttonType='submit' | |
isDisabled={isSubmitting} | |
isLoading={isSubmitting} | |
/> | |
</div> | |
</form> | |
</RegistrationContainer> | |
)} | |
</Formik> | |
</> | |
); | |
} | |
} | |
AccountDetails.defaultProps = {}; | |
AccountDetails.propTypes = { | |
goForward: propTypes.func.isRequired, | |
hasVisitedAccountDetails: propTypes.bool.isRequired, | |
user: propTypes.shape({ | |
firstName: propTypes.string.isRequired, | |
lastName: propTypes.string.isRequired, | |
emailAddress: propTypes.string.isRequired, | |
password: propTypes.string.isRequired, | |
hasTickedMarketingPreference: propTypes.bool.isRequired, | |
mobileNumber: propTypes.string.isRequired | |
}).isRequired, | |
dispatch: propTypes.func.isRequired | |
}; | |
const mapStateToProps = (state) => ({ | |
user: state.registration.user, | |
hasVisitedAccountDetails: state.registration.hasVisitedAccountDetails | |
}); | |
export default withTheme(connect(mapStateToProps)(AccountDetails)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment