change login

This commit is contained in:
hamid zarghami
2025-11-16 11:19:40 +03:30
parent 3c14645fb5
commit 3592b4cdae
7 changed files with 61 additions and 61 deletions
+3
View File
@@ -23,6 +23,9 @@
"enter_info_login": "لطفا اطلاعات خود را وارد کنید.",
"mobile_or_email": " شماره موبایل یا ایمیل",
"enter_mobile_or_email": " شماره موبایل یا ایمیل خود را وارد کنید",
"mobile": "شماره موبایل",
"enter_mobile": "شماره موبایل خود را وارد کنید",
"otp_sent": "کد تایید ارسال شد",
"have_account": "آیا حساب کاربری ندارید؟",
"register": "ثبت نام",
"enter_otp": "کد تایید را وارد کنید",
+2 -7
View File
@@ -4,11 +4,10 @@ import LogoSmallImage from '../../assets/images/logo-small.svg'
import { useAuthStore } from './store/AuthStore'
import LoginStep1 from './components/LoginStep1'
import LoginStep2 from './components/LoginStep2'
import LoginStep3 from './components/LoginStep3'
const Login: FC = () => {
const { stepLogin, phone, email } = useAuthStore()
const { stepLogin, phone } = useAuthStore()
return (
<div className='w-full h-full flex justify-center lg:py-[75px] py-4 lg:items-center lg:px-10 px-4'>
@@ -24,11 +23,7 @@ const Login: FC = () => {
:
stepLogin === 2 && !!phone ?
<LoginStep2 />
: stepLogin === 2 && !!email ?
<LoginStep3 />
: stepLogin === 3 ?
<LoginStep3 />
: null
: null
}
</div>
+28 -37
View File
@@ -1,55 +1,46 @@
import { type FC } from 'react'
import Input from '../../../components/Input'
import { useTranslation } from 'react-i18next'
import { type LoginType } from '../types/AuthTypes'
import { useFormik } from 'formik'
import * as Yup from 'yup'
import { useAuthStore } from '../store/AuthStore'
import Error from '../../../components/Error'
import Button from '../../../components/Button'
import { isEmail } from '../../../config/func'
import { useCheckHasAccount, useLoginWithOtp } from '../hooks/useAuthData'
import { useLoginWithOtp } from '../hooks/useAuthData'
import { toast } from 'react-toastify'
import { type ErrorType } from '../../../helpers/types'
import { useParams } from 'react-router-dom'
type LoginStep1FormType = {
phone: string;
}
const LoginStep1: FC = () => {
const { t } = useTranslation('global')
const { setPhone, phone, setStepLogin, setEmail } = useAuthStore()
const { setPhone, phone, setStepLogin } = useAuthStore()
const loginWithOtp = useLoginWithOtp()
const checkHasAccount = useCheckHasAccount()
const { slug } = useParams()
const formik = useFormik<LoginType>({
const formik = useFormik<LoginStep1FormType>({
initialValues: {
phone_email: phone,
phone: phone,
},
validationSchema: Yup.object({
phone_email: Yup.string()
phone: Yup.string()
.required(t('errors.required'))
}),
onSubmit(values) {
if (isEmail(values.phone_email)) {
setEmail(values.phone_email)
checkHasAccount.mutate({ email: values.phone_email }, {
onSuccess() {
setStepLogin(2)
},
onError(error: ErrorType) {
toast.error(error?.response?.data?.error?.message[0])
},
})
} else {
setPhone(values.phone_email)
loginWithOtp.mutate({ phone: values.phone_email }, {
onSuccess() {
setStepLogin(2)
toast.success(t('auth.otp_sent'))
},
onError(error: ErrorType) {
toast.error(error?.response?.data?.error?.message[0])
},
})
}
setPhone(values.phone)
loginWithOtp.mutate({ phone: values.phone, slug: slug as string }, {
onSuccess() {
setStepLogin(2)
toast.success(t('auth.otp_sent'))
},
onError(error: ErrorType) {
toast.error(error?.response?.data?.error?.message[0])
},
})
},
})
@@ -66,19 +57,19 @@ const LoginStep1: FC = () => {
<div className='mt-16'>
<Input
label={t('auth.mobile_or_email')}
placeholder={t('auth.enter_mobile_or_email')}
label={t('auth.mobile')}
placeholder={t('auth.enter_mobile')}
type='text'
className='text-right'
name='phone_email'
name='phone'
onChange={formik.handleChange}
value={formik.values.phone_email}
value={formik.values.phone}
/>
{
formik.touched.phone_email && formik.errors.phone_email &&
formik.touched.phone && formik.errors.phone &&
<Error
errorText={formik.errors.phone_email}
errorText={formik.errors.phone}
/>
}
@@ -89,7 +80,7 @@ const LoginStep1: FC = () => {
label={t('auth.next')}
className='mt-8'
onClick={() => formik.handleSubmit()}
isLoading={loginWithOtp.isPending || checkHasAccount.isPending}
isLoading={loginWithOtp.isPending}
/>
</div>
+22 -13
View File
@@ -7,12 +7,12 @@ 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 { Pages } from '../../../config/Pages'
import { useOtpVerify } from '../hooks/useAuthData'
import { type ErrorType } from '../../../helpers/types'
import { toast } from 'react-toastify'
import { setToken, setRefreshToken } from '../../../config/func'
import { useParams } from 'react-router-dom'
const LoginStep2: FC = () => {
@@ -20,25 +20,26 @@ const LoginStep2: FC = () => {
const { phone, setStepLogin } = useAuthStore()
const { value } = useCountDown(2, true)
const otpVerify = useOtpVerify()
const { slug } = useParams()
const formik = useFormik<OtpVerifyType>({
const formik = useFormik<{ otp: string }>({
initialValues: {
phone: phone,
code: ''
otp: ''
},
validationSchema: Yup.object({
code: Yup.string()
otp: Yup.string()
.required(t('errors.required'))
}),
onSubmit(values) {
const params: OtpVerifyType = {
phone: phone,
code: values.code
otp: values.otp,
slug: slug as string
}
otpVerify.mutate(params, {
onSuccess(data) {
setToken(data?.data?.accessToken?.token)
setRefreshToken(data?.data?.refreshToken?.token)
setToken(data?.data?.tokens?.accessToken?.token)
setRefreshToken(data?.data?.tokens?.refreshToken?.token)
window.location.href = Pages.dashboard
},
onError(error: ErrorType) {
@@ -75,17 +76,25 @@ const LoginStep2: FC = () => {
<div className='mt-2 w-full flex justify-center dltr otp'>
<OTPInput
shouldAutoFocus
value={formik.values.code}
value={formik.values.otp}
numInputs={5}
inputType='tel'
onChange={(otp: string) => formik.setFieldValue('code', otp)}
renderInput={(props) => <input {...props} className='w-full h-[50px] flex-1 mx-2 bg-white border rounded-2.5' />}
containerStyle={{ direction: 'ltr', width: '100%' }}
onChange={(otp: string) => formik.setFieldValue('otp', otp)}
renderInput={(props) =>
<input
{...props}
type='tel'
autoComplete="one-time-code"
inputMode="numeric"
className='w-full min-w-[50px] h-[45px] sm:h-[50px] flex-1 mx-1 sm:mx-2 bg-white border border-gray-300 outline-0 rounded-[10px] text-center text-sm' />
}
/>
</div>
{
formik.touched.code && formik.errors.code &&
<div className='text-xs mt-2 text-red-500'>{formik.errors.code}</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'>
+2 -2
View File
@@ -15,12 +15,12 @@ export const loginWithPassword = async (params: LoginWithPasswordType) => {
};
export const loginWithOtp = async (params: LoginWithOtpType) => {
const { data } = await axios.post(`/auth/otp/send`, params);
const { data } = await axios.post(`/admin/auth/otp/request`, params);
return data;
};
export const otpVerify = async (params: OtpVerifyType) => {
const { data } = await axios.post(`/auth/otp/verify/admin`, params);
const { data } = await axios.post(`/admin/auth/otp/verify`, params);
return data;
};
export const checkHasAccount = async (params: CheckHasAccountType) => {
+3 -1
View File
@@ -25,11 +25,13 @@ export type LoginWithPasswordType = XOR<
export type LoginWithOtpType = {
phone: string;
slug: string;
};
export type OtpVerifyType = {
phone: string;
code: string;
otp: string;
slug: string;
};
export type CheckHasAccountType = {
+1 -1
View File
@@ -6,7 +6,7 @@ import Login from '../pages/auth/Login'
const Auth: FC = () => {
return (
<Routes>sa
<Route path={Pages.auth.login} element={<Login />} />
<Route path={Pages.auth.login + '/:slug'} element={<Login />} />
</Routes>
)
}