improve: overall ux in auth page

This commit is contained in:
Mahyar Khanbolooki
2025-07-14 20:59:01 +03:30
parent b344e7d291
commit 69540a67f2
10 changed files with 165 additions and 119 deletions
+82 -77
View File
@@ -1,6 +1,6 @@
'use client';
import React, { useState, type FormEvent, type ChangeEvent, useEffect } from 'react'
import React, { useState, type FormEvent, type ChangeEvent, useEffect, useTransition } from 'react'
import { useAuthStore } from '@/zustand/authStore';
import { redirect } from 'next/navigation';
import StepEnterPassword from '@/features/auth/components/StepEnterPassword';
@@ -20,7 +20,6 @@ import { useResetPassword } from '@/hooks/auth/useResetPassword';
type Props = object
function AuthIndex({ }: Props) {
const [isPending, setIsPending] = useState(false);
const [number, setNumber] = useState("");
const [password, setPassword] = useState("");
const [passwordRepeat, setPasswordRepeat] = useState("");
@@ -30,12 +29,14 @@ function AuthIndex({ }: Props) {
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 loginMutation = useLogin()
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 { run: runResetPassword } = useResetPassword();
@@ -58,10 +59,13 @@ function AuthIndex({ }: Props) {
useEffect(() => {
if (step === AUTH_STEP.ENTER_OTP) {
setOtp('');
console.log("REQUEST OTP")
runOtpRequest(number);
startTransition(() => {
setOtp('');
console.log("REQUEST OTP")
runOtpRequest(number);
});
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [step]);
const onChange = (e: ChangeEvent<HTMLInputElement>) => {
@@ -106,90 +110,91 @@ function AuthIndex({ }: Props) {
}
else if (target.id === AUTH_PAGE_ELEMENT.RESEND_OTP) {
if (!timerRunning) {
try {
await runOtpRequest(number);
restart();
} catch {
console.error("Could not ask for otp")
}
startTransition(async () => {
try {
await runOtpRequest(number);
restart();
} catch {
console.error("Could not ask for otp")
}
});
}
}
};
const onSubmit = async (e: FormEvent<HTMLFormElement>) => {
e.preventDefault();
try {
setIsPending(true);
if (step == AUTH_STEP.ENTER_NUMBER) {
startTransition(async () => {
try {
if (step == AUTH_STEP.ENTER_NUMBER) {
if (await runUserExistCheck(number)) {
setStep(AUTH_STEP.ENTER_PASSWORD)
} else {
setStep(AUTH_STEP.ENTER_OTP);
if (await runUserExistCheck(number)) {
setStep(AUTH_STEP.ENTER_PASSWORD)
} else {
setStep(AUTH_STEP.ENTER_OTP);
}
}
else if (step == AUTH_STEP.ENTER_PASSWORD) {
try {
await loginMutation.mutateAsync({ phone: number, password })
console.log("Logged in")
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();
setStep(AUTH_STEP.ENTER_NUMBER)
} catch (ex) {
console.error('Password reset failed: ', ex)
}
}
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) {
console.error(ex)
}
else if (step == AUTH_STEP.ENTER_PASSWORD) {
try {
await loginMutation.mutateAsync({ phone: number, password })
console.log("Logged in")
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();
setStep(AUTH_STEP.ENTER_NUMBER)
} catch (ex) {
console.error('Password reset failed: ', ex)
}
}
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) {
console.error(ex)
} finally {
setIsPending(false);
}
});
}
const stepMap = {
[AUTH_STEP.ENTER_NUMBER]: <StepEnterNumber disabled={isPending} onChange={onChange} value={number} />,
[AUTH_STEP.ENTER_PASSWORD]: <StepEnterPassword disabled={isPending} onChange={onChange} onClick={onClick} value={password} passwordVisible={showPassword} rememberMe={rememberMe} />,
[AUTH_STEP.ENTER_OTP]: <StepEnterOtp disabled={isPending} onChange={onChange} onClick={onClick} phoneNumber={number} value={otp} timerRunning={timerRunning} secondsLeft={secondsLeft} />,
[AUTH_STEP.ENTER_NEW_PASSWORD]: <StepNewPassword disabled={isPending} onChange={onChange} onClick={onClick} value={password} repeatValue={passwordRepeat} passwordVisible={showPassword} repeatPasswordVisible={showPasswordRepeat} />,
[AUTH_STEP.ENTER_RESET_PASSWORD]: <StepNewPassword isReset disabled={isPending} onChange={onChange} onClick={onClick} value={password} repeatValue={passwordRepeat} passwordVisible={showPassword} repeatPasswordVisible={showPasswordRepeat} />,
[AUTH_STEP.ENTER_NUMBER]: <StepEnterNumber pending={isPending} onChange={onChange} value={number} />,
[AUTH_STEP.ENTER_PASSWORD]: <StepEnterPassword pending={isPending} onChange={onChange} onClick={onClick} value={password} passwordVisible={showPassword} rememberMe={rememberMe} />,
[AUTH_STEP.ENTER_OTP]: <StepEnterOtp pending={isPending} onChange={onChange} onClick={onClick} phoneNumber={number} value={otp} timerRunning={timerRunning} secondsLeft={secondsLeft} />,
[AUTH_STEP.ENTER_NEW_PASSWORD]: <StepNewPassword pending={isPending} onChange={onChange} onClick={onClick} value={password} repeatValue={passwordRepeat} passwordVisible={showPassword} repeatPasswordVisible={showPasswordRepeat} />,
[AUTH_STEP.ENTER_RESET_PASSWORD]: <StepNewPassword isReset pending={isPending} onChange={onChange} onClick={onClick} value={password} repeatValue={passwordRepeat} passwordVisible={showPassword} repeatPasswordVisible={showPasswordRepeat} />,
}
return (