From bd7b9bea1aa128b17a6bc636602c68a8705187ab Mon Sep 17 00:00:00 2001 From: nmemmert Date: Thu, 15 Jan 2026 16:13:27 -0500 Subject: [PATCH] fix: simplify theme switching to use direct DOM manipulation and localStorage --- src/components/ClientLayout.tsx | 27 ++++++++++++++++++++++++- src/components/SettingsPage.tsx | 36 ++++++++++++++++++++------------- 2 files changed, 48 insertions(+), 15 deletions(-) diff --git a/src/components/ClientLayout.tsx b/src/components/ClientLayout.tsx index 59a5895..bb44039 100644 --- a/src/components/ClientLayout.tsx +++ b/src/components/ClientLayout.tsx @@ -1,5 +1,6 @@ 'use client'; +import { useEffect } from 'react'; import { ThemeProvider } from 'next-themes'; import { AuthProvider } from '@/context/AuthContext'; import { Toaster } from 'react-hot-toast'; @@ -9,8 +10,32 @@ export default function ClientLayout({ }: { children: React.ReactNode; }) { + useEffect(() => { + // Initialize theme from localStorage on mount + const stored = localStorage.getItem('theme-mode'); + const html = document.documentElement; + + if (stored === 'light') { + html.classList.remove('dark'); + html.style.colorScheme = 'light'; + } else if (stored === 'system') { + const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches; + if (prefersDark) { + html.classList.add('dark'); + html.style.colorScheme = 'dark'; + } else { + html.classList.remove('dark'); + html.style.colorScheme = 'light'; + } + } else { + // Default to dark + html.classList.add('dark'); + html.style.colorScheme = 'dark'; + } + }, []); + return ( - + {children} ('dark'); useEffect(() => { - setMounted(true); - // Get the current theme from localStorage or system preference - const stored = localStorage.getItem('theme'); + // Get the current theme from localStorage or HTML class + const stored = localStorage.getItem('theme-mode'); if (stored) { setCurrentTheme(stored); - } else if (theme) { - setCurrentTheme(theme); + } else { + const isDark = document.documentElement.classList.contains('dark'); + setCurrentTheme(isDark ? 'dark' : 'light'); } - }, [theme]); + }, []); const handleThemeChange = (newTheme: string) => { setCurrentTheme(newTheme); - localStorage.setItem('theme', newTheme); - setTheme(newTheme); + localStorage.setItem('theme-mode', newTheme); - // Update the HTML element immediately const html = document.documentElement; - if (newTheme === 'dark' || (newTheme === 'system' && window.matchMedia('(prefers-color-scheme: dark)').matches)) { + + if (newTheme === 'dark') { html.classList.add('dark'); - } else { + document.documentElement.style.colorScheme = 'dark'; + } else if (newTheme === 'light') { html.classList.remove('dark'); + document.documentElement.style.colorScheme = 'light'; + } else if (newTheme === 'system') { + // Use system preference + const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches; + if (prefersDark) { + html.classList.add('dark'); + document.documentElement.style.colorScheme = 'dark'; + } else { + html.classList.remove('dark'); + document.documentElement.style.colorScheme = 'light'; + } } };