Files
admin-edu-space/frontend/public/js/theme-toggle.js
T

89 lines
3.2 KiB
JavaScript

/**
* Theme Toggle Manager - Edu-Space Admin
* Manejo de Modo Claro y Modo Oscuro con persistencia en localStorage y anti-flickering.
*/
(function() {
'use strict';
// 1. Obtener tema almacenado o preferencia del sistema
function getPreferredTheme() {
const storedTheme = localStorage.getItem('theme');
if (storedTheme) {
return storedTheme;
}
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
}
// 2. Aplicar tema al elemento <html>
function applyTheme(theme) {
document.documentElement.setAttribute('data-bs-theme', theme);
updateToggleButtons(theme);
}
// 3. Actualizar iconos de los botones de toggle
function updateToggleButtons(theme) {
const buttons = document.querySelectorAll('.theme-toggle-btn');
buttons.forEach(btn => {
const icon = btn.querySelector('i');
if (icon) {
if (theme === 'dark') {
icon.className = 'bi bi-sun-fill';
btn.setAttribute('aria-label', 'Cambiar a modo claro');
btn.setAttribute('title', 'Modo Claro');
} else {
icon.className = 'bi bi-moon-stars-fill';
btn.setAttribute('aria-label', 'Cambiar a modo oscuro');
btn.setAttribute('title', 'Modo Oscuro');
}
}
});
}
// 4. Función global para alternar tema
window.toggleTheme = function() {
const currentTheme = document.documentElement.getAttribute('data-bs-theme') || getPreferredTheme();
const newTheme = currentTheme === 'dark' ? 'light' : 'dark';
localStorage.setItem('theme', newTheme);
applyTheme(newTheme);
// Si el usuario está autenticado, sincronizar asíncronamente con su perfil en el backend
if (document.body && document.body.getAttribute('data-user-authenticated') === 'true') {
fetch('/api/user/theme', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ theme: newTheme })
}).catch(err => {
console.warn('No se pudo sincronizar el tema con el servidor:', err);
});
}
};
// 5. Inicializar tema inmediatamente (anti-flicker)
const initialTheme = getPreferredTheme();
applyTheme(initialTheme);
// 6. Al cargar el DOM, registrar eventos en los botones de toggle
document.addEventListener('DOMContentLoaded', () => {
updateToggleButtons(document.documentElement.getAttribute('data-bs-theme') || initialTheme);
document.querySelectorAll('.theme-toggle-btn').forEach(btn => {
btn.addEventListener('click', (e) => {
e.preventDefault();
window.toggleTheme();
});
});
});
// 7. Escuchar cambios de preferencia del sistema si el usuario no fijó una manual
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => {
if (!localStorage.getItem('theme')) {
applyTheme(e.matches ? 'dark' : 'light');
}
});
})();