Files
flxn-app/src/contexts/auth-context.tsx
2025-09-20 20:50:44 -05:00

80 lines
2.0 KiB
TypeScript

import {
createContext,
PropsWithChildren,
useCallback,
useContext,
useMemo,
} from "react";
import { MantineColor, MantineColorScheme } from "@mantine/core";
import { useQueryClient } from "@tanstack/react-query";
import { Player } from "@/features/players/types";
import { playerKeys, playerQueries, useMe } from "@/features/players/queries";
interface AuthData {
user: Player | undefined;
metadata: { accentColor: MantineColor; colorScheme: MantineColorScheme };
roles: string[];
phone: string;
}
export const defaultAuthData: AuthData = {
user: undefined,
metadata: { accentColor: "blue", colorScheme: "auto" },
roles: [],
phone: ""
};
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 } = useMe();
const set = useCallback(
(updates: Partial<AuthData>) => {
queryClient.setQueryData(
playerKeys.auth,
(oldData: AuthData | undefined) => {
const currentData = oldData || defaultAuthData;
return {
...currentData,
...updates,
metadata: updates.metadata
? { ...currentData.metadata, ...updates.metadata }
: currentData.metadata,
};
}
);
},
[queryClient]
);
const value = useMemo(
() => ({
user: data?.user || defaultAuthData.user,
metadata: data?.metadata || defaultAuthData.metadata,
roles: data?.roles || defaultAuthData.roles,
phone: data?.phone || "",
set,
}),
[data, defaultAuthData]
);
return <AuthContext value={value}>{children}</AuthContext>;
};
export const useAuth = () => {
const context = useContext(AuthContext);
if (!context) {
throw new Error("useAuth must be used within an AuthProvider");
}
return context;
};