import React, { createContext, useContext, useEffect, useState } from "react"; import { tokenStore } from "./token"; import { createApiClient } from "./axios"; import { AuthUser } from "./models"; interface AuthContextModel { currentUser: AuthUser | null; token: string | null; loading: boolean; error: string | null; login(username: string, password: string): Promise; register(username: string, password: string): Promise; logout(): void; } const AuthContext = createContext(undefined); export function AuthProvider({ children, authBaseUrl, }: { children: React.ReactNode; authBaseUrl: string; }) { const [currentUser, setCurrentUser] = useState(null); const [token, setToken] = useState(tokenStore.get()); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const auth = createApiClient(authBaseUrl); const login = async (username: string, password: string) => { try { setLoading(true); setError(null); const res = await auth.post("/login", { username, password }); const { access_token, user } = res.data; tokenStore.set(access_token); setToken(access_token); setCurrentUser(user); } catch (e: any) { setError(e.response?.data?.detail ?? "Login failed"); } finally { setLoading(false); } }; const register = async (username: string, password: string) => { try { setLoading(true); setError(null); await auth.post("/register", { username, password }); await login(username, password); } catch (e: any) { setError(e.response?.data?.detail ?? "Registration failed"); } finally { setLoading(false); } }; const logout = () => { tokenStore.clear(); setToken(null); setCurrentUser(null); }; const fetchCurrentUser = async () => { if (!token) return; try { const me = await auth.get("/me"); setCurrentUser({ ...me.data }); } catch { logout(); } }; useEffect(() => { fetchCurrentUser(); }, [token]); return ( {children} ); } export function useAuth(): AuthContextModel { const ctx = useContext(AuthContext); if (!ctx) throw new Error("useAuth must be used inside AuthProvider"); return ctx; }