Skip to content

Instantly share code, notes, and snippets.

@MattBevis
Created November 26, 2019 13:48
Show Gist options
  • Save MattBevis/30800ad37bfb6783977a5b9f2027064e to your computer and use it in GitHub Desktop.
Save MattBevis/30800ad37bfb6783977a5b9f2027064e to your computer and use it in GitHub Desktop.
/* 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