Files
timetracker/frontend/src/contexts/AuthContext.tsx
simon.franken d3b8df3deb fix
2026-02-16 11:01:07 +01:00

63 lines
1.6 KiB
TypeScript

import { createContext, useContext, useCallback, type ReactNode } from "react";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import { authApi } from "@/api/auth";
import type { User } from "@/types";
interface AuthContextType {
user: User | null;
isLoading: boolean;
isAuthenticated: boolean;
login: () => void;
logout: () => Promise<void>;
refetchUser: () => Promise<void>;
}
const AuthContext = createContext<AuthContextType | undefined>(undefined);
export function AuthProvider({ children }: { children: ReactNode }) {
const queryClient = useQueryClient();
const { data: user, isLoading } = useQuery({
queryKey: ["currentUser"],
queryFn: authApi.getCurrentUser,
staleTime: 5 * 60 * 1000, // 5 minutes
});
const login = useCallback(() => {
authApi.login();
}, []);
const logout = useCallback(async () => {
await authApi.logout();
queryClient.setQueryData(["currentUser"], null);
queryClient.clear();
}, [queryClient]);
const refetchUser = useCallback(async () => {
await queryClient.invalidateQueries({ queryKey: ["currentUser"] });
}, [queryClient]);
return (
<AuthContext.Provider
value={{
user: user ?? null,
isLoading,
isAuthenticated: !!user,
login,
logout,
refetchUser,
}}
>
{children}
</AuthContext.Provider>
);
}
export function useAuth() {
const context = useContext(AuthContext);
if (context === undefined) {
throw new Error("useAuth must be used within an AuthProvider");
}
return context;
}