|
|
@@ -0,0 +1,52 @@
|
|
|
+import { createContext, useContext, useEffect, useState, type ReactNode } from 'react';
|
|
|
+
|
|
|
+type Theme = 'light' | 'dark';
|
|
|
+
|
|
|
+interface ThemeContextType {
|
|
|
+ theme: Theme;
|
|
|
+ toggleTheme: () => void;
|
|
|
+ setTheme: (theme: Theme) => void;
|
|
|
+}
|
|
|
+
|
|
|
+const ThemeContext = createContext<ThemeContextType | undefined>(undefined);
|
|
|
+
|
|
|
+export function ThemeProvider({ children }: { children: ReactNode }) {
|
|
|
+ const [theme, setThemeState] = useState<Theme>(() => {
|
|
|
+ const stored = localStorage.getItem('theme') as Theme | null;
|
|
|
+ if (stored) return stored;
|
|
|
+ // Default to dark theme
|
|
|
+ return 'dark';
|
|
|
+ });
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ const root = document.documentElement;
|
|
|
+ if (theme === 'dark') {
|
|
|
+ root.classList.add('dark');
|
|
|
+ } else {
|
|
|
+ root.classList.remove('dark');
|
|
|
+ }
|
|
|
+ localStorage.setItem('theme', theme);
|
|
|
+ }, [theme]);
|
|
|
+
|
|
|
+ const toggleTheme = () => {
|
|
|
+ setThemeState((prev) => (prev === 'dark' ? 'light' : 'dark'));
|
|
|
+ };
|
|
|
+
|
|
|
+ const setTheme = (newTheme: Theme) => {
|
|
|
+ setThemeState(newTheme);
|
|
|
+ };
|
|
|
+
|
|
|
+ return (
|
|
|
+ <ThemeContext.Provider value={{ theme, toggleTheme, setTheme }}>
|
|
|
+ {children}
|
|
|
+ </ThemeContext.Provider>
|
|
|
+ );
|
|
|
+}
|
|
|
+
|
|
|
+export function useTheme() {
|
|
|
+ const context = useContext(ThemeContext);
|
|
|
+ if (!context) {
|
|
|
+ throw new Error('useTheme must be used within a ThemeProvider');
|
|
|
+ }
|
|
|
+ return context;
|
|
|
+}
|