import React, { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react'; import type { AppUser } from '../types'; import { authApi, clearToken, getToken, setToken, setUnauthorizedHandler } from './api'; interface AuthContextValue { user: AppUser | null; isLoading: boolean; isAdmin: boolean; login: (identifier: string, password: string) => Promise; logout: () => void; /** Aktualisiert den lokalen Benutzer, z.B. nach Bearbeiten des eigenen Kontos. */ updateUser: (user: AppUser) => void; } const AuthContext = createContext(null); export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { const [user, setUser] = useState(null); const [isLoading, setIsLoading] = useState(true); const logout = useCallback(() => { clearToken(); setUser(null); }, []); // Ein 401 aus irgendeinem API-Call wirft den Benutzer sauber zurueck // auf den Login, statt eine leere Ansicht zu zeigen. useEffect(() => { setUnauthorizedHandler(() => setUser(null)); return () => setUnauthorizedHandler(null); }, []); // Beim Start pruefen, ob das gespeicherte Token noch gilt. useEffect(() => { let cancelled = false; const restore = async () => { if (!getToken()) { setIsLoading(false); return; } try { const { user: current } = await authApi.me(); if (!cancelled) setUser(current); } catch { clearToken(); } finally { if (!cancelled) setIsLoading(false); } }; restore(); return () => { cancelled = true; }; }, []); const login = useCallback(async (identifier: string, password: string) => { const { token, user: loggedIn } = await authApi.login(identifier, password); setToken(token); setUser(loggedIn); }, []); const value = useMemo( () => ({ user, isLoading, isAdmin: user?.role === 'admin', login, logout, updateUser: setUser, }), [user, isLoading, login, logout] ); return {children}; }; export function useAuth(): AuthContextValue { const ctx = useContext(AuthContext); if (!ctx) throw new Error('useAuth muss innerhalb von verwendet werden.'); return ctx; }