"use client"; import { useState, useEffect, useCallback } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; import { Lock, Loader2 } from 'lucide-react'; import ModernAdminDashboard from '@/components/ModernAdminDashboard'; // Constants const LOCKOUT_DURATION = 15 * 60 * 1000; // 15 minutes const RATE_LIMIT_DELAY = 1000; // 1 second base delay const getRateLimitDelay = (attempts: number): number => { return RATE_LIMIT_DELAY * Math.pow(2, attempts); }; interface AuthState { isAuthenticated: boolean; isLoading: boolean; showLogin: boolean; password: string; showPassword: boolean; error: string; attempts: number; isLocked: boolean; lastAttempt: number; csrfToken: string; } const AdminPage = () => { const [authState, setAuthState] = useState({ isAuthenticated: false, isLoading: true, showLogin: false, password: '', showPassword: false, error: '', attempts: 0, isLocked: false, lastAttempt: 0, csrfToken: '' }); // Fetch CSRF token const fetchCSRFToken = useCallback(async () => { try { const response = await fetch('/api/auth/csrf'); const data = await response.json(); if (response.ok && data.csrfToken) { setAuthState(prev => ({ ...prev, csrfToken: data.csrfToken })); return data.csrfToken; } } catch { console.error('Failed to fetch CSRF token'); } return ''; }, []); // Check if user is locked out const checkLockout = useCallback(() => { const lockoutData = localStorage.getItem('admin_lockout'); if (lockoutData) { try { const { timestamp, attempts } = JSON.parse(lockoutData); const now = Date.now(); if (now - timestamp < LOCKOUT_DURATION) { setAuthState(prev => ({ ...prev, isLocked: true, attempts, isLoading: false })); return true; } else { localStorage.removeItem('admin_lockout'); } } catch { localStorage.removeItem('admin_lockout'); } } return false; }, []); // Check session validity via API const checkSession = useCallback(async () => { try { const sessionToken = sessionStorage.getItem('admin_session_token'); if (!sessionToken) { setAuthState(prev => ({ ...prev, isAuthenticated: false, showLogin: true, isLoading: false })); return; } const response = await fetch('/api/auth/validate', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': authState.csrfToken }, body: JSON.stringify({ sessionToken, csrfToken: authState.csrfToken }) }); const data = await response.json(); if (response.ok && data.valid) { setAuthState(prev => ({ ...prev, isAuthenticated: true, showLogin: false, isLoading: false })); sessionStorage.setItem('admin_authenticated', 'true'); } else { sessionStorage.removeItem('admin_authenticated'); sessionStorage.removeItem('admin_session_token'); setAuthState(prev => ({ ...prev, isAuthenticated: false, showLogin: true, isLoading: false })); } } catch { setAuthState(prev => ({ ...prev, isAuthenticated: false, showLogin: true, isLoading: false })); } }, [authState.csrfToken]); // Initialize useEffect(() => { const init = async () => { if (checkLockout()) return; const token = await fetchCSRFToken(); if (token) { setAuthState(prev => ({ ...prev, csrfToken: token })); } }; init(); }, [checkLockout, fetchCSRFToken]); useEffect(() => { if (authState.csrfToken && !authState.isLocked) { checkSession(); } }, [authState.csrfToken, authState.isLocked, checkSession]); // Handle logout const handleLogout = useCallback(() => { sessionStorage.removeItem('admin_authenticated'); sessionStorage.removeItem('admin_session_token'); setAuthState(prev => ({ ...prev, isAuthenticated: false, showLogin: true, password: '', error: '' })); }, []); // Handle login form submission const handleLogin = async (e: React.FormEvent) => { e.preventDefault(); if (!authState.password.trim() || authState.isLoading) return; setAuthState(prev => ({ ...prev, isLoading: true, error: '' })); // Rate limiting delay const delay = getRateLimitDelay(authState.attempts); await new Promise(resolve => setTimeout(resolve, delay)); try { const response = await fetch('/api/auth/login', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': authState.csrfToken }, body: JSON.stringify({ password: authState.password, csrfToken: authState.csrfToken }) }); const data = await response.json(); if (response.ok && data.success) { sessionStorage.setItem('admin_authenticated', 'true'); sessionStorage.setItem('admin_session_token', data.sessionToken); setAuthState(prev => ({ ...prev, isAuthenticated: true, showLogin: false, password: '', error: '', attempts: 0, isLoading: false })); localStorage.removeItem('admin_lockout'); } else { const newAttempts = authState.attempts + 1; setAuthState(prev => ({ ...prev, error: data.error || 'Login failed', attempts: newAttempts, isLoading: false })); if (newAttempts >= 5) { localStorage.setItem('admin_lockout', JSON.stringify({ timestamp: Date.now(), attempts: newAttempts })); setAuthState(prev => ({ ...prev, isLocked: true, error: 'Too many failed attempts. Please try again in 15 minutes.' })); } } } catch { setAuthState(prev => ({ ...prev, error: 'Network error. Please try again.', isLoading: false })); } }; // Loading state if (authState.isLoading) { return (

Loading...

); } // Lockout state if (authState.isLocked) { return (

Account Locked

Too many failed attempts. Please try again in 15 minutes.

); } // Login form if (authState.showLogin || !authState.isAuthenticated) { return (

Admin Access

Enter your password to continue

setAuthState(prev => ({ ...prev, password: e.target.value }))} placeholder="Enter password" className="w-full px-4 py-3 bg-white/10 border border-white/20 rounded-xl text-white placeholder-white/50 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent" disabled={authState.isLoading} />
{authState.error && (

{authState.error}

)}
); } // Authenticated state - show admin dashboard return (
); }; export default AdminPage;