erp-platform/ui/src/views/auth/ForgotPassword.tsx
Sedat ÖZTÜRK e1a9562b22 init project
2025-05-06 09:45:49 +03:00

128 lines
3.9 KiB
TypeScript

import ActionLink from '@/components/shared/ActionLink'
import Captcha from '@/components/shared/Captcha'
import Alert from '@/components/ui/Alert'
import Button from '@/components/ui/Button'
import { FormContainer, FormItem } from '@/components/ui/Form'
import Input from '@/components/ui/Input'
import { ROUTES_ENUM } from '@/constants/route.constant'
import { sendPasswordResetCode } from '@/proxy/account/account.service'
import { store } from '@/store'
import useTimeOutMessage from '@/utils/hooks/useTimeOutMessage'
import type { AxiosError } from 'axios'
import { Field, Form, Formik } from 'formik'
import { motion } from 'framer-motion'
import { useState } from 'react'
import * as Yup from 'yup'
type ForgotPasswordFormSchema = {
email: string
captchaResponse: string
}
const validationSchema = Yup.object().shape({
email: Yup.string().required('Please enter your email'),
captchaResponse: Yup.string().required(),
})
const ForgotPassword = () => {
const { userName } = store.getState().auth.user
const disableSubmit = false
const signInUrl = ROUTES_ENUM.account.login
const [emailSent, setEmailSent] = useState(false)
const [message, setMessage] = useTimeOutMessage()
const onSendMail = async (
values: ForgotPasswordFormSchema,
setSubmitting: (isSubmitting: boolean) => void,
) => {
setSubmitting(true)
try {
const resp = await sendPasswordResetCode(values)
if (resp.data) {
setSubmitting(false)
setEmailSent(true)
}
} catch (errors) {
setMessage(
(errors as AxiosError<{ message: string }>)?.response?.data?.message ||
(errors as Error).toString(),
)
setSubmitting(false)
}
}
return (
<motion.div
initial={{ opacity: 0, x: 100 }}
animate={{ opacity: 1, x: 0 }}
transition={{ duration: 0.5, origin: 1 }}
>
<div className="mb-6">
{emailSent ? (
<>
<h3 className="mb-1">Check your email</h3>
<p>We have sent a password recovery instruction to your email</p>
</>
) : (
<>
<h3 className="mb-1">Forgot Password</h3>
<p>Please enter your email address to receive a verification code</p>
</>
)}
</div>
{message && (
<Alert showIcon className="mb-4" type="danger">
{message}
</Alert>
)}
<Formik
initialValues={{
email: userName,
captchaResponse: '',
}}
validationSchema={validationSchema}
onSubmit={(values, { setSubmitting }) => {
if (!disableSubmit) {
onSendMail(values, setSubmitting)
} else {
setSubmitting(false)
}
}}
>
{({ touched, errors, isSubmitting, setFieldValue }) => (
<Form>
<FormContainer>
<div className={emailSent ? 'hidden' : ''}>
<FormItem invalid={errors.email && touched.email} errorMessage={errors.email}>
<Field
type="email"
autoComplete="off"
name="email"
placeholder="Email"
component={Input}
/>
</FormItem>
</div>
<Captcha
onError={() => setFieldValue('captchaResponse', '')}
onExpire={() => setFieldValue('captchaResponse', '')}
onSuccess={(token: string) => setFieldValue('captchaResponse', token)}
/>
<Button block loading={isSubmitting} variant="solid" type="submit">
{emailSent ? 'Resend Email' : 'Send Email'}
</Button>
<div className="mt-4 text-center">
<span>Back to </span>
<ActionLink to={signInUrl}>Sign in</ActionLink>
</div>
</FormContainer>
</Form>
)}
</Formik>
</motion.div>
)
}
export default ForgotPassword