diff --git a/src/features/Auth/v1/Pages/LoginPage.tsx b/src/features/Auth/v1/Pages/LoginPage.tsx index 67f39ef..360e1c3 100644 --- a/src/features/Auth/v1/Pages/LoginPage.tsx +++ b/src/features/Auth/v1/Pages/LoginPage.tsx @@ -4,22 +4,47 @@ import { Link, useNavigate } from "react-router"; import { useAuth } from "../hooks/useAuth"; import Input from "@/Component/ui/Input"; -import { useCallback } from "react"; +import { useCallback, useState } from "react"; const LoginPage = () => { const { loginMutation } = useAuth(); const navigate = useNavigate(); + const [fieldErrors, setFieldErrors] = useState<{ email?: string; password?: string }>({}); + const [serverError, setServerError] = useState(null); + + const validateFields = useCallback((email: string, password: string): boolean => { + const errors: { email?: string; password?: string } = {}; + + if (!email.trim()) { + errors.email = "Email is required"; + } else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) { + errors.email = "Please enter a valid email address"; + } + + if (!password) { + errors.password = "Password is required"; + } + + setFieldErrors(errors); + return Object.keys(errors).length === 0; + }, []); + const handleLogin = useCallback( async (e: React.FormEvent) => { e.preventDefault(); + setServerError(null); const formData = new FormData(e.currentTarget); const email = formData.get("email") as string; const password = formData.get("password") as string; + if (!validateFields(email, password)) { + return; + } + try { const response = await loginMutation.mutateAsync({ email, @@ -27,21 +52,27 @@ const LoginPage = () => { }); const Role = response.data.role; - console.log("User role:", Role); if (Role === "organization") { navigate("/org/dashboard"); return; } - console.log("Login successful:", response); + if (Role === "member") { + navigate("/member/dashboard"); + return; + } - // redirect / save token / navigate - } catch (error) { - console.error("Login failed:", error); + navigate("/"); + } catch (error: any) { + const message = + error?.response?.data?.message || + error?.message || + "Login failed. Please check your credentials and try again."; + setServerError(message); } }, - [loginMutation], + [loginMutation, navigate, validateFields], ); return ( @@ -62,7 +93,12 @@ const LoginPage = () => {

Sign in

Please login to your account to continue.

-
+ + {serverError && ( +
+ {serverError} +
+ )}
+ {fieldErrors.email && ( +

{fieldErrors.email}

+ )}
diff --git a/src/features/Auth/v1/Store/Auth.Store.ts b/src/features/Auth/v1/Store/Auth.Store.ts index 453db3c..3ef1d30 100644 --- a/src/features/Auth/v1/Store/Auth.Store.ts +++ b/src/features/Auth/v1/Store/Auth.Store.ts @@ -9,14 +9,16 @@ const useAuthStore = create()( token: null, user: null, - setAuthData: (user: User) => + setAuthData: (user: User, token?: string) => set({ user, + token: token ?? null, }), clearAuthData: () => set({ user: null, + token: null, }), }), { diff --git a/src/features/Auth/v1/Types/Auth.type.ts b/src/features/Auth/v1/Types/Auth.type.ts index 7956fd8..2ab71fb 100644 --- a/src/features/Auth/v1/Types/Auth.type.ts +++ b/src/features/Auth/v1/Types/Auth.type.ts @@ -6,9 +6,9 @@ export interface User { } export interface AuthState { - // token: string | null; + token: string | null; user: User | null; - setAuthData: (user: User) => void; + setAuthData: (user: User, token?: string) => void; clearAuthData: () => void; } diff --git a/src/features/Auth/v1/hooks/useAuth.ts b/src/features/Auth/v1/hooks/useAuth.ts index 76a86c2..ed568c6 100644 --- a/src/features/Auth/v1/hooks/useAuth.ts +++ b/src/features/Auth/v1/hooks/useAuth.ts @@ -58,11 +58,12 @@ const useLoginMutation = () => { onSuccess: async (response) => { const user = response.data; + const token = response.token; console.log("Login successful:", user); // Save auth first - useAuthStore.getState().setAuthData(user); + useAuthStore.getState().setAuthData(user, token); // Fetch organization if needed if (user.role === "organization") { diff --git a/src/routes/OrgRoute.tsx b/src/routes/OrgRoute.tsx index 54ce651..8497333 100644 --- a/src/routes/OrgRoute.tsx +++ b/src/routes/OrgRoute.tsx @@ -14,7 +14,6 @@ import TaskDetailPage from "@/features/Tasks/v1/pages/TaskDetailPage"; import TaskManagementPage from "@/features/Tasks/v1/pages/TaskManagementPage"; import ProtectedRoute from "./ProtectedRoute"; -import { dashboardData } from "@/features/Member/v1/mock/dashboardData"; // Lazy-loaded Webhook pages const WebhookListPage = lazy(() => import("@/features/Webhooks/v1/pages/WebhookListPage")); @@ -60,7 +59,6 @@ const OrgRoute = () => { path="dashboard/webhooks/*" element={ diff --git a/src/routes/ProtectedRoute.tsx b/src/routes/ProtectedRoute.tsx index cdff5b5..a08e3e4 100644 --- a/src/routes/ProtectedRoute.tsx +++ b/src/routes/ProtectedRoute.tsx @@ -1,12 +1,14 @@ import { Navigate } from "react-router-dom"; +import useAuthStore from "@/features/Auth/v1/Store/Auth.Store"; interface Props { children: React.ReactNode; - user: { role: string } | null; allowedRoles: string[]; } -export default function ProtectedRoute({ children, user, allowedRoles }: Props) { +export default function ProtectedRoute({ children, allowedRoles }: Props) { + const user = useAuthStore((state) => state.user); + // Not logged in if (!user) { return ;