"use client"; import { fetchData } from "@/lib/data-service"; import { clientFetch } from "@/lib/client-utils"; import { useState, useEffect } from "react"; import { useRouter } from "next/navigation"; import Image from "next/image"; import Link from "next/link"; import { Button } from "@/components/ui/button"; import { Checkbox } from "@/components/ui/checkbox"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { toast } from "sonner"; export default function LoginPage() { const [username, setUsername] = useState(""); const [password, setPassword] = useState(""); const [isLoading, setIsLoading] = useState(false); const [isRedirecting, setIsRedirecting] = useState(false); const [authStatus, setAuthStatus] = useState<{ loading: boolean; progress: number; message: string; }>({ loading: false, progress: 0, message: "Preparing your session..." }); const [error, setError] = useState(""); const router = useRouter(); // Check if already logged in useEffect(() => { const authToken = document.cookie .split("; ") .find((row) => row.startsWith("Authorization=")) ?.split("=")[1]; if (authToken) { router.push("/dashboard"); } }, [router]); // Function to verify authentication and prepare navigation const prepareNavigation = async (token: string) => { try { setAuthStatus(prev => ({ ...prev, loading: true, message: "Verifying your credentials..." })); // Step 1: Verify token is valid by making a simple auth check // This ensures we don't redirect with an invalid token await clientFetch("/auth/me", { headers: { Authorization: `Bearer ${token}` } }); setAuthStatus(prev => ({ ...prev, progress: 50, message: "Authentication successful!" })); // Slight delay to show success message await new Promise(resolve => setTimeout(resolve, 300)); setAuthStatus(prev => ({ ...prev, progress: 100, message: "Redirecting to dashboard..." })); // Tell Next.js to prefetch the dashboard page // This helps with faster page load but doesn't affect server data fetching router.prefetch('/dashboard'); // Short delay to show completion await new Promise(resolve => setTimeout(resolve, 500)); // Redirect to dashboard router.push("/dashboard"); // Fallback redirect if router.push fails setTimeout(() => { window.location.href = "/dashboard"; }, 1000); } catch (error) { console.error("Authentication verification error:", error); // Even if verification fails, still try to redirect // The dashboard will handle invalid auth setAuthStatus(prev => ({ ...prev, progress: 100, message: "Authentication issue, redirecting anyway..." })); toast.warning("Authentication issue detected", { description: "You may need to log in again if the dashboard doesn't load." }); // Still redirect setTimeout(() => { router.push("/dashboard"); // Ultimate fallback setTimeout(() => { window.location.href = "/dashboard"; }, 1000); }, 500); } }; async function handleLogin(e: React.FormEvent) { e.preventDefault(); if (isLoading || isRedirecting) return; setIsLoading(true); try { const response = await fetch(`/api/auth/login`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ username, password }), credentials: "include", }); const data = await response.json(); if (response.ok && data.token) { // Set redirecting state to prevent multiple redirect attempts setIsRedirecting(true); // Store the token in both cookie and localStorage for redundancy document.cookie = `Authorization=${data.token}; path=/; Secure; SameSite=Strict; max-age=604800`; localStorage.setItem("Authorization", data.token); // Show toast before redirect toast.success("Login successful"); // Now verify auth and handle redirect await prepareNavigation(data.token); } else { // Handle HTTP error responses (including 401) const errorMessage = data.error || "Invalid credentials"; toast.error("Login Failed", { description: errorMessage, }); } } catch (error) { // This will now only catch network errors or JSON parsing errors toast.error("Connection Error", { description: "Unable to connect to the server. Please check your internet connection and try again.", }); console.error("Login error:", error); } finally { setIsLoading(false); } } // If already redirecting, show loading state with progress if (isRedirecting) { return (
{authStatus.message}
{/* Progress bar */}Please sign in to your account
Don't have an account?{" "} Sign up