"use client"; import { createContext, useContext, useState, useEffect, useCallback, ReactNode, } from "react"; import { useRouter, usePathname } from "next/navigation"; import { AuthUser, AuthState, LoginCredentials, login as authLogin, logout as authLogout, getAuthState, verifyToken, } from "@/lib/authService"; // Rutas públicas que no requieren autenticación const PUBLIC_ROUTES = ["/login"]; interface AuthContextType { user: AuthUser | null; isAuthenticated: boolean; isLoading: boolean; login: (credentials: LoginCredentials) => Promise<{ success: boolean; error?: string }>; logout: () => Promise; } const AuthContext = createContext(undefined); interface AuthProviderProps { children: ReactNode; } export function AuthProvider({ children }: AuthProviderProps) { const router = useRouter(); const pathname = usePathname(); const [authState, setAuthState] = useState({ isAuthenticated: false, user: null, token: null, }); const [isLoading, setIsLoading] = useState(true); // Verificar autenticación al cargar useEffect(() => { async function checkAuth() { setIsLoading(true); // Obtener estado guardado const storedState = getAuthState(); if (storedState.isAuthenticated) { // Verificar que el token sigue siendo válido const isValid = await verifyToken(); if (isValid) { setAuthState(storedState); } else { // Token inválido, limpiar setAuthState({ isAuthenticated: false, user: null, token: null, }); } } setIsLoading(false); } checkAuth(); }, []); // Redirección basada en autenticación useEffect(() => { if (isLoading) return; const isPublicRoute = PUBLIC_ROUTES.includes(pathname); if (!authState.isAuthenticated && !isPublicRoute) { // No autenticado y en ruta privada -> redirigir a login router.push("/login"); } else if (authState.isAuthenticated && pathname === "/login") { // Autenticado y en login -> redirigir a home router.push("/"); } }, [authState.isAuthenticated, isLoading, pathname, router]); // Login const login = useCallback(async (credentials: LoginCredentials) => { const result = await authLogin(credentials); if (result.success) { setAuthState({ isAuthenticated: true, user: result.user || null, token: result.token || null, }); return { success: true }; } return { success: false, error: result.error }; }, []); // Logout const logout = useCallback(async () => { await authLogout(); setAuthState({ isAuthenticated: false, user: null, token: null, }); router.push("/login"); }, [router]); const value: AuthContextType = { user: authState.user, isAuthenticated: authState.isAuthenticated, isLoading, login, logout, }; return {children}; } /** * Hook para acceder al contexto de autenticación */ export function useAuth(): AuthContextType { const context = useContext(AuthContext); if (context === undefined) { throw new Error("useAuth must be used within an AuthProvider"); } return context; }