'use client' import { useEffect } from 'react' import { ACCESS_KEY_NAME, decodeJWT, useCookie } from '@baseapp-frontend/utils' import type { JWTContent } from '@baseapp-frontend/utils/types/jwt' import { useQuery, useQueryClient } from '@tanstack/react-query' import UserApi, { USER_API_KEY } from '../../../services/user' import type { User } from '../../../types/user' import type { UseJWTUserOptions } from './types' /** * Fetches the most recent user data from the server with JWT token data as instant placeholder. * * The key advantage of using this hook is automatic cache invalidation when user * data is mutated, ensuring UI stays in sync with server state. * * Use this when you need fresh user data and automatic updates after user mutations. * * Reads the access token via the `useCookie()` context (seeded server-side by the * dynamic-layout's `cookies()` call) so first-paint avatar/auth state for logged-in * users is correct without relying on any module-level Zustand state. */ const useJWTUser = & JWTContent>({ options, accessKeyName = ACCESS_KEY_NAME, ApiClass = UserApi, }: UseJWTUserOptions = {}) => { // TODO: placeholderData generic type is not working as expected, open an issue on react-query github type NonFunctionGuard = T extends Function ? never : T const { cookies } = useCookie>() const token = cookies?.[accessKeyName] ?? '' const placeholderData = (token ? decodeJWT(token) : null) as NonFunctionGuard const queryClient = useQueryClient() const { data: user, ...query } = useQuery({ queryFn: () => ApiClass.getUser(), queryKey: USER_API_KEY.getUser(), staleTime: Infinity, // makes cache never expire automatically enabled: !!token, throwOnError: false, placeholderData, ...options, // needs to be placed bellow all overridable options }) useEffect(() => { if ((query.error as any)?.response?.status === 401) { queryClient.resetQueries({ queryKey: USER_API_KEY.getUser() }) } }, [query.error]) return { user, ...query } } export default useJWTUser