feat(theme): add theme toggle functionality and initialize theme state

This commit is contained in:
2025-11-04 22:27:31 -06:00
parent dd566f408b
commit d2ae76ef81
2 changed files with 62 additions and 1 deletions

View File

@@ -1,10 +1,19 @@
<!doctype html>
<html lang="%paraglide.lang%" class="dark">
<html lang="%paraglide.lang%">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Anexo76 - Gestión de Comercio Exterior</title>
<meta name="description" content="Plataforma SaaS para gestión de comercio exterior conforme a Anexos 24, 31 y 22 del SAT" />
<script>
// Cargar el tema antes de renderizar para evitar flash
(function() {
const theme = localStorage.getItem('theme') || 'dark';
if (theme === 'dark') {
document.documentElement.classList.add('dark');
}
})();
</script>
%sveltekit.head%
</head>
<body data-sveltekit-preload-data="hover">

View File

@@ -10,6 +10,8 @@
import LogOutIcon from "@lucide/svelte/icons/log-out";
import SparklesIcon from "@lucide/svelte/icons/sparkles";
import LanguagesIcon from "@lucide/svelte/icons/languages";
import MoonIcon from "@lucide/svelte/icons/moon";
import SunIcon from "@lucide/svelte/icons/sun";
import { logout } from "$lib/auth";
import { cookieName } from "$lib/paraglide/runtime";
import { page } from "$app/state";
@@ -21,6 +23,30 @@
// Estado reactivo del idioma actual
let currentLocale = $derived(page.data.locale || 'en');
// Estado reactivo del tema actual
let isDarkMode = $state(false);
// Inicializar el estado del tema al montar el componente
$effect(() => {
if (browser) {
// Cargar la preferencia guardada o usar el valor actual del HTML
const savedTheme = localStorage.getItem('theme');
if (savedTheme) {
isDarkMode = savedTheme === 'dark';
if (savedTheme === 'dark') {
document.documentElement.classList.add('dark');
} else {
document.documentElement.classList.remove('dark');
}
} else {
// Si no hay preferencia guardada, usar el valor actual
isDarkMode = document.documentElement.classList.contains('dark');
// Guardar el estado actual
localStorage.setItem('theme', isDarkMode ? 'dark' : 'light');
}
}
});
async function handleLogout() {
await logout();
}
@@ -42,6 +68,23 @@
// Recargar la página para que el servidor procese el nuevo idioma
window.location.reload();
}
function toggleTheme() {
if (!browser) return;
const html = document.documentElement;
const newTheme = html.classList.contains('dark') ? 'light' : 'dark';
if (newTheme === 'dark') {
html.classList.add('dark');
} else {
html.classList.remove('dark');
}
// Guardar la preferencia en localStorage
localStorage.setItem('theme', newTheme);
isDarkMode = newTheme === 'dark';
}
</script>
<Sidebar.Menu>
@@ -111,6 +154,15 @@
<LanguagesIcon />
Language: {currentLocale.toUpperCase()}
</DropdownMenu.Item>
<DropdownMenu.Item onclick={toggleTheme}>
{#if isDarkMode}
<SunIcon />
Light Mode
{:else}
<MoonIcon />
Dark Mode
{/if}
</DropdownMenu.Item>
<DropdownMenu.Separator />
<DropdownMenu.Item onclick={handleLogout}>
<LogOutIcon />