Files
flxn-app/src/contexts/auth-context.tsx
2025-08-20 22:35:40 -05:00

74 lines
1.9 KiB
TypeScript

import { createContext, PropsWithChildren, useCallback, useContext, useMemo } from "react";
import { MantineColor, MantineColorScheme } from "@mantine/core";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import { fetchMe } from "@/features/players/server";
const queryKey = ['auth'];
export const authQueryConfig = {
queryKey,
queryFn: fetchMe
}
interface AuthData {
user: any;
metadata: { accentColor: MantineColor; colorScheme: MantineColorScheme };
roles: string[];
}
export const defaultAuthData: AuthData = {
user: undefined,
metadata: { accentColor: 'blue', colorScheme: 'auto' },
roles: [],
}
export interface AuthContextType extends AuthData {
set: ({ user, metadata, roles }: Partial<AuthContextType>) => void;
}
const AuthContext = createContext<AuthContextType>({
...defaultAuthData,
set: () => {},
});
export const AuthProvider: React.FC<PropsWithChildren> = ({ children }) => {
const queryClient = useQueryClient();
const { data, isLoading } = useQuery<AuthData>(authQueryConfig);
const set = useCallback((updates: Partial<AuthData>) => {
queryClient.setQueryData(queryKey, (oldData: AuthData | undefined) => {
const currentData = oldData || defaultAuthData;
return {
...currentData,
...updates,
metadata: updates.metadata
? { ...currentData.metadata, ...updates.metadata }
: currentData.metadata
};
});
}, [queryClient]);
if (isLoading) {
return <p>Loading...</p>
}
return (
<AuthContext
value={{
user: data?.user || defaultAuthData.user,
metadata: data?.metadata || defaultAuthData.metadata,
roles: data?.roles || defaultAuthData.roles,
set
}}>
{children}
</AuthContext>
)
};
export const useAuth = () => {
const context = useContext(AuthContext);
if (!context) {
throw new Error('useAuth must be used within an AuthProvider');
}
return context;
};