Path: blob/1.0-develop/resources/scripts/components/auth/ForgotPasswordContainer.tsx
7461 views
import * as React from 'react';1import { useEffect, useRef, useState } from 'react';2import { Link } from 'react-router-dom';3import requestPasswordResetEmail from '@/api/auth/requestPasswordResetEmail';4import { httpErrorToHuman } from '@/api/http';5import LoginFormContainer from '@/components/auth/LoginFormContainer';6import { useStoreState } from 'easy-peasy';7import Field from '@/components/elements/Field';8import { Formik, FormikHelpers } from 'formik';9import { object, string } from 'yup';10import tw from 'twin.macro';11import Button from '@/components/elements/Button';12import Reaptcha from 'reaptcha';13import useFlash from '@/plugins/useFlash';1415interface Values {16email: string;17}1819export default () => {20const ref = useRef<Reaptcha>(null);21const [token, setToken] = useState('');2223const { clearFlashes, addFlash } = useFlash();24const { enabled: recaptchaEnabled, siteKey } = useStoreState((state) => state.settings.data!.recaptcha);2526useEffect(() => {27clearFlashes();28}, []);2930const handleSubmission = ({ email }: Values, { setSubmitting, resetForm }: FormikHelpers<Values>) => {31clearFlashes();3233// If there is no token in the state yet, request the token and then abort this submit request34// since it will be re-submitted when the recaptcha data is returned by the component.35if (recaptchaEnabled && !token) {36ref.current!.execute().catch((error) => {37console.error(error);3839setSubmitting(false);40addFlash({ type: 'error', title: 'Error', message: httpErrorToHuman(error) });41});4243return;44}4546requestPasswordResetEmail(email, token)47.then((response) => {48resetForm();49addFlash({ type: 'success', title: 'Success', message: response });50})51.catch((error) => {52console.error(error);53addFlash({ type: 'error', title: 'Error', message: httpErrorToHuman(error) });54})55.then(() => {56setToken('');57if (ref.current) ref.current.reset();5859setSubmitting(false);60});61};6263return (64<Formik65onSubmit={handleSubmission}66initialValues={{ email: '' }}67validationSchema={object().shape({68email: string()69.email('A valid email address must be provided to continue.')70.required('A valid email address must be provided to continue.'),71})}72>73{({ isSubmitting, setSubmitting, submitForm }) => (74<LoginFormContainer title={'Request Password Reset'} css={tw`w-full flex`}>75<Field76light77label={'Email'}78description={79'Enter your account email address to receive instructions on resetting your password.'80}81name={'email'}82type={'email'}83/>84<div css={tw`mt-6`}>85<Button type={'submit'} size={'xlarge'} disabled={isSubmitting} isLoading={isSubmitting}>86Send Email87</Button>88</div>89{recaptchaEnabled && (90<Reaptcha91ref={ref}92size={'invisible'}93sitekey={siteKey || '_invalid_key'}94onVerify={(response) => {95setToken(response);96submitForm();97}}98onExpire={() => {99setSubmitting(false);100setToken('');101}}102/>103)}104<div css={tw`mt-6 text-center`}>105<Link106to={'/auth/login'}107css={tw`text-xs text-neutral-500 tracking-wide uppercase no-underline hover:text-neutral-700`}108>109Return to Login110</Link>111</div>112</LoginFormContainer>113)}114</Formik>115);116};117118119