This commit is contained in:
hamid zarghami
2024-12-24 11:43:25 +03:30
parent 67135204ab
commit 6d5ce71b2f
17 changed files with 609 additions and 51 deletions
+16 -39
View File
@@ -1,15 +1,15 @@
import { FC } from 'react'
import LogoImage from '../../assets/images/logo.svg'
import LogoSmallImage from '../../assets/images/logo-small.svg'
import { useTranslation } from 'react-i18next'
import Input from '../../components/Input'
import Button from '../../components/Button'
import { Link } from 'react-router-dom'
import { Pages } from '../../config/Pages'
import { useAuthStore } from '../store/AuthStore'
import LoginStep1 from './components/LoginStep1'
import LoginStep2 from './components/LoginStep2'
import LoginStep3 from './components/LoginStep3'
const Login: FC = () => {
const { t } = useTranslation('global')
const { stepLogin } = useAuthStore()
return (
<div className='w-full h-full flex justify-center py-[75px] items-center px-10'>
@@ -19,39 +19,16 @@ const Login: FC = () => {
<img src={LogoSmallImage} className='w-8' />
<div className='flex flex-1 flex-col h-full justify-center'>
<div className='mt-5'>
<h2 className='text-2xl font-bold'>
{t('auth.welcome')}
</h2>
<p className='text-description text-sm mt-2'>
{t('auth.enter_info_login')}
</p>
</div>
<div className='mt-16 rowTwoInput'>
<Input
label={t('auth.mobile_or_email')}
placeholder={t('auth.enter_mobile_or_email')}
type='tel'
className='text-right'
/>
</div>
<Button
label={t('auth.next')}
className='mt-8'
/>
<div className='mt-6 flex justify-center gap-2 items-center text-sm'>
<p className='text-description'>
{t('auth.have_account')}
</p>
<Link to={Pages.auth.register}>
<div>{t('auth.register')}</div>
</Link>
</div>
{
stepLogin === 1 ?
<LoginStep1 />
:
stepLogin === 2 ?
<LoginStep2 />
: stepLogin === 3 ?
<LoginStep3 />
: null
}
</div>
+82
View File
@@ -0,0 +1,82 @@
import { FC } from 'react'
import Input from '../../../components/Input'
import { useTranslation } from 'react-i18next'
import { 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 { Link } from 'react-router-dom'
import { Pages } from '../../../config/Pages'
const LoginStep1: FC = () => {
const { t } = useTranslation('global')
const { setPhone, phone, setStepLogin } = useAuthStore()
const formik = useFormik<LoginType>({
initialValues: {
phone_email: phone,
},
validationSchema: Yup.object({
phone_email: Yup.string()
.required(t('errors.required'))
}),
onSubmit(values) {
setPhone(values.phone_email)
setStepLogin(2)
},
})
return (
<div>
<div className='mt-5'>
<h2 className='text-2xl font-bold'>
{t('auth.welcome')}
</h2>
<p className='text-description text-sm mt-2'>
{t('auth.enter_info_login')}
</p>
</div>
<div className='mt-16'>
<Input
label={t('auth.mobile_or_email')}
placeholder={t('auth.enter_mobile_or_email')}
type='text'
className='text-right'
name='phone_email'
onChange={formik.handleChange}
value={formik.values.phone_email}
/>
{
formik.touched.phone_email && formik.errors.phone_email &&
<Error
errorText={formik.errors.phone_email}
/>
}
</div>
<Button
label={t('auth.next')}
className='mt-8'
onClick={() => formik.handleSubmit()}
/>
<div className='mt-6 flex justify-center gap-2 items-center text-sm'>
<p className='text-description'>
{t('auth.have_account')}
</p>
<Link to={Pages.auth.register}>
<div>{t('auth.register')}</div>
</Link>
</div>
</div>
)
}
export default LoginStep1
+91
View File
@@ -0,0 +1,91 @@
import { FC, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { LoginType } 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'
const LoginStep2: FC = () => {
const { t } = useTranslation('global')
const { setPhone, phone, setStepLogin } = useAuthStore()
const [otpValue, setOtpValue] = useState<string>()
const { value } = useCountDown(2, true)
const formik = useFormik<LoginType>({
initialValues: {
phone_email: '',
},
validationSchema: Yup.object({
phone_email: Yup.string()
.required(t('errors.required'))
}),
onSubmit(values) {
setPhone(values.phone_email)
},
})
return (
<div>
<div className='mt-5'>
<h2 className='text-2xl font-bold'>
{t('auth.enter_otp')}
</h2>
<p className='text-description flex gap-1 text-sm mt-2'>
<div>{t('auth.verfify_code_text_1')}</div>
<div>{phone}</div>
<div>
{t('auth.verfify_code_text_2')}
</div>
<div onClick={() => setStepLogin(1)} className='text-black cursor-pointer'>
{t('auth.change_number')}
</div>
</p>
</div>
<div className='mt-16'>
<div className='text-sm'>
{t('auth.verify_code')}
</div>
<div className='mt-2 w-full flex justify-center dltr otp'>
<OTPInput
shouldAutoFocus
value={otpValue}
numInputs={5}
inputType='tel'
onChange={(otp: string) => setOtpValue(otp)}
renderInput={(props) => <input {...props} className='w-full h-[50px] flex-1 mx-2 bg-white border rounded-2.5' />}
/>
</div>
<div className='flex mt-4 justify-end'>
<div className='flex gap-1 text-description text-xs'>
<div>{value}</div>
<div>{t('auth.counter_otp')}</div>
</div>
</div>
</div>
<Button
label={t('auth.login')}
className='mt-8'
onClick={() => formik.handleSubmit()}
/>
<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
+84
View File
@@ -0,0 +1,84 @@
import { FC } from 'react'
import Input from '../../../components/Input'
import { useTranslation } from 'react-i18next'
import { LoginPasswordType } 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 { Link } from 'react-router-dom'
import { Pages } from '../../../config/Pages'
import ArrowLeftIcon from '../../../assets/images/arrow-left.svg'
const LoginStep3: FC = () => {
const { t } = useTranslation('global')
const { setStepLogin } = useAuthStore()
const formik = useFormik<LoginPasswordType>({
initialValues: {
password: '',
},
validationSchema: Yup.object({
phone_email: Yup.string()
.required(t('errors.required'))
}),
onSubmit(values) {
console.log(values);
},
})
return (
<div>
<div className='mt-5'>
<h2 className='text-2xl font-bold'>
{t('auth.enter_password_step3')}
</h2>
<p className='text-description text-sm mt-2'>
{t('auth.enter_your_password')}
</p>
</div>
<div className='mt-16'>
<Input
label={t('auth.password')}
type='password'
className='text-right'
name='password'
onChange={formik.handleChange}
value={formik.values.password}
/>
{
formik.touched.password && formik.errors.password &&
<Error
errorText={formik.errors.password}
/>
}
</div>
<Link to={Pages.auth.forgotPassword}>
<div className='mt-4 flex justify-end text-sm'>
{t('auth.forgot_password')}
</div>
</Link>
<Button
label={t('auth.login')}
className='mt-8'
onClick={() => formik.handleSubmit()}
/>
<div onClick={() => setStepLogin(2)} className='mt-6 cursor-pointer flex gap-2 items-center text-sm'>
<p className='text-description'>
{t('auth.login_with_otp')}
</p>
<img src={ArrowLeftIcon} className='w-4' />
</div>
</div>
)
}
export default LoginStep3
+13
View File
@@ -0,0 +1,13 @@
export type LoginType = {
phone_email: string;
};
export type LoginPasswordType = {
password: string;
};
export type AuthStoreType = {
phone: string;
setPhone: (value: string) => void;
stepLogin: number;
setStepLogin: (value: number) => void;
};
+13
View File
@@ -0,0 +1,13 @@
import { create } from "zustand";
import { AuthStoreType } from "../auth/types/AuthTypes";
export const useAuthStore = create<AuthStoreType>((set) => ({
phone: "",
setPhone(value) {
set({ phone: value });
},
stepLogin: 1,
setStepLogin(value) {
set({ stepLogin: value });
},
}));