From 194087c0a3dee4a3f254570f54b3cfc3008fb812 Mon Sep 17 00:00:00 2001 From: Pramod Mahajan Date: Sat, 7 Jun 2025 17:39:37 +0530 Subject: [PATCH] added login with otp feature, added send otp api --- src/pages/authentication/LoginPage.jsx | 216 ++++++++++++++----------- 1 file changed, 126 insertions(+), 90 deletions(-) diff --git a/src/pages/authentication/LoginPage.jsx b/src/pages/authentication/LoginPage.jsx index 8ba33fca..9fd879b8 100644 --- a/src/pages/authentication/LoginPage.jsx +++ b/src/pages/authentication/LoginPage.jsx @@ -1,4 +1,4 @@ -import { useState } from "react"; +import { useEffect, useState } from "react"; import { Link } from "react-router-dom"; import { AuthWrapper } from "./AuthWrapper"; import { useNavigate } from "react-router-dom"; @@ -9,16 +9,23 @@ import { useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import { z } from "zod"; -const loginScheam = z.object({ - username: z.string().email(), - password: z.string().min(1, { message: "Password required" }), - rememberMe: z.boolean(), -}); - const LoginPage = () => { const navigate = useNavigate(); const [loading, setLoading] = useState(false); const [hidepass, setHidepass] = useState(true); + const [IsLoginWithOTP, setLoginWithOtp] = useState(false); + const [IsTriedOTPThrough, setIsTriedOTPThrough] = useState(false); + const now = Date.now(); + + const loginSchema = IsLoginWithOTP + ? z.object({ + username: z.string().email({ message: "Valid email required" }), + }) + : z.object({ + username: z.string().email({ message: "Valid email required" }), + password: z.string().min(1, { message: "Password required" }), + rememberMe: z.boolean(), + }); const { register, @@ -27,35 +34,49 @@ const LoginPage = () => { reset, getValues, } = useForm({ - resolver: zodResolver(loginScheam), + resolver: zodResolver(loginSchema), }); const onSubmit = async (data) => { setLoading(true); try { - let userCredential = { - username: data.username, - password: data.password, - }; - const response = await AuthRepository.login(userCredential); - localStorage.setItem("jwtToken", response.data.token); - localStorage.setItem("refreshToken", response.data.refreshToken); - setLoading(false); - navigate("/dashboard"); + if (!IsLoginWithOTP) { + const userCredential = { + username: data.username, + password: data.password, + }; + const response = await AuthRepository.login(userCredential); + localStorage.setItem("jwtToken", response.data.token); + localStorage.setItem("refreshToken", response.data.refreshToken); + setLoading(false); + navigate("/dashboard"); + } else { + await AuthRepository.sendOTP({ email: data.username }); + localStorage.setItem("otpUsername", data.username); + localStorage.setItem("otpSentTime", now.toString()); + navigate("/auth/login-otp"); + } } catch (err) { - showToast("Invalid username or password.","error") + showToast("Invalid username or password.", "error"); setLoading(false); } }; + useEffect( () => + { const otpSentTime = localStorage.getItem("otpSentTime"); + if (localStorage.getItem("otpUsername") && IsLoginWithOTP && now - Number(otpSentTime) < 10 * 60 * 1000) { + navigate("/auth/login-otp"); + } + }, [IsLoginWithOTP]); return (

Welcome to PMS!

- Please sign-in to your account and start the adventure + {IsLoginWithOTP + ? "Enter your email to receive a one-time password (OTP)." + : "Please sign-in to your account and start the adventure."}

-
{ className="form-control" id="username" {...register("username")} - name="username" placeholder="Enter your email or username" autoFocus /> @@ -83,87 +103,103 @@ const LoginPage = () => { )} -
-
- -
-
- - +
+ {errors.password && ( +
+ {errors.password.message} +
)} - -
- {errors.password && ( -
- {errors.password.message}
- )} - -
-
- - -
- - Forgot Password? - -
+ +
+
+ + +
+ Forgot Password? +
+ + )} +
+ {!IsLoginWithOTP && ( + + )}

New on our platform? - - Request a Demo - + {IsLoginWithOTP ? ( + setLoginWithOtp(false)} + > + Login With Password + + ) : ( + + Request a Demo + + )}

);