import { createContext, useContext, useState, useEffect, ReactNode } from 'react'; import { User, LoginDTO, JwtResponseDTO } from '@/types/auth'; import { api } from '@/services/api'; interface AuthContextType { user: User | null; loading: boolean; login: (credentials: LoginDTO) => Promise; logout: () => void; isAuthenticated: boolean; hasRole: (role: string) => boolean; hasAnyRole: (roles: string[]) => boolean; } const AuthContext = createContext(undefined); export function AuthProvider({ children }: { children: ReactNode }) { const [user, setUser] = useState(null); const [loading, setLoading] = useState(true); useEffect(() => { // Verificar se há token e dados do usuário no localStorage const token = localStorage.getItem('token'); const userData = localStorage.getItem('user'); if (token && userData) { try { const parsedUser = JSON.parse(userData); // Validar se o usuário tem ID (compatibilidade com versões anteriores) if (!parsedUser.id) { console.warn('Usuário sem ID encontrado no storage. Forçando logout.'); localStorage.removeItem('token'); localStorage.removeItem('user'); setUser(null); } else { setUser(parsedUser); } } catch (error) { console.error('Erro ao parsear dados do usuário:', error); localStorage.removeItem('token'); localStorage.removeItem('user'); } } setLoading(false); }, []); const login = async (credentials: LoginDTO) => { try { const response: JwtResponseDTO = await api.post( '/auth/login', credentials ); // Salvar token e dados do usuário localStorage.setItem('token', response.token); localStorage.setItem('refreshToken', response.refreshToken); const userData: User = { id: response.id, username: response.username, fullName: response.fullName, email: response.email, roles: response.roles, }; localStorage.setItem('user', JSON.stringify(userData)); setUser(userData); } catch (error: any) { const errorMessage = error.response?.data?.message || error.message || 'Erro ao fazer login'; throw new Error(errorMessage); } }; const logout = () => { localStorage.removeItem('token'); localStorage.removeItem('refreshToken'); localStorage.removeItem('user'); setUser(null); }; const hasRole = (role: string): boolean => { return user?.roles.includes(role) ?? false; }; const hasAnyRole = (roles: string[]): boolean => { if (!user) return false; return roles.some((role) => user.roles.includes(role)); }; return ( {children} ); } export function useAuth() { const context = useContext(AuthContext); if (context === undefined) { throw new Error('useAuth deve ser usado dentro de um AuthProvider'); } return context; }