import { createContext, useContext, useState, useEffect, useCallback } from 'react'; const AuthContext = createContext(); const API_BASE = import.meta.env.VITE_API_URL || ''; export function AuthProvider({ children }) { const [user, setUser] = useState(null); const [token, setToken] = useState(null); const [loading, setLoading] = useState(true); // On mount, check if we have a stored token and verify it useEffect(() => { const storedToken = sessionStorage.getItem('ot-token'); const storedUser = sessionStorage.getItem('ot-user'); if (storedToken && storedUser) { // Verify the token is still valid fetch(`${API_BASE}/api/verify`, { headers: { Authorization: `Bearer ${storedToken}` }, }) .then(res => { if (res.ok) { setToken(storedToken); setUser(storedUser); } else { // Token invalid/expired — clear storage sessionStorage.removeItem('ot-token'); sessionStorage.removeItem('ot-user'); } }) .catch(() => { sessionStorage.removeItem('ot-token'); sessionStorage.removeItem('ot-user'); }) .finally(() => setLoading(false)); } else { setLoading(false); } }, []); const login = useCallback(async (username, password) => { const res = await fetch(`${API_BASE}/api/login`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username, password }), }); if (!res.ok) { const err = await res.json().catch(() => ({})); throw new Error(err.detail || 'Login failed'); } const data = await res.json(); setToken(data.token); setUser(data.username); sessionStorage.setItem('ot-token', data.token); sessionStorage.setItem('ot-user', data.username); return data; }, []); const logout = useCallback(() => { setToken(null); setUser(null); sessionStorage.removeItem('ot-token'); sessionStorage.removeItem('ot-user'); }, []); const getAuthHeaders = useCallback(() => { if (!token) return {}; return { Authorization: `Bearer ${token}` }; }, [token]); const isAuthenticated = !!token && !!user; return ( {children} ); } export function useAuth() { const ctx = useContext(AuthContext); if (!ctx) throw new Error('useAuth must be used within AuthProvider'); return ctx; }