import { createContext, useContext, useState, useCallback, useEffect, type ReactNode } from 'react' export interface User { id: string username: string email?: string real_name?: string roles: string[] is_active: boolean } interface AuthState { user: User | null token: string | null refreshToken: string | null isAuthenticated: boolean login: (token: string, refreshToken: string, user: User) => void logout: () => Promise } const AuthContext = createContext(null) export function AuthProvider({ children }: { children: ReactNode }) { const [user, setUser] = useState(null) const [token, setToken] = useState(null) const [refreshToken, setRefreshToken] = useState(null) useEffect(() => { const stored = localStorage.getItem('token') const storedRt = localStorage.getItem('refresh_token') const storedUser = localStorage.getItem('user') if (stored && storedUser) { setToken(stored) setRefreshToken(storedRt) setUser(JSON.parse(storedUser)) } }, []) const login = useCallback((t: string, rt: string, u: User) => { setToken(t) setRefreshToken(rt) setUser(u) localStorage.setItem('token', t) localStorage.setItem('refresh_token', rt) localStorage.setItem('user', JSON.stringify(u)) }, []) const logout = useCallback(async () => { const currentToken = localStorage.getItem('token') const currentRt = localStorage.getItem('refresh_token') if (currentToken && currentRt) { try { const res = await fetch('/api/v1/auth/logout', { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${currentToken}`, }, body: JSON.stringify({ token: currentToken, refresh_token: currentRt }), }) const data = await res.json() if (data.data?.sso_logout_url) { clearAuth() window.location.href = data.data.sso_logout_url return } } catch { // ignore network errors during logout } } clearAuth() window.location.href = '/login' }, []) const clearAuth = useCallback(() => { setToken(null) setRefreshToken(null) setUser(null) localStorage.removeItem('token') localStorage.removeItem('refresh_token') localStorage.removeItem('user') }, []) return ( {children} ) } export function useAuth() { const ctx = useContext(AuthContext) if (!ctx) throw new Error('useAuth must be used inside AuthProvider') return ctx }