import { useState, useEffect, useCallback, type ReactNode } from "react"; import { AuthContext, type AuthUser } from "./AuthTypes"; const BASE = "/api"; async function fetchMe(token: string) { try { const res = await fetch(`${BASE}/auth/me`, { headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}`, }, }); if (!res.ok) return null; return res.json(); } catch { return null; } } export function AuthProvider({ children }: { children: ReactNode }) { const [user, setUser] = useState(null); const [token, setToken] = useState(() => localStorage.getItem("token")); const [isLoading, setIsLoading] = useState(true); useEffect(() => { let cancelled = false; async function validateToken() { if (!token) return; const u = await fetchMe(token); if (cancelled) return; if (u) { setUser(u); } else { localStorage.removeItem("token"); setToken(null); } } validateToken().finally(() => { if (!cancelled) setIsLoading(false); }); return () => { cancelled = true; }; }, [token]); const login = useCallback(async (username: string, password: string) => { const res = await fetch(`${BASE}/auth/login`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ username, password }), }); if (!res.ok) { const text = await res.text().catch(() => ""); throw new Error(`${res.status}: ${text}`); } const data = await res.json(); const newToken = data.access_token; localStorage.setItem("token", newToken); setToken(newToken); }, []); const logout = useCallback(() => { localStorage.removeItem("token"); setToken(null); setUser(null); }, []); return ( {children} ); }