updated forget password functionality with backend

This commit is contained in:
2025-08-23 14:29:25 +05:30
parent c86509e812
commit 1018c42500
10 changed files with 519 additions and 247 deletions

View File

@@ -38,11 +38,13 @@ const SidePannel: React.FC<SidePannelProps> = ({ setActiveTab, activeTab }) => {
const handleCreateNewProject = async () => { const handleCreateNewProject = async () => {
const token = localStorage.getItem("token"); const token = localStorage.getItem("token");
const refreshToken = localStorage.getItem("refreshToken") const refreshToken = localStorage.getItem("refreshToken");
console.log('refreshToken: ', refreshToken); console.log("refreshToken: ", refreshToken);
try { try {
const projectId = generateProjectId(); const projectId = generateProjectId();
useSocketStore.getState().initializeSocket(email, organization, token, refreshToken); useSocketStore
.getState()
.initializeSocket(email, organization, token, refreshToken);
//API for creating new Project //API for creating new Project
// const project = await createProject( // const project = await createProject(
@@ -59,12 +61,12 @@ const SidePannel: React.FC<SidePannelProps> = ({ setActiveTab, activeTab }) => {
projectUuid: projectId, projectUuid: projectId,
}; };
console.log('projectSocket: ', projectSocket); console.log("projectSocket: ", projectSocket);
if (projectSocket) { if (projectSocket) {
const handleResponse = (data: any) => { const handleResponse = (data: any) => {
if (data.message === "Project created successfully") { if (data.message === "Project created successfully") {
setLoadingProgress(1) setLoadingProgress(1);
navigate(`/${data.data.projectId}`); navigate(`/projects/${data.data.projectId}`);
} }
projectSocket.off("v1-project:response:add", handleResponse); // Clean up projectSocket.off("v1-project:response:add", handleResponse); // Clean up
}; };
@@ -88,7 +90,8 @@ const SidePannel: React.FC<SidePannelProps> = ({ setActiveTab, activeTab }) => {
</div> </div>
<div className="user-name"> <div className="user-name">
{userName {userName
? userName.charAt(0).toUpperCase() + userName.slice(1).toLowerCase() ? userName.charAt(0).toUpperCase() +
userName.slice(1).toLowerCase()
: "Anonymous"} : "Anonymous"}
</div> </div>
</div> </div>
@@ -162,10 +165,14 @@ const SidePannel: React.FC<SidePannelProps> = ({ setActiveTab, activeTab }) => {
<SettingsIcon /> <SettingsIcon />
Settings Settings
</div> </div>
<div className="option-list" style={{ cursor: "pointer" }} onClick={() => { <div
localStorage.clear(); className="option-list"
navigate("/"); style={{ cursor: "pointer" }}
}}> onClick={() => {
localStorage.clear();
navigate("/");
}}
>
<LogoutIcon /> <LogoutIcon />
Log out Log out
</div> </div>
@@ -179,4 +186,4 @@ const SidePannel: React.FC<SidePannelProps> = ({ setActiveTab, activeTab }) => {
); );
}; };
export default SidePannel; export default SidePannel;

View File

@@ -1,30 +1,39 @@
import React from 'react'; import React from "react";
interface Props { interface Props {
email: string; email: string;
setEmail: (value: string) => void; setEmail: (value: string) => void;
onSubmit: () => void; onSubmit: (e: React.FormEvent<HTMLFormElement>) => void;
} }
const EmailInput: React.FC<Props> = ({ email, setEmail, onSubmit }) => { const EmailInput: React.FC<Props> = ({ email, setEmail, onSubmit }) => {
return ( return (
<div className='request-container'> <div className="request-container">
<h1 className='header'>Forgot password</h1> <h1 className="header">Forgot password</h1>
<p className='sub-header'> <p className="sub-header">
Enter your email for the verification process, we will send a 4-digit code to your email. Enter your email for the verification process, we will send a 4-digit
</p> code to your email.
<form className='auth-form' onSubmit={(e) => { e.preventDefault(); onSubmit(); }}> </p>
<input <form
type='email' className="auth-form"
placeholder='Email' onSubmit={(e) => {
value={email} e.preventDefault();
onChange={(e) => setEmail(e.target.value)} onSubmit(e);
required }}
/> >
<button type='submit' className='continue-button'>Continue</button> <input
</form> type="email"
</div> placeholder="Email"
); value={email}
onChange={(e) => setEmail(e.target.value)}
required
/>
<button type="submit" className="continue-button">
Continue
</button>
</form>
</div>
);
}; };
export default EmailInput; export default EmailInput;

View File

@@ -1,10 +1,95 @@
import React, { useState, useRef, useEffect } from 'react'; // import React, { useState, useRef, useEffect } from "react";
const OTPInput: React.FC<{ length?: number; onComplete: (otp: string) => void }> = ({ length = 4, onComplete }) => { // const OTPInput: React.FC<{
const [otpValues, setOtpValues] = useState<string[]>(Array(length).fill('')); // length?: number;
// onComplete: (otp: string) => void;
// code: string;
// }> = ({ length = 4, onComplete, code }) => {
// const [otpValues, setOtpValues] = useState<string[]>(Array(length).fill(""));
// const inputsRef = useRef<(HTMLInputElement | null)[]>([]);
// useEffect(() => {
// if (code) {
// console.log("code: ", code);
// const codeString = String(code); // convert number → string
// setOtpValues(codeString.split(""));
// onComplete(codeString);
// }
// }, [code, length]);
// // Auto focus first input on mount
// useEffect(() => {
// inputsRef.current[0]?.focus();
// }, []);
// const handleChange = (value: string, index: number) => {
// if (/^[0-9]?$/.test(value)) {
// const newOtp = [...otpValues];
// newOtp[index] = value;
// setOtpValues(newOtp);
// if (value && index < length - 1) {
// inputsRef.current[index + 1]?.focus();
// }
// if (newOtp.every((digit) => digit !== "")) {
// console.log('newOtp.join(""): ', newOtp.join(""));
// onComplete(newOtp.join(""));
// }
// }
// };
// const handleKeyDown = (
// e: React.KeyboardEvent<HTMLInputElement>,
// index: number
// ) => {
// if (e.key === "Backspace" && !otpValues[index] && index > 0) {
// inputsRef.current[index - 1]?.focus();
// }
// };
// return (
// <div className="otp-container">
// {otpValues.map((value, index) => (
// <input
// key={index}
// type="text"
// className="otp-input"
// maxLength={1}
// value={value}
// onChange={(e) => handleChange(e.target.value, index)}
// onKeyDown={(e) => handleKeyDown(e, index)}
// ref={(el) => (inputsRef.current[index] = el)}
// />
// ))}
// </div>
// );
// };
// export default OTPInput;
import React, { useState, useRef, useEffect } from "react";
const OTPInput: React.FC<{
length?: number;
onComplete: (otp: string) => void;
code: string | number;
}> = ({ length = 4, onComplete, code }) => {
const [otpValues, setOtpValues] = useState<string[]>(Array(length).fill(""));
const inputsRef = useRef<(HTMLInputElement | null)[]>([]); const inputsRef = useRef<(HTMLInputElement | null)[]>([]);
// Auto focus first input on mount // ✅ Pre-fill inputs if code is passed
useEffect(() => {
if (code) {
const codeString = String(code);
const filled = codeString.split("").slice(0, length);
const padded = filled.concat(Array(length - filled.length).fill(""));
setOtpValues(padded);
if (filled.length === length) {
onComplete(filled.join(""));
}
}
}, [code, length, onComplete]);
// ✅ Focus first input on mount
useEffect(() => { useEffect(() => {
inputsRef.current[0]?.focus(); inputsRef.current[0]?.focus();
}, []); }, []);
@@ -19,14 +104,18 @@ const OTPInput: React.FC<{ length?: number; onComplete: (otp: string) => void }>
inputsRef.current[index + 1]?.focus(); inputsRef.current[index + 1]?.focus();
} }
if (newOtp.every((digit) => digit !== '')) { // ✅ Only trigger onComplete when all digits are filled
onComplete(newOtp.join('')); if (newOtp.every((digit) => digit !== "")) {
onComplete(newOtp.join(""));
} }
} }
}; };
const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>, index: number) => { const handleKeyDown = (
if (e.key === 'Backspace' && !otpValues[index] && index > 0) { e: React.KeyboardEvent<HTMLInputElement>,
index: number
) => {
if (e.key === "Backspace" && !otpValues[index] && index > 0) {
inputsRef.current[index - 1]?.focus(); inputsRef.current[index - 1]?.focus();
} }
}; };
@@ -39,7 +128,7 @@ const OTPInput: React.FC<{ length?: number; onComplete: (otp: string) => void }>
type="text" type="text"
className="otp-input" className="otp-input"
maxLength={1} maxLength={1}
value={value} value={value ?? ""}
onChange={(e) => handleChange(e.target.value, index)} onChange={(e) => handleChange(e.target.value, index)}
onKeyDown={(e) => handleKeyDown(e, index)} onKeyDown={(e) => handleKeyDown(e, index)}
ref={(el) => (inputsRef.current[index] = el)} ref={(el) => (inputsRef.current[index] = el)}

