From 64149320acc6fd7db4aedf3de5f69cb72a13f442 Mon Sep 17 00:00:00 2001 From: Halit Aksoy Date: Sat, 17 Oct 2026 02:40:07 +0300 Subject: [PATCH] feat(frontend): remember the theme in a cookie for the login pages Keycloak's pages are on another origin; a mancala_theme cookie reaches them on localhost's ports and, set for playmancala.app, on its auth subdomain. --- apps/frontend/src/theme/themes.ts | 16 ++++++++++++++++ docs/specs/theme-polish/tasks.md | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/apps/frontend/src/theme/themes.ts b/apps/frontend/src/theme/themes.ts index 09baab5..30d118e 100644 --- a/apps/frontend/src/theme/themes.ts +++ b/apps/frontend/src/theme/themes.ts @@ -87,8 +87,24 @@ export function getWebTheme(theme: Theme): WebTheme { return webThemes.find((webTheme) => webTheme.id === theme.id) ?? walnut; } +// Puts the theme's class on and remembers the theme for the login pages. export function applyThemeClass(theme: Theme) { const root = document.documentElement; webThemes.forEach((webTheme) => root.classList.remove(webTheme.className)); root.classList.add(getWebTheme(theme).className); + saveThemeCookie(theme); +} + +const THEME_COOKIE = "mancala_theme"; +const COOKIE_MAX_AGE_SECONDS = 365 * 24 * 60 * 60; + +// The Keycloak login pages are on another origin and read the theme from this cookie (docs/specs/theme-polish). +// On localhost a host-only cookie reaches every port; on a domain the cookie is set for its last two labels, so +// playmancala.app shares it with auth.playmancala.app. +export function saveThemeCookie(theme: Theme) { + const { hostname, protocol } = window.location; + const isDomain = hostname.includes(".") && !/^[\d.]+$/.test(hostname); + const domain = isDomain ? `; domain=${hostname.split(".").slice(-2).join(".")}` : ""; + const secure = protocol === "https:" ? "; Secure" : ""; + document.cookie = `${THEME_COOKIE}=${getWebTheme(theme).id}; path=/; max-age=${COOKIE_MAX_AGE_SECONDS}; SameSite=Lax${domain}${secure}`; } diff --git a/docs/specs/theme-polish/tasks.md b/docs/specs/theme-polish/tasks.md index cf4b511..5ae6e72 100644 --- a/docs/specs/theme-polish/tasks.md +++ b/docs/specs/theme-polish/tasks.md @@ -4,7 +4,7 @@ Work through the tasks in order; each ends with its checks passing and a commit. - [x] 1. **Spec**: requirements, design and tasks. - [x] 2. **Web app messages**: Notyf at the top centre in the theme's colors. -- [ ] 3. **Theme cookie**: the web app saves the chosen theme for the login pages. +- [x] 3. **Theme cookie**: the web app saves the chosen theme for the login pages. - [ ] 4. **Login theme**: the script, the three themes' styles, logo and board masks; checked in Chrome in all three themes, at desktop and phone width, with and without the cookie. - [ ] 5. **Docs**: `AGENTS.md` (specs list, the cookie), `apps/keycloak/README.md`, `TODO.md`.