makerstash/client/theme.js

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();
});