Handle fetch fail in client app, fix data binding in location data (#243)

* Improve error handling for server rendered routes

* Fix data binding issue for country/state codes (use alias in sql)
This commit is contained in:
2026-08-23 03:26:48 -04:00
committed by GitHub
parent 1621313daa
commit 5816634809
10 changed files with 97 additions and 185 deletions

View File

@@ -1,26 +1,16 @@
import { useState } from 'react';
import {
biergartenThemes,
defaultThemeName,
isBiergartenTheme,
type ThemeName,
themeStorageKey,
} from '../themes';
import { useRouteLoaderData } from 'react-router';
import type { loader as rootLoader } from '../../../root';
import { biergartenThemes, defaultThemeName, themeCookieName, type ThemeName } from '../themes';
const applyTheme = (theme: ThemeName) => {
document.documentElement.setAttribute('data-theme', theme);
localStorage.setItem(themeStorageKey, theme);
document.cookie = `${themeCookieName}=${theme}; path=/; max-age=${60 * 60 * 24 * 365}; SameSite=Lax`;
};
const ThemeSwitcher = () => {
const [selectedTheme, setSelectedTheme] = useState<ThemeName>(() => {
if (typeof window === 'undefined') {
return defaultThemeName;
}
const savedTheme = localStorage.getItem(themeStorageKey);
return isBiergartenTheme(savedTheme) ? savedTheme : defaultThemeName;
});
const rootTheme = useRouteLoaderData<typeof rootLoader>('root')?.theme ?? defaultThemeName;
const [selectedTheme, setSelectedTheme] = useState<ThemeName>(rootTheme);
const activeTheme =
biergartenThemes.find((theme) => theme.value === selectedTheme) ?? biergartenThemes[0];

View File

@@ -8,7 +8,7 @@ export interface ThemeOption {
}
export const defaultThemeName: ThemeName = 'biergarten-lager';
export const themeStorageKey = 'biergarten-theme';
export const themeCookieName = 'biergarten-theme';
export const biergartenThemes: ThemeOption[] = [
{
@@ -36,3 +36,9 @@ export const biergartenThemes: ThemeOption[] = [
export const isBiergartenTheme = (value: string | null | undefined): value is ThemeName => {
return biergartenThemes.some((theme) => theme.value === value);
};
export const parseThemeCookie = (cookieHeader: string | null): ThemeName => {
const match = cookieHeader?.match(new RegExp(`(?:^|; )${themeCookieName}=([^;]*)`));
const value = match ? decodeURIComponent(match[1]) : null;
return isBiergartenTheme(value) ? value : defaultThemeName;
};