import React, { createContext, useContext, useState, useEffect, useCallback } from "react"; interface User { id: number; username: string; email: string; created_at: string; } interface AuthContextType { user: User | null; token: string | null; isLoading: boolean; login: (email: string, password: string) => Promise; register: (username: string, email: string, password: string) => Promise; logout: () => void; } const AuthContext = createContext(null); const API_BASE = ""; export function AuthProvider({ children }: { children: React.ReactNode }) { const [user, setUser] = useState(null); const [token, setToken] = useState(() => localStorage.getItem("pettalk_token")); const [isLoading, setIsLoading] = useState(true); const fetchMe = useCallback(async (t: string) => { try { const res = await fetch("/api/me", { headers: { Authorization: `Bearer ${t}` }, }); if (res.ok) { const data = await res.json(); setUser(data.user); } else { localStorage.removeItem("pettalk_token"); setToken(null); } } catch { // Network error — keep token but mark as loaded } }, []); useEffect(() => { if (token) { fetchMe(token).finally(() => setIsLoading(false)); } else { setIsLoading(false); } }, [token, fetchMe]); const login = async (email: string, password: string) => { const res = await fetch("/api/login", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ email, password }), }); const data = await res.json(); if (!res.ok) { throw new Error(data.error || "Login failed"); } localStorage.setItem("pettalk_token", data.token); setToken(data.token); setUser(data.user); }; const register = async (username: string, email: string, password: string) => { const res = await fetch("/api/register", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ username, email, password }), }); const data = await res.json(); if (!res.ok) { throw new Error(data.error || "Registration failed"); } localStorage.setItem("pettalk_token", data.token); setToken(data.token); setUser(data.user); }; const logout = () => { localStorage.removeItem("pettalk_token"); setToken(null); setUser(null); }; return ( {children} ); } export function useAuth(): AuthContextType { const ctx = useContext(AuthContext); if (!ctx) { throw new Error("useAuth must be used within an AuthProvider"); } return ctx; } /** Helper to get auth headers for fetch calls */ export function getAuthHeaders(): Record { const token = localStorage.getItem("pettalk_token"); if (!token) return {}; return { Authorization: `Bearer ${token}` }; }