All files / web/src/components ClientProviders.tsx

0% Statements 0/99
0% Branches 0/1
0% Functions 0/1
0% Lines 0/99

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100                                                                                                                                                                                                       
'use client'

import { AbacusDisplayProvider } from '@soroban/abacus-react'
import { HydrationBoundary, QueryClientProvider, type DehydratedState } from '@tanstack/react-query'
import { SessionProvider } from 'next-auth/react'
import { NextIntlClientProvider } from 'next-intl'
import dynamic from 'next/dynamic'
import { type ReactNode, useState } from 'react'
import { ToastProvider } from '@/components/common/ToastContext'
import { AudioManagerProvider } from '@/contexts/AudioManagerContext'
import { DeploymentInfoProvider } from '@tidepool/debug-panel'
import { DeploymentInfoPanel } from './DeploymentInfoPanel'
import { FullscreenProvider } from '@/contexts/FullscreenContext'
import { HomeHeroProvider } from '@/contexts/HomeHeroContext'
import { LocaleProvider, useLocaleContext } from '@/contexts/LocaleContext'
import { MyAbacusProvider } from '@/contexts/MyAbacusContext'
import { PageTransitionProvider } from '@/contexts/PageTransitionContext'
import { ThemeProvider } from '@/contexts/ThemeContext'
import { UserProfileProvider } from '@/contexts/UserProfileContext'
import { VisualDebugProvider } from '@/contexts/VisualDebugContext'
import type { Locale } from '@/i18n/messages'
import { createQueryClient } from '@/lib/queryClient'
import { AbacusSettingsSync } from './AbacusSettingsSync'
import { HeartbeatTracker } from './HeartbeatTracker'
import { PageTransitionOverlay } from './PageTransitionOverlay'
import { PracticeNotificationListener } from './PracticeNotificationListener'

// Lazy load MyAbacus - it includes @react-spring/web, AbacusReact, and Vision components
// Most pages don't need the floating abacus immediately on load
const MyAbacus = dynamic(() => import('./MyAbacus').then((m) => m.MyAbacus), {
  ssr: false,
})

interface ClientProvidersProps {
  children: ReactNode
  initialLocale: Locale
  initialMessages: Record<string, any>
  dehydratedState?: DehydratedState
}

function InnerProviders({ children }: { children: ReactNode }) {
  const { locale, messages } = useLocaleContext()

  return (
    <NextIntlClientProvider locale={locale} messages={messages} timeZone="UTC">
      <ToastProvider>
        <AbacusDisplayProvider>
          <AbacusSettingsSync />
          <UserProfileProvider>
            <FullscreenProvider>
              <HomeHeroProvider>
                <MyAbacusProvider>
                  <AudioManagerProvider>
                    <DeploymentInfoProvider>
                      <PageTransitionProvider>
                        {children}
                        <PageTransitionOverlay />
                        <DeploymentInfoPanel />
                        <HeartbeatTracker />
                        <PracticeNotificationListener />
                        <MyAbacus />
                      </PageTransitionProvider>
                    </DeploymentInfoProvider>
                  </AudioManagerProvider>
                </MyAbacusProvider>
              </HomeHeroProvider>
            </FullscreenProvider>
          </UserProfileProvider>
        </AbacusDisplayProvider>
      </ToastProvider>
    </NextIntlClientProvider>
  )
}

export function ClientProviders({
  children,
  initialLocale,
  initialMessages,
  dehydratedState,
}: ClientProvidersProps) {
  // Create a stable QueryClient instance that persists across renders
  const [queryClient] = useState(() => createQueryClient())

  return (
    <SessionProvider>
      <QueryClientProvider client={queryClient}>
        <HydrationBoundary state={dehydratedState}>
          <ThemeProvider>
            <VisualDebugProvider>
              <LocaleProvider initialLocale={initialLocale} initialMessages={initialMessages}>
                <InnerProviders>{children}</InnerProviders>
              </LocaleProvider>
            </VisualDebugProvider>
          </ThemeProvider>
        </HydrationBoundary>
      </QueryClientProvider>
    </SessionProvider>
  )
}