Merge pull request #45 from edx/formik_and_yup_reset_form

apply formik to reset form
This commit is contained in:
Uzair Rasheed
2020-12-28 12:17:04 +05:00
committed by GitHub
5 changed files with 119 additions and 83 deletions

26
package-lock.json generated
View File

@@ -10502,6 +10502,27 @@
"integrity": "sha512-V8gLm+41I/8kguQ4/o1D3RIHRmhYFG4pnNyonvua+40rqcEmT4+V71yaZ3B457xbbgCsCfjSPi65u/W6vK1U5Q==",
"dev": true
},
"formik": {
"version": "2.2.6",
"resolved": "https://registry.npmjs.org/formik/-/formik-2.2.6.tgz",
"integrity": "sha512-Kxk2zQRafy56zhLmrzcbryUpMBvT0tal5IvcifK5+4YNGelKsnrODFJ0sZQRMQboblWNym4lAW3bt+tf2vApSA==",
"requires": {
"deepmerge": "^2.1.1",
"hoist-non-react-statics": "^3.3.0",
"lodash": "^4.17.14",
"lodash-es": "^4.17.14",
"react-fast-compare": "^2.0.1",
"tiny-warning": "^1.0.2",
"tslib": "^1.10.0"
},
"dependencies": {
"deepmerge": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz",
"integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA=="
}
}
},
"forwarded": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
@@ -18468,6 +18489,11 @@
"integrity": "sha512-HvPuUQnLp5H7TouGq3kzBeioJmXms1wHy9EGjz2OURWBp4qZO6AfGEcnxts1D/CbwPLRAgTMPCEgYhA3sEM4vw==",
"dev": true
},
"react-fast-compare": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-2.0.4.tgz",
"integrity": "sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw=="
},
"react-focus-lock": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/react-focus-lock/-/react-focus-lock-2.5.0.tgz",

View File

@@ -47,6 +47,7 @@
"classnames": "^2.2.6",
"extract-react-intl-messages": "^4.1.1",
"form-urlencoded": "^4.2.1",
"formik": "^2.2.6",
"lodash.camelcase": "^4.3.0",
"lodash.snakecase": "^4.1.1",
"prop-types": "15.7.2",

View File

