import { createContext, useContext, useState, useEffect, useCallback } from 'react'; import { useLocation } from 'react-router-dom'; import api, { setTokens, clearTokens, getAccessToken } from '../api/client'; const AuthContext = createContext(null); export function AuthProvider({ children }) { const [user, setUser] = useState(() => { try { const stored = localStorage.getItem('user'); return stored ? JSON.parse(stored) : null; } catch { return null; } }); const [loading, setLoading] = useState(true); const location = useLocation(); const refreshUser = useCallback(async () => { try { const { data } = await api.get('/auth/me'); setUser(data.user); localStorage.setItem('user', JSON.stringify(data.user)); } catch { /* If /me fails, we might be logged out or server is down */ } }, []); /* On mount, verify the stored token is still valid */ useEffect(() => { async function verify() { const token = getAccessToken(); if (!token) { setLoading(false); return; } try { const { data } = await api.get('/auth/me'); setUser(data.user); localStorage.setItem('user', JSON.stringify(data.user)); } catch { clearTokens(); setUser(null); } finally { setLoading(false); } } verify(); }, []); /* Refresh user profile on navigation to ensure role is up to date */ useEffect(() => { if (user) { refreshUser(); } }, [location.pathname, user?.id]); const login = useCallback(async (email, password) => { const { data } = await api.post('/auth/login', { email, password }); setTokens(data.accessToken, data.refreshToken); setUser(data.user); localStorage.setItem('user', JSON.stringify(data.user)); return data.user; }, []); const logout = useCallback(async () => { try { await api.post('/auth/logout'); } catch { /* ignore — we clear locally regardless */ } clearTokens(); setUser(null); }, []); const isAdmin = ['office', 'admin', 'super_admin'].includes(user?.role); const value = { user, loading, login, logout, isAdmin, isAuthenticated: !!user, }; return {children}; } export function useAuth() { const ctx = useContext(AuthContext); if (!ctx) { throw new Error('useAuth must be used within an AuthProvider'); } return ctx; } export default AuthContext;