otp request + otp verify + component toast
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
import { useMutation } from "@tanstack/react-query";
|
||||
import * as api from "../service/LoginService";
|
||||
|
||||
export const useOtpRequest = () => {
|
||||
return useMutation({
|
||||
mutationFn: api.loginOTP,
|
||||
});
|
||||
};
|
||||
|
||||
export const useOtpVerify = () => {
|
||||
return useMutation({
|
||||
mutationFn: api.loginVerifyOTP,
|
||||
});
|
||||
};
|
||||
+12
-158
@@ -1,169 +1,23 @@
|
||||
'use client'
|
||||
|
||||
import React, {
|
||||
useState,
|
||||
type FormEvent,
|
||||
type ChangeEvent,
|
||||
useEffect,
|
||||
useTransition
|
||||
} from 'react'
|
||||
import { useAuthStore } from '@/zustand/authStore'
|
||||
import { redirect, useParams, useRouter } from 'next/navigation'
|
||||
import StepEnterPassword from '@/features/auth/components/StepEnterPassword'
|
||||
import React from 'react'
|
||||
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()
|
||||
const { name } = useParams()
|
||||
const basePath = `/${name ?? ''}`
|
||||
|
||||
useEffect(() => {
|
||||
if (isAuthenticated) {
|
||||
redirect(basePath)
|
||||
}
|
||||
}, [isAuthenticated, basePath])
|
||||
|
||||
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(`${basePath}/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')
|
||||
router.replace(basePath)
|
||||
} 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')
|
||||
router.replace(basePath)
|
||||
} catch (e) {
|
||||
console.error('Could not Login: ', e)
|
||||
}
|
||||
}
|
||||
/* END OF DEV SECTION */
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function AuthIndex({ }: Props) {
|
||||
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 isPending={false} onSubmit={() => undefined}>
|
||||
<StepEnterNumber />
|
||||
{/* <StepEnterPassword
|
||||
pending={false}
|
||||
onChange={() => undefined}
|
||||
onClick={() => undefined}
|
||||
value=''
|
||||
passwordVisible={false}
|
||||
rememberMe={false}
|
||||
/> */}
|
||||
</AuthFormWrapper>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
import { api } from "@/lib/api/axiosInstance";
|
||||
import { LoginOTPRequestType, LoginVerifyOTPType } from "../types/Types";
|
||||
|
||||
export const loginOTP = async (params: LoginOTPRequestType) => {
|
||||
const { data } = await api.post("/auth/otp/request", params);
|
||||
return data;
|
||||
};
|
||||
|
||||
export const loginVerifyOTP = async (params: LoginVerifyOTPType) => {
|
||||
const { data } = await api.post("/auth/otp/verify", params);
|
||||
return data;
|
||||
};
|
||||
@@ -0,0 +1,9 @@
|
||||
export type LoginOTPRequestType = {
|
||||
phone: string;
|
||||
slug: string;
|
||||
};
|
||||
|
||||
export type LoginVerifyOTPType = {
|
||||
phone: string;
|
||||
otp: string;
|
||||
};
|
||||
Reference in New Issue
Block a user