View File

@@ -1,57 +1,77 @@
import React, { useState } from 'react'; import React, { FormEvent, useState } from "react";
import OTPInput from './OTPInput'; import OTPInput from "./OTPInput";
interface Props { interface Props {
email: string; email: string;
timer: number; code: string;
setCode: (value: string) => void; timer: number;
onSubmit: () => void; setCode: (value: string) => void;
resendCode: () => void; onSubmit: (e: React.FormEvent<HTMLFormElement>) => void;
resendCode: () => void;
} }
const OTPVerification: React.FC<Props> = ({ email, timer, setCode, onSubmit, resendCode }) => { const OTPVerification: React.FC<Props> = ({
const [otp, setOtp] = useState(''); email,
timer,
setCode,
onSubmit,
resendCode,
code,
}) => {
const [otp, setOtp] = useState("");
const handleSubmit = (e: React.FormEvent) => { const handleSubmit = (e: FormEvent<HTMLFormElement>) => {
e.preventDefault(); e.preventDefault();
console.log('otp.length: ', otp.length);
if (otp.length === 4) {
onSubmit();
} else {
alert('Please enter the 4-digit code');
}
};
return ( if (otp.length === 4) {
<div className='request-container'> onSubmit(e);
<h1 className='header'>Verification</h1> } else {
<p className='sub-header'> alert("Please enter the 4-digit code");
Enter the 4-digit code sent to <strong>{email}</strong>. }
</p> };
<form className='auth-form' onSubmit={handleSubmit}>
<OTPInput length={4} onComplete={(code) => { setOtp(code); setCode(code); }} /> return (
<div className="timing"> <div className="request-container">
{timer > 0 <h1 className="header">Verification</h1>
? `${String(Math.floor(timer / 60)).padStart(2, '0')}:${String(timer % 60).padStart(2, '0')}` <p className="sub-header">
: ''} Enter the 4-digit code sent to <strong>{email}</strong>.
</div> </p>
<button <form className="auth-form" onSubmit={handleSubmit}>
type='submit' <OTPInput
className='continue-button' length={4}
disabled={otp.length < 4} // prevent clicking if not complete onComplete={(codes) => {
> setOtp(code);
Verify setCode(codes);
</button> }}
</form> code={code}
<div />
className={`resend ${timer > 0 ? 'disabled' : ''}`} <div className="timing">
onClick={timer === 0 ? resendCode : undefined} {timer > 0
style={{ cursor: timer === 0 ? 'pointer' : 'not-allowed', opacity: timer === 0 ? 1 : 0.5 }} ? `${String(Math.floor(timer / 60)).padStart(2, "0")}:${String(
> timer % 60
If you didnt receive a code, <span>Resend</span> ).padStart(2, "0")}`
</div> : ""}
</div> </div>
); <button
type="submit"
className="continue-button"
// disabled={otp.length < 4} // prevent clicking if not complete
>
Verify
</button>
</form>
<div
className={`resend ${timer > 0 ? "disabled" : ""}`}
onClick={timer === 0 ? resendCode : undefined}
style={{
cursor: timer === 0 ? "pointer" : "not-allowed",
opacity: timer === 0 ? 1 : 0.5,
}}
>
If you didnt receive a code, <span>Resend</span>
</div>
</div>
);
}; };
export default OTPVerification; export default OTPVerification;

