|
'use client' |
|
import React, { useEffect, useState } from 'react' |
|
import { useTranslation } from 'react-i18next' |
|
|
|
import { useRouter } from 'next/navigation' |
|
|
|
import { useForm } from 'react-hook-form' |
|
import { z } from 'zod' |
|
import { zodResolver } from '@hookform/resolvers/zod' |
|
import Loading from '../components/base/loading' |
|
import Input from '../components/base/input' |
|
import Button from '@/app/components/base/button' |
|
|
|
import { |
|
fetchInitValidateStatus, |
|
fetchSetupStatus, |
|
sendForgotPasswordEmail, |
|
} from '@/service/common' |
|
import type { InitValidateStatusResponse, SetupStatusResponse } from '@/models/common' |
|
|
|
const accountFormSchema = z.object({ |
|
email: z |
|
.string() |
|
.min(1, { message: 'login.error.emailInValid' }) |
|
.email('login.error.emailInValid'), |
|
}) |
|
|
|
type AccountFormValues = z.infer<typeof accountFormSchema> |
|
|
|
const ForgotPasswordForm = () => { |
|
const { t } = useTranslation() |
|
const router = useRouter() |
|
const [loading, setLoading] = useState(true) |
|
const [isEmailSent, setIsEmailSent] = useState(false) |
|
const { register, trigger, getValues, formState: { errors } } = useForm<AccountFormValues>({ |
|
resolver: zodResolver(accountFormSchema), |
|
defaultValues: { email: '' }, |
|
}) |
|
|
|
const handleSendResetPasswordEmail = async (email: string) => { |
|
try { |
|
const res = await sendForgotPasswordEmail({ |
|
url: '/forgot-password', |
|
body: { email }, |
|
}) |
|
if (res.result === 'success') |
|
setIsEmailSent(true) |
|
|
|
else console.error('Email verification failed') |
|
} |
|
catch (error) { |
|
console.error('Request failed:', error) |
|
} |
|
} |
|
|
|
const handleSendResetPasswordClick = async () => { |
|
if (isEmailSent) { |
|
router.push('/signin') |
|
} |
|
else { |
|
const isValid = await trigger('email') |
|
if (isValid) { |
|
const email = getValues('email') |
|
await handleSendResetPasswordEmail(email) |
|
} |
|
} |
|
} |
|
|
|
useEffect(() => { |
|
fetchSetupStatus().then((res: SetupStatusResponse) => { |
|
fetchInitValidateStatus().then((res: InitValidateStatusResponse) => { |
|
if (res.status === 'not_started') |
|
window.location.href = '/init' |
|
}) |
|
|
|
setLoading(false) |
|
}) |
|
}, []) |
|
|
|
return ( |
|
loading |
|
? <Loading /> |
|
: <> |
|
<div className="sm:mx-auto sm:w-full sm:max-w-md"> |
|
<h2 className="text-[32px] font-bold text-gray-900"> |
|
{isEmailSent ? t('login.resetLinkSent') : t('login.forgotPassword')} |
|
</h2> |
|
<p className='mt-1 text-sm text-gray-600'> |
|
{isEmailSent ? t('login.checkEmailForResetLink') : t('login.forgotPasswordDesc')} |
|
</p> |
|
</div> |
|
<div className="grow mt-8 sm:mx-auto sm:w-full sm:max-w-md"> |
|
<div className="bg-white "> |
|
<form> |
|
{!isEmailSent && ( |
|
<div className='mb-5'> |
|
<label htmlFor="email" |
|
className="my-2 flex items-center justify-between text-sm font-medium text-gray-900"> |
|
{t('login.email')} |
|
</label> |
|
<div className="mt-1"> |
|
<Input |
|
{...register('email')} |
|
placeholder={t('login.emailPlaceholder') || ''} |
|
/> |
|
{errors.email && <span className='text-red-400 text-sm'>{t(`${errors.email?.message}`)}</span>} |
|
</div> |
|
</div> |
|
)} |
|
<div> |
|
<Button variant='primary' className='w-full' onClick={handleSendResetPasswordClick}> |
|
{isEmailSent ? t('login.backToSignIn') : t('login.sendResetLink')} |
|
</Button> |
|
</div> |
|
</form> |
|
</div> |
|
</div> |
|
</> |
|
) |
|
} |
|
|
|
export default ForgotPasswordForm |
|
|