import { createContext, useContext, useEffect, useState } from "react"; import { jwtDecode } from "jwt-decode"; export interface User { id: string; email: string; accessToken: string; refreshToken: string; isAdmin: boolean; } interface AuthContextType { user: User | null; isLoading: boolean; login: (accessToken: string, refreshToken: string) => void; logout: () => void; } const AuthContext = createContext({ user: null, isLoading: true, login: () => {}, logout: () => {}, }); export function AuthProvider({ children }: { children: React.ReactNode }) { const [user, setUser] = useState(null); const [isLoading, setIsLoading] = useState(true); useEffect(() => { try { const stored = localStorage.getItem("user"); if (stored) { const storedUser: User = JSON.parse(stored); try { const decoded: { exp: number } = jwtDecode(storedUser.accessToken); if (decoded.exp * 1000 < Date.now()) { // Token is expired, clear user data localStorage.removeItem("user"); localStorage.removeItem("accessToken"); localStorage.removeItem("refreshToken"); setUser(null); } else { setUser(storedUser); } } catch (error) { // If token is invalid, clear user data localStorage.removeItem("user"); localStorage.removeItem("accessToken"); localStorage.removeItem("refreshToken"); setUser(null); } } } finally { setIsLoading(false); } }, []); const login = (accessToken: string, refreshToken: string) => { const decoded: any = jwtDecode(accessToken); const roleField = decoded["http://schemas.microsoft.com/ws/2008/06/identity/claims/role"]; const isAdmin = Array.isArray(roleField) ? roleField.includes("Admin") : roleField === "Admin"; const newUser: User = { id: decoded.sub, email: decoded.email, accessToken, refreshToken, isAdmin, }; setUser(newUser); localStorage.setItem("user", JSON.stringify(newUser)); localStorage.setItem("accessToken", accessToken); localStorage.setItem("refreshToken", refreshToken); }; const logout = () => { setUser(null); localStorage.removeItem("user"); localStorage.removeItem("accessToken"); localStorage.removeItem("refreshToken"); }; return ( {children} ); } export const useAuth = () => useContext(AuthContext);