// Module d'affichage des données de la modale // Contient les fonctions d'affichage en mode lecture seule import { setText, toggleElement } from './agenda-modal-dom.js'; import { checkAndDisplayIncidentsButton } from './agenda-modal.js'; /** * Extrait la date et l'heure d'un événement selon différentes sources * @param {Object} event - Données de l'événement * @returns {Object} - {dateFormatted, heureFormatted} */ function extractDateTime(event) { let dateFormatted = ''; let heureFormatted = ''; // Priorité 1: Données directes de l'API if (event?.date && event?.heure) { const dateObj = new Date(event.date + 'T' + event.heure); dateFormatted = dateObj.toLocaleDateString('fr-FR'); heureFormatted = dateObj.toLocaleTimeString('fr-FR', { hour: '2-digit', minute: '2-digit' }); } // Priorité 2: Données dans extendedProps else if (event?.extendedProps?.date && event?.extendedProps?.heure) { const dateObj = new Date(event.extendedProps.date + 'T' + event.extendedProps.heure); dateFormatted = dateObj.toLocaleDateString('fr-FR'); heureFormatted = dateObj.toLocaleTimeString('fr-FR', { hour: '2-digit', minute: '2-digit' }); } // Priorité 3: Données FullCalendar else if (event?.start) { const startDate = new Date(event.start); dateFormatted = startDate.toLocaleDateString('fr-FR'); heureFormatted = startDate.toLocaleTimeString('fr-FR', { hour: '2-digit', minute: '2-digit' }); } return { dateFormatted, heureFormatted }; } /** * Récupère le nom d'une entité depuis le select ou les données * @param {string} entityName - Nom de l'entité ('beneficiaire', 'intervenant', etc.) * @param {Object} event - Données de l'événement * @param {string} selectId - ID du select * @param {string} idField - Nom du champ ID * @returns {string} - Nom formaté */ function getEntityName(entityName, event, selectId, idField) { let name = ''; // Vérifier dans les relations directes if (event?.[entityName]?.nom) { name = event[entityName].nom + (event[entityName].prenom ? ' ' + event[entityName].prenom : ''); } else if (event?.extendedProps?.[entityName]?.nom) { name = event.extendedProps[entityName].nom + (event.extendedProps[entityName].prenom ? ' ' + event.extendedProps[entityName].prenom : ''); } else { // Chercher par ID dans le select const entityId = event?.[idField] || event?.extendedProps?.[idField]; if (entityId) { const select = document.getElementById(selectId); // Vérifier si c'est un SELECT (pour intervenant côté front c'est un input hidden) if (select && select.tagName === 'SELECT') { const option = select.querySelector(`option[value="${entityId}"]`); if (option) { name = option.textContent; } } else if (select && selectId === 'id_intervenant') { // Cas spécial pour intervenant côté front (input hidden) const displayEl = document.getElementById('id_intervenant_display'); if (displayEl && displayEl.textContent) { name = displayEl.textContent; } } if (!name) { name = `ID: ${entityId}`; } } } return name; } /** * Récupère le nom d'un terme taxonomy depuis les données ou le select * @param {Object} event - Données de l'événement * @param {string} labelField - Champ de label (_label) * @param {string} relationField - Champ de relation * @param {string} idField - Champ ID * @param {string} selectId - ID du select * @returns {string} - Nom du terme */ function getTermName(event, labelField, relationField, idField, selectId) { let name = ''; // Priorité 1: Label direct name = event?.[labelField] || event?.extendedProps?.[labelField] || ''; // Priorité 2: Relation if (!name && event?.[relationField]?.nom) { name = event[relationField].nom; } else if (!name && event?.extendedProps?.[relationField]?.nom) { name = event.extendedProps[relationField].nom; } // Priorité 3: Chercher dans le select if (!name) { const termId = event?.[idField] || event?.extendedProps?.[idField]; if (termId && termId !== '0' && termId !== 0) { const select = document.getElementById(selectId); if (select) { const option = select.querySelector(`option[value="${termId}"]`); if (option) { name = option.textContent; } } if (!name) { name = `ID: ${termId}`; } } } return name; } /** * Remplit le bloc de vue avec les données d'un événement * @param {Object} event - Données de l'événement */ export function fillViewBlock(event) { // Date et heure const { dateFormatted, heureFormatted } = extractDateTime(event); setText('view_date_rdv', dateFormatted); setText('view_heure_rdv', heureFormatted); // Type et langue const type = event?.type || event?.extendedProps?.type || ''; setText('view_type', type); let langue = event?.langue_label || event?.extendedProps?.langue_label || ''; if (!langue || /^\d+$/.test(langue)) { const langueId = langue || event?.langue || event?.extendedProps?.langue || ''; if (langueId) { const langueSelect = document.getElementById('langue'); if (langueSelect) { const option = langueSelect.querySelector(`option[value="${langueId}"]`); if (option) { langue = option.textContent; } else { langue = langueId; } } else { langue = langueId; } } } if (!langue) { langue = event?.langue || event?.extendedProps?.langue || ''; } setText('view_langue', langue); // Entités setText('view_beneficiaire', getEntityName('beneficiaire', event, 'id_beneficiaire', 'id_beneficiaire')); setText('view_intervenant', getEntityName('intervenant', event, 'id_intervenant', 'id_intervenant')); setText('view_local', getEntityName('local', event, 'id_local', 'id_local')); // Termes taxonomy setText('view_departement', getTermName(event, 'departement_label', 'departement', 'id_departement', 'id_departement')); setText('view_type_intervention', getTermName(event, 'type_intervention_label', 'type_intervention', 'id_type_intervention', 'id_type_intervention')); // Traducteur (logique spéciale) let traducteurNom = ''; const traducteurId = event?.id_traducteur || event?.extendedProps?.id_traducteur; const hasValidTraducteurId = traducteurId && parseInt(traducteurId, 10) > 0; if (hasValidTraducteurId) { traducteurNom = getEntityName('traducteur', event, 'id_traducteur', 'id_traducteur'); } else { traducteurNom = event?.nom_traducteur || event?.extendedProps?.nom_traducteur || ''; } setText('view_traducteur', traducteurNom); // Données de groupe const eventType = event?.type || event?.extendedProps?.type || ''; const groupeFields = document.querySelectorAll('.groupe-only-field'); if (eventType === 'groupe') { groupeFields.forEach(field => field.style.display = ''); setText('view_nb_participants', event?.nb_participants || event?.extendedProps?.nb_participants || ''); setText('view_nb_hommes', event?.nb_hommes || event?.extendedProps?.nb_hommes || ''); setText('view_nb_femmes', event?.nb_femmes || event?.extendedProps?.nb_femmes || ''); } else { groupeFields.forEach(field => field.style.display = 'none'); setText('view_nb_participants', ''); setText('view_nb_hommes', ''); setText('view_nb_femmes', ''); } // Commentaire setText('view_commentaire', event?.commentaire || event?.extendedProps?.commentaire || ''); // Bouton historique bénéficiaire (uniquement pour événements individuels) const historiqueBtn = document.getElementById('showBeneficiaireHistoriqueBtn'); if (historiqueBtn) { const beneficiaireId = event?.id_beneficiaire || event?.extendedProps?.id_beneficiaire; if (eventType === 'individuel' && beneficiaireId) { historiqueBtn.style.display = 'block'; historiqueBtn.setAttribute('data-benef', beneficiaireId); } else { historiqueBtn.style.display = 'none'; historiqueBtn.removeAttribute('data-benef'); } } // Vérifier et afficher le bouton "Détail incident(s)" si l'événement a des incidents const eventId = event?.id || event?.extendedProps?.id; if (eventId) { checkAndDisplayIncidentsButton(eventId); } } /** * Met à jour l'affichage de la modale selon le mode * @param {string} mode - Mode actuel ('view', 'edit', 'create') * @param {boolean} canEdit - Permission d'édition * @param {boolean} canDelete - Permission de suppression */ export function updateModalDisplay(mode, canEdit, canDelete) { const viewBlock = document.getElementById('eventViewBlock'); const formBlock = document.getElementById('eventForm'); const editBtn = document.getElementById('editEventBtn'); const deleteBtn = document.getElementById('deleteEvent'); const saveBtn = document.getElementById('saveEvent'); const cancelBtn = document.getElementById('cancelEditBtn'); const closeViewBtn = document.getElementById('closeViewBtn'); const markPresentBtn = document.getElementById('markPresentBtn'); const markAbsentBtn = document.getElementById('markAbsentBtn'); const cancelAppointmentBtn = document.getElementById('cancelAppointmentBtn'); const reportIncidentBtn = document.getElementById('reportIncidentBtn'); if (mode === 'view') { if (viewBlock) viewBlock.style.display = 'block'; if (formBlock) formBlock.style.display = 'none'; if (editBtn) editBtn.style.display = canEdit ? 'inline-block' : 'none'; if (deleteBtn) deleteBtn.style.display = canDelete ? 'inline-block' : 'none'; if (saveBtn) saveBtn.style.display = 'none'; if (cancelBtn) cancelBtn.style.display = 'none'; if (closeViewBtn) closeViewBtn.style.display = 'inline-block'; if (markPresentBtn) markPresentBtn.style.display = canEdit ? 'inline-block' : 'none'; if (markAbsentBtn) markAbsentBtn.style.display = canEdit ? 'inline-block' : 'none'; if (cancelAppointmentBtn) cancelAppointmentBtn.style.display = canEdit ? 'inline-block' : 'none'; if (reportIncidentBtn) reportIncidentBtn.style.display = 'inline-block'; } else if (mode === 'edit' || mode === 'create') { if (viewBlock) viewBlock.style.display = 'none'; if (formBlock) formBlock.style.display = 'block'; if (editBtn) editBtn.style.display = 'none'; if (deleteBtn) deleteBtn.style.display = 'none'; if (saveBtn) saveBtn.style.display = 'inline-block'; if (cancelBtn) cancelBtn.style.display = 'inline-block'; if (closeViewBtn) closeViewBtn.style.display = 'none'; if (markPresentBtn) markPresentBtn.style.display = 'none'; if (markAbsentBtn) markAbsentBtn.style.display = 'none'; if (cancelAppointmentBtn) cancelAppointmentBtn.style.display = 'none'; if (reportIncidentBtn) reportIncidentBtn.style.display = 'none'; } } /** * Vérifie si un événement est passé * @param {Object} eventData - Données de l'événement * @returns {boolean} - True si l'événement est passé */ export function checkIfEventIsPast(eventData) { if (!eventData) return false; let eventDate = null; let eventTime = null; // Essayer différentes sources pour la date if (eventData.date_rdv) { eventDate = eventData.date_rdv; eventTime = eventData.heure_rdv || '00:00'; } else if (eventData.start) { const startDate = new Date(eventData.start); eventDate = startDate.toISOString().split('T')[0]; eventTime = startDate.toTimeString().substring(0, 5); } else if (eventData.extendedProps?.date_rdv) { eventDate = eventData.extendedProps.date_rdv; eventTime = eventData.extendedProps.heure_rdv || '00:00'; } if (!eventDate) return false; const eventDateTime = new Date(`${eventDate}T${eventTime}`); const now = new Date(); return eventDateTime <= now; }