import React, { useEffect } from 'react'
import ReactDOM from 'react-dom/client'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { Toaster } from 'sonner'
import App from './App'
import './index.css'
import { useThemeStore, applyTheme, resolveTheme, type ThemeMode, type AccentKey } from './store/theme'
/* ---------------------------------------------------------------
Flash prevention: apply theme BEFORE React hydrates.
Reads directly from localStorage to avoid the Zustand wrapper.
--------------------------------------------------------------- */
;(function () {
try {
const raw = localStorage.getItem('schaeffler-theme')
if (raw) {
const { state } = JSON.parse(raw) as { state: { mode: ThemeMode; accent: AccentKey; customHex?: string } }
applyTheme(state.mode ?? 'light', state.accent ?? 'green', state.customHex)
}
} catch {
// ignore — default theme already applied by CSS
}
})()
const queryClient = new QueryClient({
defaultOptions: {
queries: {
staleTime: 30_000,
retry: 1,
},
},
})
/** Subscribes to store changes and system preference changes */
function ThemeProvider({ children }: { children: React.ReactNode }) {
const mode = useThemeStore((s) => s.mode)
const accent = useThemeStore((s) => s.accent)
const customHex = useThemeStore((s) => s.customHex)
const resolvedTheme = resolveTheme(mode)
// Apply whenever mode, accent, or customHex changes
useEffect(() => {
applyTheme(mode, accent, customHex)
}, [mode, accent, customHex])
// Listen to system preference changes when mode='system'
useEffect(() => {
if (mode !== 'system') return
const mq = window.matchMedia('(prefers-color-scheme: dark)')
const handler = () => applyTheme('system', accent, customHex)
mq.addEventListener('change', handler)
return () => mq.removeEventListener('change', handler)
}, [mode, accent, customHex])
return (
<>
{children}
>
)
}
ReactDOM.createRoot(document.getElementById('root')!).render(
,
)