feat(theme): add complete theme support to all web apps

- ManaCore: add /themes page, use bg-background, add themeMode props
- ManaDeck: fix bg-gray to bg-background, add themeMode/onThemeModeChange
- Picture: add themeMode/onThemeModeChange props
- Zitare: add themeMode/onThemeModeChange props
- Presi: add themeMode/onThemeModeChange props

All apps now support:
- Theme variant dropdown (Lume, Ocean, Nature, Ember)
- Light/Dark/System mode selector
- Dynamic background colors via CSS variables

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Till-JS 2025-11-30 00:36:47 +01:00
parent 52d43b25e6
commit 2d17b720f8
5 changed files with 49 additions and 6 deletions

View file

@ -0,0 +1,19 @@
<script lang="ts">
import { goto } from '$app/navigation';
import { ThemePage } from '@manacore/shared-theme-ui';
import { theme } from '$lib/stores/theme';
</script>
<svelte:head>
<title>Themes | ManaCore</title>
</svelte:head>
<ThemePage
currentVariant={theme.variant}
onSelectTheme={(v) => theme.setVariant(v)}
showModeSelector={true}
currentMode={theme.mode}
onModeChange={(m) => theme.setMode(m)}
showBackButton={true}
onBack={() => goto('/dashboard')}
/>

View file

@ -18,7 +18,7 @@
let isCollapsed = $state(false);
// Get theme state
let effectiveMode = $derived(theme.effectiveMode);
let isDark = $derived(theme.isDark);
// Navigation items for ManaDeck
const navItems: PillNavItem[] = [
@ -100,6 +100,10 @@
theme.toggleMode();
}
function handleThemeModeChange(mode: 'light' | 'dark' | 'system') {
theme.setMode(mode);
}
async function handleSignOut() {
await authStore.signOut();
goto('/login');
@ -132,16 +136,16 @@
<svelte:window onkeydown={handleKeydown} />
{#if authStore.loading}
<div class="min-h-screen flex items-center justify-center bg-gray-50 dark:bg-gray-900">
<div class="min-h-screen flex items-center justify-center bg-background">
<div class="text-center">
<div
class="inline-block animate-spin h-8 w-8 border-4 border-primary-500 border-t-transparent rounded-full"
class="inline-block animate-spin h-8 w-8 border-4 border-primary border-t-transparent rounded-full"
></div>
<p class="mt-4 text-gray-500 dark:text-gray-400">Loading...</p>
<p class="mt-4 text-muted-foreground">Loading...</p>
</div>
</div>
{:else if authStore.isAuthenticated}
<div class="min-h-screen bg-gray-50 dark:bg-gray-900">
<div class="min-h-screen bg-background">
<!-- Pill Navigation -->
<PillNavigation
items={navItems}
@ -150,7 +154,7 @@
homeRoute="/decks"
onLogout={handleSignOut}
onToggleTheme={handleToggleTheme}
isDark={effectiveMode === 'dark'}
{isDark}
{isSidebarMode}
onModeChange={handleModeChange}
{isCollapsed}
@ -159,6 +163,8 @@
showThemeVariants={true}
{themeVariantItems}
{currentThemeVariantLabel}
themeMode={theme.mode}
onThemeModeChange={handleThemeModeChange}
showLanguageSwitcher={false}
primaryColor="#6366f1"
/>

View file

@ -46,6 +46,10 @@
theme.toggleMode();
}
function handleThemeModeChange(mode: 'light' | 'dark' | 'system') {
theme.setMode(mode);
}
// Client-side auth check
$effect(() => {
if (authStore.initialized && !authStore.loading && !authStore.user) {
@ -203,6 +207,8 @@
showThemeVariants={true}
{themeVariantItems}
{currentThemeVariantLabel}
themeMode={theme.mode}
onThemeModeChange={handleThemeModeChange}
showLanguageSwitcher={false}
primaryColor="#3b82f6"
/>

View file

@ -78,6 +78,10 @@
theme.toggleMode();
}
function handleThemeModeChange(mode: 'light' | 'dark' | 'system') {
theme.setMode(mode);
}
function handleLogout() {
auth.logout();
goto('/login');
@ -167,6 +171,8 @@
showThemeVariants={true}
{themeVariantItems}
{currentThemeVariantLabel}
themeMode={theme.mode}
onThemeModeChange={handleThemeModeChange}
showLanguageSwitcher={false}
showLogout={true}
onLogout={handleLogout}

View file

@ -107,6 +107,10 @@
theme.toggleMode();
}
function handleThemeModeChange(mode: 'light' | 'dark' | 'system') {
theme.setMode(mode);
}
async function handleLogout() {
await authStore.signOut();
goto('/login');
@ -169,6 +173,8 @@
showThemeVariants={true}
{themeVariantItems}
{currentThemeVariantLabel}
themeMode={theme.mode}
onThemeModeChange={handleThemeModeChange}
showLanguageSwitcher={false}
showLogout={authStore.isAuthenticated}
onLogout={handleLogout}