diff --git a/src/components/dashboard/universal/ThemeToggle.tsx b/src/components/dashboard/universal/ThemeToggle.tsx new file mode 100644 index 0000000..a5a7aba --- /dev/null +++ b/src/components/dashboard/universal/ThemeToggle.tsx @@ -0,0 +1,115 @@ +import { useState, useEffect } from 'react'; +import { getCurrentTheme, toggleTheme } from '../../../utils/themeUtils'; +import { ThemeService } from '../../../scripts/database/ThemeService'; +import { Update } from '../../../scripts/pocketbase/Update'; +import { Authentication } from '../../../scripts/pocketbase/Authentication'; +import { Collections } from '../../../schemas/pocketbase/schema'; + +export default function ThemeToggle() { + const [theme, setTheme] = useState<'light' | 'dark'>(getCurrentTheme()); + const [isLoading, setIsLoading] = useState(false); + const auth = Authentication.getInstance(); + const update = Update.getInstance(); + + useEffect(() => { + // Initialize theme from IndexedDB + const loadTheme = async () => { + try { + const themeService = ThemeService.getInstance(); + const settings = await themeService.getThemeSettings(); + setTheme(settings.theme); + } catch (error) { + console.error('Error loading theme:', error); + } + }; + + loadTheme(); + + // Add event listener for theme changes + const handleThemeChange = () => { + setTheme(getCurrentTheme()); + }; + + window.addEventListener('themechange', handleThemeChange); + + return () => { + window.removeEventListener('themechange', handleThemeChange); + }; + }, []); + + const handleToggle = async () => { + setIsLoading(true); + try { + // Toggle theme in IndexedDB + await toggleTheme(); + const newTheme = getCurrentTheme(); + setTheme(newTheme); + + // Also update user preferences in PocketBase if user is authenticated + const user = auth.getCurrentUser(); + if (user) { + try { + // Get current display preferences + let displayPreferences = { theme: newTheme, fontSize: 'medium' }; + + if (user.display_preferences && typeof user.display_preferences === 'string') { + try { + const userPrefs = JSON.parse(user.display_preferences); + displayPreferences = { + ...userPrefs, + theme: newTheme + }; + } catch (e) { + console.error('Error parsing display preferences:', e); + } + } + + // Update user record + await update.updateFields( + Collections.USERS, + user.id, + { + display_preferences: JSON.stringify(displayPreferences) + } + ); + } catch (error) { + console.error('Error updating user preferences:', error); + } + } + } catch (error) { + console.error('Error toggling theme:', error); + } finally { + setIsLoading(false); + } + }; + + return ( +
+ +
+
+

Warning:

+

Light mode is experimental and not fully supported yet. Some UI elements may not display correctly.

+
+
+
+ ); +} \ No newline at end of file