Commit 25d1b083 by Arjun Jhukal

updated the new functionality for the the verify email and completed the flow of reset password

parent c16f74ef
import ForgotPasswordPage from '@/components/pages/auth/forgotPassword'
import React from 'react'
export default function ForgotPassword() {
return (
<h1>Forgot Passwoord</h1>
<ForgotPasswordPage />
)
}
import ResetPasswordPage from '@/components/pages/auth/resetPassword'
import React from 'react'
export default function ResetPassword() {
return (
<ResetPasswordPage />
)
}
// "use client";
// import { useAppDispatch } from '@/hooks/hook';
// import { PATH } from '@/routes/PATH';
// import { useSendVerificationLinkAgainMutation } from '@/services/authApi';
// import { showToast, ToastVariant } from '@/slice/toastSlice';
// import { Box, Button, Typography } from '@mui/material'
// import Image from 'next/image'
// import Link from 'next/link'
// import { useRouter, useSearchParams } from 'next/navigation';
// import React from 'react'
// export default function VerifyEmail() {
// const router = useRouter();
// const searchParams = useSearchParams();
// const email = searchParams.get("email");
// const [sendEmailVerificationAgain, { isLoading: sendingLink }] = useSendVerificationLinkAgainMutation();
// const dispatch = useAppDispatch();
// const handleLinkResend = async () => {
// try {
// const response = await sendEmailVerificationAgain({ email: email || "" }).unwrap();
// dispatch(
// showToast({
// message: response?.message || "Link sent successfully",
// variant: ToastVariant.SUCCESS,
// autoTime: true,
// }),
// );
// }
// catch (e: any) {
// dispatch(
// showToast({
// message: e?.data?.message || "Unable to send link. Try again later",
// variant: ToastVariant.ERROR,
// autoTime: true,
// }),
// );
// }
// }
// return (
// <Box className="max-w-[520px] mx-auto flex flex-col gap-3 items-center text-center">
// <Image src={"/assets/images/verify-email.png"} alt='' width={180} height={140} />
// <h1 className='text-[24px] lg:text-[32px] leading-[120%] font-bold mb-4'>Verify your email to
// get the fun started</h1>
// {/* <Typography variant="h1" className='font-[700]'></Typography> */}
// <p className='text-[14px] leading-[120%] font-normal lg:text-[16px] mb-4'>Check the link sent to <strong className='underline text-secondary'>{email}</strong> to activate your account.</p>
// {/* <p className='text-[14px] leading-[120%] font-normal lg:text-[16px] mb-4'>Check your email for verification link.</p> */}
// <Button fullWidth size="large" type="submit" variant="contained" color="primary" className='!mb-6' onClick={() => {
// router.replace(PATH.DASHBOARD.ROOT)
// }}>
// Verify now
// </Button>
// <h2 className='text-[20px] lg:text-[28px] leading-[120%] font-bold'>Don’t see the email?</h2>
// <p className='text-[11px] lg:text-[14px] leading-[150%] font-normal'>Please check <strong>your spam or junk folder,</strong> as the email may have been filtered there. Also, ensure that the email address you entered is correct. Still not found?</p>
// <Button fullWidth variant="contained" color="secondary" onClick={handleLinkResend}>
// {sendingLink ? "Sending Again" : "Send Again"}
// </Button>
// </Box>
// )
// }
"use client";
import { useAppDispatch } from '@/hooks/hook';
......
// import VerifyOTPPage from '@/components/pages/auth/VerifyOtp'
import VerifyOTPPage from '@/components/pages/auth/VerifyOtp'
import React from 'react'
export default function VerifyOTP() {
return (
<h1>Verify OTP</h1>
<VerifyOTPPage />
)
}
......@@ -136,7 +136,7 @@ export default function LoginPage() {
</div>
<div className="action__group text-center flex flex-col gap-4 mt-8">
<button className='ss-btn bg-primary-grad' disabled={!dirty}>{isLoading ? "Logging In" : "Login"}</button>
<p className='text-[12px] leading-[120%] font-bold lg:text-[16px] text-secondary'>Forgot password? <Link href={PATH.AUTH.RESET_PASSWORD.ROOT}>Reset Here</Link></p>
<p className='text-[12px] leading-[120%] font-bold lg:text-[16px] '>Forgot password? <Link href={PATH.AUTH.FORGOT_PASSWORD.ROOT} className="text-secondary">Reset Here</Link></p>
<p className='text-[12px] leading-[120%] font-bold lg:text-[16px]'>Don’t have an account yet?</p>
<Link href={PATH.AUTH.REGISTER.ROOT} className='ss-btn bg-secondary-grad'>Setup an account</Link>
</div>
......
......@@ -37,8 +37,8 @@ const validationSchema = Yup.object().shape({
})
export default function RegisterPage() {
const router = useRouter();
const [registerUser, { isLoading }] = useRegisterUserMutation();
const router = useRouter();
const dispatch = useAppDispatch();
const initialValues = {
emailAddress: "",
......@@ -66,7 +66,7 @@ export default function RegisterPage() {
autoTime: true,
}),
);
router.replace(`${PATH.AUTH.VERIFY_EMAIL.ROOT}?email=${response?.data?.data?.user?.email}`);
router.replace(`${PATH.AUTH.VERIFY_EMAIL.ROOT}?email=${values.emailAddress}`);
}
catch (e: any) {
console.log("Error", e);
......
"use client";
import React, { useEffect, useState } from 'react'
import AuthMessageBlock from '../authMessageBlock'
import { Box, InputLabel, OutlinedInput } from '@mui/material'
import PasswordField from '@/components/molecules/PasswordField'
import { ArrowLeft } from '@wandersonalwes/iconsax-react'
import Link from 'next/link'
import { PATH } from '@/routes/PATH'
import * as Yup from 'yup';
import { useFormik } from 'formik';
import { useAppDispatch } from '@/hooks/hook'
import { showToast, ToastVariant } from '@/slice/toastSlice';
import { useResetPasswordMutation } from '@/services/authApi';
import { useRouter, useSearchParams } from 'next/navigation';
const validationSchema = Yup.object().shape({
emailAddress: Yup.string()
.email('Must be a valid email')
.max(255)
.required('Email is required'),
password: Yup.string()
.required('Password is required')
.test(
'no-leading-trailing-whitespace',
'Password cannot start or end with spaces',
(value) => value === value?.trim()
)
.max(16, 'Password must be less than 10 characters'),
confirmPassword: Yup.string()
.oneOf([Yup.ref('password')], 'Passwords must match')
.required('Confirm Password is required'),
})
export default function ResetPasswordPage() {
const router = useRouter();
const dispatch = useAppDispatch();
const initialValues = {
emailAddress: "",
password: "",
confirmPassword: "",
}
const [resetPassword, { isLoading }] = useResetPasswordMutation();
const { handleSubmit, handleBlur, handleChange, errors, dirty, values, touched } = useFormik(
{
initialValues,
validationSchema,
onSubmit: async (values) => {
try {
const response = await resetPassword({
email: values.emailAddress,
password: values.password,
password_confirmation: values.confirmPassword,
}).unwrap();
dispatch(
showToast({
message: response?.message || "New password is updated",
variant: ToastVariant.SUCCESS,
autoTime: true,
}),
);
router.replace(PATH.AUTH.LOGIN.ROOT);
}
catch (e: any) {
console.log("Error", e);
dispatch(
showToast({
message: e?.data?.message || "Unable to reset password. Try again later",
variant: ToastVariant.ERROR,
autoTime: true,
}),
);
}
}
}
)
return (
<>
<AuthMessageBlock
title="Forgot your password? Let’s get you back in!"
features={[
"Secure Account Recovery",
"Quick & Easy Process",
"No Worries, We've Got You Covered",
"24/7 Support Availability"
]}
/>
<Box className="auth__form__wrapper lg:w-[50%] p-8">
<div className="section__title mb-4 lg:mb-6">
<Link href={PATH.DASHBOARD.ROOT} className='text-[12px] leading-[120%] font-bold lg:text-[16px] hover:text-primary flex gap-2 items-center'><ArrowLeft />Back to Dashboard</Link>
<h1 className="text-[24px] leading-[120%] font-bold lg:text-[48px]">Forgot Password</h1>
</div>
<form action="" onSubmit={handleSubmit}>
<div className="grid md:grid-cols-2 gap-x-3 gap-y-5">
<div className="col-span-2">
<div className="input_field">
<InputLabel htmlFor="emailAddress">Email Address*</InputLabel>
<OutlinedInput
name='emailAddress'
id='emailAddress'
placeholder='example@example.com'
value={values.emailAddress}
onChange={handleChange}
onBlur={handleBlur}
error={Boolean(touched.emailAddress && errors.emailAddress)}
/>
{
touched.emailAddress && errors.emailAddress ?
<span className="error ">{errors.emailAddress}</span> : null
}
</div>
</div>
<div className="col-span-2">
<div className="input_field">
<PasswordField
name="password"
label="Password*"
placeholder="XXXXXXX"
value={values.password}
onChange={handleChange}
onBlur={handleBlur}
error={touched.password ? errors.password : undefined}
/>
</div>
</div>
<div className="col-span-2">
<div className="input_field">
<PasswordField
name="confirmPassword"
label="Confirm Password*"
placeholder="XXXXXXX"
value={values.confirmPassword}
onChange={handleChange}
onBlur={handleBlur}
error={touched.confirmPassword ? errors.confirmPassword : undefined}
/>
</div>
</div>
</div>
<div className="action__group text-center flex flex-col gap-4 mt-8">
<button className='ss-btn bg-primary-grad' disabled={!dirty}>{isLoading ? "Changing Password" : "Reset Password"}</button>
<Link href={PATH.DASHBOARD.ROOT} className='ss-btn bg-secondary-grad'>Login</Link>
</div>
</form>
</Box>
</>
)
}
......@@ -12,6 +12,12 @@ export const PATH = {
RESET_PASSWORD: {
ROOT: "/reset-password"
},
FORGOT_PASSWORD: {
ROOT: "/forgot-password"
},
VERIFY_OTP: {
ROOT: "/verify-otp"
},
VERIFY_EMAIL: {
ROOT: "/verify-email"
}
......
import { createApi } from "@reduxjs/toolkit/query/react";
import { baseQuery } from "./baseQuery";
import { LoginProps, LoginResponse, RegisterProps } from "@/types/auth";
import { GlobalResponse } from "@/types/config";
export const authApi = createApi({
reducerPath: "authApi",
......@@ -34,8 +35,35 @@ export const authApi = createApi({
method: "POST",
body: { email },
})
}),
forgotPassword: builder.mutation<GlobalResponse, { email: string }>({
query: ({ email }) => ({
url: "/api/forgot-password/send",
method: "POST",
body: { email },
})
}),
verifyOTP: builder.mutation<GlobalResponse, { email: string; otp: string }>({
query: ({ email, otp }) => ({
url: "/api/forgot-password/send",
method: "POST",
body: { email, otp },
})
}),
resetPassword: builder.mutation<GlobalResponse, { email: string, password: string, password_confirmation: string }>({
query: ({ email,
password,
password_confirmation }) => ({
url: `/api/forgot-password/reset`,
method: "POST",
body: {
email,
password,
password_confirmation
},
})
}),
})
})
export const { useLoginMutation, useRegisterUserMutation, useSendVerificationLinkAgainMutation } = authApi;
\ No newline at end of file
export const { useLoginMutation, useRegisterUserMutation, useSendVerificationLinkAgainMutation, useForgotPasswordMutation, useVerifyOTPMutation, useResetPasswordMutation } = authApi;
\ No newline at end of file
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