Files
tabungin/apps/web/src/components/ThemeProvider.tsx
Dwindi Ramadhana 6a6e74562c checkpoint: goals feature, wallet balance, and goals/wallet detail UI
- Add goals feature (models, migrations, API, web pages)
- Add reserved/centralized wallet balance service
- Add wallet detail page and overview components
- Add new UI components (progress, multi-select, FAB)
- Remove stray empty -H/-d files from working tree
2026-06-17 20:40:00 +07:00

52 lines
1.2 KiB
TypeScript
Executable File

import { useEffect, useState } from 'react'
import { ThemeProviderContext, type Theme } from '../hooks/useTheme'
type ThemeProviderProps = {
children: React.ReactNode
defaultTheme?: Theme
storageKey?: string
}
export function ThemeProvider({
children,
defaultTheme = 'light',
storageKey = 'tabungin-ui-theme',
}: ThemeProviderProps) {
const [theme, setTheme] = useState<Theme>(() => {
const stored = localStorage.getItem(storageKey) as Theme
// If system theme is stored, convert to light
if (stored === 'system') {
return 'light'
}
return stored || defaultTheme
})
const [actualTheme, setActualTheme] = useState<'dark' | 'light'>('light')
useEffect(() => {
const root = window.document.documentElement
root.classList.remove('light', 'dark')
// Only support light and dark, no system
const themeToApply = theme === 'system' ? 'light' : theme
root.classList.add(themeToApply)
setActualTheme(themeToApply)
}, [theme])
const value = {
theme,
setTheme: (theme: Theme) => {
localStorage.setItem(storageKey, theme)
setTheme(theme)
},
actualTheme,
}
return (
<ThemeProviderContext.Provider value={value}>
{children}
</ThemeProviderContext.Provider>
)
}