// Module ES6 pour le tableau de statistiques Agenda import { apiFetch } from './agenda-api.js'; let currentPage = 1; let currentFilters = {}; /** * Initialise le module de tableau de stats */ export function initStatsTable() { // Initialiser Select2 sur les filtres if (typeof jQuery !== 'undefined' && jQuery.fn.select2) { jQuery('.stats-filters .select2').select2({ width: '100%' }); } // Écouter le bouton de filtre const filterBtn = document.getElementById('stats_filterBtn'); if (filterBtn) { filterBtn.addEventListener('click', handleFilter); } // Écouter le bouton de réinitialisation const resetBtn = document.getElementById('stats_resetFiltersBtn'); if (resetBtn) { resetBtn.addEventListener('click', handleReset); } // Charger les événements au démarrage loadEvents(); } /** * Collecte les filtres du formulaire */ function collectFilters() { const filters = {}; // Date (convertir en date pour recherche exacte sur une journée) const dateInput = document.getElementById('stats_date'); if (dateInput && dateInput.value) { filters.date = dateInput.value; } // Local const localSelect = document.getElementById('stats_local'); if (localSelect && localSelect.value) { filters.local = localSelect.value; } // Personne (intervenant) const personneSelect = document.getElementById('stats_personne'); if (personneSelect && personneSelect.value) { filters.intervenant = personneSelect.value; } // Type d'intervention const typeInterventionSelect = document.getElementById('stats_type_intervention'); if (typeInterventionSelect && typeInterventionSelect.value) { filters.type_intervention = typeInterventionSelect.value; } // Bénéficiaire const beneficiaireSelect = document.getElementById('stats_beneficiaire'); if (beneficiaireSelect && beneficiaireSelect.value) { filters.beneficiaire = beneficiaireSelect.value; } // Langue const langueSelect = document.getElementById('stats_langue'); if (langueSelect && langueSelect.value) { filters.langue = langueSelect.value; } // Intervenant externe (traducteur) const intervenantExterneSelect = document.getElementById('stats_intervenant_externe'); if (intervenantExterneSelect && intervenantExterneSelect.value) { filters.traducteur = intervenantExterneSelect.value; } // Année const anneeInput = document.getElementById('stats_annee'); if (anneeInput && anneeInput.value) { filters.annee = parseInt(anneeInput.value, 10); } // Statut const statutSelect = document.getElementById('stats_statut'); if (statutSelect && statutSelect.value) { filters.statut = statutSelect.value; } // Filtre permanence const permanenceCheckbox = document.getElementById('stats_filtre_permanence'); if (permanenceCheckbox && permanenceCheckbox.checked) { filters.type = 'permanence'; } return filters; } /** * Gère le clic sur le bouton Filtrer */ function handleFilter() { currentPage = 1; loadEvents(); } /** * Gère le clic sur le bouton Réinitialiser */ function handleReset() { // Réinitialiser tous les champs const form = document.querySelector('.stats-filters'); if (form) { form.reset(); // Réinitialiser Select2 if (typeof jQuery !== 'undefined' && jQuery.fn.select2) { jQuery('.stats-filters .select2').val(null).trigger('change'); } } currentPage = 1; currentFilters = {}; loadEvents(); } /** * Charge les événements depuis l'API */ async function loadEvents() { const loadingIndicator = document.getElementById('stats-loading-indicator'); const table = document.getElementById('stats-events-table'); const tableBody = document.getElementById('stats-events-table-body'); const paginationContainer = document.getElementById('stats-pagination-container'); const tableWrapper = document.getElementById('stats-table-wrapper'); // Afficher le loading et masquer le tableau if (loadingIndicator) { loadingIndicator.style.display = 'flex'; } if (tableWrapper) { tableWrapper.style.display = 'none'; } if (table) { table.style.display = 'none'; } if (paginationContainer) { paginationContainer.style.display = 'none'; } try { // Collecter les filtres currentFilters = collectFilters(); // Ajouter la pagination const params = { ...currentFilters, page: currentPage, per_page: 20 }; // Appel API const result = await apiFetch(`events/table?${new URLSearchParams(params).toString()}`); // Afficher les résultats displayEvents(result.events || []); // Afficher le nombre d'événements filtrés comme total, et le nombre d'événements sur la page courante comme affichés updateCounters(result.filtered || 0, (result.events || []).length); displayPagination(result.page || 1, result.total_pages || 0); // IMPORTANT: Masquer le loader EN PREMIER, puis afficher le tableau if (loadingIndicator) { loadingIndicator.style.display = 'none'; } // Afficher le conteneur du tableau if (tableWrapper) { tableWrapper.style.display = 'block'; } // Afficher le tableau if (table) { table.style.display = 'table'; } // Afficher la pagination si nécessaire if (paginationContainer && result.total_pages > 0) { paginationContainer.style.display = 'block'; } } catch (error) { console.error('Erreur lors du chargement des événements:', error); // En cas d'erreur, masquer le loader et afficher le tableau avec le message d'erreur if (loadingIndicator) { loadingIndicator.style.display = 'none'; } if (tableWrapper) { tableWrapper.style.display = 'block'; } if (table) { table.style.display = 'table'; } if (tableBody) { tableBody.innerHTML = `Erreur lors du chargement des données`; } } } /** * Affiche les événements dans le tableau */ function displayEvents(events) { const tableBody = document.getElementById('stats-events-table-body'); if (!tableBody) return; if (events.length === 0) { tableBody.innerHTML = 'Aucun événement trouvé'; return; } let html = ''; events.forEach(event => { const dateHeure = event.date_rdv && event.heure_rdv ? `${formatDate(event.date_rdv)} ${event.heure_rdv}` : '-'; const statutLabel = formatStatutLabel(event.statut); const statutClass = getStatutBadgeClass(event.statut); html += ` ${event.id || '-'} ${dateHeure} ${event.intervenant_nom || '-'} ${event.beneficiaire_nom || '-'} ${event.traducteur_nom || '-'} ${event.langue || '-'} ${statutLabel} ${event.commentaire || '-'} `; }); tableBody.innerHTML = html; } /** * Formate une date au format français */ function formatDate(dateString) { if (!dateString) return '-'; const date = new Date(dateString + 'T00:00:00'); return date.toLocaleDateString('fr-FR', { year: 'numeric', month: '2-digit', day: '2-digit' }); } /** * Formate le label du statut pour l'affichage */ function formatStatutLabel(statut) { if (!statut) return '-'; const statutMap = { 'prevu': 'Prévu', 'annule': 'Annulé', 'non_tenu': 'Non tenu', 'cloture': 'Clôturé', 'absence': 'Absence' }; return statutMap[statut.toLowerCase()] || statut; } /** * Retourne la classe Bootstrap pour le badge de statut */ function getStatutBadgeClass(statut) { if (!statut) return 'secondary'; const statutMap = { 'prevu': 'success', 'annule': 'danger', 'non_tenu': 'warning', 'cloture': 'secondary', 'absence': 'warning' }; return statutMap[statut.toLowerCase()] || 'secondary'; } /** * Échappe les caractères HTML pour éviter les injections XSS */ function escapeHtml(text) { if (!text) return ''; const div = document.createElement('div'); div.textContent = text; return div.innerHTML; } /** * Met à jour les compteurs */ function updateCounters(total, filtered) { const totalCount = document.getElementById('total-count'); const filteredCount = document.getElementById('filtered-count'); if (totalCount) { totalCount.textContent = total; } if (filteredCount) { filteredCount.textContent = filtered; } } /** * Affiche la pagination (uniquement les numéros de page) */ function displayPagination(currentPageNum, totalPages) { const paginationContainer = document.getElementById('stats-pagination-container'); if (!paginationContainer || totalPages <= 1) { if (paginationContainer) { paginationContainer.style.display = 'none'; } return; } // Afficher le conteneur paginationContainer.style.display = 'block'; let html = ''; paginationContainer.innerHTML = html; // Ajouter les écouteurs d'événements const pageLinks = paginationContainer.querySelectorAll('a[data-page]'); pageLinks.forEach(link => { link.addEventListener('click', (e) => { e.preventDefault(); const page = parseInt(link.getAttribute('data-page'), 10); if (page && page !== currentPage) { currentPage = page; loadEvents(); } }); }); }