Feature: Mejorar UX del tema y persistencia
All checks were successful
build-and-deploy / build-and-deploy (push) Successful in 55s

- Mover botón editar al lado del nombre (siempre visible, sutil)
- Quitar efecto hover del header
- Detectar tema del sistema operativo automáticamente
- Actualizar theme-color dinámicamente (azul cielo día / oscuro noche)
- Usar cookies para persistir tema y filtros (1 año)
- Sincronizar filtros de apps con cookies
This commit is contained in:
2025-10-16 23:03:43 -06:00
parent 8b94e81dc8
commit 9a3dc1f0e6
3 changed files with 74 additions and 68 deletions

View File

@@ -6,23 +6,43 @@
export type Theme = 'day' | 'night'
export const useTheme = () => {
// Estado del tema con persistencia
const themeCookie = useCookie<Theme>('theme', {
maxAge: 60 * 60 * 24 * 365, // 1 año
sameSite: 'lax'
})
// Estado del tema con persistencia en cookies
const currentTheme = useState<Theme>('theme', () => {
if (import.meta.client && typeof window !== 'undefined') {
const saved = localStorage.getItem('theme')
if (saved === 'day' || saved === 'night') {
return saved
}
// Detectar preferencia del sistema
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches
return prefersDark ? 'night' : 'day'
// Primero intentar obtener de la cookie
if (themeCookie.value) {
return themeCookie.value
}
// Si no hay cookie, detectar preferencia del sistema
if (import.meta.client && typeof window !== 'undefined') {
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches
const systemTheme = prefersDark ? 'night' : 'day'
themeCookie.value = systemTheme
return systemTheme
}
return 'day'
})
// Computed para saber si es modo noche
const isNight = computed(() => currentTheme.value === 'night')
// Función para actualizar theme-color meta tag
const updateThemeColor = (theme: Theme) => {
if (import.meta.client && typeof window !== 'undefined') {
const metaThemeColor = document.querySelector('meta[name="theme-color"]')
const color = theme === 'night' ? '#0B1026' : '#87CEEB' // Cielo nocturno / Cielo diurno
if (metaThemeColor) {
metaThemeColor.setAttribute('content', color)
}
}
}
// Función para aplicar la clase dark al HTML
const applyThemeClass = (theme: Theme) => {
if (import.meta.client && typeof window !== 'undefined') {
@@ -34,6 +54,7 @@ export const useTheme = () => {
html.classList.add('light')
html.classList.remove('dark')
}
updateThemeColor(theme)
}
}
@@ -46,23 +67,18 @@ export const useTheme = () => {
// Sincronizar clase cuando cambie el tema
watch(currentTheme, (newTheme) => {
applyThemeClass(newTheme)
themeCookie.value = newTheme
})
}
// Alternar tema
const toggleTheme = () => {
currentTheme.value = currentTheme.value === 'day' ? 'night' : 'day'
if (import.meta.client && typeof window !== 'undefined') {
localStorage.setItem('theme', currentTheme.value)
}
}
// Establecer tema específico
const setTheme = (theme: Theme) => {
currentTheme.value = theme
if (import.meta.client && typeof window !== 'undefined') {
localStorage.setItem('theme', theme)
}
}
return {