(() => { 'use strict'; const PTA = window.PTA; if (!PTA) throw new Error('PTA core doit être chargé avant pending-validation.js'); const { utils } = PTA; const { readJsonResponse, apiErrorMessage, escapeHtml, formatDuration, formatDate } = utils; const badge = document.querySelector('#pending-validation-tab-badge'); const refreshButton = document.querySelector('#refresh-pending-validation'); const countElement = document.querySelector('#pending-validation-count'); const hoursElement = document.querySelector('#pending-validation-hours'); const countedHoursElement = document.querySelector('#pending-validation-counted-hours'); const loadingElement = document.querySelector('#pending-validation-loading'); const emptyElement = document.querySelector('#pending-validation-empty'); const contentElement = document.querySelector('#pending-validation-content'); const bodyElement = document.querySelector('#pending-validation-body'); const messageElement = document.querySelector('#pending-validation-message'); let items = []; let loading = false; function weekValue(item) { return `${item.annee}-W${String(item.numero_semaine).padStart(2, '0')}`; } function formatDateTime(value) { if (!value) return '—'; const normalized = String(value).replace(' ', 'T'); const date = new Date(normalized); if (Number.isNaN(date.getTime())) return escapeHtml(value); return date.toLocaleString('fr-FR', { day: '2-digit', month: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit', }); } function structureTypeLabel(value) { return value === 'EXTRASCOLAIRE' ? 'Extrascolaire' : 'Périscolaire'; } function setBadge(count) { if (!badge) return; badge.textContent = String(count); badge.hidden = count === 0; badge.setAttribute('aria-label', `${count} planning${count > 1 ? 's' : ''} en attente de validation`); } function setMessage(text = '', type = 'info') { if (!messageElement) return; messageElement.className = text ? `message message-${type}` : 'message'; messageElement.textContent = text; } function render(data) { items = Array.isArray(data.plannings) ? data.plannings : []; const summary = data.summary || {}; const count = Number(summary.count ?? items.length); setBadge(count); if (countElement) countElement.textContent = String(count); if (hoursElement) hoursElement.textContent = formatDuration(Number(summary.total_minutes || 0)); if (countedHoursElement) countedHoursElement.textContent = formatDuration(Number(summary.counted_minutes || 0)); if (loadingElement) loadingElement.hidden = true; if (emptyElement) emptyElement.hidden = items.length !== 0; if (contentElement) contentElement.hidden = items.length === 0; if (!bodyElement) return; bodyElement.innerHTML = items.map((item) => { const week = weekValue(item); const rowId = Number(item.id_planning); return ` ${escapeHtml(item.agent_prenom)} ${escapeHtml(item.agent_nom)} ${escapeHtml(item.matricule || '')} ${escapeHtml(item.structure_nom)} ${escapeHtml(structureTypeLabel(item.structure_type_affectation))} Semaine ${Number(item.numero_semaine)} ${formatDate(item.date_debut)} → ${formatDate(item.date_fin_ouvrable || item.date_fin)} ${Number(item.nombre_creneaux)} ${formatDuration(Number(item.total_minutes || 0))} ${formatDuration(Number(item.minutes_decomptees || 0))} décomptées ${formatDateTime(item.date_modification)} `; }).join(''); } async function refresh(options = {}) { if (loading) return; loading = true; if (!options.silent) setMessage(''); if (loadingElement) { loadingElement.hidden = false; if (emptyElement) emptyElement.hidden = true; if (contentElement) contentElement.hidden = true; } if (refreshButton) refreshButton.disabled = true; try { const response = await fetch('api/pending_plannings.php', { headers: { Accept: 'application/json' } }); const data = await readJsonResponse(response); if (!response.ok) throw new Error(apiErrorMessage(data, 'Impossible de charger les plannings en attente de validation.')); render(data); } catch (error) { if (loadingElement) loadingElement.hidden = true; setMessage(error.message, 'error'); } finally { loading = false; if (refreshButton) refreshButton.disabled = false; } } function openPlanning(item) { if (!item) return; const params = new URLSearchParams({ structure_id: String(item.id_structure), agent_id: String(item.id_agent), week: weekValue(item), focus: 'validation', notice: `Planning de ${item.agent_prenom} ${item.agent_nom} chargé depuis la file de validation.`, }); window.location.href = `planning.php?${params.toString()}`; } function findItemFromEventTarget(target) { const trigger = target.closest('[data-planning-id]'); if (!trigger) return null; const id = Number(trigger.dataset.planningId); return items.find((item) => Number(item.id_planning) === id) || null; } function init() { refreshButton?.addEventListener('click', () => refresh()); bodyElement?.addEventListener('click', (event) => { const item = findItemFromEventTarget(event.target); if (item) openPlanning(item); }); bodyElement?.addEventListener('keydown', (event) => { if (!['Enter', ' '].includes(event.key)) return; if (event.target.closest('button')) return; const row = event.target.closest('.pending-validation-row'); if (!row) return; event.preventDefault(); const item = findItemFromEventTarget(row); if (item) openPlanning(item); }); refresh({ silent: true }); } PTA.modules.pendingValidation = { init, refresh, openPlanning }; })();