/** * Système de Filtres Simplifié pour Notytex * Interface cohérente avec le design system existant */ class SimpleFilters { constructor() { this.currentFilters = {}; this.totalItems = 0; this.filteredItems = 0; this.init(); } init() { // Charger les filtres depuis l'URL this.loadFiltersFromURL(); // Attacher les événements this.attachEvents(); // Initialiser l'état visuel this.updateUI(); console.log('SimpleFilters initialized'); } attachEvents() { // Tous les boutons de filtres document.querySelectorAll('.filter-btn').forEach(btn => { btn.addEventListener('click', (e) => { e.preventDefault(); this.handleButtonFilter(btn.dataset.filter, btn.dataset.value); }); }); // Bouton reset const resetBtn = document.getElementById('reset-filters'); if (resetBtn) { resetBtn.addEventListener('click', (e) => { e.preventDefault(); this.resetAllFilters(); }); } // Suppression de tags individuels document.addEventListener('click', (e) => { if (e.target.classList.contains('remove-filter-tag')) { e.preventDefault(); const filterType = e.target.dataset.filter; this.removeFilter(filterType); } }); } handleButtonFilter(filterType, value) { // Mettre à jour visuellement tous les boutons de ce type document.querySelectorAll(`[data-filter="${filterType}"]`).forEach(btn => { this.resetButtonStyle(btn, filterType); }); // Activer le bouton sélectionné const activeBtn = document.querySelector(`[data-filter="${filterType}"][data-value="${value}"]`); if (activeBtn) { this.activateButton(activeBtn, filterType); } // Mettre à jour le filtre if (value) { this.currentFilters[filterType] = value; } else { delete this.currentFilters[filterType]; } this.applyFilters(); } resetButtonStyle(btn, filterType) { // Supprimer toutes les classes actives btn.classList.remove('bg-blue-600', 'text-white', 'border-blue-600'); btn.classList.remove('bg-red-500', 'text-white', 'border-red-500'); btn.classList.remove('bg-orange-500', 'text-white', 'border-orange-500'); btn.classList.remove('bg-green-500', 'text-white', 'border-green-500'); // Appliquer le style par défaut selon le type if (filterType === 'correction' && btn.dataset.value === 'not_started') { btn.classList.add('bg-white', 'text-red-600', 'border-red-200', 'hover:bg-red-50'); } else if (filterType === 'correction' && btn.dataset.value === 'incomplete') { btn.classList.add('bg-white', 'text-orange-600', 'border-orange-200', 'hover:bg-orange-50'); } else if (filterType === 'correction' && btn.dataset.value === 'complete') { btn.classList.add('bg-white', 'text-green-600', 'border-green-200', 'hover:bg-green-50'); } else { btn.classList.add('bg-white', 'text-gray-600', 'border-gray-300', 'hover:bg-gray-50'); } } activateButton(btn, filterType) { // Appliquer le style actif selon le type if (filterType === 'correction' && btn.dataset.value === 'not_started') { btn.classList.add('bg-red-500', 'text-white', 'border-red-500'); } else if (filterType === 'correction' && btn.dataset.value === 'incomplete') { btn.classList.add('bg-orange-500', 'text-white', 'border-orange-500'); } else if (filterType === 'correction' && btn.dataset.value === 'complete') { btn.classList.add('bg-green-500', 'text-white', 'border-green-500'); } else { btn.classList.add('bg-blue-600', 'text-white', 'border-blue-600'); } } applyFilters() { // Construire les paramètres URL const params = new URLSearchParams(); Object.keys(this.currentFilters).forEach(key => { params.set(key, this.currentFilters[key]); }); // Mettre à jour l'URL et recharger const newURL = window.location.pathname + (params.toString() ? '?' + params.toString() : ''); window.location.href = newURL; } updateUI() { this.updateActiveFilters(); } updateActiveFilters() { const tagsContainer = document.getElementById('active-filter-tags'); const resetBtn = document.getElementById('reset-filters'); if (!tagsContainer) return; // Vider les tags existants tagsContainer.innerHTML = ''; const hasActiveFilters = Object.keys(this.currentFilters).length > 0; if (hasActiveFilters) { // Afficher le bouton reset if (resetBtn) resetBtn.classList.remove('hidden'); // Créer les tags discrets const filterLabels = { trimester: (value) => `T${value}`, correction: (value) => { const labels = { 'not_started': 'Non commencées', 'incomplete': 'En cours', 'complete': 'Terminées' }; return labels[value] || value; }, class: (value) => { // Rechercher dans les boutons de classe const classBtn = document.querySelector(`[data-filter="class"][data-value="${value}"]`); return classBtn ? classBtn.textContent : value; } }; Object.keys(this.currentFilters).forEach(filterType => { const value = this.currentFilters[filterType]; const label = filterLabels[filterType] ? filterLabels[filterType](value) : value; const tag = document.createElement('span'); tag.className = 'px-1 py-0.5 bg-blue-100 text-blue-700 rounded text-xs flex items-center'; tag.innerHTML = ` ${label} `; tagsContainer.appendChild(tag); }); } else { // Masquer le bouton reset if (resetBtn) resetBtn.classList.add('hidden'); } } removeFilter(filterType) { delete this.currentFilters[filterType]; // Réactiver le bouton "Tous/Toutes" pour ce type de filtre this.handleButtonFilter(filterType, ''); } resetAllFilters() { this.currentFilters = {}; // Réinitialiser tous les filtres ['trimester', 'class', 'correction'].forEach(filterType => { this.handleButtonFilter(filterType, ''); }); } loadFiltersFromURL() { const params = new URLSearchParams(window.location.search); ['trimester', 'class', 'correction'].forEach(param => { const value = params.get(param); if (value) { this.currentFilters[param] = value; } }); } // Méthode publique pour mettre à jour le nombre d'éléments updateCounts(total, filtered) { this.totalItems = total; this.filteredItems = filtered; const countElement = document.getElementById('filtered-count'); if (countElement) { countElement.textContent = filtered; } } } // Initialisation automatique quand le DOM est prêt document.addEventListener('DOMContentLoaded', () => { // Vérifier si on est sur une page avec des filtres if (document.querySelector('.filter-btn') || document.querySelector('.filter-control')) { window.simpleFilters = new SimpleFilters(); } });