import { createContext, useContext, useEffect, type ReactNode, } from 'react' import { useNavigate, useRouterState } from '@tanstack/react-router' import { Center, Loader } from '@pikku/mantine/core' import { usePikkuQuery } from '@germantax/functions-sdk/pikku/api.gen' export interface Session { userId: string email: string displayName: string } interface SessionContextValue { session: Session refetch: () => void } const SessionContext = createContext(null) const PUBLIC_ROUTES = new Set(['/login', '/logout']) const isPublicRoute = (pathname: string) => PUBLIC_ROUTES.has(pathname) export function SessionProvider({ children }: { children: ReactNode }) { const navigate = useNavigate() const pathname = useRouterState({ select: (s) => s.location.pathname }) const onPublicRoute = isPublicRoute(pathname) const me = usePikkuQuery('getMe', undefined as never, { enabled: !onPublicRoute, retry: false, staleTime: 60_000, }) useEffect(() => { if (onPublicRoute) return if (me.error) { navigate({ to: '/login', search: { redirect: pathname } as never, replace: true, }) } }, [me.error, onPublicRoute, navigate, pathname]) if (onPublicRoute) { return <>{children} } if (me.isLoading || me.error || !me.data) { return (
) } return ( me.refetch() }} > {children} ) } export function useSession(): Session { const ctx = useContext(SessionContext) if (!ctx) { throw new Error('useSession must be used inside ') } return ctx.session } export function useOptionalSession(): Session | null { const ctx = useContext(SessionContext) return ctx?.session ?? null } export function useSessionRefetch(): () => void { const ctx = useContext(SessionContext) return ctx?.refetch ?? (() => {}) }