xtablo-source/apps/main/src/providers/UserStoreProvider.tsx

97 lines
2.4 KiB
TypeScript
Raw Normal View History

2025-06-23 09:34:30 +00:00
import { useQuery } from "@tanstack/react-query";
2025-10-23 19:05:49 +00:00
import { useSession } from "@xtablo/shared/contexts/SessionContext";
2025-10-23 09:54:45 +00:00
import { Tables } from "@xtablo/shared/types/database.types";
2025-10-10 09:06:44 +00:00
import React from "react";
import { createStore, StoreApi, useStore } from "zustand";
2025-10-23 12:18:08 +00:00
import { LoadingSpinner } from "../components/LoadingSpinner";
2025-10-23 19:36:21 +00:00
import { api } from "../lib/api";
2025-10-23 09:54:45 +00:00
2025-10-05 18:25:29 +00:00
export type User = Tables<"profiles"> & {
2025-06-23 09:34:30 +00:00
streamToken: string | null;
};
const UserStoreContext = React.createContext<StoreApi<User> | null>(null);
2025-10-10 06:21:56 +00:00
export const UserStoreProvider = ({ children }: { children: React.ReactNode }) => {
2025-06-23 09:34:30 +00:00
const { session } = useSession();
2025-06-28 12:52:57 +00:00
const shouldFetchUser = !!session?.access_token;
const { data: user, isPending } = useQuery<User | null>({
2025-06-23 09:34:30 +00:00
queryKey: ["user"],
queryFn: async () => {
2025-06-24 19:20:24 +00:00
try {
const { data: user } = await api.get<User>("/api/v1/users/me", {
2025-06-24 19:20:24 +00:00
headers: {
Authorization: `Bearer ${session?.access_token}`,
},
});
return user;
2025-06-24 19:20:24 +00:00
} catch (error) {
console.error("Failed to get user:", error);
return null;
2025-06-24 19:20:24 +00:00
}
2025-06-23 09:34:30 +00:00
},
2025-06-28 12:52:57 +00:00
enabled: shouldFetchUser,
2025-06-23 09:34:30 +00:00
});
2025-06-28 12:52:57 +00:00
if (isPending && shouldFetchUser) {
2025-06-24 19:20:24 +00:00
return <LoadingSpinner />;
2025-06-23 09:34:30 +00:00
}
if (!user) {
2025-06-23 09:34:30 +00:00
return children;
}
const store = createStore<User>()(() => user);
2025-06-23 09:34:30 +00:00
return (
<UserStoreContext.Provider value={store as StoreApi<User>}>
{children}
</UserStoreContext.Provider>
);
};
export const useUser = () => {
const store = React.useContext(UserStoreContext);
if (!store) {
throw new Error("Missing UserStoreProvider");
}
return useStore(store);
};
2025-07-05 16:42:23 +00:00
2025-10-02 17:54:42 +00:00
export const useMaybeUser = () => {
const store = React.useContext(UserStoreContext);
if (!store) {
return null;
}
return useStore(store);
};
2025-07-05 16:42:23 +00:00
// TestUserStoreProvider component
export const TestUserStoreProvider = ({
children,
user,
}: {
children: React.ReactNode;
2025-10-16 15:45:35 +00:00
user: User | null;
2025-07-05 16:42:23 +00:00
}) => {
2025-10-16 15:45:35 +00:00
if (!user) {
return children;
}
2025-07-05 16:42:23 +00:00
const store = createStore<User>()(() => user);
return (
<UserStoreContext.Provider value={store as StoreApi<User>}>
{children}
</UserStoreContext.Provider>
);
};
// // Test useUser hook
// export const useTestUser = () => {
// const store = React.useContext(TestUserStoreContext);
// if (!store) {
// throw new Error("Missing TestUserStoreProvider");
// }
// return useStore(store);
// };