import { createContext, useContext, useState, useEffect, useCallback, useMemo } from 'react' import { useLocation, useNavigate } from 'react-router-dom' import api, { AUTH_UNAUTHORIZED_EVENT, startTokenRefresh, stopTokenRefresh } from '../api/client' import { mutate } from 'swr' const AuthContext = createContext(null) export function AuthProvider({ children }) { const location = useLocation() const navigate = useNavigate() const [user, setUser] = useState(null) const [loading, setLoading] = useState(true) const [sessionExpired, setSessionExpired] = useState(false) useEffect(() => { api.get('/auth/me') .then(r => { setUser(r.data) startTokenRefresh({ refreshNow: true }) }) .catch(() => { setUser(null) }) .finally(() => setLoading(false)) }, []) useEffect(() => { const handleUnauthorized = () => { setSessionExpired(true) } window.addEventListener(AUTH_UNAUTHORIZED_EVENT, handleUnauthorized) return () => window.removeEventListener(AUTH_UNAUTHORIZED_EVENT, handleUnauthorized) }, []) useEffect(() => { return () => stopTokenRefresh() }, []) // Called after successful login or registration const saveUser = useCallback((userData) => { const u = { id: userData.id ?? userData.user_id, email: userData.email, role: userData.role, full_name: userData.full_name, } setUser(u) setSessionExpired(false) startTokenRefresh() return u }, []) const logout = useCallback(async () => { try { await api.post('/auth/logout') } catch (err) { console.error('Logout API error:', err) } stopTokenRefresh() setUser(null) setSessionExpired(false) mutate(() => true, undefined, { revalidate: false }) navigate('/login', { replace: true }) }, [navigate]) const confirmSessionExpired = useCallback(() => { stopTokenRefresh() setUser(null) setSessionExpired(false) mutate(() => true, undefined, { revalidate: false }) navigate('/login', { replace: true, state: { from: `${location.pathname}${location.search}` }, }) }, [location.pathname, location.search, navigate]) const value = useMemo(() => ({ user, loading, saveUser, logout, sessionExpired, }), [user, loading, saveUser, logout, sessionExpired]) return ( {children} {sessionExpired && (

Session expired

Sign in again to continue.

)}
) } export const useAuth = () => { const ctx = useContext(AuthContext) if (!ctx) throw new Error('useAuth must be used within AuthProvider') return ctx }