Files
Dwinzo_Demo/app/src/pages/UserAuth.tsx
Nalvazhuthi cd465edc56 Add Forgot Password functionality and related components
- Introduced new components for the Forgot Password flow: EmailInput, OTPInput, OTPVerification, PasswordSetup, and ConfirmationMessage.
- Implemented navigation updates in DashboardCard for project links.
- Added a new decal image asset for the categories.
- Updated sidebar assets to include decals.
- Enhanced UserAuth page to include a link for forgotten passwords.
- Created a dedicated ForgotPassword page to manage the entire password recovery process.
- Added styles for the new Forgot Password components and updated existing styles for consistency.
2025-08-18 10:07:47 +05:30

243 lines
8.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import React, { useState, FormEvent, useEffect } from "react";
import { useNavigate } from "react-router-dom";
import { LogoIconLarge } from "../components/icons/Logo";
import { EyeIcon } from "../components/icons/ExportCommonIcons";
import {
useLoadingProgress,
useOrganization,
useUserName,
} from "../store/builder/store";
import { signInApi } from "../services/factoryBuilder/signInSignUp/signInApi";
import { signUpApi } from "../services/factoryBuilder/signInSignUp/signUpApi";
import FingerprintJS from "@fingerprintjs/fingerprintjs";
import { recentlyViewed } from "../services/dashboard/recentlyViewed";
import { getUserData } from "../functions/getUserData";
const UserAuth: React.FC = () => {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [showPassword, setShowPassword] = useState(false);
const [error, setError] = useState("");
const [isSignIn, setIsSignIn] = useState(true);
const { userName, setUserName } = useUserName();
const { setOrganization } = useOrganization();
const { setLoadingProgress } = useLoadingProgress();
const [fingerprint, setFingerprint] = useState("");
const navigate = useNavigate();
const initializeFingerprint = async () => {
const fp = await FingerprintJS.load();
const result = await fp.get();
setFingerprint(result.visitorId); // Set the fingerprint
};
useEffect(() => {
initializeFingerprint();
}, [])
const { userId, organization } = getUserData();
const handleLogin = async (e: FormEvent<HTMLFormElement>) => {
e.preventDefault();
const organization = email.split("@")[1].split(".")[0];
try {
const res = await signInApi(email, password, organization, fingerprint);
if (res.message.message === "login successfull") {
setError("");
setOrganization(organization);
setUserName(res.message.name);
// console.log(' res.userId: ', res.message.userId);
localStorage.setItem("userId", res.message.userId);
localStorage.setItem("email", res.message.email);
localStorage.setItem("userName", res.message.name);
localStorage.setItem("token", res.message.token);
localStorage.setItem("refreshToken", res.message.refreshToken);
try {
const projects = await recentlyViewed(organization, res.message.userId);
if (res.message.isShare) {
if (Object.values(projects.RecentlyViewed).length > 0) {
const recent_opend_projectID = (Object.values(projects?.RecentlyViewed || {})[0] as any)?._id;
if (Object.values(projects?.RecentlyViewed).filter((val: any) => val._id == recent_opend_projectID)) {
setLoadingProgress(1)
navigate(`/projects/${recent_opend_projectID}`)
} else {
navigate("/Dashboard")
}
} else {
setLoadingProgress(1);
navigate("/Dashboard");
}
}
} catch (error) {
console.error("Error fetching recent projects:", error);
}
} else if (res.message === "User Not Found!!! Kindly signup...") {
setError("Account not found");
} else if (res.message === "Email & Password is invalid...Check the credentials") {
setError(res.message)
} else if (res.message === "Already LoggedIn on another browser....Please logout!!!") {
setError("Already logged in on another browser. Please logout first.");
navigate("/");
setError("")
// setError("");
// setOrganization(organization);
// setUserName(res.ForceLogoutData.userName);
// console.log(' res.userId: ', res.ForceLogoutData.userId);
// localStorage.setItem("userId", res.ForceLogoutData.userId);
// localStorage.setItem("email", res.ForceLogoutData.Email);
// localStorage.setItem("userName", res.ForceLogoutData.userName);
// localStorage.setItem("token", res.ForceLogoutData.token);
// localStorage.setItem("refreshToken", res.ForceLogoutData.refreshToken);
// if (res.ForceLogoutData.isShare) {
// setLoadingProgress(1);
// navigate("/Dashboard");
// }
}
} catch (error) {
echo.error("Login failed");
}
};
const handleRegister = async (e: FormEvent) => {
e.preventDefault();
if (email && password && userName) {
setError("");
try {
const organization = email.split("@")[1].split(".")[0];
const res = await signUpApi(userName, email, password, organization);
if (res.message === "New User created") {
setIsSignIn(true);
}
if (res.message === "User already exists") {
setError("User already exists");
}
} catch (error) {
echo.error("Register user failed");
}
} else {
setError("Please fill all the fields!");
}
};
return (
<div className="auth-container">
<div className="logo-icon">
<LogoIconLarge />
</div>
<h1>Welcome to Aalai</h1>
<p>
{isSignIn ? (
<>
Dont have an account?{" "}
<span
className="link"
onClick={() => setIsSignIn(false)}
style={{ cursor: "pointer" }}
>
Register here!
</span>
</>
) : (
<>
Already have an account?{" "}
<span
className="link"
onClick={() => setIsSignIn(true)}
style={{ cursor: "pointer" }}
>
Login here!
</span>
</>
)}
</p>
<button id="google-login" className="google-login">
<span className="google-icon">G</span> Continue with Google
</button>
{error && <div className="error-message">🛈 {error}</div>}
<form
onSubmit={isSignIn ? handleLogin : handleRegister}
className="auth-form"
>
{!isSignIn && (
<input
type="text"
value={userName}
placeholder="Username"
onChange={(e) => setUserName(e.target.value)}
required
/>
)}
<input
type="email"
name="email"
value={email}
placeholder="Email"
onChange={(e) => setEmail(e.target.value)}
required
/>
<div className="password-container">
<input
name="password"
type={showPassword ? "text" : "password"}
value={password}
placeholder="Password"
onChange={(e) => setPassword(e.target.value)}
required
/>
<button
id="toogle-password"
type="button"
className="toggle-password"
onClick={() => setShowPassword(!showPassword)}
>
<EyeIcon isClosed={showPassword} />
</button>
</div>
{isSignIn && <a href="forgot" className="forgot-password">Forgot password ?</a>}
{!isSignIn && (
<div className="policy-checkbox">
<input type="checkbox" id="tos" required />
<label htmlFor="tos" className="label">
I have read and agree to the terms of service
</label>
</div>
)}
<button id="form-submit" type="submit" className="continue-button">
{isSignIn ? "Continue" : "Register"}
</button>
</form>
<p className="policy">
By signing up for, or logging into, an account, you agree to our{" "}
<span
className="link"
onClick={() => navigate("/privacy")}
style={{ cursor: "pointer" }}
>
privacy policy
</span>{" "}
&{" "}
<span
className="link"
onClick={() => navigate("/terms")}
style={{ cursor: "pointer" }}
>
terms of service
</span>{" "}
whether you read them or not. You can also find these terms on our
website.
</p>
</div>
);
};
export default UserAuth;