diff options
Diffstat (limited to 'web/src/context/AuthContext.tsx')
| -rw-r--r-- | web/src/context/AuthContext.tsx | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/web/src/context/AuthContext.tsx b/web/src/context/AuthContext.tsx new file mode 100644 index 0000000..f86a940 --- /dev/null +++ b/web/src/context/AuthContext.tsx @@ -0,0 +1,79 @@ +/** + * AuthContext.tsx + * + * Contexto global de autenticação. + * Persiste o JWT no localStorage e expõe o estado do usuário logado. + */ + +import { + createContext, + useContext, + useState, + useCallback, + type ReactNode, +} from 'react'; +import type { UserResponse } from '@/lib/api'; + +// ─── Tipos ──────────────────────────────────────────────────────────────────── + +interface AuthState { + user: UserResponse | null; + token: string | null; + isAuthenticated: boolean; + login: (token: string, user: UserResponse) => void; + logout: () => void; +} + +// ─── Chave no localStorage ──────────────────────────────────────────────────── + +const TOKEN_KEY = 'helpdesk:token'; +const USER_KEY = 'helpdesk:user'; + +// ─── Context ────────────────────────────────────────────────────────────────── + +const AuthContext = createContext<AuthState | null>(null); + +// ─── Provider ───────────────────────────────────────────────────────────────── + +export function AuthProvider({ children }: { children: ReactNode }) { + // Inicializa com dados persistidos (restaura sessão ao recarregar) + const [token, setToken] = useState<string | null>( + () => localStorage.getItem(TOKEN_KEY), + ); + const [user, setUser] = useState<UserResponse | null>(() => { + const stored = localStorage.getItem(USER_KEY); + return stored ? (JSON.parse(stored) as UserResponse) : null; + }); + + const login = useCallback((newToken: string, newUser: UserResponse) => { + localStorage.setItem(TOKEN_KEY, newToken); + localStorage.setItem(USER_KEY, JSON.stringify(newUser)); + setToken(newToken); + setUser(newUser); + }, []); + + const logout = useCallback(() => { + localStorage.removeItem(TOKEN_KEY); + localStorage.removeItem(USER_KEY); + setToken(null); + setUser(null); + }, []); + + return ( + <AuthContext.Provider + value={{ user, token, isAuthenticated: Boolean(token), login, logout }} + > + {children} + </AuthContext.Provider> + ); +} + +// ─── Hook ───────────────────────────────────────────────────────────────────── + +export function useAuth(): AuthState { + const ctx = useContext(AuthContext); + if (!ctx) { + throw new Error('useAuth deve ser usado dentro de <AuthProvider>'); + } + return ctx; +} |