Commit 66776795 by Arjun Jhukal

updated the minor changes

parent 80064300
"use client"; // "use client";
import React, { useState, useEffect, useRef } from "react"; // import React, { useState, useEffect, useRef } from "react";
import { Box, Button, Typography, CircularProgress } from "@mui/material"; // import { Box, Button, Typography, CircularProgress } from "@mui/material";
import Image from "next/image"; // import Image from "next/image";
import { useRouter } from "next/navigation"; // import { useRouter } from "next/navigation";
import { PATH } from "@/routes/PATH"; // import { PATH } from "@/routes/PATH";
import { useForgotPasswordMutation, useVerifyOTPMutation } from "@/services/authApi"; // import { useForgotPasswordMutation, useVerifyOTPMutation } from "@/services/authApi";
import { useAppDispatch } from "@/hooks/hook"; // import { useAppDispatch } from "@/hooks/hook";
import { showToast, ToastVariant } from "@/slice/toastSlice"; // import { showToast, ToastVariant } from "@/slice/toastSlice";
export default function VerifyOTPPage() { // export default function VerifyOTPPage() {
const router = useRouter(); // const router = useRouter();
const dispatch = useAppDispatch(); // const dispatch = useAppDispatch();
const [otp, setOtp] = useState<string[]>(["", "", "", "", "", ""]); // const [otp, setOtp] = useState<string[]>(["", "", "", "", "", ""]);
const inputRefs = useRef<(HTMLInputElement | null)[]>([]); // const inputRefs = useRef<(HTMLInputElement | null)[]>([]);
const [email, setEmail] = useState<string | null>(null); // const [email, setEmail] = useState<string | null>(null);
const [forgotPassword, { isLoading: sending }] = useForgotPasswordMutation(); // const [forgotPassword, { isLoading: sending }] = useForgotPasswordMutation();
const [verifyOTP, { isLoading: verifying }] = useVerifyOTPMutation(); // const [verifyOTP, { isLoading: verifying }] = useVerifyOTPMutation();
// ✅ Get stored email // // ✅ Get stored email
useEffect(() => { // useEffect(() => {
const storedData = localStorage.getItem("passwordResetData"); // const storedData = localStorage.getItem("passwordResetData");
if (storedData) { // if (storedData) {
const parsed = JSON.parse(storedData); // const parsed = JSON.parse(storedData);
setEmail(parsed.email || parsed.emailAddress || null); // setEmail(parsed.email || parsed.emailAddress || null);
} // }
}, []); // }, []);
// ✅ Back to login // // ✅ Back to login
const handleBackToLogin = () => { // const handleBackToLogin = () => {
localStorage.removeItem("passwordResetData"); // localStorage.removeItem("passwordResetData");
router.replace(PATH.AUTH.LOGIN.ROOT); // router.replace(PATH.AUTH.LOGIN.ROOT);
}; // };
// ✅ Handle OTP input change // // ✅ Handle OTP input change
const handleChange = (value: string, index: number) => { // const handleChange = (value: string, index: number) => {
if (!/^\d*$/.test(value)) return; // if (!/^\d*$/.test(value)) return;
const newOtp = [...otp]; // const newOtp = [...otp];
newOtp[index] = value; // newOtp[index] = value;
setOtp(newOtp); // setOtp(newOtp);
if (value && index < 5) { // if (value && index < 5) {
inputRefs.current[index + 1]?.focus(); // inputRefs.current[index + 1]?.focus();
} // }
}; // };
const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>, index: number) => { // const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>, index: number) => {
if (e.key === "Backspace" && !otp[index] && index > 0) { // if (e.key === "Backspace" && !otp[index] && index > 0) {
inputRefs.current[index - 1]?.focus(); // inputRefs.current[index - 1]?.focus();
} // }
}; // };
// ✅ Verify OTP // // ✅ Verify OTP
const handleSubmit = async (e: React.FormEvent) => { // const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault(); // e.preventDefault();
const enteredOTP = otp.join(""); // const enteredOTP = otp.join("");
if (enteredOTP.length < 6) { // if (enteredOTP.length < 6) {
dispatch(showToast({ message: "Please enter all 6 digits", variant: ToastVariant.ERROR })); // dispatch(showToast({ message: "Please enter all 6 digits", variant: ToastVariant.ERROR }));
return; // return;
} // }
if (!email) { // if (!email) {
dispatch(showToast({ message: "Email not available", variant: ToastVariant.ERROR })); // dispatch(showToast({ message: "Email not available", variant: ToastVariant.ERROR }));
return; // return;
} // }
try { // try {
const res = await verifyOTP({ email, otp: enteredOTP }).unwrap(); // const res = await verifyOTP({ email, otp: enteredOTP }).unwrap();
dispatch( // dispatch(
showToast({ // showToast({
message: res.message || "OTP verified successfully!", // message: res.message || "OTP verified successfully!",
variant: ToastVariant.SUCCESS, // variant: ToastVariant.SUCCESS,
}) // })
); // );
router.push(PATH.AUTH.RESET_PASSWORD.ROOT); // router.push(PATH.AUTH.RESET_PASSWORD.ROOT);
} catch (err: any) { // } catch (err: any) {
dispatch( // dispatch(
showToast({ // showToast({
message: err?.data?.message || "Invalid OTP", // message: err?.data?.message || "Invalid OTP",
variant: ToastVariant.ERROR, // variant: ToastVariant.ERROR,
}) // })
); // );
} // }
}; // };
// ✅ Resend OTP using stored email // // ✅ Resend OTP using stored email
const handleResendOTP = async () => { // const handleResendOTP = async () => {
if (!email) { // if (!email) {
dispatch( // dispatch(
showToast({ // showToast({
message: "Email not found in session. Please restart the process.", // message: "Email not found in session. Please restart the process.",
variant: ToastVariant.ERROR, // variant: ToastVariant.ERROR,
}) // })
); // );
return; // return;
} // }
try { // try {
const response = await forgotPassword({ email }).unwrap(); // const response = await forgotPassword({ email }).unwrap();
dispatch( // dispatch(
showToast({ // showToast({
message: response.message || "OTP sent successfully!", // message: response.message || "OTP sent successfully!",
variant: ToastVariant.SUCCESS, // variant: ToastVariant.SUCCESS,
}) // })
); // );
} catch (err: any) { // } catch (err: any) {
dispatch( // dispatch(
showToast({ // showToast({
message: err?.data?.message || "Failed to resend OTP", // message: err?.data?.message || "Failed to resend OTP",
variant: ToastVariant.ERROR, // variant: ToastVariant.ERROR,
}) // })
); // );
} // }
}; // };
return ( // return (
<Box className="max-w-[520px] mx-auto flex flex-col gap-3 items-center text-center"> // <Box className="max-w-[520px] mx-auto flex flex-col gap-3 items-center text-center">
<Image src="/assets/images/verify-email.png" alt="Verify OTP" width={180} height={140} /> // <Image src="/assets/images/verify-email.png" alt="Verify OTP" width={180} height={140} />
<h1 className="text-[24px] lg:text-[32px] leading-[120%] font-bold mb-4"> // <h1 className="text-[24px] lg:text-[32px] leading-[120%] font-bold mb-4">
Enter the OTP to verify your account // Enter the OTP to verify your account
</h1> // </h1>
<p className="text-[14px] leading-[120%] font-normal lg:text-[16px] mb-6"> // <p className="text-[14px] leading-[120%] font-normal lg:text-[16px] mb-6">
We’ve sent a 6-digit code to{" "} // We’ve sent a 6-digit code to{" "}
<strong className="underline text-secondary"> // <strong className="underline text-secondary">
{email || "your email"} // {email || "your email"}
</strong> // </strong>
</p> // </p>
<form onSubmit={handleSubmit} className="w-full flex flex-col items-center gap-6"> // <form onSubmit={handleSubmit} className="w-full flex flex-col items-center gap-6">
<div className="flex justify-center gap-3"> // <div className="flex justify-center gap-3">
{otp.map((digit, index) => ( // {otp.map((digit, index) => (
<input // <input
key={index} // key={index}
ref={(el) => (inputRefs.current[index] = el)} // ✅ type safe ref // ref={(el) => (inputRefs.current[index] = el)} // ✅ type safe ref
type="text" // type="text"
inputMode="numeric" // inputMode="numeric"
maxLength={1} // maxLength={1}
value={digit} // value={digit}
onChange={(e) => handleChange(e.target.value, index)} // onChange={(e) => handleChange(e.target.value, index)}
onKeyDown={(e) => handleKeyDown(e, index)} // onKeyDown={(e) => handleKeyDown(e, index)}
className="w-12 h-14 text-center text-[24px] font-semibold border border-gray-300 rounded-md focus:outline-none focus:border-primary transition-all" // className="w-12 h-14 text-center text-[24px] font-semibold border border-gray-300 rounded-md focus:outline-none focus:border-primary transition-all"
/> // />
))} // ))}
</div> // </div>
<Button // <Button
fullWidth // fullWidth
size="large" // size="large"
type="submit" // type="submit"
variant="contained" // variant="contained"
color="primary" // color="primary"
disabled={verifying} // disabled={verifying}
> // >
{verifying ? "Verifying..." : "Verify OTP"} // {verifying ? "Verifying..." : "Verify OTP"}
</Button> // </Button>
</form> // </form>
<Typography variant="h6" className="text-[20px] lg:text-[28px] leading-[120%] font-bold"> // <Typography variant="h6" className="text-[20px] lg:text-[28px] leading-[120%] font-bold">
Didn’t get the code? // Didn’t get the code?
</Typography> // </Typography>
<p className="text-[11px] lg:text-[14px] leading-[150%] font-normal"> // <p className="text-[11px] lg:text-[14px] leading-[150%] font-normal">
Please check your <strong>spam or junk folder</strong>. Still not found?{" "} // Please check your <strong>spam or junk folder</strong>. Still not found?{" "}
<strong>Resend OTP below</strong>. // <strong>Resend OTP below</strong>.
</p> // </p>
<Button // <Button
fullWidth // fullWidth
variant="contained" // variant="contained"
color="secondary" // color="secondary"
disabled={sending} // disabled={sending}
onClick={handleResendOTP} // onClick={handleResendOTP}
startIcon={sending && <CircularProgress size={18} color="inherit" />} // startIcon={sending && <CircularProgress size={18} color="inherit" />}
> // >
{sending ? "Sending..." : "Send Again"} // {sending ? "Sending..." : "Send Again"}
</Button> // </Button>
<Button // <Button
fullWidth // fullWidth
variant="outlined" // variant="outlined"
color="primary" // color="primary"
onClick={handleBackToLogin} // onClick={handleBackToLogin}
className="!mt-4" // className="!mt-4"
> // >
Back to Login // Back to Login
</Button> // </Button>
</Box> // </Box>
); // );
} // }
"use client"; // "use client";
import React from "react"; // import React from "react";
import Link from "next/link"; // import Link from "next/link";
import { PATH } from "@/routes/PATH"; // import { PATH } from "@/routes/PATH";
import { // import {
Box, // Box,
InputLabel, // InputLabel,
OutlinedInput, // OutlinedInput,
} from "@mui/material"; // } from "@mui/material";
import AuthMessageBlock from "../authMessageBlock"; // import AuthMessageBlock from "../authMessageBlock";
import { useFormik } from "formik"; // import { useFormik } from "formik";
import * as Yup from "yup"; // import * as Yup from "yup";
import { useRouter } from "next/navigation"; // import { useRouter } from "next/navigation";
import { useAppDispatch } from "@/hooks/hook"; // import { useAppDispatch } from "@/hooks/hook";
import { useForgotPasswordMutation } from "@/services/authApi"; // import { useForgotPasswordMutation } from "@/services/authApi";
import { showToast, ToastVariant } from "@/slice/toastSlice"; // import { showToast, ToastVariant } from "@/slice/toastSlice";
export default function ForgotPasswordPage() { // export default function ForgotPasswordPage() {
const router = useRouter(); // const router = useRouter();
const dispatch = useAppDispatch(); // const dispatch = useAppDispatch();
const [forgotPassword, { isLoading }] = useForgotPasswordMutation(); // const [forgotPassword, { isLoading }] = useForgotPasswordMutation();
const { // const {
values, // values,
errors, // errors,
touched, // touched,
handleBlur, // handleBlur,
handleChange, // handleChange,
handleSubmit, // handleSubmit,
dirty, // dirty,
} = useFormik({ // } = useFormik({
initialValues: { // initialValues: {
emailAddress: "", // emailAddress: "",
}, // },
validationSchema: Yup.object({ // validationSchema: Yup.object({
emailAddress: Yup.string() // emailAddress: Yup.string()
.email("Invalid email format") // .email("Invalid email format")
.required("Email is required"), // .required("Email is required"),
}), // }),
onSubmit: async (values) => { // onSubmit: async (values) => {
try { // try {
const response = await forgotPassword({ // const response = await forgotPassword({
email: values.emailAddress, // email: values.emailAddress,
}).unwrap(); // }).unwrap();
// ✅ Show success toast // // ✅ Show success toast
dispatch( // dispatch(
showToast({ // showToast({
message: response.message || "OTP sent successfully!", // message: response.message || "OTP sent successfully!",
variant: ToastVariant.SUCCESS, // variant: ToastVariant.SUCCESS,
}) // })
); // );
// ✅ Store email in localStorage correctly // // ✅ Store email in localStorage correctly
localStorage.setItem( // localStorage.setItem(
"passwordResetData", // "passwordResetData",
JSON.stringify({ email: values.emailAddress }) // JSON.stringify({ email: values.emailAddress })
); // );
// ✅ Navigate to Verify OTP page // // ✅ Navigate to Verify OTP page
router.push(PATH.AUTH.VERIFY_OTP.ROOT); // router.push(PATH.AUTH.VERIFY_OTP.ROOT);
} catch (error: any) { // } catch (error: any) {
console.error("Error:", error); // console.error("Error:", error);
dispatch( // dispatch(
showToast({ // showToast({
message: error.message || "Something went wrong", // message: error.message || "Something went wrong",
variant: ToastVariant.ERROR, // variant: ToastVariant.ERROR,
}) // })
); // );
} // }
}, // },
}); // });
return ( // return (
<> // <>
<AuthMessageBlock // <AuthMessageBlock
title="Ready to get started and win BIG?" // title="Ready to get started and win BIG?"
features={[ // features={[
"Fun & Fair Gameplay", // "Fun & Fair Gameplay",
"Exciting Prizes", // "Exciting Prizes",
"Accessible Anytime, Anywhere", // "Accessible Anytime, Anywhere",
"Trusted & Secure", // "Trusted & Secure",
]} // ]}
/> // />
<Box className="auth__form__wrapper lg:w-[50%] p-8"> // <Box className="auth__form__wrapper lg:w-[50%] p-8">
<div className="section__title mb-4 lg:mb-6"> // <div className="section__title mb-4 lg:mb-6">
<h1 className="text-[24px] leading-[120%] font-bold lg:text-[48px]"> // <h1 className="text-[24px] leading-[120%] font-bold lg:text-[48px]">
Setup an account // Setup an account
</h1> // </h1>
</div> // </div>
<form onSubmit={handleSubmit}> // <form onSubmit={handleSubmit}>
<div className="grid md:grid-cols-2 gap-x-3 gap-y-5"> // <div className="grid md:grid-cols-2 gap-x-3 gap-y-5">
<div className="col-span-2"> // <div className="col-span-2">
<div className="input_field"> // <div className="input_field">
<InputLabel htmlFor="emailAddress">Email Address*</InputLabel> // <InputLabel htmlFor="emailAddress">Email Address*</InputLabel>
<OutlinedInput // <OutlinedInput
name="emailAddress" // name="emailAddress"
id="emailAddress" // id="emailAddress"
placeholder="example@example.com" // placeholder="example@example.com"
value={values.emailAddress} // value={values.emailAddress}
onChange={handleChange} // onChange={handleChange}
onBlur={handleBlur} // onBlur={handleBlur}
error={Boolean(touched.emailAddress && errors.emailAddress)} // error={Boolean(touched.emailAddress && errors.emailAddress)}
fullWidth // fullWidth
/> // />
{touched.emailAddress && errors.emailAddress ? ( // {touched.emailAddress && errors.emailAddress ? (
<span className="error">{errors.emailAddress}</span> // <span className="error">{errors.emailAddress}</span>
) : null} // ) : null}
</div> // </div>
</div> // </div>
</div> // </div>
<div className="action__group text-center flex flex-col gap-4 mt-8"> // <div className="action__group text-center flex flex-col gap-4 mt-8">
<button // <button
type="submit" // type="submit"
className="ss-btn bg-primary-grad flex items-center justify-center" // className="ss-btn bg-primary-grad flex items-center justify-center"
disabled={!dirty || isLoading} // disabled={!dirty || isLoading}
> // >
{isLoading ? "Sending OTP..." : "Send OTP"} // {isLoading ? "Sending OTP..." : "Send OTP"}
</button> // </button>
<Link // <Link
href={PATH.AUTH.LOGIN.ROOT} // href={PATH.AUTH.LOGIN.ROOT}
className="ss-btn bg-secondary-grad" // className="ss-btn bg-secondary-grad"
> // >
Back To Login // Back To Login
</Link> // </Link>
</div> // </div>
</form> // </form>
</Box> // </Box>
</> // </>
); // );
} // }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment