Files
notytex/static/js/simple-filters.js

223 lines
8.1 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 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}
<button type="button" class="remove-filter-tag ml-1 text-blue-600 hover:text-blue-800 font-bold" data-filter="${filterType}">×</button>
`;
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();
}
});