fix: seperated auth pages
This commit is contained in:
@@ -0,0 +1,251 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import React, {
|
||||||
|
useState,
|
||||||
|
type FormEvent,
|
||||||
|
type ChangeEvent,
|
||||||
|
useEffect,
|
||||||
|
useTransition
|
||||||
|
} from 'react'
|
||||||
|
import { useAuthStore } from '@/zustand/authStore'
|
||||||
|
import { redirect, useRouter } from 'next/navigation'
|
||||||
|
import StepEnterNumber from '@/features/auth/components/StepEnterNumber'
|
||||||
|
import StepEnterOtp from '@/features/auth/components/StepEnterOtp'
|
||||||
|
import { AUTH_PAGE_ELEMENT, AUTH_STEP } from '@/enums'
|
||||||
|
import { useCountdown } from '@/hooks/useCountdown'
|
||||||
|
import StepNewPassword from '@/features/auth/components/StepNewPassword'
|
||||||
|
import AuthFormWrapper from '@/features/auth/components/AuthFormWrapper'
|
||||||
|
import { useCheckUserExistsLazy } from '@/hooks/auth/useCheckUserExists'
|
||||||
|
import { useOtpRequest } from '@/hooks/auth/useOtpRequest'
|
||||||
|
import { useOtpValidation } from '@/hooks/auth/useOtpValidation'
|
||||||
|
import { useResetPassword } from '@/hooks/auth/useResetPassword'
|
||||||
|
import { useAuthTempStore } from '@/zustand/authTempStroe'
|
||||||
|
|
||||||
|
type Props = object
|
||||||
|
|
||||||
|
function AuthIndex ({}: Props) {
|
||||||
|
const update_temp_store = useAuthTempStore(state => state.update)
|
||||||
|
const user_temp_store = useAuthTempStore(state => state.user)
|
||||||
|
const user_auth_store = useAuthStore(state => state.user)
|
||||||
|
const isAuthenticated = useAuthStore(state => state.isAuthenticated)
|
||||||
|
const [number, setNumber] = useState(
|
||||||
|
user_temp_store?.number ?? user_auth_store?.number ?? ''
|
||||||
|
)
|
||||||
|
const [password, setPassword] = useState('')
|
||||||
|
const [passwordRepeat, setPasswordRepeat] = useState('')
|
||||||
|
const [otp, setOtp] = useState('')
|
||||||
|
const [showPassword, setShowPassword] = useState(false)
|
||||||
|
const [showPasswordRepeat, setShowPasswordRepeat] = useState(false)
|
||||||
|
const [step, setStep] = useState(
|
||||||
|
number == '' ? AUTH_STEP.ENTER_NUMBER : AUTH_STEP.ENTER_OTP
|
||||||
|
)
|
||||||
|
const { timerRunning, secondsLeft, restart, stop } = useCountdown(
|
||||||
|
step === AUTH_STEP.ENTER_OTP
|
||||||
|
)
|
||||||
|
const [isPending, startTransition] = useTransition()
|
||||||
|
|
||||||
|
const { run: runUserExistCheck } = useCheckUserExistsLazy()
|
||||||
|
const { run: runOtpRequest } = useOtpRequest()
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
const { run: runOtpValidation } = useOtpValidation()
|
||||||
|
const { run: runResetPassword } = useResetPassword()
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (isAuthenticated) {
|
||||||
|
redirect('/')
|
||||||
|
}
|
||||||
|
}, [isAuthenticated])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (step === AUTH_STEP.ENTER_OTP) {
|
||||||
|
startTransition(() => {
|
||||||
|
setOtp('')
|
||||||
|
console.log('REQUEST OTP')
|
||||||
|
runOtpRequest(number)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [step])
|
||||||
|
|
||||||
|
const onChange = (e: ChangeEvent<HTMLInputElement>) => {
|
||||||
|
if (e.target.name == AUTH_PAGE_ELEMENT.INPUT_PHONE) {
|
||||||
|
setNumber(() => e.target.value)
|
||||||
|
} else if (e.target.name == AUTH_PAGE_ELEMENT.INPUT_PASSWORD) {
|
||||||
|
setPassword(() => e.target.value)
|
||||||
|
} else if (e.target.name == AUTH_PAGE_ELEMENT.INPUT_PASSWORD_REPEAT) {
|
||||||
|
setPasswordRepeat(() => e.target.value)
|
||||||
|
} else if (e.target.name.startsWith(AUTH_PAGE_ELEMENT.INPUT_OTP)) {
|
||||||
|
const index = +e.target.name.split('-')[2]
|
||||||
|
const prev = otp.padEnd(6).split('')
|
||||||
|
prev[index] = e.target.value
|
||||||
|
const next = prev.join('')
|
||||||
|
if (otp.length >= 6 && next.trim().length >= otp.length) return
|
||||||
|
setOtp(next.trimEnd())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const onClick = async (
|
||||||
|
e:
|
||||||
|
| React.MouseEvent<HTMLButtonElement, MouseEvent>
|
||||||
|
| React.MouseEvent<HTMLInputElement, MouseEvent>
|
||||||
|
) => {
|
||||||
|
e.stopPropagation()
|
||||||
|
const target = e.target as HTMLButtonElement
|
||||||
|
|
||||||
|
if (target.id === AUTH_PAGE_ELEMENT.TOGGLE_PASSWORD) {
|
||||||
|
setShowPassword(state => !state)
|
||||||
|
}
|
||||||
|
if (target.id === AUTH_PAGE_ELEMENT.TOGGLE_REPEAT_PASSWORD) {
|
||||||
|
setShowPasswordRepeat(state => !state)
|
||||||
|
} else if (target.id === AUTH_PAGE_ELEMENT.RESET_PASSWORD) {
|
||||||
|
setShowPassword(false)
|
||||||
|
setShowPasswordRepeat(false)
|
||||||
|
setPassword('')
|
||||||
|
setPasswordRepeat('')
|
||||||
|
setStep(() => AUTH_STEP.ENTER_OTP)
|
||||||
|
} else if (target.id === AUTH_PAGE_ELEMENT.RESEND_OTP) {
|
||||||
|
if (!timerRunning) {
|
||||||
|
startTransition(async () => {
|
||||||
|
try {
|
||||||
|
await runOtpRequest(number)
|
||||||
|
restart()
|
||||||
|
} catch {
|
||||||
|
console.error('Could not ask for otp')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const onSubmit = async (e: FormEvent<HTMLFormElement>) => {
|
||||||
|
e.preventDefault()
|
||||||
|
startTransition(async () => {
|
||||||
|
try {
|
||||||
|
/* DEV SECTION */
|
||||||
|
/* REMOVE THIS CODE FOR PRODUCTION */
|
||||||
|
throw false
|
||||||
|
/* END OF DEV SECTION */
|
||||||
|
|
||||||
|
/* SECTION DETAILS */
|
||||||
|
/* if number is entered in the /auth page or is available in main auth store this page directly shows the OTP page */
|
||||||
|
/* Otherwise it shows the number page */
|
||||||
|
if (step == AUTH_STEP.ENTER_NUMBER) {
|
||||||
|
const userExists = await runUserExistCheck(number)
|
||||||
|
update_temp_store({
|
||||||
|
number: number,
|
||||||
|
mustLogin: userExists
|
||||||
|
})
|
||||||
|
if (userExists) {
|
||||||
|
setStep(AUTH_STEP.ENTER_RESET_PASSWORD)
|
||||||
|
} else {
|
||||||
|
// TODO: error user not found
|
||||||
|
}
|
||||||
|
} else if (step == AUTH_STEP.ENTER_OTP) {
|
||||||
|
// if (!await runOtpValidation({ phone: number, otp })) {
|
||||||
|
// setOtp('');
|
||||||
|
// console.error('Wrong otp');
|
||||||
|
// }
|
||||||
|
stop()
|
||||||
|
console.log(await runUserExistCheck(number))
|
||||||
|
if (await runUserExistCheck(number)) {
|
||||||
|
setStep(AUTH_STEP.ENTER_RESET_PASSWORD)
|
||||||
|
} else {
|
||||||
|
// TODO: error user not found
|
||||||
|
}
|
||||||
|
} else if (
|
||||||
|
step == AUTH_STEP.ENTER_CREATE_PASSWORD ||
|
||||||
|
step == AUTH_STEP.ENTER_CURRENT_PASSWORD
|
||||||
|
) {
|
||||||
|
setStep(AUTH_STEP.ENTER_RESET_PASSWORD)
|
||||||
|
} else if (step == AUTH_STEP.ENTER_RESET_PASSWORD) {
|
||||||
|
update_temp_store({
|
||||||
|
password,
|
||||||
|
repeatPassword: passwordRepeat
|
||||||
|
})
|
||||||
|
try {
|
||||||
|
await runResetPassword({
|
||||||
|
phone: number,
|
||||||
|
newPassword: password,
|
||||||
|
otp: otp
|
||||||
|
})
|
||||||
|
console.log('Password changed')
|
||||||
|
redirect('/')
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Could not reset password: ', e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (ex) {
|
||||||
|
console.error(ex)
|
||||||
|
// TODO: Add toast errors
|
||||||
|
|
||||||
|
/* DEV SECTION */
|
||||||
|
/* REMOVE THIS CODE FOR PRODUCTION */
|
||||||
|
if (step == AUTH_STEP.ENTER_NUMBER) {
|
||||||
|
update_temp_store({
|
||||||
|
number
|
||||||
|
})
|
||||||
|
setStep(AUTH_STEP.ENTER_OTP)
|
||||||
|
} else if (step === AUTH_STEP.ENTER_OTP) {
|
||||||
|
setStep(AUTH_STEP.ENTER_RESET_PASSWORD)
|
||||||
|
} else if (
|
||||||
|
step == AUTH_STEP.ENTER_CREATE_PASSWORD ||
|
||||||
|
step == AUTH_STEP.ENTER_CURRENT_PASSWORD
|
||||||
|
) {
|
||||||
|
setStep(AUTH_STEP.ENTER_RESET_PASSWORD)
|
||||||
|
} else if (step == AUTH_STEP.ENTER_RESET_PASSWORD) {
|
||||||
|
update_temp_store({
|
||||||
|
password,
|
||||||
|
repeatPassword: passwordRepeat
|
||||||
|
})
|
||||||
|
try {
|
||||||
|
console.log('Password changed')
|
||||||
|
router.replace('/auth')
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Could not reset password: ', e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* END OF DEV SECTION */
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<AuthFormWrapper isPending={isPending} onSubmit={onSubmit}>
|
||||||
|
{step === AUTH_STEP.ENTER_NUMBER && (
|
||||||
|
<StepEnterNumber
|
||||||
|
pending={isPending}
|
||||||
|
onChange={onChange}
|
||||||
|
value={number}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{step === AUTH_STEP.ENTER_OTP && (
|
||||||
|
<StepEnterOtp
|
||||||
|
pending={isPending}
|
||||||
|
onChange={onChange}
|
||||||
|
onClick={onClick}
|
||||||
|
phoneNumber={number}
|
||||||
|
value={otp}
|
||||||
|
timerRunning={timerRunning}
|
||||||
|
secondsLeft={secondsLeft}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{step === AUTH_STEP.ENTER_RESET_PASSWORD && (
|
||||||
|
<StepNewPassword
|
||||||
|
isReset
|
||||||
|
pending={isPending}
|
||||||
|
onChange={onChange}
|
||||||
|
onClick={onClick}
|
||||||
|
value={password}
|
||||||
|
repeatValue={passwordRepeat}
|
||||||
|
passwordVisible={showPassword}
|
||||||
|
repeatPasswordVisible={showPasswordRepeat}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</AuthFormWrapper>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AuthIndex
|
||||||
@@ -0,0 +1,169 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import React, {
|
||||||
|
useState,
|
||||||
|
type FormEvent,
|
||||||
|
type ChangeEvent,
|
||||||
|
useEffect,
|
||||||
|
useTransition
|
||||||
|
} from 'react'
|
||||||
|
import { useAuthStore } from '@/zustand/authStore'
|
||||||
|
import { redirect, useRouter } from 'next/navigation'
|
||||||
|
import StepEnterPassword from '@/features/auth/components/StepEnterPassword'
|
||||||
|
import StepEnterNumber from '@/features/auth/components/StepEnterNumber'
|
||||||
|
import { AUTH_PAGE_ELEMENT, AUTH_STEP } from '@/enums'
|
||||||
|
import AuthFormWrapper from '@/features/auth/components/AuthFormWrapper'
|
||||||
|
import { useLogin } from '@/hooks/auth/useLogin'
|
||||||
|
import { useCheckUserExistsLazy } from '@/hooks/auth/useCheckUserExists'
|
||||||
|
import { useAuthTempStore } from '@/zustand/authTempStroe'
|
||||||
|
|
||||||
|
type Props = object
|
||||||
|
|
||||||
|
function AuthIndex ({}: Props) {
|
||||||
|
const update_temp_store = useAuthTempStore(state => state.update)
|
||||||
|
const user_temp_store = useAuthTempStore(state => state.user)
|
||||||
|
const [number, setNumber] = useState(user_temp_store?.number ?? '')
|
||||||
|
const [password, setPassword] = useState('')
|
||||||
|
const [showPassword, setShowPassword] = useState(false)
|
||||||
|
const [rememberMe, setRememberMe] = useState(false)
|
||||||
|
const [step, setStep] = useState(
|
||||||
|
number == '' ? AUTH_STEP.ENTER_NUMBER : AUTH_STEP.ENTER_CURRENT_PASSWORD
|
||||||
|
)
|
||||||
|
const [isPending, startTransition] = useTransition()
|
||||||
|
|
||||||
|
const isAuthenticated = useAuthStore(state => state.isAuthenticated)
|
||||||
|
const loginMutation = useLogin()
|
||||||
|
const { run: runUserExistCheck } = useCheckUserExistsLazy()
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (isAuthenticated) {
|
||||||
|
redirect('/')
|
||||||
|
}
|
||||||
|
}, [isAuthenticated])
|
||||||
|
|
||||||
|
const onChange = (e: ChangeEvent<HTMLInputElement>) => {
|
||||||
|
if (e.target.name == AUTH_PAGE_ELEMENT.INPUT_PHONE) {
|
||||||
|
setNumber(() => e.target.value)
|
||||||
|
} else if (e.target.name == AUTH_PAGE_ELEMENT.INPUT_PASSWORD) {
|
||||||
|
setPassword(() => e.target.value)
|
||||||
|
} else if (e.target.name == AUTH_PAGE_ELEMENT.INPUT_REMEMBER_ME) {
|
||||||
|
setRememberMe(state => !state)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const onClick = async (
|
||||||
|
e:
|
||||||
|
| React.MouseEvent<HTMLButtonElement, MouseEvent>
|
||||||
|
| React.MouseEvent<HTMLInputElement, MouseEvent>
|
||||||
|
) => {
|
||||||
|
e.stopPropagation()
|
||||||
|
const target = e.target as HTMLButtonElement
|
||||||
|
|
||||||
|
if (target.id === AUTH_PAGE_ELEMENT.TOGGLE_PASSWORD) {
|
||||||
|
setShowPassword(state => !state)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const onSubmit = async (e: FormEvent<HTMLFormElement>) => {
|
||||||
|
e.preventDefault()
|
||||||
|
startTransition(async () => {
|
||||||
|
try {
|
||||||
|
/* DEV SECTION */
|
||||||
|
/* REMOVE THIS CODE FOR PRODUCTION */
|
||||||
|
throw false
|
||||||
|
/* END OF DEV SECTION */
|
||||||
|
|
||||||
|
/* SECTION DETAILS */
|
||||||
|
/* if number is entered in the /auth page this page directly shows the password page */
|
||||||
|
/* Otherwise it shows the number page */
|
||||||
|
if (step == AUTH_STEP.ENTER_NUMBER) {
|
||||||
|
const userExists = await runUserExistCheck(number)
|
||||||
|
update_temp_store({
|
||||||
|
number: number,
|
||||||
|
mustLogin: userExists
|
||||||
|
})
|
||||||
|
if (userExists) {
|
||||||
|
setStep(AUTH_STEP.ENTER_CURRENT_PASSWORD)
|
||||||
|
} else {
|
||||||
|
router.replace('/auth/signup')
|
||||||
|
}
|
||||||
|
} else if (
|
||||||
|
step == AUTH_STEP.ENTER_OTP ||
|
||||||
|
step == AUTH_STEP.ENTER_CREATE_PASSWORD ||
|
||||||
|
step == AUTH_STEP.ENTER_RESET_PASSWORD
|
||||||
|
) {
|
||||||
|
setStep(AUTH_STEP.ENTER_CURRENT_PASSWORD)
|
||||||
|
} else if (step == AUTH_STEP.ENTER_CURRENT_PASSWORD) {
|
||||||
|
update_temp_store({
|
||||||
|
password,
|
||||||
|
rememberMe
|
||||||
|
})
|
||||||
|
try {
|
||||||
|
await loginMutation.mutateAsync({ phone: number, password })
|
||||||
|
console.log('Signed in')
|
||||||
|
redirect('/')
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Could not Login: ', e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (ex) {
|
||||||
|
console.error(ex)
|
||||||
|
// TODO: Add toast errors
|
||||||
|
|
||||||
|
/* DEV SECTION */
|
||||||
|
/* REMOVE THIS CODE FOR PRODUCTION */
|
||||||
|
if (step == AUTH_STEP.ENTER_NUMBER) {
|
||||||
|
update_temp_store({
|
||||||
|
number,
|
||||||
|
mustLogin: !number.endsWith('0')
|
||||||
|
})
|
||||||
|
setStep(AUTH_STEP.ENTER_CURRENT_PASSWORD)
|
||||||
|
} else if (
|
||||||
|
step == AUTH_STEP.ENTER_OTP ||
|
||||||
|
step == AUTH_STEP.ENTER_CREATE_PASSWORD ||
|
||||||
|
step == AUTH_STEP.ENTER_RESET_PASSWORD
|
||||||
|
) {
|
||||||
|
setStep(AUTH_STEP.ENTER_CURRENT_PASSWORD)
|
||||||
|
} else if (step == AUTH_STEP.ENTER_CURRENT_PASSWORD) {
|
||||||
|
update_temp_store({
|
||||||
|
password,
|
||||||
|
rememberMe
|
||||||
|
})
|
||||||
|
try {
|
||||||
|
console.log('Signed in')
|
||||||
|
redirect('/')
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Could not Login: ', e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* END OF DEV SECTION */
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<AuthFormWrapper isPending={isPending} onSubmit={onSubmit}>
|
||||||
|
{step === AUTH_STEP.ENTER_NUMBER && (
|
||||||
|
<StepEnterNumber
|
||||||
|
pending={isPending}
|
||||||
|
onChange={onChange}
|
||||||
|
value={number}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{step === AUTH_STEP.ENTER_CURRENT_PASSWORD && (
|
||||||
|
<StepEnterPassword
|
||||||
|
pending={isPending}
|
||||||
|
onChange={onChange}
|
||||||
|
onClick={onClick}
|
||||||
|
value={password}
|
||||||
|
passwordVisible={showPassword}
|
||||||
|
rememberMe={rememberMe}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</AuthFormWrapper>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AuthIndex
|
||||||
+57
-169
@@ -1,205 +1,93 @@
|
|||||||
'use client';
|
'use client'
|
||||||
|
|
||||||
import React, { useState, type FormEvent, type ChangeEvent, useEffect, useTransition } from 'react'
|
import React, {
|
||||||
import { useAuthStore } from '@/zustand/authStore';
|
useState,
|
||||||
import { redirect } from 'next/navigation';
|
type FormEvent,
|
||||||
import StepEnterPassword from '@/features/auth/components/StepEnterPassword';
|
type ChangeEvent,
|
||||||
import StepEnterNumber from '@/features/auth/components/StepEnterNumber';
|
useEffect,
|
||||||
import StepEnterOtp from '@/features/auth/components/StepEnterOtp';
|
useTransition
|
||||||
import { AUTH_PAGE_ELEMENT, AUTH_STEP } from '@/enums';
|
} from 'react'
|
||||||
import { useCountdown } from '@/hooks/useCountdown';
|
import { useAuthStore } from '@/zustand/authStore'
|
||||||
import StepNewPassword from '@/features/auth/components/StepNewPassword';
|
import { redirect, useRouter } from 'next/navigation'
|
||||||
import AuthFormWrapper from '@/features/auth/components/AuthFormWrapper';
|
import StepEnterNumber from '@/features/auth/components/StepEnterNumber'
|
||||||
import { useLogin } from '@/hooks/auth/useLogin';
|
import { AUTH_PAGE_ELEMENT } from '@/enums'
|
||||||
import { useSignup } from '@/hooks/auth/useSignup';
|
import AuthFormWrapper from '@/features/auth/components/AuthFormWrapper'
|
||||||
import { useCheckUserExistsLazy } from '@/hooks/auth/useCheckUserExists';
|
import { useCheckUserExistsLazy } from '@/hooks/auth/useCheckUserExists'
|
||||||
import { useOtpRequest } from '@/hooks/auth/useOtpRequest';
|
import { useAuthTempStore } from '@/zustand/authTempStroe'
|
||||||
import { useOtpValidation } from '@/hooks/auth/useOtpValidation';
|
|
||||||
import { useResetPassword } from '@/hooks/auth/useResetPassword';
|
|
||||||
|
|
||||||
type Props = object
|
type Props = object
|
||||||
|
|
||||||
function AuthIndex ({}: Props) {
|
function AuthIndex ({}: Props) {
|
||||||
const [number, setNumber] = useState("");
|
const update_temp_store = useAuthTempStore(state => state.update)
|
||||||
const [password, setPassword] = useState("");
|
const user_temp_store = useAuthTempStore(state => state.user)
|
||||||
const [passwordRepeat, setPasswordRepeat] = useState("");
|
const [number, setNumber] = useState(user_temp_store?.number ?? '')
|
||||||
const [otp, setOtp] = useState("");
|
const [isPending, startTransition] = useTransition()
|
||||||
const [showPassword, setShowPassword] = useState(false);
|
|
||||||
const [showPasswordRepeat, setShowPasswordRepeat] = useState(false);
|
|
||||||
const [rememberMe, setRememberMe] = useState(false);
|
|
||||||
const [step, setStep] = useState(AUTH_STEP.ENTER_NUMBER);
|
|
||||||
const { timerRunning, secondsLeft, restart, stop } = useCountdown(step === AUTH_STEP.ENTER_OTP);
|
|
||||||
const [isPending, startTransition] = useTransition();
|
|
||||||
|
|
||||||
const isAuthenticated = useAuthStore((state) => state.isAuthenticated)
|
const isAuthenticated = useAuthStore(state => state.isAuthenticated)
|
||||||
const loginMutation = useLogin()
|
|
||||||
const signupMutation = useSignup()
|
|
||||||
const { run: runUserExistCheck } = useCheckUserExistsLazy()
|
const { run: runUserExistCheck } = useCheckUserExistsLazy()
|
||||||
const { run: runOtpRequest } = useOtpRequest();
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
||||||
const { run: runOtpValidation } = useOtpValidation();
|
|
||||||
const { run: runResetPassword } = useResetPassword();
|
|
||||||
|
|
||||||
const resetStates = () => {
|
const router = useRouter()
|
||||||
setNumber('');
|
|
||||||
setPassword('');
|
|
||||||
setPasswordRepeat('');
|
|
||||||
setOtp('');
|
|
||||||
setShowPassword(false);
|
|
||||||
setShowPasswordRepeat(false);
|
|
||||||
setRememberMe(false);
|
|
||||||
stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isAuthenticated) {
|
if (isAuthenticated) {
|
||||||
redirect("/");
|
redirect('/')
|
||||||
}
|
}
|
||||||
}, [isAuthenticated])
|
}, [isAuthenticated])
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (step === AUTH_STEP.ENTER_OTP) {
|
|
||||||
startTransition(() => {
|
|
||||||
setOtp('');
|
|
||||||
console.log("REQUEST OTP")
|
|
||||||
runOtpRequest(number);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
||||||
}, [step]);
|
|
||||||
|
|
||||||
const onChange = (e: ChangeEvent<HTMLInputElement>) => {
|
const onChange = (e: ChangeEvent<HTMLInputElement>) => {
|
||||||
if (e.target.name == AUTH_PAGE_ELEMENT.INPUT_PHONE) {
|
if (e.target.name == AUTH_PAGE_ELEMENT.INPUT_PHONE) {
|
||||||
setNumber(() => e.target.value)
|
setNumber(() => e.target.value)
|
||||||
}
|
}
|
||||||
else if (e.target.name == AUTH_PAGE_ELEMENT.INPUT_PASSWORD) {
|
|
||||||
setPassword(() => e.target.value)
|
|
||||||
}
|
}
|
||||||
else if (e.target.name == AUTH_PAGE_ELEMENT.INPUT_PASSWORD_REPEAT) {
|
|
||||||
setPasswordRepeat(() => e.target.value)
|
|
||||||
}
|
|
||||||
else if (e.target.name == AUTH_PAGE_ELEMENT.INPUT_REMEMBER_ME) {
|
|
||||||
setRememberMe((state) => !state)
|
|
||||||
}
|
|
||||||
else if (e.target.name.startsWith(AUTH_PAGE_ELEMENT.INPUT_OTP)) {
|
|
||||||
const index = +e.target.name.split('-')[2];
|
|
||||||
const prev = otp.padEnd(6).split('');
|
|
||||||
prev[index] = e.target.value;
|
|
||||||
const next = prev.join('');
|
|
||||||
if (otp.length >= 6 && next.trim().length >= otp.length) return;
|
|
||||||
setOtp(next.trimEnd());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const onClick = async (e: React.MouseEvent<HTMLButtonElement, MouseEvent> | React.MouseEvent<HTMLInputElement, MouseEvent>) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
const target = e.target as HTMLButtonElement;
|
|
||||||
|
|
||||||
if (target.id === AUTH_PAGE_ELEMENT.TOGGLE_PASSWORD) {
|
|
||||||
setShowPassword((state) => !state);
|
|
||||||
}
|
|
||||||
if (target.id === AUTH_PAGE_ELEMENT.TOGGLE_REPEAT_PASSWORD) {
|
|
||||||
setShowPasswordRepeat((state) => !state);
|
|
||||||
}
|
|
||||||
else if (target.id === AUTH_PAGE_ELEMENT.RESET_PASSWORD) {
|
|
||||||
setShowPassword(false);
|
|
||||||
setShowPasswordRepeat(false);
|
|
||||||
setPassword('');
|
|
||||||
setPasswordRepeat('');
|
|
||||||
setStep(() => AUTH_STEP.ENTER_OTP)
|
|
||||||
}
|
|
||||||
else if (target.id === AUTH_PAGE_ELEMENT.RESEND_OTP) {
|
|
||||||
if (!timerRunning) {
|
|
||||||
startTransition(async () => {
|
|
||||||
try {
|
|
||||||
await runOtpRequest(number);
|
|
||||||
restart();
|
|
||||||
} catch {
|
|
||||||
console.error("Could not ask for otp")
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const onSubmit = async (e: FormEvent<HTMLFormElement>) => {
|
const onSubmit = async (e: FormEvent<HTMLFormElement>) => {
|
||||||
e.preventDefault();
|
e.preventDefault()
|
||||||
startTransition(async () => {
|
startTransition(async () => {
|
||||||
try {
|
try {
|
||||||
if (step == AUTH_STEP.ENTER_NUMBER) {
|
/* DEV SECTION */
|
||||||
|
/* REMOVE THIS CODE FOR PRODUCTION */
|
||||||
|
throw false
|
||||||
|
/* EMD OF DEV SECTION */
|
||||||
|
|
||||||
if (await runUserExistCheck(number)) {
|
/* SECTION DETAILS */
|
||||||
setStep(AUTH_STEP.ENTER_PASSWORD)
|
/* If user is already registered, go to login page */
|
||||||
} else {
|
/* Otherwise go to signup page */
|
||||||
setStep(AUTH_STEP.ENTER_OTP);
|
/* We store auth data in a temp auth store so the next page must */
|
||||||
}
|
/* access the phone number entered in this page */
|
||||||
}
|
/* and if it doesnt, it will ask for the number again */
|
||||||
else if (step == AUTH_STEP.ENTER_PASSWORD) {
|
const userExists = await runUserExistCheck(number)
|
||||||
try {
|
update_temp_store({
|
||||||
await loginMutation.mutateAsync({ phone: number, password })
|
number: number,
|
||||||
console.log("Logged in")
|
mustLogin: userExists
|
||||||
redirect("/")
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
console.error("Wrong credentials: ", e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (step == AUTH_STEP.ENTER_OTP) {
|
|
||||||
// if (!await runOtpValidation({ phone: number, otp })) {
|
|
||||||
// setOtp('');
|
|
||||||
// console.error('Wrong otp');
|
|
||||||
// }
|
|
||||||
stop();
|
|
||||||
console.log(await runUserExistCheck(number));
|
|
||||||
if (await runUserExistCheck(number)) {
|
|
||||||
console.log("1")
|
|
||||||
setStep(AUTH_STEP.ENTER_RESET_PASSWORD)
|
|
||||||
} else {
|
|
||||||
console.log("2")
|
|
||||||
setStep(AUTH_STEP.ENTER_NEW_PASSWORD)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (step == AUTH_STEP.ENTER_RESET_PASSWORD) {
|
|
||||||
console.log("Password changed")
|
|
||||||
try {
|
|
||||||
await runResetPassword({
|
|
||||||
phone: number,
|
|
||||||
newPassword: password,
|
|
||||||
otp
|
|
||||||
})
|
})
|
||||||
resetStates();
|
if (userExists) {
|
||||||
setStep(AUTH_STEP.ENTER_NUMBER)
|
router.push('/auth/login')
|
||||||
} catch (ex) {
|
} else {
|
||||||
console.error('Password reset failed: ', ex)
|
router.push('/auth/signup')
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (step == AUTH_STEP.ENTER_NEW_PASSWORD) {
|
|
||||||
try {
|
|
||||||
await signupMutation.mutateAsync({ phone: number, password })
|
|
||||||
console.log("Signed up")
|
|
||||||
redirect("/")
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
console.error("Could not signup: ", e)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
console.error(ex)
|
console.error(ex)
|
||||||
}
|
// TODO: Add toast errors
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const stepMap = {
|
/* DEV SECTION */
|
||||||
[AUTH_STEP.ENTER_NUMBER]: <StepEnterNumber pending={isPending} onChange={onChange} value={number} />,
|
/* REMOVE THIS CODE FOR PRODUCTION */
|
||||||
[AUTH_STEP.ENTER_PASSWORD]: <StepEnterPassword pending={isPending} onChange={onChange} onClick={onClick} value={password} passwordVisible={showPassword} rememberMe={rememberMe} />,
|
update_temp_store({
|
||||||
[AUTH_STEP.ENTER_OTP]: <StepEnterOtp pending={isPending} onChange={onChange} onClick={onClick} phoneNumber={number} value={otp} timerRunning={timerRunning} secondsLeft={secondsLeft} />,
|
number: number,
|
||||||
[AUTH_STEP.ENTER_NEW_PASSWORD]: <StepNewPassword pending={isPending} onChange={onChange} onClick={onClick} value={password} repeatValue={passwordRepeat} passwordVisible={showPassword} repeatPasswordVisible={showPasswordRepeat} />,
|
mustLogin: !number.endsWith('0')
|
||||||
[AUTH_STEP.ENTER_RESET_PASSWORD]: <StepNewPassword isReset pending={isPending} onChange={onChange} onClick={onClick} value={password} repeatValue={passwordRepeat} passwordVisible={showPassword} repeatPasswordVisible={showPasswordRepeat} />,
|
})
|
||||||
|
if (number.endsWith('0')) {
|
||||||
|
router.push('/auth/signup')
|
||||||
|
} else {
|
||||||
|
router.push('/auth/login')
|
||||||
|
}
|
||||||
|
/* END OF DEV SECTION */
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AuthFormWrapper isPending={isPending} onSubmit={onSubmit}>
|
<AuthFormWrapper isPending={isPending} onSubmit={onSubmit}>
|
||||||
{stepMap[step] || 'say what now?'}
|
<StepEnterNumber pending={isPending} onChange={onChange} value={number} />
|
||||||
</AuthFormWrapper>
|
</AuthFormWrapper>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,241 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import React, {
|
||||||
|
useState,
|
||||||
|
type FormEvent,
|
||||||
|
type ChangeEvent,
|
||||||
|
useEffect,
|
||||||
|
useTransition
|
||||||
|
} from 'react'
|
||||||
|
import { useAuthStore } from '@/zustand/authStore'
|
||||||
|
import { redirect, useRouter } from 'next/navigation'
|
||||||
|
import StepEnterNumber from '@/features/auth/components/StepEnterNumber'
|
||||||
|
import StepEnterOtp from '@/features/auth/components/StepEnterOtp'
|
||||||
|
import { AUTH_PAGE_ELEMENT, AUTH_STEP } from '@/enums'
|
||||||
|
import { useCountdown } from '@/hooks/useCountdown'
|
||||||
|
import StepNewPassword from '@/features/auth/components/StepNewPassword'
|
||||||
|
import AuthFormWrapper from '@/features/auth/components/AuthFormWrapper'
|
||||||
|
import { useSignup } from '@/hooks/auth/useSignup'
|
||||||
|
import { useCheckUserExistsLazy } from '@/hooks/auth/useCheckUserExists'
|
||||||
|
import { useOtpRequest } from '@/hooks/auth/useOtpRequest'
|
||||||
|
import { useOtpValidation } from '@/hooks/auth/useOtpValidation'
|
||||||
|
import { useAuthTempStore } from '@/zustand/authTempStroe'
|
||||||
|
|
||||||
|
type Props = object
|
||||||
|
|
||||||
|
function AuthIndex ({}: Props) {
|
||||||
|
const update_temp_store = useAuthTempStore(state => state.update)
|
||||||
|
const user_temp_store = useAuthTempStore(state => state.user)
|
||||||
|
const [number, setNumber] = useState(user_temp_store?.number ?? '')
|
||||||
|
const [password, setPassword] = useState('')
|
||||||
|
const [passwordRepeat, setPasswordRepeat] = useState('')
|
||||||
|
const [otp, setOtp] = useState('')
|
||||||
|
const [showPassword, setShowPassword] = useState(false)
|
||||||
|
const [showPasswordRepeat, setShowPasswordRepeat] = useState(false)
|
||||||
|
const [step, setStep] = useState(
|
||||||
|
number == '' ? AUTH_STEP.ENTER_NUMBER : AUTH_STEP.ENTER_OTP
|
||||||
|
)
|
||||||
|
const { timerRunning, secondsLeft, restart, stop } = useCountdown(
|
||||||
|
step === AUTH_STEP.ENTER_OTP
|
||||||
|
)
|
||||||
|
const [isPending, startTransition] = useTransition()
|
||||||
|
|
||||||
|
const isAuthenticated = useAuthStore(state => state.isAuthenticated)
|
||||||
|
const signupMutation = useSignup()
|
||||||
|
const { run: runUserExistCheck } = useCheckUserExistsLazy()
|
||||||
|
const { run: runOtpRequest } = useOtpRequest()
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
const { run: runOtpValidation } = useOtpValidation()
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (isAuthenticated) {
|
||||||
|
redirect('/')
|
||||||
|
}
|
||||||
|
}, [isAuthenticated])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (step === AUTH_STEP.ENTER_OTP) {
|
||||||
|
startTransition(() => {
|
||||||
|
setOtp('')
|
||||||
|
console.log('REQUEST OTP')
|
||||||
|
runOtpRequest(number)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [step])
|
||||||
|
|
||||||
|
const onChange = (e: ChangeEvent<HTMLInputElement>) => {
|
||||||
|
if (e.target.name == AUTH_PAGE_ELEMENT.INPUT_PHONE) {
|
||||||
|
setNumber(() => e.target.value)
|
||||||
|
} else if (e.target.name == AUTH_PAGE_ELEMENT.INPUT_PASSWORD) {
|
||||||
|
setPassword(() => e.target.value)
|
||||||
|
} else if (e.target.name == AUTH_PAGE_ELEMENT.INPUT_PASSWORD_REPEAT) {
|
||||||
|
setPasswordRepeat(() => e.target.value)
|
||||||
|
} else if (e.target.name.startsWith(AUTH_PAGE_ELEMENT.INPUT_OTP)) {
|
||||||
|
const index = +e.target.name.split('-')[2]
|
||||||
|
const prev = otp.padEnd(6).split('')
|
||||||
|
prev[index] = e.target.value
|
||||||
|
const next = prev.join('')
|
||||||
|
if (otp.length >= 6 && next.trim().length >= otp.length) return
|
||||||
|
setOtp(next.trimEnd())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const onClick = async (
|
||||||
|
e:
|
||||||
|
| React.MouseEvent<HTMLButtonElement, MouseEvent>
|
||||||
|
| React.MouseEvent<HTMLInputElement, MouseEvent>
|
||||||
|
) => {
|
||||||
|
e.stopPropagation()
|
||||||
|
const target = e.target as HTMLButtonElement
|
||||||
|
|
||||||
|
if (target.id === AUTH_PAGE_ELEMENT.TOGGLE_PASSWORD) {
|
||||||
|
setShowPassword(state => !state)
|
||||||
|
}
|
||||||
|
if (target.id === AUTH_PAGE_ELEMENT.TOGGLE_REPEAT_PASSWORD) {
|
||||||
|
setShowPasswordRepeat(state => !state)
|
||||||
|
} else if (target.id === AUTH_PAGE_ELEMENT.RESET_PASSWORD) {
|
||||||
|
setShowPassword(false)
|
||||||
|
setShowPasswordRepeat(false)
|
||||||
|
setPassword('')
|
||||||
|
setPasswordRepeat('')
|
||||||
|
setStep(() => AUTH_STEP.ENTER_OTP)
|
||||||
|
} else if (target.id === AUTH_PAGE_ELEMENT.RESEND_OTP) {
|
||||||
|
if (!timerRunning) {
|
||||||
|
startTransition(async () => {
|
||||||
|
try {
|
||||||
|
await runOtpRequest(number)
|
||||||
|
restart()
|
||||||
|
} catch {
|
||||||
|
console.error('Could not ask for otp')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const onSubmit = async (e: FormEvent<HTMLFormElement>) => {
|
||||||
|
e.preventDefault()
|
||||||
|
startTransition(async () => {
|
||||||
|
try {
|
||||||
|
/* DEV SECTION */
|
||||||
|
/* REMOVE THIS CODE FOR PRODUCTION */
|
||||||
|
throw false
|
||||||
|
/* END OF DEV SECTION */
|
||||||
|
|
||||||
|
/* SECTION DETAILS */
|
||||||
|
/* if number is entered in the /auth page this page directly shows the OTP page */
|
||||||
|
/* Otherwise it shows the number page */
|
||||||
|
if (step == AUTH_STEP.ENTER_NUMBER) {
|
||||||
|
const userExists = await runUserExistCheck(number)
|
||||||
|
update_temp_store({
|
||||||
|
number: number,
|
||||||
|
mustLogin: userExists
|
||||||
|
})
|
||||||
|
if (userExists) {
|
||||||
|
setStep(AUTH_STEP.ENTER_CURRENT_PASSWORD)
|
||||||
|
} else {
|
||||||
|
setStep(AUTH_STEP.ENTER_OTP)
|
||||||
|
}
|
||||||
|
} else if (step == AUTH_STEP.ENTER_OTP) {
|
||||||
|
// if (!await runOtpValidation({ phone: number, otp })) {
|
||||||
|
// setOtp('');
|
||||||
|
// console.error('Wrong otp');
|
||||||
|
// }
|
||||||
|
update_temp_store({
|
||||||
|
otp: otp
|
||||||
|
})
|
||||||
|
stop()
|
||||||
|
setStep(AUTH_STEP.ENTER_CREATE_PASSWORD)
|
||||||
|
} else if (
|
||||||
|
step == AUTH_STEP.ENTER_CREATE_PASSWORD ||
|
||||||
|
step == AUTH_STEP.ENTER_CURRENT_PASSWORD
|
||||||
|
) {
|
||||||
|
update_temp_store({
|
||||||
|
password: password,
|
||||||
|
repeatPassword: passwordRepeat
|
||||||
|
})
|
||||||
|
try {
|
||||||
|
await signupMutation.mutateAsync({ phone: number, password })
|
||||||
|
console.log('Signed up')
|
||||||
|
redirect('/')
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Could not signup: ', e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (ex) {
|
||||||
|
console.error(ex)
|
||||||
|
// TODO: Add toast errors
|
||||||
|
|
||||||
|
/* DEV SECTION */
|
||||||
|
/* REMOVE THIS CODE FOR PRODUCTION */
|
||||||
|
if (step == AUTH_STEP.ENTER_NUMBER) {
|
||||||
|
update_temp_store({
|
||||||
|
number: number,
|
||||||
|
mustLogin: !number.endsWith('0')
|
||||||
|
})
|
||||||
|
setStep(AUTH_STEP.ENTER_OTP)
|
||||||
|
} else if (step == AUTH_STEP.ENTER_OTP) {
|
||||||
|
stop()
|
||||||
|
update_temp_store({
|
||||||
|
otp: otp
|
||||||
|
})
|
||||||
|
setStep(AUTH_STEP.ENTER_CREATE_PASSWORD)
|
||||||
|
} else if (step == AUTH_STEP.ENTER_CREATE_PASSWORD) {
|
||||||
|
update_temp_store({
|
||||||
|
password: password,
|
||||||
|
repeatPassword: passwordRepeat
|
||||||
|
})
|
||||||
|
try {
|
||||||
|
console.log('Signed up')
|
||||||
|
// redirect('/')
|
||||||
|
router.replace('/') // TODO: redirect to target menu page
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Could not signup: ', e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* END OF DEV SECTION */
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<AuthFormWrapper isPending={isPending} onSubmit={onSubmit}>
|
||||||
|
{step === AUTH_STEP.ENTER_NUMBER && (
|
||||||
|
<StepEnterNumber
|
||||||
|
pending={isPending}
|
||||||
|
onChange={onChange}
|
||||||
|
value={number}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{step === AUTH_STEP.ENTER_OTP && (
|
||||||
|
<StepEnterOtp
|
||||||
|
pending={isPending}
|
||||||
|
onChange={onChange}
|
||||||
|
onClick={onClick}
|
||||||
|
phoneNumber={number}
|
||||||
|
value={otp}
|
||||||
|
timerRunning={timerRunning}
|
||||||
|
secondsLeft={secondsLeft}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{step === AUTH_STEP.ENTER_CREATE_PASSWORD && (
|
||||||
|
<StepNewPassword
|
||||||
|
isReset
|
||||||
|
pending={isPending}
|
||||||
|
onChange={onChange}
|
||||||
|
onClick={onClick}
|
||||||
|
value={password}
|
||||||
|
repeatValue={passwordRepeat}
|
||||||
|
passwordVisible={showPassword}
|
||||||
|
repeatPasswordVisible={showPasswordRepeat}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</AuthFormWrapper>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AuthIndex
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
export enum AUTH_STEP {
|
export enum AUTH_STEP {
|
||||||
ENTER_NUMBER = 0,
|
ENTER_NUMBER = 0,
|
||||||
ENTER_PASSWORD = 1,
|
ENTER_CURRENT_PASSWORD = 1,
|
||||||
ENTER_OTP = 2,
|
ENTER_OTP = 2,
|
||||||
ENTER_NEW_PASSWORD = 3,
|
ENTER_CREATE_PASSWORD = 3,
|
||||||
ENTER_RESET_PASSWORD = 4,
|
ENTER_RESET_PASSWORD = 4,
|
||||||
}
|
}
|
||||||
@@ -5,6 +5,7 @@ import { EyeToggleIcon } from '@/components/icons/EyeToggleIcon'
|
|||||||
import InputField from '@/components/input/InputField'
|
import InputField from '@/components/input/InputField'
|
||||||
import { AUTH_PAGE_ELEMENT } from '@/enums'
|
import { AUTH_PAGE_ELEMENT } from '@/enums'
|
||||||
import Image from 'next/image'
|
import Image from 'next/image'
|
||||||
|
import Link from 'next/link'
|
||||||
import React, { useEffect, useState } from 'react'
|
import React, { useEffect, useState } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
|
|
||||||
@@ -88,14 +89,14 @@ function StepEnterPassword ({
|
|||||||
</button>
|
</button>
|
||||||
</InputField>
|
</InputField>
|
||||||
<div className='inline-flex justify-between items-center w-full pt-3'>
|
<div className='inline-flex justify-between items-center w-full pt-3'>
|
||||||
<button
|
<Link
|
||||||
|
href={'/auth/forgot-password'}
|
||||||
id={AUTH_PAGE_ELEMENT.RESET_PASSWORD}
|
id={AUTH_PAGE_ELEMENT.RESET_PASSWORD}
|
||||||
type='button'
|
type='button'
|
||||||
onClick={onClick}
|
|
||||||
className='text-sm2 cursor-pointer'
|
className='text-sm2 cursor-pointer'
|
||||||
>
|
>
|
||||||
{t('EnterPass.ButtonRecover')}
|
{t('EnterPass.ButtonRecover')}
|
||||||
</button>
|
</Link>
|
||||||
|
|
||||||
<div className='inline-flex justify-between items-center'>
|
<div className='inline-flex justify-between items-center'>
|
||||||
{/* TODO: customize checkbox */}
|
{/* TODO: customize checkbox */}
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
// zustand/userStore.ts
|
||||||
|
import { create } from 'zustand'
|
||||||
|
import { createJSONStorage, persist } from 'zustand/middleware'
|
||||||
|
|
||||||
|
type TempUser = {
|
||||||
|
number?: string
|
||||||
|
otp?: string
|
||||||
|
password?: string
|
||||||
|
repeatPassword?: string
|
||||||
|
previousPassword?: string
|
||||||
|
mustLogin?: boolean
|
||||||
|
rememberMe?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
type AuthTempStore = {
|
||||||
|
user: TempUser | null
|
||||||
|
update: (userData: TempUser) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useAuthTempStore = create<AuthTempStore>()(
|
||||||
|
persist(
|
||||||
|
set => ({
|
||||||
|
user: null,
|
||||||
|
mustLogin: false,
|
||||||
|
update: userData => {
|
||||||
|
set(state => {
|
||||||
|
if (!userData) return state // no user to update
|
||||||
|
return {
|
||||||
|
user: {
|
||||||
|
...state.user,
|
||||||
|
...userData
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
name: 'auth-temp-storage', // Key in localStorage
|
||||||
|
storage: createJSONStorage(() => sessionStorage)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
Reference in New Issue
Block a user