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