View File

@@ -1,77 +1,82 @@
import React, { useState } from 'react'; import React, { useState } from "react";
import { EyeIcon } from '../icons/ExportCommonIcons'; import { EyeIcon } from "../icons/ExportCommonIcons";
interface Props { interface Props {
newPassword: string; newPassword: string;
confirmPassword: string; confirmPassword: string;
setNewPassword: (value: string) => void; setNewPassword: (value: string) => void;
setConfirmPassword: (value: string) => void; setConfirmPassword: (value: string) => void;
onSubmit: () => void; onSubmit: (e: React.FormEvent<HTMLFormElement>) => void;
} }
const PasswordSetup: React.FC<Props> = ({ const PasswordSetup: React.FC<Props> = ({
newPassword, newPassword,
confirmPassword, confirmPassword,
setNewPassword, setNewPassword,
setConfirmPassword, setConfirmPassword,
onSubmit onSubmit,
}) => { }) => {
const [showNewPassword, setShowNewPassword] = useState(false); const [showNewPassword, setShowNewPassword] = useState(false);
const [showConfirmPassword, setShowConfirmPassword] = useState(false); const [showConfirmPassword, setShowConfirmPassword] = useState(false);
return ( return (
<div className='request-container'> <div className="request-container">
<h1 className='header'>New Password</h1> <h1 className="header">New Password</h1>
<p className='sub-header'>Set the new password for your account so you can login and access all features.</p> <p className="sub-header">
<form Set the new password for your account so you can login and access all
className='auth-form' features.
onSubmit={(e) => { </p>
e.preventDefault(); <form
if (newPassword !== confirmPassword) { className="auth-form"
alert('Passwords do not match'); onSubmit={(e) => {
return; e.preventDefault();
} if (newPassword !== confirmPassword) {
onSubmit(); alert("Passwords do not match");
}} return;
> }
<div className="password-container"> onSubmit(e);
<input }}
type={showNewPassword ? 'text' : 'password'} >
placeholder='Enter new password' <div className="password-container">
value={newPassword} <input
onChange={(e) => setNewPassword(e.target.value)} type={showNewPassword ? "text" : "password"}
required placeholder="Enter new password"
/> value={newPassword}
<button onChange={(e) => setNewPassword(e.target.value)}
type="button" required
className="toggle-password" />
onClick={() => setShowNewPassword(prev => !prev)} <button
> type="button"
<EyeIcon isClosed={!showNewPassword} /> className="toggle-password"
</button> onClick={() => setShowNewPassword((prev) => !prev)}
</div> >
<EyeIcon isClosed={!showNewPassword} />
<div className="password-container"> </button>
<input
type={showConfirmPassword ? 'text' : 'password'}
placeholder='Confirm password'
value={confirmPassword}
onChange={(e) => setConfirmPassword(e.target.value)}
required
/>
<button
type="button"
className="toggle-password"
onClick={() => setShowConfirmPassword(prev => !prev)}
>
<EyeIcon isClosed={!showConfirmPassword} />
</button>
</div>
<button type='submit' className='continue-button'>Update password</button>
</form>
</div> </div>
);
<div className="password-container">
<input
type={showConfirmPassword ? "text" : "password"}
placeholder="Confirm password"
value={confirmPassword}
onChange={(e) => setConfirmPassword(e.target.value)}
required
/>
<button
type="button"
className="toggle-password"
onClick={() => setShowConfirmPassword((prev) => !prev)}
>
<EyeIcon isClosed={!showConfirmPassword} />
</button>
</div>
<button type="submit" className="continue-button">
Update password
</button>
</form>
</div>
);
}; };
export default PasswordSetup; export default PasswordSetup;

