Mobile support to come.
"use client";
import {
createContext,
useCallback,
useContext,
useEffect,
useState,
} from "react";
import { getCurrentUserAction } from "@/actions";
import type { UserResponse } from "@/lib/dto";
type UserContextType = {
user: UserResponse | null;
refreshUser: () => void;
};
const UserContext = createContext<UserContextType | null>(null);
/**
* to enable static-site generation, we have to ensure that _all_ user-specific data is fetched in client-side components
*
* luckly this isn't too difficult, but for ergonomics, we do this once at a root-level user provider to avoid repeated data fetching
* in client-side components
*/
export function UserProvider({ children }: { children: React.ReactNode }) {
const [user, setUser] = useState<UserResponse | null>(null);
const refreshUser = useCallback(() => {
getCurrentUserAction().then(setUser);
}, []);
useEffect(() => {
refreshUser();
}, [refreshUser]);
return (
<UserContext.Provider value={{ user, refreshUser }}>
{children}
</UserContext.Provider>
);
}
export function useUser(): UserContextType {
const context = useContext(UserContext);
if (!context) {
throw new Error("useUser must be used within an UserProvider");
}
return context;
}