feat: register and otp integration

This commit is contained in:
boboiazumi
2025-05-26 20:14:26 +07:00
parent 363f1582c9
commit 935d23887c
14 changed files with 273 additions and 90 deletions
+2 -2
View File
@@ -34,8 +34,8 @@ export const postVerifyEmail = async (
): Promise<TResponseMessage> => {
const { data } = await api({
method: 'POST',
url: '/auth/verify',
data: payload,
url: '/auth/verify-email',
data: {otp: parseInt(payload.otp), email: payload.email},
});
return data;
};
+9
View File
@@ -57,3 +57,12 @@ export const authRegisterSchema = z
message: 'Password dan Konfirmasi Password harus sama',
path: ['confirm_password'],
});
export const verifyEmailSchema = z
.object({
otp: z
.string({
required_error: 'OTP tidak boleh kosong',
})
.min(6, 'Masukkan kode 6 digit yang dikirimkan ke email')
})
+2 -2
View File
@@ -20,10 +20,10 @@ export type TRegisterRequest = z.infer<typeof authRegisterSchema>;
export type TRegisterResponse = TResponseDetail<TResponseMessage>;
export type TVerifyOtpRequest = {
otp: number;
otp: string;
};
export type TVerifyEmailRequest = {
email: string;
otp: number;
otp: string;
};
+7 -2
View File
@@ -1,21 +1,26 @@
// eslint-disable-next-line @nx/enforce-module-boundaries
import { Input } from "@imphnen-frontend-service/ui/atoms";
import { ChangeEvent, DetailedHTMLProps, FC, InputHTMLAttributes, ReactElement, useRef, useState } from "react"
import { ChangeEvent, DetailedHTMLProps, FC, InputHTMLAttributes, ReactElement, useEffect, useRef, useState } from "react"
type TForgotStepProps = Omit<
DetailedHTMLProps<InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>,
'size' | 'type'
> & {
setChange?: React.Dispatch<React.SetStateAction<any[]>>
};
export const OtpForm: FC<TForgotStepProps> = ({
step = 1,
setChange = (x: string[]) => {return},
...rest
}): ReactElement => {
const [cell, setCell] = useState(new Array(6).fill(""))
const inputRef = useRef([])
useEffect(() => {
setChange(cell)
}, [cell, setChange])
const handleChange = (index: number, e: ChangeEvent<HTMLInputElement>) => {
const value = e.target.value
if (!(/^[0-9]?$/.test(value))) return;
+2
View File
@@ -2,3 +2,5 @@ export * from './use-query-state';
export * from './use-auth-store';
export * from './use-modal-login';
export * from './use-session';
export * from './use-register';
export * from './use-otp';
+29
View File
@@ -0,0 +1,29 @@
import { TVerifyOtpRequest, usePostVerifyEmail } from '@imphnen-frontend-service/service';
import { toast } from 'sonner';
import { useNavigate, useSearchParams } from 'react-router';
export const useOtp = () => {
const navigate = useNavigate();
const { mutate, isPending } = usePostVerifyEmail();
const [ searchParams ] = useSearchParams();
const otp = (payload: TVerifyOtpRequest) => {
mutate({ ...payload, email: searchParams.get("email") || "" }, {
onSuccess: (data) => {
toast.success('Berhasil Registrasi');
navigate("/auth/register/success");
},
onError: (err) => {
toast.error(
err?.response?.data?.message ??
'Terjadi Kesalahan yang tidak diketahui'
);
},
});
};
return {
otp,
isLoading: isPending,
};
};
+28
View File
@@ -0,0 +1,28 @@
import { TRegisterRequest, usePostRegister } from '@imphnen-frontend-service/service';
import { toast } from 'sonner';
import { useNavigate } from 'react-router';
export const useRegister = () => {
const navigate = useNavigate();
const { mutate, isPending } = usePostRegister();
const register = (payload: TRegisterRequest) => {
mutate(payload, {
onSuccess: (data) => {
toast.success('Berhasil Registrasi');
navigate(`/auth/register/otp?email=${payload.email}`);
},
onError: (err) => {
toast.error(
err?.response?.data?.message ??
'Terjadi Kesalahan yang tidak diketahui'
);
},
});
};
return {
register,
isLoading: isPending,
};
};