125 lines
3.1 KiB
JavaScript
125 lines
3.1 KiB
JavaScript
/**
|
|
* Dark/Light Theme Manager
|
|
* Handles theme switching and persistence
|
|
*/
|
|
|
|
// Theme configuration
|
|
const themes = {
|
|
light: {
|
|
'--primary-color': '#00C17A',
|
|
'--primary-dark': '#00A063',
|
|
'--primary-light': '#33D999',
|
|
'--bg-primary': '#ffffff',
|
|
'--bg-secondary': '#f5f5f5',
|
|
'--text-primary': '#222222',
|
|
'--text-secondary': '#666666',
|
|
'--border-color': '#e0e0e0',
|
|
'--shadow-color': 'rgba(0, 0, 0, 0.1)',
|
|
'--dark-bg': '#f5f5f5',
|
|
'--card-bg': '#ffffff',
|
|
'--hover-bg': '#e8e8e8',
|
|
},
|
|
dark: {
|
|
'--primary-color': '#00C17A',
|
|
'--primary-dark': '#00A063',
|
|
'--primary-light': '#33D999',
|
|
'--bg-primary': '#1a1a1a',
|
|
'--bg-secondary': '#2d2d2d',
|
|
'--text-primary': '#ffffff',
|
|
'--text-secondary': '#cccccc',
|
|
'--border-color': '#404040',
|
|
'--shadow-color': 'rgba(0, 0, 0, 0.3)',
|
|
'--dark-bg': '#1e1e1e',
|
|
'--card-bg': '#2d2d2d',
|
|
'--hover-bg': '#353535',
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Get current theme preference
|
|
*/
|
|
function getCurrentTheme() {
|
|
const saved = localStorage.getItem('theme');
|
|
if (saved) return saved;
|
|
|
|
// Check system preference
|
|
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
|
return 'dark';
|
|
}
|
|
return 'light';
|
|
}
|
|
|
|
/**
|
|
* Set theme and apply CSS variables
|
|
*/
|
|
function setTheme(theme) {
|
|
if (!themes[theme]) {
|
|
console.warn(`Unknown theme: ${theme}`);
|
|
return;
|
|
}
|
|
|
|
localStorage.setItem('theme', theme);
|
|
|
|
const root = document.documentElement;
|
|
const themeVars = themes[theme];
|
|
|
|
Object.entries(themeVars).forEach(([variable, value]) => {
|
|
root.style.setProperty(variable, value);
|
|
});
|
|
|
|
// Update body class for CSS-based theming
|
|
document.body.classList.remove('light-theme', 'dark-theme');
|
|
document.body.classList.add(`${theme}-theme`);
|
|
|
|
// Update theme toggle button icon
|
|
const themeToggleBtn = document.getElementById('themeToggle');
|
|
if (themeToggleBtn) {
|
|
const icon = themeToggleBtn.querySelector('i');
|
|
if (theme === 'dark') {
|
|
icon.classList.remove('fa-moon');
|
|
icon.classList.add('fa-sun');
|
|
themeToggleBtn.title = 'Switch to light mode';
|
|
} else {
|
|
icon.classList.remove('fa-sun');
|
|
icon.classList.add('fa-moon');
|
|
themeToggleBtn.title = 'Switch to dark mode';
|
|
}
|
|
}
|
|
|
|
// Save to server if user is logged in
|
|
if (currentUser && authToken) {
|
|
fetch(`${API_BASE}/auth/me/theme`, {
|
|
method: 'PUT',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'Authorization': `Bearer ${authToken}`
|
|
},
|
|
body: JSON.stringify({ theme })
|
|
}).catch(err => console.error('Error saving theme preference:', err));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Toggle between light and dark theme
|
|
*/
|
|
function toggleTheme() {
|
|
const current = getCurrentTheme();
|
|
const newTheme = current === 'light' ? 'dark' : 'light';
|
|
setTheme(newTheme);
|
|
}
|
|
|
|
/**
|
|
* Initialize theme on page load
|
|
*/
|
|
function initializeTheme() {
|
|
const savedTheme = getCurrentTheme();
|
|
setTheme(savedTheme);
|
|
}
|
|
|
|
// Initialize theme IMMEDIATELY when script loads
|
|
initializeTheme();
|
|
|
|
// Also initialize when DOM is ready
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
initializeTheme();
|
|
});
|