"use client"; import { createContext, useContext, useState, useEffect, useCallback } from "react"; import { useRouter, usePathname } from "next/navigation"; interface User { id: string; email: string; name: string | null; isAdmin: boolean; } interface AuthContextType { user: User | null; isLoading: boolean; logout: () => Promise; refresh: () => Promise; } const AuthContext = createContext({ user: null, isLoading: true, logout: async () => {}, refresh: async () => {}, }); export function useAuth() { return useContext(AuthContext); } const PUBLIC_PATHS = ["/login", "/register"]; export function AuthProvider({ children }: { children: React.ReactNode }) { const [user, setUser] = useState(null); const [isLoading, setIsLoading] = useState(true); const router = useRouter(); const pathname = usePathname(); const fetchUser = useCallback(async () => { try { const res = await fetch("/api/auth/me"); const data = await res.json(); setUser(data.user); return data.user; } catch { setUser(null); return null; } finally { setIsLoading(false); } }, []); useEffect(() => { fetchUser().then((user) => { if (!user && !PUBLIC_PATHS.includes(pathname)) { router.push("/login"); } }); }, [fetchUser, pathname, router]); const logout = async () => { try { await fetch("/api/auth/logout", { method: "POST" }); setUser(null); router.push("/login"); } catch { // Ignore errors } }; const refresh = async () => { await fetchUser(); }; // Show nothing while checking auth on protected pages if (isLoading && !PUBLIC_PATHS.includes(pathname)) { return (
Loading...
); } return ( {children} ); }