@@ -1,10 +1,16 @@
import React, { useState } from 'react';
import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { Redirect } from 'react-router-dom';
import { Input, StatefulButton, ValidationFormGroup } from '@edx/paragon';
import {
Form,
Input,
StatefulButton,
ValidationFormGroup,
} from '@edx/paragon';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { Formik } from 'formik';
import messages from './messages';
import { forgotPassword } from './data/actions';
import { forgotPasswordResultSelector } from './data/selectors';
@@ -12,87 +18,89 @@ import RequestInProgressAlert from './RequestInProgressAlert';
import { LOGIN_PAGE } from '../data/constants';
import LoginHelpLinks from '../logistration/LoginHelpLinks';
const validateEmail = (e, values, setFieldValue) => {
const inputEmail = e.target.value;
const isEmailValid = inputEmail.match(/^([\w.%+-]+)@([\w-]+\.)+([\w]{2,})$/i);
setFieldValue('email', inputEmail);
setFieldValue('isEmailValid', isEmailValid !== null);
};
const ForgotPasswordPage = (props) => {
const { intl, status } = props;
const [emailInput, setEmailValue] = useState('');
const [emailValid, setEmailValidValue] = useState(true);
const validateEmail = (email) => {
const isEmailValid = email.match(/^([\w.%+-]+)@([\w-]+\.)+([\w]{2,})$/i);
setEmailValidValue(isEmailValid !== null);
};
const handleOnChange = (e) => {
const emailValue = e.target.value;
setEmailValue(emailValue);
validateEmail(emailValue);
};
const handleSubmit = (e) => {
e.preventDefault();
if (emailInput === '') {
setEmailValidValue(false);
}
if (emailValid && emailInput !== '') {
props.forgotPassword(emailInput);
}
};
return (
<>
{status === 'complete' ? <Redirect to={LOGIN_PAGE} /> : null}
<div className="d-flex justify-content-center forgot-password-container">
<div className="d-flex flex-column" style={{ width: '450px' }}>
<form className="m-4">
<div className="form-group">
{status === 'forbidden' ? <RequestInProgressAlert /> : null}
<h3 className="text-center mt-3">
{intl.formatMessage(messages['logisration.forgot.password.page.heading'])}
</h3>
<p className="mb-4">
{intl.formatMessage(messages['logisration.forgot.password.page.instructions'])}
</p>
<div className="d-flex flex-column align-items-start">
<ValidationFormGroup
className="mb-0"
for="email"
invalid={!emailValid}
invalidMessage={intl.formatMessage(
messages['logisration.forgot.password.page.invalid.email.message'],
)}
>
<label htmlFor="forgot-password-input" className="h6 mr-1">
{intl.formatMessage(messages['logisration.forgot.password.page.email.field.label'])}
</label>
<Input
name="email"
id="forgot-password-input"
type="email"
placeholder="username@domain.com"
value={emailInput}
onChange={e => handleOnChange(e)}
style={{ width: '400px' }}
/>
</ValidationFormGroup>
</div>
<p className="mb-2">
{intl.formatMessage(messages['logisration.forgot.password.page.email.field.help.text'])}
</p>
<LoginHelpLinks page="forgot-password" />
<Formik
onSubmit={(values) => {
if (values.isEmailValid) {
props.forgotPassword(values.email);
}
}}
initialValues={{
email: '',
isEmailValid: true,
}}
>
{({
handleSubmit,
values,
setFieldValue,
}) => (
<>
{status === 'complete' ? <Redirect to={LOGIN_PAGE} /> : null}
<div className="d-flex justify-content-center forgot-password-container">
<div className="d-flex flex-column" style={{ width: '450px' }}>
<Form className="m-4">
<div className="form-group">
{status === 'forbidden' ? <RequestInProgressAlert /> : null}
<h3 className="text-center mt-3">
{intl.formatMessage(messages['logisration.forgot.password.page.heading'])}
</h3>
<p className="mb-4">
{intl.formatMessage(messages['logisration.forgot.password.page.instructions'])}
</p>
<div className="d-flex flex-column align-items-start">
<ValidationFormGroup
className="mb-0"
for="email"
invalid={!values.isEmailValid}
invalidMessage={intl.formatMessage(
messages['logisration.forgot.password.page.invalid.email.message'],
)}
>
<label htmlFor="forgot-password-input" className="h6 mr-1">
{intl.formatMessage(messages['logisration.forgot.password.page.email.field.label'])}
</label>
<Input
name="email"
id="forgot-password-input"
type="email"
placeholder="username@domain.com"
value={values.email}
onChange={e => validateEmail(e, values, setFieldValue)}
style={{ width: '400px' }}
/>
</ValidationFormGroup>
</div>
<p className="mb-2">
{intl.formatMessage(messages['logisration.forgot.password.page.email.field.help.text'])}
</p>
<LoginHelpLinks page="forgot-password" />
</div>
<StatefulButton
type="button"
className="btn-primary submit"
state={status}
labels={{
default: intl.formatMessage(messages['logisration.forgot.password.page.submit.button']),
}}
onClick={handleSubmit}
/>
</Form>
</div>
<StatefulButton
type="submit"
className="btn-primary submit"
state={status}
labels={{
default: intl.formatMessage(messages['logisration.forgot.password.page.submit.button']),
}}
onClick={e => handleSubmit(e)}
/>
</form>
</div>
</div>
</>
</div>
</>
)}
</Formik>
);
};

View File

@@ -115,7 +115,7 @@ exports[`ForgotPasswordPage should match default section snapshot 1`] = `
className="pgn__stateful-btn pgn__stateful-btn-state-null btn-primary submit btn btn-primary"
disabled={false}
onClick={[Function]}
type="submit"
type="button"
>
<span
className="d-flex align-items-center justify-content-center"
@@ -271,7 +271,7 @@ exports[`ForgotPasswordPage should match forbidden section snapshot 1`] = `
className="pgn__stateful-btn pgn__stateful-btn-state-forbidden btn-primary submit btn btn-primary"
disabled={false}
onClick={[Function]}
type="submit"
type="button"
>
<span
className="d-flex align-items-center justify-content-center"
@@ -399,7 +399,7 @@ exports[`ForgotPasswordPage should match pending section snapshot 1`] = `
className="pgn__stateful-btn pgn__stateful-btn-state-pending btn-primary submit disabled btn btn-primary"
disabled={false}
onClick={[Function]}
type="submit"
type="button"
>
<span
className="d-flex align-items-center justify-content-center"

View File

@@ -6,6 +6,7 @@ import {
StatefulButton,
Hyperlink,
ValidationFormGroup,
Form,
} from '@edx/paragon';
import {
@@ -444,7 +445,7 @@ class RegistrationPage extends React.Component {
</span>
</div>
) : null}
<form className="mb-4 mx-auto form-group">
<Form className="mb-4 mx-auto form-group">
<ValidationFormGroup
for="name"
invalid={this.state.errors.name !== ''}
@@ -551,7 +552,7 @@ class RegistrationPage extends React.Component {
}}
onClick={this.handleSubmit}
/>
</form>
</Form>
</div>
</>
);