login
This commit is contained in:
@@ -0,0 +1,180 @@
|
||||
import { type FC, useEffect } from 'react'
|
||||
import { type OtpVerifyType } from '../types/AuthTypes'
|
||||
import { useFormik } from 'formik'
|
||||
import * as Yup from 'yup'
|
||||
import { useAuthStore } from '../store/AuthStore'
|
||||
import Button from '../../../components/Button'
|
||||
import OTPInput from 'react-otp-input'
|
||||
import { useCountDown } from '../../../hooks/useCountDown'
|
||||
// import ArrowLeftIcon from '../../../assets/images/arrow-left.svg'
|
||||
import { useLoginWithOtp, useOtpVerify } from '../hooks/useAuthData'
|
||||
import { extractErrorMessage, setRefreshToken } from '../../../config/func'
|
||||
import { setToken } from '../../../config/func'
|
||||
import { toast } from '@/shared/toast'
|
||||
import { Paths } from '@/config/Paths'
|
||||
|
||||
const LoginStep2: FC = () => {
|
||||
|
||||
const { phone, setStepLogin } = useAuthStore()
|
||||
const { value, reset } = useCountDown(2, true)
|
||||
const otpVerify = useOtpVerify()
|
||||
const loginWithOtp = useLoginWithOtp()
|
||||
|
||||
const formik = useFormik<OtpVerifyType>({
|
||||
initialValues: {
|
||||
phone: phone,
|
||||
otp: ''
|
||||
},
|
||||
validationSchema: Yup.object({
|
||||
otp: Yup.string()
|
||||
.required('این فیلد اجباری است.')
|
||||
}),
|
||||
onSubmit(values) {
|
||||
const params: OtpVerifyType = {
|
||||
phone: phone,
|
||||
otp: values.otp
|
||||
}
|
||||
otpVerify.mutate(params, {
|
||||
onSuccess(data) {
|
||||
setToken(data?.data?.tokens?.accessToken?.token)
|
||||
setRefreshToken(data?.data?.tokens?.refreshToken?.token)
|
||||
// Check if there's a redirect parameter in the URL
|
||||
window.location.href = Paths.home
|
||||
},
|
||||
onError(error) {
|
||||
toast(extractErrorMessage(error), 'error')
|
||||
},
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
// بررسی پشتیبانی از Web OTP API
|
||||
if (!("OTPCredential" in window)) return;
|
||||
|
||||
const ac = new AbortController();
|
||||
|
||||
navigator.credentials
|
||||
.get({
|
||||
otp: { transport: ["sms"] },
|
||||
signal: ac.signal,
|
||||
} as CredentialRequestOptions) // اطمینان از تطابق تایپها
|
||||
.then((otpCredential) => {
|
||||
if (otpCredential && "otp" in otpCredential) {
|
||||
formik.setFieldValue("otp", (otpCredential).otp);
|
||||
}
|
||||
})
|
||||
.catch((err) => console.error("SMS AutoFill Error:", err));
|
||||
|
||||
return () => ac.abort();
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
const reSend = () => {
|
||||
loginWithOtp.mutate({ phone: phone }, {
|
||||
onSuccess: () => {
|
||||
reset()
|
||||
toast('کد مجدد ارسال شد', 'success')
|
||||
},
|
||||
onError: (error) => {
|
||||
toast(extractErrorMessage(error), 'error')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
if (formik.values.otp.length === 5) {
|
||||
formik.handleSubmit()
|
||||
}
|
||||
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [formik.values.otp])
|
||||
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className='mt-5'>
|
||||
<h2 className='lg:text-2xl font-bold'>
|
||||
کد تایید را وارد کنید
|
||||
</h2>
|
||||
<p className='text-description flex lg:flex-row flex-col lg:gap-1 gap-2 text-sm lg:mt-2 mt-3'>
|
||||
<div className='flex gap-1'>
|
||||
<div>کد تایید برای</div>
|
||||
<div>{phone}</div>
|
||||
<div>
|
||||
ارسال شد.
|
||||
</div>
|
||||
</div>
|
||||
<div onClick={() => setStepLogin(1)} className='text-black cursor-pointer'>
|
||||
تغییر شماره
|
||||
</div>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className='mt-16'>
|
||||
<div className='text-sm'>
|
||||
کد تایید
|
||||
</div>
|
||||
<div className='mt-2 w-full flex justify-center dltr otp'>
|
||||
<OTPInput
|
||||
shouldAutoFocus
|
||||
value={formik.values.otp}
|
||||
numInputs={5}
|
||||
inputType='tel'
|
||||
onChange={(otp: string) => formik.setFieldValue('otp', otp)}
|
||||
renderInput={(props) =>
|
||||
<input
|
||||
{...props}
|
||||
type='tel'
|
||||
autoComplete="one-time-otp"
|
||||
inputMode="numeric"
|
||||
className='w-full h-[50px] min-w-[50px] flex-1 mx-2 bg-white border border-border rounded-[10px]' />
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{
|
||||
formik.touched.otp && formik.errors.otp &&
|
||||
<div className='text-xs mt-2 text-red-500'>{formik.errors.otp}</div>
|
||||
}
|
||||
|
||||
<div className='flex mt-4 justify-end'>
|
||||
{
|
||||
value !== '00:00' ?
|
||||
<div className='flex gap-1 text-description text-xs'>
|
||||
<div>{value}</div>
|
||||
<div>مانده تا دریافت مجدد کد</div>
|
||||
</div>
|
||||
:
|
||||
<div onClick={reSend} className='flex cursor-pointer gap-1 pl-2 text-black text-sm'>
|
||||
<div className=''>
|
||||
ارسال مجدد
|
||||
</div>
|
||||
</div>
|
||||
|
||||
}
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<Button
|
||||
label={'ورود'}
|
||||
className='mt-8'
|
||||
onClick={() => formik.handleSubmit()}
|
||||
isLoading={otpVerify.isPending}
|
||||
/>
|
||||
|
||||
{/* <div onClick={() => setStepLogin(3)} className='mt-6 cursor-pointer flex gap-2 items-center text-sm'>
|
||||
<p className='text-description'>
|
||||
{t('auth.login_with_password')}
|
||||
</p>
|
||||
<img src={ArrowLeftIcon} className='w-5' />
|
||||
</div> */}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default LoginStep2
|
||||
Reference in New Issue
Block a user