Des tonnes de modifications notamment VIM / Couleurs / typos
This commit is contained in:
205
frontend/src/theme-manager.js
Normal file
205
frontend/src/theme-manager.js
Normal file
@ -0,0 +1,205 @@
|
||||
/**
|
||||
* ThemeManager - Gère le système de thèmes de l'application
|
||||
* Permet de changer entre différents thèmes et persiste le choix dans localStorage
|
||||
*/
|
||||
class ThemeManager {
|
||||
constructor() {
|
||||
this.themes = [
|
||||
{
|
||||
id: 'material-dark',
|
||||
name: 'Material Dark',
|
||||
icon: '🌙',
|
||||
description: 'Thème professionnel inspiré de Material Design'
|
||||
},
|
||||
{
|
||||
id: 'monokai-dark',
|
||||
name: 'Monokai Dark',
|
||||
icon: '🎨',
|
||||
description: 'Palette Monokai classique pour les développeurs'
|
||||
},
|
||||
{
|
||||
id: 'dracula',
|
||||
name: 'Dracula',
|
||||
icon: '🧛',
|
||||
description: 'Thème sombre élégant avec des accents violets et cyan'
|
||||
},
|
||||
{
|
||||
id: 'one-dark',
|
||||
name: 'One Dark',
|
||||
icon: '⚡',
|
||||
description: 'Thème populaire d\'Atom avec des couleurs douces'
|
||||
},
|
||||
{
|
||||
id: 'solarized-dark',
|
||||
name: 'Solarized Dark',
|
||||
icon: '☀️',
|
||||
description: 'Palette scientifiquement optimisée pour réduire la fatigue oculaire'
|
||||
},
|
||||
{
|
||||
id: 'nord',
|
||||
name: 'Nord',
|
||||
icon: '❄️',
|
||||
description: 'Palette arctique apaisante avec des tons bleus froids'
|
||||
},
|
||||
{
|
||||
id: 'catppuccin',
|
||||
name: 'Catppuccin',
|
||||
icon: '🌸',
|
||||
description: 'Thème pastel doux et chaleureux avec des accents roses et bleus'
|
||||
},
|
||||
{
|
||||
id: 'everforest',
|
||||
name: 'Everforest',
|
||||
icon: '🌲',
|
||||
description: 'Palette naturelle inspirée de la forêt avec des tons verts et beiges'
|
||||
}
|
||||
];
|
||||
|
||||
this.currentTheme = this.loadTheme();
|
||||
this.init();
|
||||
}
|
||||
|
||||
init() {
|
||||
// Appliquer le thème sauvegardé
|
||||
this.applyTheme(this.currentTheme);
|
||||
|
||||
// Écouter les événements HTMX pour réinitialiser les listeners
|
||||
document.body.addEventListener('htmx:afterSwap', (event) => {
|
||||
if (event.detail.target.id === 'sidebar' || event.detail.target.closest('#sidebar')) {
|
||||
this.attachModalListeners();
|
||||
}
|
||||
});
|
||||
|
||||
console.log('ThemeManager initialized with theme:', this.currentTheme);
|
||||
}
|
||||
|
||||
loadTheme() {
|
||||
// Charger le thème depuis localStorage, par défaut 'material-dark'
|
||||
return localStorage.getItem('app-theme') || 'material-dark';
|
||||
}
|
||||
|
||||
saveTheme(themeId) {
|
||||
localStorage.setItem('app-theme', themeId);
|
||||
}
|
||||
|
||||
applyTheme(themeId) {
|
||||
// Appliquer le thème sur l'élément racine
|
||||
document.documentElement.setAttribute('data-theme', themeId);
|
||||
this.currentTheme = themeId;
|
||||
this.saveTheme(themeId);
|
||||
|
||||
// Mettre à jour les cartes de thème si la modale est ouverte
|
||||
this.updateThemeCards();
|
||||
|
||||
console.log('Theme applied:', themeId);
|
||||
}
|
||||
|
||||
openThemeModal() {
|
||||
const modal = document.getElementById('theme-modal');
|
||||
if (modal) {
|
||||
modal.style.display = 'flex';
|
||||
this.updateThemeCards();
|
||||
}
|
||||
}
|
||||
|
||||
closeThemeModal() {
|
||||
const modal = document.getElementById('theme-modal');
|
||||
if (modal) {
|
||||
modal.style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
updateThemeCards() {
|
||||
// Mettre à jour l'état actif des cartes de thème
|
||||
const cards = document.querySelectorAll('.theme-card');
|
||||
cards.forEach(card => {
|
||||
const themeId = card.dataset.theme;
|
||||
if (themeId === this.currentTheme) {
|
||||
card.classList.add('active');
|
||||
} else {
|
||||
card.classList.remove('active');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
attachModalListeners() {
|
||||
// Ré-attacher les listeners après un swap HTMX
|
||||
const settingsBtn = document.getElementById('theme-settings-btn');
|
||||
if (settingsBtn) {
|
||||
settingsBtn.replaceWith(settingsBtn.cloneNode(true));
|
||||
const newBtn = document.getElementById('theme-settings-btn');
|
||||
newBtn.addEventListener('click', () => this.openThemeModal());
|
||||
}
|
||||
}
|
||||
|
||||
getThemes() {
|
||||
return this.themes;
|
||||
}
|
||||
|
||||
getCurrentTheme() {
|
||||
return this.currentTheme;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fonctions globales pour les boutons
|
||||
*/
|
||||
window.openThemeModal = function() {
|
||||
if (window.themeManager) {
|
||||
window.themeManager.openThemeModal();
|
||||
}
|
||||
};
|
||||
|
||||
window.closeThemeModal = function() {
|
||||
if (window.themeManager) {
|
||||
window.themeManager.closeThemeModal();
|
||||
}
|
||||
};
|
||||
|
||||
window.selectTheme = function(themeId) {
|
||||
if (window.themeManager) {
|
||||
window.themeManager.applyTheme(themeId);
|
||||
}
|
||||
};
|
||||
|
||||
window.switchSettingsTab = function(tabName) {
|
||||
console.log('Switching to tab:', tabName);
|
||||
|
||||
// Désactiver tous les onglets
|
||||
const tabs = document.querySelectorAll('.settings-tab');
|
||||
tabs.forEach(tab => tab.classList.remove('active'));
|
||||
|
||||
// Cacher toutes les sections
|
||||
document.getElementById('themes-section').style.display = 'none';
|
||||
document.getElementById('fonts-section').style.display = 'none';
|
||||
document.getElementById('editor-section').style.display = 'none';
|
||||
|
||||
// Activer l'onglet cliqué
|
||||
const activeTab = Array.from(tabs).find(tab => {
|
||||
const text = tab.textContent.toLowerCase();
|
||||
if (tabName === 'themes') return text.includes('thème');
|
||||
if (tabName === 'fonts') return text.includes('police');
|
||||
if (tabName === 'editor') return text.includes('éditeur');
|
||||
return false;
|
||||
});
|
||||
if (activeTab) {
|
||||
activeTab.classList.add('active');
|
||||
}
|
||||
|
||||
// Afficher la section correspondante
|
||||
const sectionId = tabName + '-section';
|
||||
const section = document.getElementById(sectionId);
|
||||
if (section) {
|
||||
section.style.display = 'block';
|
||||
console.log('Showing section:', sectionId);
|
||||
} else {
|
||||
console.error('Section not found:', sectionId);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialisation automatique
|
||||
*/
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
window.themeManager = new ThemeManager();
|
||||
});
|
||||
Reference in New Issue
Block a user