aboutsummaryrefslogtreecommitdiffstats
path: root/frontend/src/components/shared/ThemeProvider.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/src/components/shared/ThemeProvider.tsx')
-rw-r--r--frontend/src/components/shared/ThemeProvider.tsx56
1 files changed, 56 insertions, 0 deletions
diff --git a/frontend/src/components/shared/ThemeProvider.tsx b/frontend/src/components/shared/ThemeProvider.tsx
new file mode 100644
index 0000000..2fc67d9
--- /dev/null
+++ b/frontend/src/components/shared/ThemeProvider.tsx
@@ -0,0 +1,56 @@
+'use client';
+
+import { createContext, useContext, useEffect, useState, ReactNode } from 'react';
+
+type Theme = 'light' | 'dark' | 'system';
+
+interface ThemeContextType {
+ theme: Theme;
+ setTheme: (theme: Theme) => void;
+}
+
+const ThemeContext = createContext<ThemeContextType | undefined>(undefined);
+
+export function ThemeProvider({ children }: { children: ReactNode }) {
+ const [theme, setTheme] = useState<Theme>('system');
+
+ useEffect(() => {
+ // Get the theme preference from localStorage if available
+ const storedTheme = localStorage.getItem('theme') as Theme | null;
+ if (storedTheme) {
+ setTheme(storedTheme);
+ }
+ }, []);
+
+ useEffect(() => {
+ const root = window.document.documentElement;
+
+ // Remove all theme classes
+ root.classList.remove('light', 'dark');
+
+ // Add the appropriate class based on theme
+ if (theme === 'system') {
+ const systemTheme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
+ root.classList.add(systemTheme);
+ } else {
+ root.classList.add(theme);
+ }
+
+ // Store the preference
+ localStorage.setItem('theme', theme);
+ }, [theme]);
+
+ return (
+ <ThemeContext.Provider value={{ theme, setTheme }}>
+ {children}
+ </ThemeContext.Provider>
+ );
+}
+
+export function useTheme() {
+ const context = useContext(ThemeContext);
+ if (context === undefined) {
+ throw new Error('useTheme must be used within a ThemeProvider');
+ }
+ return context;
+} \ No newline at end of file