diff --git a/apps/dimentorin/src/app/_hooks/use-resend-otp.ts b/apps/dimentorin/src/app/_hooks/use-resend-otp.ts
new file mode 100644
index 0000000..29f0b71
--- /dev/null
+++ b/apps/dimentorin/src/app/_hooks/use-resend-otp.ts
@@ -0,0 +1,10 @@
+import { useSendOTP } from '@imphnen-frontend-service/utils';
+
+export const useResendOtpHook = () => {
+
+ const { resendOTP, isLoading } = useSendOTP();
+
+ return {
+ resendOTP
+ };
+};
\ No newline at end of file
diff --git a/apps/dimentorin/src/app/auth/register/otp/page.tsx b/apps/dimentorin/src/app/auth/register/otp/page.tsx
index 249ca78..a79b525 100644
--- a/apps/dimentorin/src/app/auth/register/otp/page.tsx
+++ b/apps/dimentorin/src/app/auth/register/otp/page.tsx
@@ -1,12 +1,38 @@
-import { FC, ReactElement } from 'react';
+import { FC, ReactElement, useEffect, useState } from 'react';
import { ControlledInputField, RegisterResetBanner } from "@imphnen-frontend-service/ui/organisms";
import { useOtpHook } from '../../../_hooks/use-otp';
import { Button } from '@imphnen-frontend-service/ui/atoms';
import { useSearchParams } from 'react-router-dom';
+import { useResendOtpHook } from '../../../_hooks/use-resend-otp';
export const Components: FC = (): ReactElement => {
const { form, onSubmit, isLoading } = useOtpHook()
const [ searchParams ] = useSearchParams()
+ const [ disabled, setDisabled] = useState(true);
+ const [ timeLeft, setTimeLeft ] = useState(5 * 60);
+ const { resendOTP } = useResendOtpHook()
+
+ useEffect(() => {
+ if (disabled) {
+ const interval = setInterval(() => {
+ setTimeLeft(prev => {
+ if (prev <= 1) {
+ clearInterval(interval);
+ setDisabled(false);
+ return 0;
+ }
+ return prev - 1;
+ });
+ }, 1000);
+ return () => clearInterval(interval);
+ }
+ }, [disabled]);
+
+ const formatTime = (seconds: number) => {
+ const m = Math.floor(seconds / 60);
+ const s = seconds % 60;
+ return `${m}:${s.toString().padStart(2, '0')}`;
+ };
return (
@@ -26,6 +52,13 @@ export const Components: FC = (): ReactElement => {
maxLength={6}
control={form.control}
/>
+
diff --git a/apps/dimentorin/src/middleware.ts b/apps/dimentorin/src/middleware.ts
index c172d70..c9e06f7 100644
--- a/apps/dimentorin/src/middleware.ts
+++ b/apps/dimentorin/src/middleware.ts
@@ -10,7 +10,7 @@ const mappingPublicRoutes = [
'/auth/login',
'/auth/forgot',
'/auth/forgot/otp',
- '/auth/register',
+ '/auth/register',
'/auth/register/otp',
'/auth/register/success',
'/auth/new-password',
diff --git a/libs/service/src/api/auth/index.ts b/libs/service/src/api/auth/index.ts
index 7f1024c..08cb959 100644
--- a/libs/service/src/api/auth/index.ts
+++ b/libs/service/src/api/auth/index.ts
@@ -3,6 +3,7 @@ import {
TLoginRequest,
TLoginResponse,
TRegisterRequest,
+ TSendOTPRequest,
TVerifyEmailRequest,
} from '../../types/auth';
import { TResponseMessage } from '../../types/common';
@@ -35,7 +36,18 @@ export const postVerifyEmail = async (
const { data } = await api({
method: 'POST',
url: '/auth/verify-email',
- data: { otp: parseInt(payload.otp), email: payload.email },
+ data: {otp: parseInt(payload.otp), email: payload.email},
+ });
+ return data;
+};
+
+export const postSendOtp = async (
+ payload: TSendOTPRequest
+): Promise => {
+ const { data } = await api({
+ method: 'POST',
+ url: '/auth/send-otp',
+ data: payload,
});
return data;
};
diff --git a/libs/service/src/hooks/auth/index.ts b/libs/service/src/hooks/auth/index.ts
index 4c2540b..67570b8 100644
--- a/libs/service/src/hooks/auth/index.ts
+++ b/libs/service/src/hooks/auth/index.ts
@@ -1,9 +1,10 @@
import { useMutation, UseMutationResult } from '@tanstack/react-query';
-import { postLogin, postRegister, postVerifyEmail } from '../../api/auth';
+import { postLogin, postRegister, postSendOtp, postVerifyEmail } from '../../api/auth';
import {
TLoginRequest,
TLoginResponse,
TRegisterRequest,
+ TSendOTPRequest,
TVerifyEmailRequest,
} from '../../types/auth';
@@ -44,3 +45,16 @@ export const usePostVerifyEmail = (): UseMutationResult<
mutationFn: async (payload) => await postVerifyEmail(payload),
});
};
+
+export const usePostSendOTP = (): UseMutationResult<
+ TResponseMessage,
+ TResponseError,
+ TSendOTPRequest,
+ unknown
+> => {
+ return useMutation({
+ mutationKey: ['post-send-otp'],
+ mutationFn: async (payload) => await postSendOtp(payload),
+ });
+};
+
diff --git a/libs/service/src/types/auth/index.ts b/libs/service/src/types/auth/index.ts
index 8471fcd..b1b133c 100644
--- a/libs/service/src/types/auth/index.ts
+++ b/libs/service/src/types/auth/index.ts
@@ -27,3 +27,7 @@ export type TVerifyEmailRequest = {
email: string;
otp: string;
};
+
+export type TSendOTPRequest = {
+ email: string
+};
\ No newline at end of file
diff --git a/libs/utils/src/hooks/index.ts b/libs/utils/src/hooks/index.ts
index 40fb27d..749ecb2 100644
--- a/libs/utils/src/hooks/index.ts
+++ b/libs/utils/src/hooks/index.ts
@@ -3,4 +3,5 @@ export * from './use-auth-store';
export * from './use-modal-login';
export * from './use-session';
export * from './use-register';
-export * from './use-otp';
\ No newline at end of file
+export * from './use-otp';
+export * from './use-send-otp';
\ No newline at end of file
diff --git a/libs/utils/src/hooks/use-send-otp.ts b/libs/utils/src/hooks/use-send-otp.ts
new file mode 100644
index 0000000..107197c
--- /dev/null
+++ b/libs/utils/src/hooks/use-send-otp.ts
@@ -0,0 +1,25 @@
+import { TSendOTPRequest, usePostSendOTP } from '@imphnen-frontend-service/service';
+import { toast } from 'sonner';
+
+export const useSendOTP = () => {
+ const { mutate, isPending } = usePostSendOTP();
+
+ const resendOTP = (payload: TSendOTPRequest) => {
+ mutate(payload, {
+ onSuccess: (data) => {
+ toast.success('Berhasil Mengirim Ulang OTP');
+ },
+ onError: (err) => {
+ toast.error(
+ err?.response?.data?.message ??
+ 'Terjadi Kesalahan yang tidak diketahui'
+ );
+ },
+ });
+ };
+
+ return {
+ resendOTP,
+ isLoading: isPending,
+ };
+};