Files
ProxmoxVE-Local/src/app/_components/ThemeProvider.tsx
Michel Roegl-Brunner 7833d5d408 Fix type errors
2025-11-28 13:21:37 +01:00

68 lines
1.7 KiB
TypeScript

'use client';
import { createContext, useContext, useEffect, useState, startTransition } from 'react';
type Theme = 'light' | 'dark';
interface ThemeContextType {
theme: Theme;
setTheme: (theme: Theme) => void;
}
const ThemeContext = createContext<ThemeContextType | undefined>(undefined);
export function useTheme() {
const context = useContext(ThemeContext);
if (context === undefined) {
throw new Error('useTheme must be used within a ThemeProvider');
}
return context;
}
interface ThemeProviderProps {
children: React.ReactNode;
}
export function ThemeProvider({ children }: ThemeProviderProps) {
const [theme, setThemeState] = useState<Theme>('dark'); // Default to dark mode
const [mounted, setMounted] = useState(false);
// Load theme from localStorage on mount
useEffect(() => {
const savedTheme = localStorage.getItem('theme') as Theme;
if (savedTheme && (savedTheme === 'light' || savedTheme === 'dark')) {
startTransition(() => {
setThemeState(savedTheme);
});
}
startTransition(() => {
setMounted(true);
});
}, []);
// Apply theme to document element
useEffect(() => {
if (mounted) {
const root = document.documentElement;
root.classList.remove('light', 'dark');
root.classList.add(theme);
}
}, [theme, mounted]);
const setTheme = (newTheme: Theme) => {
setThemeState(newTheme);
localStorage.setItem('theme', newTheme);
};
// Prevent hydration mismatch by not rendering until mounted
if (!mounted) {
return <div className="dark">{children}</div>;
}
return (
<ThemeContext.Provider value={{ theme, setTheme }}>
{children}
</ThemeContext.Provider>
);
}