View File

@@ -1,92 +1,134 @@
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect, FormEvent } from "react";
import { LogoIconLarge } from '../components/icons/Logo'; import { LogoIconLarge } from "../components/icons/Logo";
import EmailInput from '../components/forgotPassword/EmailInput'; import EmailInput from "../components/forgotPassword/EmailInput";
import OTPVerification from '../components/forgotPassword/OTP_Verification'; import OTPVerification from "../components/forgotPassword/OTP_Verification";
import PasswordSetup from '../components/forgotPassword/PasswordSetup'; import PasswordSetup from "../components/forgotPassword/PasswordSetup";
import ConfirmationMessage from '../components/forgotPassword/ConfirmationMessgae'; import ConfirmationMessage from "../components/forgotPassword/ConfirmationMessgae";
import { changePasswordApi } from "../services/factoryBuilder/signInSignUp/changePasswordApi";
import { checkEmailApi } from "../services/factoryBuilder/signInSignUp/checkEmailApi";
import { verifyOtpApi } from "../services/factoryBuilder/signInSignUp/verifyOtpApi";
const ForgotPassword: React.FC = () => { const ForgotPassword: React.FC = () => {
const [step, setStep] = useState(1); const [step, setStep] = useState(1);
const [email, setEmail] = useState(''); const [email, setEmail] = useState("");
const [code, setCode] = useState(''); const [code, setCode] = useState("");
const [newPassword, setNewPassword] = useState(''); const [newPassword, setNewPassword] = useState("");
const [confirmPassword, setConfirmPassword] = useState(''); const [confirmPassword, setConfirmPassword] = useState("");
const [timer, setTimer] = useState(30); const [timer, setTimer] = useState(30);
const [resetToken, setResetToken] = useState("");
useEffect(() => { useEffect(() => {
let countdown: NodeJS.Timeout; let countdown: NodeJS.Timeout;
if (step === 2 && timer > 0) { if (step === 2 && timer > 0) {
countdown = setTimeout(() => setTimer(prev => prev - 1), 1000); countdown = setTimeout(() => setTimer((prev) => prev - 1), 1000);
}
return () => clearTimeout(countdown);
}, [step, timer]);
const handleSubmitEmail = () => {
setStep(2);
setTimer(30);
} }
const resendCode = () => { return () => clearTimeout(countdown);
// TODO: call API to resend code }, [step, timer]);
setTimer(30);
};
return ( const resendCode = async () => {
<div className='forgot-password-page auth-container'> // TODO: call API to resend code
<div className='forgot-password-wrapper'> setTimer(30);
<div className='logo-icon'> try {
<LogoIconLarge /> const emailResponse = await checkEmailApi(email);
</div>
if (emailResponse.message == "OTP sent Successfully") {
setCode(emailResponse.OTP);
}
} catch {}
};
const handleEmailSubmit = async (e: FormEvent<HTMLFormElement>) => {
setTimer(30);
try {
const emailResponse = await checkEmailApi(email);
{step === 1 && ( if (emailResponse.message == "OTP sent Successfully") {
<> setStep(2);
<EmailInput setCode(emailResponse.OTP);
email={email} }
setEmail={setEmail} } catch {}
onSubmit={handleSubmitEmail} };
/>
<a href='/' className='login continue-button'>Login</a>
</>
)} const handleOTPSubmit = async (e: FormEvent<HTMLFormElement>) => {
try {
const otpResponse = await verifyOtpApi(email, Number(code));
if (otpResponse.message == "OTP verified successfully") {
setResetToken(otpResponse.resetToken);
setStep(3);
} else {
alert(otpResponse.message);
}
} catch {}
};
{step === 2 && ( const handlePasswordSubmit = async (e: FormEvent<HTMLFormElement>) => {
<> try {
<OTPVerification const passwordResponse = await changePasswordApi(
email={email} resetToken,
timer={timer} newPassword,
setCode={setCode} confirmPassword
onSubmit={() => setStep(3)} );
resendCode={resendCode} if (passwordResponse.message === "Password reset successfull!!") {
/> setStep(4);
<a href='/' className='login'>Login</a> }
</> } catch {}
};
)} return (
<div className="forgot-password-page auth-container">
<div className="forgot-password-wrapper">
{step === 3 && ( <div className="logo-icon">
<> <LogoIconLarge />
<PasswordSetup
newPassword={newPassword}
confirmPassword={confirmPassword}
setNewPassword={setNewPassword}
setConfirmPassword={setConfirmPassword}
onSubmit={() => setStep(4)}
/>
<a href='/' className='login'>Login</a>
</>
)}
{step === 4 && <ConfirmationMessage />}
</div>
</div> </div>
);
{step === 1 && (
<>
<EmailInput
email={email}
setEmail={setEmail}
onSubmit={handleEmailSubmit}
/>
<a href="/" className="login continue-button">
Login
</a>
</>
)}
{step === 2 && (
<>
<OTPVerification
code={code}
email={email}
timer={timer}
setCode={setCode}
onSubmit={handleOTPSubmit}
resendCode={resendCode}
/>
<a href="/" className="login">
Login
</a>
</>
)}
{step === 3 && (
<>
<PasswordSetup
newPassword={newPassword}
confirmPassword={confirmPassword}
setNewPassword={setNewPassword}
setConfirmPassword={setConfirmPassword}
onSubmit={handlePasswordSubmit}
/>
<a href="/" className="login">
Login
</a>
</>
)}
{step === 4 && <ConfirmationMessage />}
</div>
</div>
);
}; };
export default ForgotPassword; export default ForgotPassword;

View File

@@ -34,7 +34,7 @@ const UserAuth: React.FC = () => {
useEffect(() => { useEffect(() => {
initializeFingerprint(); initializeFingerprint();
}, []) }, []);
const { userId, organization } = getUserData(); const { userId, organization } = getUserData();
@@ -47,7 +47,6 @@ const UserAuth: React.FC = () => {
setError(""); setError("");
setOrganization(organization); setOrganization(organization);
setUserName(res.message.name); setUserName(res.message.name);
// console.log(' res.userId: ', res.message.userId);
localStorage.setItem("userId", res.message.userId); localStorage.setItem("userId", res.message.userId);
localStorage.setItem("email", res.message.email); localStorage.setItem("email", res.message.email);
localStorage.setItem("userName", res.message.name); localStorage.setItem("userName", res.message.name);
@@ -55,33 +54,46 @@ const UserAuth: React.FC = () => {
localStorage.setItem("refreshToken", res.message.refreshToken); localStorage.setItem("refreshToken", res.message.refreshToken);
try { try {
const projects = await recentlyViewed(organization, res.message.userId); const projects = await recentlyViewed(
organization,
res.message.userId
);
if (res.message.isShare) { if (res.message.isShare) {
if (Object.values(projects.RecentlyViewed).length > 0) { if (Object.values(projects.RecentlyViewed).length > 0) {
const recent_opend_projectID = (Object.values(projects?.RecentlyViewed || {})[0] as any)?._id; const recent_opend_projectID = (
if (Object.values(projects?.RecentlyViewed).filter((val: any) => val._id == recent_opend_projectID)) { Object.values(projects?.RecentlyViewed || {})[0] as any
setLoadingProgress(1) )?._id;
navigate(`/projects/${recent_opend_projectID}`) if (
Object.values(projects?.RecentlyViewed).filter(
(val: any) => val._id == recent_opend_projectID
)
) {
setLoadingProgress(1);
navigate(`/projects/${recent_opend_projectID}`);
} else { } else {
navigate("/Dashboard") navigate("/Dashboard");
} }
} else { } else {
setLoadingProgress(1); setLoadingProgress(1);
navigate("/Dashboard"); navigate("/Dashboard");
} }
} }
} catch (error) { } catch (error) {
console.error("Error fetching recent projects:", error); console.error("Error fetching recent projects:", error);
} }
} else if (res.message === "User Not Found!!! Kindly signup...") { } else if (res.message === "User Not Found!!! Kindly signup...") {
setError("Account not found"); setError("Account not found");
} else if (res.message === "Email & Password is invalid...Check the credentials") { } else if (
setError(res.message) res.message === "Email & Password is invalid...Check the credentials"
} else if (res.message === "Already LoggedIn on another browser....Please logout!!!") { ) {
setError(res.message);
} else if (
res.message ===
"Already LoggedIn on another browser....Please logout!!!"
) {
setError("Already logged in on another browser. Please logout first."); setError("Already logged in on another browser. Please logout first.");
navigate("/"); navigate("/");
setError("") setError("");
// setError(""); // setError("");
// setOrganization(organization); // setOrganization(organization);
// setUserName(res.ForceLogoutData.userName); // setUserName(res.ForceLogoutData.userName);
@@ -179,6 +191,7 @@ const UserAuth: React.FC = () => {
name="email" name="email"
value={email} value={email}
placeholder="Email" placeholder="Email"
autoComplete="email"
onChange={(e) => setEmail(e.target.value)} onChange={(e) => setEmail(e.target.value)}
required required
/> />
@@ -188,6 +201,7 @@ const UserAuth: React.FC = () => {
type={showPassword ? "text" : "password"} type={showPassword ? "text" : "password"}
value={password} value={password}
placeholder="Password" placeholder="Password"
autoComplete="current-password"
onChange={(e) => setPassword(e.target.value)} onChange={(e) => setPassword(e.target.value)}
required required
/> />
@@ -201,7 +215,11 @@ const UserAuth: React.FC = () => {
</button> </button>
</div> </div>
{isSignIn && <a href="forgot" className="forgot-password">Forgot password ?</a>} {isSignIn && (
<a href="forgot" className="forgot-password">
Forgot password ?
</a>
)}
{!isSignIn && ( {!isSignIn && (
<div className="policy-checkbox"> <div className="policy-checkbox">

View File

@@ -0,0 +1,29 @@
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
export const changePasswordApi = async (
resetToken: string,
newPassword: string,
confirmPassword: string
) => {
try {
const response = await fetch(
`${url_Backend_dwinzo}/api/V1/Auth/reset-password/${resetToken}`,
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ newPassword, confirmPassword }),
}
);
const result = await response.json();
return result;
} catch (error) {
echo.error("Failed to create password");
if (error instanceof Error) {
return { error: error.message };
} else {
return { error: "An unknown error occurred" };
}
}
};

View File

@@ -0,0 +1,25 @@
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
export const checkEmailApi = async (Email: string) => {
try {
const response = await fetch(
`${url_Backend_dwinzo}/api/V1/Auth/forgetPassword`,
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ Email }),
}
);
const result = await response.json();
return result;
} catch (error) {
echo.error("Failed to create password");
if (error instanceof Error) {
return { error: error.message };
} else {
return { error: "An unknown error occurred" };
}
}
};

View File

@@ -0,0 +1,28 @@
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
export const verifyOtpApi = async (Email: string, Otp: number) => {
try {
const response = await fetch(
`${url_Backend_dwinzo}/api/V1/Auth/validate-otp`,
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
Email,
otp: Number(Otp),
}),
}
);
const result = await response.json();
return result;
} catch (error) {
echo.error("Failed to create password");
if (error instanceof Error) {
return { error: error.message };
} else {
return { error: "An unknown error occurred" };
}
}
};