"use client"; import React, { createContext, useContext, useState, useEffect } from "react"; type Language = "en" | "es"; type Theme = "light" | "dark"; interface AppContextType { lang: Language; setLang: (lang: Language) => void; theme: Theme; setTheme: (theme: Theme) => void; } const AppContext = createContext(undefined); const loginTranslations = { en: { title: "Secure Access", subtitle: "Please enter the password to access the Semillero AI Recruitment Platform.", placeholder: "Enter password", button: "Unlock", error: "Incorrect password", required: "Password is required", unlocking: "Unlocking...", }, es: { title: "Acceso Seguro", subtitle: "Por favor ingrese la contraseña para acceder a la Plataforma de Reclutamiento Semillero IA.", placeholder: "Ingrese la contraseña", button: "Desbloquear", error: "Contraseña incorrecta", required: "La contraseña es requerida", unlocking: "Desbloqueando...", } }; export function AppProvider({ children }: { children: React.ReactNode }) { const [lang, setLangState] = useState("en"); const [theme, setThemeState] = useState("light"); const [mounted, setMounted] = useState(false); const [isAuthenticated, setIsAuthenticated] = useState(false); const [password, setPassword] = useState(""); const [errorMsg, setErrorMsg] = useState(""); const [loadingAuth, setLoadingAuth] = useState(false); // Load from localStorage on mount useEffect(() => { const storedLang = localStorage.getItem("lang") as Language; const storedTheme = localStorage.getItem("theme") as Theme; const sessionTime = localStorage.getItem("auth_session_time"); setTimeout(() => { if (storedLang === "en" || storedLang === "es") { setLangState(storedLang); } if (storedTheme === "light" || storedTheme === "dark") { setThemeState(storedTheme); } else { // Check system preference const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)"); if (mediaQuery.matches) { setThemeState("dark"); } } // Check auth session: auto log off after 24 hours (1 day) if (sessionTime) { const lastSession = parseInt(sessionTime, 10); const oneDayMs = 24 * 60 * 60 * 1000; if (Date.now() - lastSession < oneDayMs) { setIsAuthenticated(true); } else { localStorage.removeItem("auth_session_time"); } } setMounted(true); }, 0); }, []); // Sync theme to document element useEffect(() => { if (!mounted) return; const root = window.document.documentElement; if (theme === "dark") { root.classList.add("dark"); } else { root.classList.remove("dark"); } }, [theme, mounted]); const setLang = (newLang: Language) => { setLangState(newLang); localStorage.setItem("lang", newLang); }; const setTheme = (newTheme: Theme) => { setThemeState(newTheme); localStorage.setItem("theme", newTheme); }; const handleLogin = async (e: React.FormEvent) => { e.preventDefault(); if (!password.trim()) { setErrorMsg(lang === "es" ? loginTranslations.es.required : loginTranslations.en.required); return; } setLoadingAuth(true); setErrorMsg(""); try { const response = await fetch("/api/auth", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ password }), }); if (response.ok) { localStorage.setItem("auth_session_time", Date.now().toString()); setIsAuthenticated(true); } else { await response.json(); setErrorMsg(lang === "es" ? loginTranslations.es.error : loginTranslations.en.error); } } catch (err) { console.error("Authentication failed:", err); setErrorMsg("Connection error. Please try again."); } finally { setLoadingAuth(false); } }; const t = lang === "es" ? loginTranslations.es : loginTranslations.en; if (!mounted) { return (
); } if (!isAuthenticated) { return (
{/* Top-right Language and Theme Controls */}
{/* Language Selector */} {/* Theme Toggle */}
{/* Login Lock Card */}
{/* Shield Lock Icon */}

{t.title}

{t.subtitle}

setPassword(e.target.value)} placeholder={t.placeholder} disabled={loadingAuth} className="w-full px-3.5 py-2 border border-slate-200 dark:border-slate-800 rounded-md text-slate-900 dark:text-white bg-slate-50 dark:bg-slate-800/40 text-sm focus:outline-none focus:border-blue-500 dark:focus:border-blue-500/80 transition duration-150" autoFocus /> {errorMsg && (

{errorMsg}

)}
); } return ( {children} ); } export function useApp() { const context = useContext(AppContext); if (context === undefined) { throw new Error("useApp must be used within an AppProvider"); } return context; }