Repository Public
1'use client';2import { useEffect, useState } from 'react';3import { QueryClient, QueryClientProvider } from '@tanstack/react-query';4import { TooltipProvider } from '@/components/ui/tooltip';5import { Toaster } from '@/components/ui/toast';6import { ApiRequestError } from '@/lib/api';7import { useConn } from '@/stores/conn';8import { useBrandingSync } from '@/stores/branding';9import { usePathname } from 'next/navigation';1011export function Providers({ children }: { children: React.ReactNode }) {12 const [client] = useState(13 () =>14 new QueryClient({15 defaultOptions: {16 queries: {17 staleTime: 15_000,18 refetchOnWindowFocus: false,19 retry: (count, err) => !(err instanceof ApiRequestError && err.status >= 400 && err.status < 500) && count < 2,20 },21 },22 }),23 );24 useBrandingSync(usePathname());25 useEffect(() => {26 const on = () => useConn.getState().set({ online: true });27 const off = () => useConn.getState().set({ online: false });28 window.addEventListener('online', on);29 window.addEventListener('offline', off);30 // The service worker caches the static shell only; it is registered in production builds.31 if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {32 navigator.serviceWorker.register('/sw.js').catch(() => undefined);33 }34 return () => {35 window.removeEventListener('online', on);36 window.removeEventListener('offline', off);37 };38 }, []);39 return (40 <QueryClientProvider client={client}>41 <TooltipProvider delayDuration={350} skipDelayDuration={200}>42 {children}43 <Toaster />44 </TooltipProvider>45 </QueryClientProvider>46 );47}48