80 lines
2.0 KiB
TypeScript
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;
|
|
};
|