redesign the homepage
Build & Deploy / Build & Push Docker Image (push) Failing after 47s
Build & Deploy / Deploy to VPS (push) Has been skipped
Test / API Unit Tests (push) Failing after 5m4s
Test / Marketplace Unit Tests (push) Failing after 4m55s
Test / Admin Unit Tests (push) Successful in 9m37s
Test / Dashboard Unit Tests (push) Successful in 9m37s
Test / API Integration Tests (push) Successful in 9m54s

This commit is contained in:
root
2026-06-26 16:27:21 -04:00
parent 256ff0814e
commit d7fb7b7a7b
1030 changed files with 107374 additions and 2657 deletions
@@ -0,0 +1,13 @@
export const themeBootstrapScript = `(function () {
var allowed = { light: true, dark: true, system: true };
var cookieMatch = document.cookie.match(/(?:^|; )hpc-theme=([^;]+)/);
var cookieValue = cookieMatch ? decodeURIComponent(cookieMatch[1]) : null;
var stored = null;
try { stored = localStorage.getItem("hpc.theme.preference"); } catch (_) {}
var preference = allowed[cookieValue] ? cookieValue : (allowed[stored] ? stored : "system");
var dark = window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches;
var resolved = preference === "system" ? (dark ? "dark" : "light") : preference;
var root = document.documentElement;
root.dataset.themePreference = preference;
root.dataset.theme = resolved;
})();`;
+44
View File
@@ -0,0 +1,44 @@
import {
isThemePreference,
resolveTheme,
themeCookie,
themeCookieMaxAgeSeconds,
themeStorageKey,
type ThemePreference,
} from './config';
export const themePreferenceEvent = 'rentaldrivego:theme-preference';
export function applyTheme(preference: ThemePreference): void {
const systemDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
const resolved = resolveTheme(preference, systemDark);
const root = document.documentElement;
root.dataset.themePreference = preference;
root.dataset.theme = resolved;
}
export function persistTheme(preference: ThemePreference): void {
try {
window.localStorage.setItem(themeStorageKey, preference);
} catch {
// Storage can be unavailable; the first-party cookie remains canonical.
}
const secure = window.location.protocol === 'https:' ? '; Secure' : '';
document.cookie =
[
`${themeCookie}=${encodeURIComponent(preference)}`,
'Path=/',
`Max-Age=${themeCookieMaxAgeSeconds}`,
'SameSite=Lax',
].join('; ') + secure;
applyTheme(preference);
window.dispatchEvent(
new CustomEvent<ThemePreference>(themePreferenceEvent, { detail: preference }),
);
}
export function currentThemePreference(): ThemePreference {
const value = document.documentElement.dataset.themePreference;
return isThemePreference(value) ? value : 'system';
}
+19
View File
@@ -0,0 +1,19 @@
export const themeCookie = 'hpc-theme';
export const themeStorageKey = 'hpc.theme.preference';
export const themePreferences = ['light', 'dark', 'system'] as const;
export type ThemePreference = (typeof themePreferences)[number];
export type ResolvedTheme = 'light' | 'dark';
export const themeCookieMaxAgeSeconds = 31_536_000;
export function isThemePreference(value: unknown): value is ThemePreference {
return typeof value === 'string' && (themePreferences as readonly string[]).includes(value);
}
export function resolveTheme(preference: ThemePreference, systemDark: boolean): ResolvedTheme {
return preference === 'system' ? (systemDark ? 'dark' : 'light') : preference;
}
export function serverResolvedTheme(preference: ThemePreference): ResolvedTheme {
return preference === 'dark' ? 'dark' : 'light';
}