From a621d80cab300b78db7dff7e6fd9464580f060ca Mon Sep 17 00:00:00 2001 From: Ankush Chauhan Date: Thu, 5 Sep 2024 13:44:14 +0530 Subject: [PATCH 1/2] update theme handling --- apps/frontend/src/components/themes.tsx | 104 +++++++++++++----------- 1 file changed, 56 insertions(+), 48 deletions(-) diff --git a/apps/frontend/src/components/themes.tsx b/apps/frontend/src/components/themes.tsx index 3ec0ed8f..964629ae 100644 --- a/apps/frontend/src/components/themes.tsx +++ b/apps/frontend/src/components/themes.tsx @@ -1,56 +1,64 @@ -import { THEMES_DATA } from "@/constants/themes"; -import { useThemeContext } from "@/hooks/useThemes"; +import { THEMES_DATA } from '@/constants/themes'; +import { useThemeContext } from '@/hooks/useThemes'; +import { useState } from 'react'; +import { THEME } from '@/context/themeContext'; export function Themes() { - const { updateTheme } = useThemeContext(); + const { theme, updateTheme } = useThemeContext(); + const [selectedTheme, setSelectedTheme] = useState(theme); + + const handleThemeClick = (themeName: THEME) => { + setSelectedTheme(themeName); + updateTheme(themeName); + }; + return (
- { - THEMES_DATA.map(theme => { - return ( -
{ - updateTheme(theme.name); - }} - > -
-

{theme.name}

-
-
- chess-piece - chess-piece - chess-piece - chess-piece -
+ {THEMES_DATA.map((themeData) => { + const isActive = themeData.name === selectedTheme; + return ( +
handleThemeClick(themeData.name)} + > +
+

{themeData.name}

+
+
+ chess-piece + chess-piece + chess-piece + chess-piece
- ) - }) - } +
+ ); + })}
- ) -} \ No newline at end of file + ); +} From cca3b5d3219ee7514ba3ae44dbef72c78b67000e Mon Sep 17 00:00:00 2001 From: Ankush Chauhan Date: Thu, 5 Sep 2024 15:04:56 +0530 Subject: [PATCH 2/2] fix: persist selected theme across page reloads by initializing state from localStorage --- apps/frontend/src/context/themeContext.tsx | 48 +++++++++------------- 1 file changed, 19 insertions(+), 29 deletions(-) diff --git a/apps/frontend/src/context/themeContext.tsx b/apps/frontend/src/context/themeContext.tsx index 3ceec3bf..58e580b1 100644 --- a/apps/frontend/src/context/themeContext.tsx +++ b/apps/frontend/src/context/themeContext.tsx @@ -1,41 +1,31 @@ -import { createContext, useEffect, useState } from "react"; +import { createContext, useEffect, useState } from 'react'; -export type THEME = "default" | "bubblegum"; +export type THEME = 'default' | 'bubblegum'; export type THEME_CONTEXT = { - theme: THEME, - updateTheme: (theme: THEME) => void -} + theme: THEME; + updateTheme: (theme: THEME) => void; +}; -const AVAILABLE_THEMES: THEME[] = ["default", "bubblegum"]; +const AVAILABLE_THEMES: THEME[] = ['default', 'bubblegum']; export const ThemeContext = createContext(null); export function ThemesProvider({ children }: { children: React.ReactNode }) { - const [theme, setTheme] = useState("default"); - - function updateTheme(theme: THEME) { - setTheme(theme); - localStorage.setItem("theme", theme); - document.querySelector("html")?.setAttribute("data-theme", theme); + const [theme, setTheme] = useState(() => { + const storedTheme = localStorage.getItem('theme') as THEME | null; + return storedTheme && AVAILABLE_THEMES.includes(storedTheme) ? storedTheme : 'default'; + }); + + function updateTheme(newTheme: THEME) { + setTheme(newTheme); + localStorage.setItem('theme', newTheme); + document.querySelector('html')?.setAttribute('data-theme', newTheme); } useEffect(() => { - const currentTheme = localStorage.getItem("theme") as THEME | null; - - if(currentTheme && AVAILABLE_THEMES.includes(currentTheme)) { - setTheme(currentTheme); - document.querySelector("html")?.setAttribute("data-theme", currentTheme); - } - }, []); - - return ( - - {children} - - ) -} + document.querySelector('html')?.setAttribute('data-theme', theme); + }, [theme]); + return {children}; +} \ No newline at end of file