63 lines
1.6 KiB
TypeScript
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;
|
|
}
|