From f50a4f6409381e7b17641a0cefc717b03bfdcaa2 Mon Sep 17 00:00:00 2001 From: ivan-sim Date: Tue, 21 May 2024 10:36:39 +0700 Subject: [PATCH] Update Add user hospital portal --- .../Http/Controllers/Api/AuthController.php | 154 +++++++++++++++--- Modules/HospitalPortal/Routes/api.php | 5 +- .../hospital-portal/public/lang/en-US.json | 20 ++- .../hospital-portal/public/lang/id-ID.json | 19 ++- .../src/pages/auth/ForgetPassword.tsx | 8 +- .../src/pages/auth/ResetPassword.tsx | 31 ++-- .../src/pages/auth/VerifyCode.tsx | 63 ++++++- frontend/hospital-portal/src/routes/index.tsx | 6 +- frontend/hospital-portal/src/routes/paths.ts | 2 +- .../forget-password/ForgetPasswordForm.tsx | 33 ++-- .../src/sections/auth/login/LoginForm.tsx | 6 +- .../auth/reset-password/ResetPasswordForm.tsx | 16 +- .../auth/verify-code/VerifyCodeForm.tsx | 114 ++++++++----- frontend/hospital-portal/src/utils/token.ts | 3 +- 14 files changed, 366 insertions(+), 114 deletions(-) diff --git a/Modules/HospitalPortal/Http/Controllers/Api/AuthController.php b/Modules/HospitalPortal/Http/Controllers/Api/AuthController.php index 44beb6b9..701b0f78 100644 --- a/Modules/HospitalPortal/Http/Controllers/Api/AuthController.php +++ b/Modules/HospitalPortal/Http/Controllers/Api/AuthController.php @@ -93,27 +93,6 @@ class AuthController extends Controller } public function verifyEmail(Request $request) - { - $request->validate([ - 'email' => 'required|email', - ]); - - $user = User::query() - ->where('email', $request->email) - ->first(); - - if (!$user) { - return response(['Message' => 'User Tidak Ditemukan'], 404); - } - - Event(new ForgetPassword($user)); - - // Mail::to($user->email)->send(new SendVerifyEmail($user)); - - return response()->json($user); - } - - public function forgotPassword(Request $request) { $data = [ 'email' => $request->email, @@ -144,7 +123,7 @@ class AuthController extends Controller 'user_id' => $user->id, 'email' => $emailTo, 'title' => 'Forgot Password', - 'description' => 'Request forgot password from App Doctor', + 'description' => 'Request forgot password from Hospital Portal', 'type' => 1, 'isUnRead' => true, 'created_by' => auth()->check() ? auth()->user()->id : null, @@ -168,7 +147,7 @@ class AuthController extends Controller $dataEmail = [ 'email' => $emailTo, 'name' => $nameTo, - 'subject' => 'Request Forgot Password from App Doctor Date '. date('Y-m-d H:i:s'), + 'subject' => 'Request Forgot Password from Hospital Portal Date '. date('Y-m-d H:i:s'), 'body' => View::make('email/forgot_password', ['token' => $token])->render(), ]; Helper::sendEmail($dataEmail); @@ -176,7 +155,7 @@ class AuthController extends Controller $res = DB::table('password_resets') ->where('email', '=', $request->email) ->where('token', '=', $token) - ->get(); + ->first(); return ApiResponse::apiResponse("Success", $res, trans('Message.success'), 200); } @@ -186,4 +165,131 @@ class AuthController extends Controller } } } + + public function verifCode(Request $request) + { + $data = [ + 'email' => $request->email, + 'token' => $request->token, + ]; + + $validator = Validator::make($request->all(), [ + 'email' => 'required|email', + 'token' => 'required|numeric', + ], [ + 'email.required' => trans('Validation.required',['attribute' => 'Email']), + 'email.email' => trans('Validation.email'), + 'token.required' => trans('Validation.required',['attribute' => 'Token']), + 'token.numeric' => trans('Validation.required',['attribute' => 'Code Numeric']), + ]); + + if ($validator->fails()) + { + return ApiResponse::apiResponse('Bad Request', $data, $validator->errors(), 400); + } + else + { + //Check Time + $check = DB::table('password_resets') + ->where('email', '=', $request->email) + ->where('token', '=', $request->token) + ->select('created_at') + ->first(); + + if($check) + { + $created_at = strtotime($check->created_at); // Konversi string waktu ke UNIX timestamp + $now = time(); // Waktu sekarang dalam UNIX timestamp + + // Hitung selisih waktu dalam menit + $diffInMinutes = ($now - $created_at) / 60; + + if ($diffInMinutes > 60) { + return ApiResponse::apiResponse('Not Found', $data, trans('Message.token_expired'), 404); + } else { + // Lanjutkan dengan proses pemulihan kata sandi + return ApiResponse::apiResponse("Success", $data, trans('Message.success'), 200); + } + } + else + { + return ApiResponse::apiResponse('Not Found', $data, trans('Message.not_found'), 404); + } + } + } + + public function forgetPassword(Request $request) + { + $data = [ + 'email' => $request->email, + 'token' => $request->token, + 'new_password' => $request->new_password + ]; + + $validator = Validator::make($request->all(), [ + 'email' => 'required|email', + 'token' => 'required|numeric', + 'new_password' => [ + 'required', + 'min:8', + 'regex:/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}$/' + ] + ], [ + 'email.required' => trans('Validation.required',['attribute' => 'Email']), + 'email.email' => trans('Validation.email'), + 'token.required' => trans('Validation.required',['attribute' => 'Token']), + 'new_password.required' => trans('Validation.required',['attribute' => 'New Password']), + 'new_password.min' => trans('Validation.min',['attribute' => 'New Password']), + 'new_password.regex' => trans('Validation.regex',['attribute' => 'New Password']), + ]); + + if($request->new_password != $request->confirm_new_password) + { + return ApiResponse::apiResponse('Bad Request', $data, 'Confirm password is not the same', 400); + } + else if ($validator->fails()) + { + return ApiResponse::apiResponse('Bad Request', $data, $validator->errors(), 400); + } + else + { + //Check Time + $check = DB::table('password_resets') + ->where('email', '=', $request->email) + ->where('token', '=', $request->token) + ->select('created_at') + ->first(); + + if($check) + { + $created_at = strtotime($check->created_at); // Konversi string waktu ke UNIX timestamp + $now = time(); // Waktu sekarang dalam UNIX timestamp + + // Hitung selisih waktu dalam menit + $diffInMinutes = ($now - $created_at) / 60; + + if ($diffInMinutes > 60) { + return ApiResponse::apiResponse('Not Found', $data, trans('Message.token_expired'), 404); + } else { + // Lanjutkan dengan proses pemulihan kata sandi + $user = User::where('email', $request->email)->first(); + if ($user) + { + $newPassword = Hash::make($request->new_password); + $user->password = $newPassword; + $user->save(); + return ApiResponse::apiResponse("Success", $data, trans('Message.success'), 200); + } + else + { + return ApiResponse::apiResponse('Not Found', $data, trans('Message.token_expired'), 404); + } + } + } + else + { + return ApiResponse::apiResponse('Not Found', $data, trans('Message.not_found'), 404); + } + } + } } diff --git a/Modules/HospitalPortal/Routes/api.php b/Modules/HospitalPortal/Routes/api.php index 7b9cbeb3..a0591a36 100644 --- a/Modules/HospitalPortal/Routes/api.php +++ b/Modules/HospitalPortal/Routes/api.php @@ -29,8 +29,9 @@ Route::prefix('v1')->group(function() { }); }); - Route::post('forgot-password', [AuthController::class, 'forgotPassword']); - // Route::post('verify-email', [AuthController::class, 'verifyEmail'])->name('verify-email'); + Route::post('forget-password', [AuthController::class, 'forgetPassword']); + Route::post('verify-email', [AuthController::class, 'verifyEmail'])->name('verify-email'); + Route::post('verify-code', [AuthController::class, 'verifCode']); Route::middleware('auth:sanctum')->group(function () { diff --git a/frontend/hospital-portal/public/lang/en-US.json b/frontend/hospital-portal/public/lang/en-US.json index 19a07abf..2f260eca 100644 --- a/frontend/hospital-portal/public/lang/en-US.json +++ b/frontend/hospital-portal/public/lang/en-US.json @@ -60,5 +60,23 @@ "txtDialogConfirmation": "Are you sure you want to proceed with this action?", "txtStartDate": "Start Date", "txtEndDate": "End Date", - "txtHelp1" : "Has problem with your account?" + "txtHelp1" : "Has problem with your account?", + "txtLupaSandi": "Forgot password?", + "txtIngatkanSaya": "Remember me", + "txtLogin": "Login", + "txtForgotYourPassword": "Forgot your password?", + "txtPleaseEnterPassword": "Please enter the email address associated with your account and We will email you a code to reset your password.", + "txtBack": "Back", + "txtSuccessSend": "Request sent successfully", + "txtCodeConfirm": "We have sent a confirmation email to", + "txtPleasCheck": "Please check your email.", + "txtCheckEmail": "Please check your email!", + "txtEmail": "We have emailed a 6-digit confirmation code and check spam folder, please enter the code in below box to verify your email.", + "txtDont": "Don’t have a code?", + "txtResendCode": "Resend code", + "txtSecond": "Second", + "txtPleaseInput": "Please enter your new password.", + "txtNewPassword": "New Password", + "txtConfPassword": "Confirm Kata Sandi" + } diff --git a/frontend/hospital-portal/public/lang/id-ID.json b/frontend/hospital-portal/public/lang/id-ID.json index b2eb32f6..52ea72a6 100644 --- a/frontend/hospital-portal/public/lang/id-ID.json +++ b/frontend/hospital-portal/public/lang/id-ID.json @@ -60,5 +60,22 @@ "txtDialogConfirmation": "Apakah Anda yakin ingin melanjutkan tindakan ini?", "txtStartDate": "Tanggal Mulai", "txtEndDate": "Tanggal Akhir", - "txtHelp1" : "Punya masalah dengan akun Anda?" + "txtHelp1" : "Punya masalah dengan akun Anda?", + "txtLupaSandi": "Lupa sandi?", + "txtIngatkanSaya": "Ingatkan saya", + "txtLogin": "Masuk", + "txtForgotYourPassword": "Lupa password anda?", + "txtPleaseEnterPassword": "Silakan masukkan alamat email yang terkait dengan akun Anda dan Kami akan mengirimkan email berisi kode untuk mengatur ulang kata sandi Anda.", + "txtBack": "Kembali", + "txtSuccessSend": "Permintaan berhasil dikirim", + "txtCodeConfirm": "Kami telah mengirimkan email konfirmasi ke", + "txtPleasCheck": "Mohon cek email Anda.", + "txtCheckEmail": "Mohon periksa email Anda!", + "txtEmail": "Kami telah mengirimkan kode konfirmasi 6 digit melalui email cek juga difolder spam, silakan masukkan kode di kotak bawah ini untuk memverifikasi email Anda.", + "txtDont": "Tidak mendapatkan kode?", + "txtResendCode": "Kirim ulang kode", + "txtSecond": "Detik", + "txtPleaseInput": "Mohon masukan kata sandi baru Anda.", + "txtNewPassword": "Kata Sandi Baru", + "txtConfPassword": "Konfirmasi Kata Sandi" } diff --git a/frontend/hospital-portal/src/pages/auth/ForgetPassword.tsx b/frontend/hospital-portal/src/pages/auth/ForgetPassword.tsx index 5920fc62..26fa1d18 100644 --- a/frontend/hospital-portal/src/pages/auth/ForgetPassword.tsx +++ b/frontend/hospital-portal/src/pages/auth/ForgetPassword.tsx @@ -12,6 +12,8 @@ import Iconify from '@/components/Iconify'; // sections import { ForgetPasswordForm } from '@/sections/auth/forget-password'; import { useSearchParams } from 'react-router-dom'; +import { useState, useContext, useEffect } from 'react'; +import { LanguageContext } from '@/contexts/LanguageContext'; // ---------------------------------------------------------------------- @@ -25,6 +27,8 @@ const RootStyle = styled('div')(({ theme }) => ({ // ---------------------------------------------------------------------- export default function ForgetPassword() { + + const { localeData } = useContext(LanguageContext); const [searchParams, setSearchParams] = useSearchParams(); const token = searchParams.get('token'); @@ -42,12 +46,12 @@ export default function ForgetPassword() { startIcon={} sx={{ mb: 3 }} > - Back + {localeData.txtBack} - Please enter your new password. + {localeData.txtPleaseInput} diff --git a/frontend/hospital-portal/src/pages/auth/ResetPassword.tsx b/frontend/hospital-portal/src/pages/auth/ResetPassword.tsx index 52e2982f..931c363e 100644 --- a/frontend/hospital-portal/src/pages/auth/ResetPassword.tsx +++ b/frontend/hospital-portal/src/pages/auth/ResetPassword.tsx @@ -1,4 +1,4 @@ -import { useState } from 'react'; +import { useState, useContext } from 'react'; import { Link as RouterLink } from 'react-router-dom'; // @mui import { styled } from '@mui/material/styles'; @@ -13,6 +13,9 @@ import Page from '@/components/Page'; import { ResetPasswordForm } from '@/sections/auth/reset-password'; // assets import { SentIcon } from '@/assets'; +import { LanguageContext } from '@/contexts/LanguageContext'; + +import { useNavigate } from 'react-router-dom'; // Import useNavigate // ---------------------------------------------------------------------- @@ -27,10 +30,17 @@ const RootStyle = styled('div')(({ theme }) => ({ // ---------------------------------------------------------------------- export default function ResetPassword() { + const { localeData } = useContext(LanguageContext); const [email, setEmail] = useState(''); const [sent, setSent] = useState(false); + const navigate = useNavigate(); + + const handleSent = () => { + setSent(true); + }; + return ( @@ -41,16 +51,15 @@ export default function ResetPassword() { {!sent ? ( <> - Forgot your password? + {localeData.txtForgotYourPassword} - Please enter the email address associated with your account and We will email you - a link to reset your password. + {localeData.txtPleaseEnterPassword} setSent(true)} + onSent={handleSent} onGetEmail={(value) => setEmail(value)} /> @@ -61,7 +70,7 @@ export default function ResetPassword() { to={PATH_AUTH.login} sx={{ mt: 3 }} > - Back + {localeData.txtBack} ) : ( @@ -69,24 +78,24 @@ export default function ResetPassword() { - Request sent successfully + {localeData.txtSuccessSend} - We have sent a confirmation email to   + {localeData.txtCodeConfirm}   {email}
- Please check your email. + {localeData.txtPleasCheck}
)} diff --git a/frontend/hospital-portal/src/pages/auth/VerifyCode.tsx b/frontend/hospital-portal/src/pages/auth/VerifyCode.tsx index 903226aa..0aaff5e3 100644 --- a/frontend/hospital-portal/src/pages/auth/VerifyCode.tsx +++ b/frontend/hospital-portal/src/pages/auth/VerifyCode.tsx @@ -1,4 +1,4 @@ -import { Link as RouterLink } from 'react-router-dom'; +import { Link as RouterLink, useLocation } from 'react-router-dom'; // @mui import { styled } from '@mui/material/styles'; import { Box, Button, Link, Container, Typography } from '@mui/material'; @@ -11,6 +11,9 @@ import Page from '@/components/Page'; import Iconify from '@/components/Iconify'; // sections import { VerifyCodeForm } from '@/sections/auth/verify-code'; +import { useState, useContext, useEffect } from 'react'; +import { LanguageContext } from '@/contexts/LanguageContext'; +import axios from '@/utils/axios'; // ---------------------------------------------------------------------- @@ -21,9 +24,41 @@ const RootStyle = styled('div')(({ theme }) => ({ padding: theme.spacing(12, 0), })); +function useQuery() { + return new URLSearchParams(useLocation().search); + } + // ---------------------------------------------------------------------- export default function VerifyCode() { + const { localeData } = useContext(LanguageContext); + const query = useQuery(); + const email = query.get('email'); + const [timer, setTimer] = useState(60); // Initialize timer with 60 seconds + const [canResend, setCanResend] = useState(false); // State to control resend button visibility + useEffect(() => { + const interval = setInterval(() => { + setTimer((prev) => { + if (prev > 0) { + return prev - 1; + } else { + clearInterval(interval); + setCanResend(true); // Enable resend button when timer reaches 0 + return 0; + } + }); + }, 1000); + + return () => clearInterval(interval); // Cleanup interval on component unmount + }, []); + + const handleResend = () => { + setCanResend(false); + setTimer(60); // Reset timer to 60 seconds + // Add logic to resend the code here + axios.post('/verify-email', {email: email}); + }; + return ( @@ -34,30 +69,42 @@ export default function VerifyCode() { - Please check your email! + {localeData.txtCheckEmail} + {email} - We have emailed a 6-digit confirmation code to acb@domain, please enter the code in - below box to verify your email. + {localeData.txtEmail} - + - + {/* Don’t have a code?   {}}> Resend code + */} + + {localeData.txtDont}   + {canResend ? ( + + {localeData.txtResendCode} + + ) : ( + {`${localeData.txtResendCode} ${timer} ${localeData.txtSecond}`} + )} diff --git a/frontend/hospital-portal/src/routes/index.tsx b/frontend/hospital-portal/src/routes/index.tsx index 132c7b1d..2bcb583b 100644 --- a/frontend/hospital-portal/src/routes/index.tsx +++ b/frontend/hospital-portal/src/routes/index.tsx @@ -52,9 +52,9 @@ export default function Router() { }, // { path: 'login-unprotected', element: }, // { path: 'register-unprotected', element: }, - { path: 'forgot-password', element: }, + { path: 'reset-password', element: }, { path: 'forget-password', element: }, - // { path: 'verify', element: }, + { path: 'verify', element: }, ], }, // { @@ -117,7 +117,7 @@ export default function Router() { } const Login = Loadable(lazy(() => import('@/pages/auth/Login'))); -const ResetPassword = Loadable(lazy(() => import('@/pages/auth/VerifyCode'))); +const ResetPassword = Loadable(lazy(() => import('@/pages/auth/ResetPassword'))); const ForgetPassword = Loadable(lazy(() => import('@/pages/auth/ForgetPassword'))); // Dashboard diff --git a/frontend/hospital-portal/src/routes/paths.ts b/frontend/hospital-portal/src/routes/paths.ts index e3735b97..07f3aa11 100644 --- a/frontend/hospital-portal/src/routes/paths.ts +++ b/frontend/hospital-portal/src/routes/paths.ts @@ -12,5 +12,5 @@ export const PATH_AUTH = { loginUnprotected: path(ROOTS_AUTH, '/login-unprotected'), registerUnprotected: path(ROOTS_AUTH, '/register-unprotected'), verify: path(ROOTS_AUTH, '/verify'), - resetPassword: path(ROOTS_AUTH, '/forgot-password'), + resetPassword: path(ROOTS_AUTH, '/reset-password'), }; diff --git a/frontend/hospital-portal/src/sections/auth/forget-password/ForgetPasswordForm.tsx b/frontend/hospital-portal/src/sections/auth/forget-password/ForgetPasswordForm.tsx index 4f6cc67c..2c1b4b2f 100644 --- a/frontend/hospital-portal/src/sections/auth/forget-password/ForgetPasswordForm.tsx +++ b/frontend/hospital-portal/src/sections/auth/forget-password/ForgetPasswordForm.tsx @@ -2,8 +2,8 @@ import * as Yup from 'yup'; // form import { yupResolver } from '@hookform/resolvers/yup'; import { useForm } from 'react-hook-form'; -import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; -import { Link as RouterLink, useNavigate } from 'react-router-dom'; +import { useCallback, useEffect, useContext, useMemo, useRef, useState } from 'react'; +import { Link as RouterLink, useNavigate, useLocation } from 'react-router-dom'; // @mui import { Alert, IconButton, InputAdornment, Stack, Typography } from '@mui/material'; @@ -14,6 +14,9 @@ import useIsMountedRef from '@/hooks/useIsMountedRef'; import { FormProvider, RHFTextField } from '@/components/hook-form'; import axios from '@/utils/axios'; import Iconify from '@/components/Iconify'; +import { LanguageContext } from '@/contexts/LanguageContext'; + +import { useSnackbar } from 'notistack'; // ---------------------------------------------------------------------- @@ -26,9 +29,19 @@ type Props = { token: string; }; +function useQuery() { + return new URLSearchParams(useLocation().search); + } + export default function ForgetPasswordForm({ token }: Props) { + const { localeData } = useContext(LanguageContext); const isMountedRef = useIsMountedRef(); const navigate = useNavigate(); + const query = useQuery(); + const email = query.get('email'); + + const token_ = query.get('token'); + const { enqueueSnackbar } = useSnackbar(); const [showPasswordNew, setShowPasswordNew] = useState(false); const [showPasswordConfirmNew, setShowPasswordConfirmNew] = useState(false); @@ -47,19 +60,19 @@ export default function ForgetPasswordForm({ token }: Props) { const onSubmit = async (data: FormValuesProps) => { try { - await axios.post('/forget-password', { ...data, token }); - console.log(data); + await axios.post('/forget-password', { ...data, email:email, token:token_ }); + // await new Promise((resolve) => setTimeout(resolve, 500)); await new Promise((resolve) => setTimeout(resolve, 500)); if (isMountedRef.current) { + enqueueSnackbar('Password reset was successful', { variant: 'success' }); navigate('/auth/login', { replace: true }); } } catch (error) { - console.log(error.response.data); if (isMountedRef.current) { - setError('afterSubmit', { ...error, message: error.response.data.message }); + setError('afterSubmit', { ...error, message: error.response.data.meta.message }); } } }; @@ -68,10 +81,10 @@ export default function ForgetPasswordForm({ token }: Props) { {!!errors.afterSubmit && {errors.afterSubmit.message}} - Kata Sandi Baru + {localeData.txtNewPassword} - Konfirmasi Kata Sandi + {localeData.txtConfPassword} - + - Forgot password? + {localeData.txtLupaSandi} @@ -114,7 +114,7 @@ export default function LoginForm() { loading={isSubmitting} sx={{ marginTop: 2 }} > - Login + {localeData.txtLogin} ); diff --git a/frontend/hospital-portal/src/sections/auth/reset-password/ResetPasswordForm.tsx b/frontend/hospital-portal/src/sections/auth/reset-password/ResetPasswordForm.tsx index 671f9f76..a30e30e2 100644 --- a/frontend/hospital-portal/src/sections/auth/reset-password/ResetPasswordForm.tsx +++ b/frontend/hospital-portal/src/sections/auth/reset-password/ResetPasswordForm.tsx @@ -10,6 +10,7 @@ import useIsMountedRef from '@/hooks/useIsMountedRef'; // components import { FormProvider, RHFTextField } from '@/components/hook-form'; import axios from '@/utils/axios'; +import { useNavigate } from 'react-router-dom'; // ---------------------------------------------------------------------- @@ -26,6 +27,8 @@ type Props = { export default function ResetPasswordForm({ onSent, onGetEmail }: Props) { const isMountedRef = useIsMountedRef(); + const navigate = useNavigate(); + const ResetPasswordSchema = Yup.object().shape({ email: Yup.string().email('Email must be a valid email address').required('Email is required'), }); @@ -43,19 +46,22 @@ export default function ResetPasswordForm({ onSent, onGetEmail }: Props) { const onSubmit = async (data: FormValuesProps) => { try { - await axios.post('/verify-email', data); - console.log(data); + const response = await axios.post('/verify-email', data); + if(response.data.data.email) + { + onGetEmail(response.data.data.email); + navigate(`/auth/verify?email=${response.data.data.email}`); + } // await new Promise((resolve) => setTimeout(resolve, 500)); await new Promise((resolve) => setTimeout(resolve, 500)); if (isMountedRef.current) { onSent(); - onGetEmail(data.email); + onGetEmail(response.data.data.email); } } catch (error) { - console.log(error.response.data); if (isMountedRef.current) { - setError('afterSubmit', { ...error, message: error.response.data.message }); + setError('afterSubmit', { ...error, message: error.response.data.meta.message }); } } }; diff --git a/frontend/hospital-portal/src/sections/auth/verify-code/VerifyCodeForm.tsx b/frontend/hospital-portal/src/sections/auth/verify-code/VerifyCodeForm.tsx index 7ebb07fc..a656270e 100644 --- a/frontend/hospital-portal/src/sections/auth/verify-code/VerifyCodeForm.tsx +++ b/frontend/hospital-portal/src/sections/auth/verify-code/VerifyCodeForm.tsx @@ -6,9 +6,12 @@ import { useEffect } from 'react'; import { useForm, Controller } from 'react-hook-form'; import { yupResolver } from '@hookform/resolvers/yup'; // @mui -import { OutlinedInput, Stack } from '@mui/material'; +import { OutlinedInput, Alert, Stack } from '@mui/material'; +import useIsMountedRef from '@/hooks/useIsMountedRef'; import { LoadingButton } from '@mui/lab'; +import { FormProvider, RHFTextField } from '@/components/hook-form'; // routes +import axios from '@/utils/axios'; // import { PATH_DASHBOARD } from '@/routes/paths'; // ---------------------------------------------------------------------- @@ -23,8 +26,11 @@ type FormValuesProps = { }; type ValueNames = 'code1' | 'code2' | 'code3' | 'code4' | 'code5' | 'code6'; - -export default function VerifyCodeForm() { +type Props = { + onGetEmail: (value: string) => void; + }; +export default function VerifyCodeForm({ onGetEmail }: Props) { + const isMountedRef = useIsMountedRef(); const navigate = useNavigate(); const { enqueueSnackbar } = useSnackbar(); @@ -51,8 +57,9 @@ export default function VerifyCodeForm() { watch, control, setValue, + setError, handleSubmit, - formState: { isSubmitting, isValid }, + formState: { isSubmitting, isValid , errors}, } = useForm({ mode: 'onBlur', resolver: yupResolver(VerifyCodeSchema), @@ -67,16 +74,36 @@ export default function VerifyCodeForm() { }, []); const onSubmit = async (data: FormValuesProps) => { + // try { + // await new Promise((resolve) => setTimeout(resolve, 500)); + // console.log('code:', Object.values(data).join('')); + + // enqueueSnackbar('Verify success!', { variant: 'success' }); + + // navigate('/dashboard', { replace: true }); + // } catch (error) { + // console.error(error); + // } + try { - await new Promise((resolve) => setTimeout(resolve, 500)); - console.log('code:', Object.values(data).join('')); - - enqueueSnackbar('Verify success!', { variant: 'success' }); - - navigate('/dashboard', { replace: true }); - } catch (error) { - console.error(error); - } + const response = await axios.post('/verify-code', {email: onGetEmail, token: Object.values(data).join('')}); + // await new Promise((resolve) => setTimeout(resolve, 500)); + await new Promise((resolve) => setTimeout(resolve, 500)); + if(response.data.meta.code === 200) + { + navigate(`/auth/forget-password?email=${response.data.data.email}&token=${response.data.data.token}`); + } + if (isMountedRef.current) { + if(response.data.meta.code === 404) + { + setError('afterSubmit', { ...response, message: response.data.meta.message }); + } + } + } catch (error) { + if (isMountedRef.current) { + setError('afterSubmit', { ...error, message: error.response.data.meta.message }); + } + } }; const handlePasteClipboard = (event: ClipboardEvent) => { @@ -115,35 +142,38 @@ export default function VerifyCodeForm() { return (
- - {Object.keys(values).map((name, index) => ( - ( - ) => - handleChangeWithNextField(event, field.onChange) - } - inputProps={{ - maxLength: 1, - sx: { - p: 0, - textAlign: 'center', - width: { xs: 36, sm: 56 }, - height: { xs: 36, sm: 56 }, - }, - }} - /> - )} - /> - ))} - + + {!!errors.afterSubmit && {errors.afterSubmit.message}} + + {Object.keys(values).map((name, index) => ( + ( + ) => + handleChangeWithNextField(event, field.onChange) + } + inputProps={{ + maxLength: 1, + sx: { + p: 0, + textAlign: 'center', + width: { xs: 36, sm: 56 }, + height: { xs: 36, sm: 56 }, + }, + }} + /> + )} + /> + ))} + + { let expires = "";