(() => { 'use strict'; const PTA = window.PTA; if (!PTA) throw new Error('PTA core doit être chargé avant administration.js'); const { structureSelect } = PTA.elements; const { escapeHtml, readJsonResponse, apiErrorMessage, formatDuration, } = PTA.utils; const typeLabel = (type) => type === 'EXTRASCOLAIRE' ? 'Extrascolaire' : 'Périscolaire'; async function saveAgentStructure(button) { const row = button.closest('tr[data-agent-id]'); const select = row?.querySelector('.agent-structure-select'); const message = document.querySelector('#assignment-message'); if (!row || !select || !message) return; button.disabled = true; message.className = 'message'; message.textContent = ''; try { const response = await fetch('api/agent_assignments.php', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ csrf_token: window.PTA_CONFIG.csrfToken, agent_id: Number(row.dataset.agentId), structure_id: select.value ? Number(select.value) : null, }), }); const data = await readJsonResponse(response); if (!response.ok) throw new Error(apiErrorMessage(data, 'Impossible de modifier le lieu principal de l’agent.')); message.className = 'message message-success'; message.textContent = data.message; if (structureSelect?.value) await PTA.modules.planning?.loadAgents?.(); if (document.querySelector('#overview-structure')?.value) await PTA.modules.structureOverview?.load?.(); if (document.querySelector('#overview-agent')?.value) await PTA.modules.agentOverview?.load?.(); } catch (error) { message.className = 'message message-error'; message.textContent = error.message; } finally { button.disabled = false; } } async function saveStructureType(button) { const row = button.closest('tr[data-structure-id]'); const select = row?.querySelector('.structure-type-select'); const message = document.querySelector('#structure-settings-message'); if (!row || !select || !message) return; button.disabled = true; message.className = 'message'; message.textContent = ''; try { const response = await fetch('api/update_structure.php', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ csrf_token: window.PTA_CONFIG.csrfToken, structure_id: Number(row.dataset.structureId), type_affectation: select.value, }), }); const data = await readJsonResponse(response); if (!response.ok) throw new Error(apiErrorMessage(data, 'Impossible de modifier le type du lieu.')); updateStructureLabels(Number(row.dataset.structureId), select.value); message.className = 'message message-success'; message.textContent = data.message; if (structureSelect?.value) await PTA.modules.planning?.loadAgents?.(); if (document.querySelector('#overview-structure')?.value === String(row.dataset.structureId)) { await PTA.modules.structureOverview?.load?.(); } if (document.querySelector('#overview-agent')?.value) await PTA.modules.agentOverview?.load?.(); } catch (error) { message.className = 'message message-error'; message.textContent = error.message; } finally { button.disabled = false; } } function addOptionIfMissing(select, value, label, selected = false) { if (!select) return; let option = Array.from(select.options).find((item) => item.value === String(value)); if (!option) { option = document.createElement('option'); option.value = String(value); select.appendChild(option); } option.textContent = label; if (selected) option.selected = true; } function structureOptionLabel(structure) { return `${structure.nom} — ${typeLabel(structure.type_affectation)}`; } function addStructureEverywhere(structure) { const id = Number(structure.id_structure); const label = structureOptionLabel(structure); [ document.querySelector('#structure'), document.querySelector('#overview-structure'), document.querySelector('#new-agent-structure'), document.querySelector('#edit-agent-entry-structure'), document.querySelector('#edit-agent-profile-structure'), document.querySelector('#coverage-structure-filter'), document.querySelector('#coverage-rules-structure'), ].forEach((select) => addOptionIfMissing(select, id, label)); document.querySelectorAll('.agent-structure-select').forEach((select) => { addOptionIfMissing(select, id, label); }); } function updateStructureLabels(structureId, type) { const source = document.querySelector(`#structure-settings-body tr[data-structure-id="${Number(structureId)}"]`); const structureName = source?.querySelector('td strong')?.textContent?.trim(); if (!structureName) return; const label = `${structureName} — ${typeLabel(type)}`; document.querySelectorAll('select').forEach((select) => { const option = Array.from(select.options).find((item) => item.value === String(structureId)); if (option && ( select.matches('#structure, #overview-structure, #new-agent-structure, #edit-agent-entry-structure, #edit-agent-profile-structure, #coverage-structure-filter, #coverage-rules-structure, .agent-structure-select') )) { option.textContent = label; } }); } function structureOptionsHtml(selectedStructureId = null) { const source = document.querySelector('#new-agent-structure'); if (!source) return ''; const options = ['']; Array.from(source.options).forEach((option) => { if (!option.value) return; const selected = Number(option.value) === Number(selectedStructureId) ? ' selected' : ''; options.push(``); }); return options.join(''); } function addStructureSettingsRow(structure) { const body = document.querySelector('#structure-settings-body'); if (!body || body.querySelector(`tr[data-structure-id="${Number(structure.id_structure)}"]`)) return; const row = document.createElement('tr'); row.dataset.structureId = String(Number(structure.id_structure)); row.innerHTML = ` ${escapeHtml(structure.nom)} ${escapeHtml(structure.code)} `; body.appendChild(row); } function qualificationLabel(agent) { if (!Number(agent.est_diplome)) return 'Non diplômé'; return agent.diplome_libelle ? `Diplômé — ${agent.diplome_libelle}` : 'Diplômé'; } function formatContractDate(value) { if (!value) return 'Non renseignée'; const [year, month, day] = String(value).split('-'); return year && month && day ? `${day}/${month}/${year}` : value; } function agentRowHtml(agent) { const structureLabel = agent.structure_nom || agent.structure_principale_nom || 'Sans lieu principal'; return ` ${escapeHtml(agent.prenom)} ${escapeHtml(agent.nom)} ${escapeHtml(agent.matricule)} ${escapeHtml(agent.poste_libelle || 'Non renseigné')} ${escapeHtml(qualificationLabel(agent))} ${escapeHtml(agent.telephone || 'Non renseigné')} ${escapeHtml(formatContractDate(agent.date_debut_contrat))} ${escapeHtml(structureLabel)} `; } function setAgentRowData(row, agent) { row.dataset.agentId = String(Number(agent.id_agent)); row.dataset.email = agent.email || ''; row.dataset.telephone = agent.telephone || ''; row.dataset.adresse = agent.adresse || ''; row.dataset.estDiplome = Number(agent.est_diplome) ? '1' : '0'; row.dataset.diplomeLibelle = agent.diplome_libelle || ''; row.dataset.dateDebutContrat = agent.date_debut_contrat || ''; row.dataset.dateFinContrat = agent.date_fin_contrat || ''; row.dataset.idPoste = agent.id_poste ? String(Number(agent.id_poste)) : ''; row.dataset.typeContrat = agent.type_contrat || 'PERMANENT'; row.dataset.formationRepartitionAnnuelle = Number(agent.formation_repartition_annuelle) ? '1' : '0'; row.dataset.commentairePta = agent.commentaire_pta || ''; row.dataset.structureId = agent.id_structure ? String(Number(agent.id_structure)) : ''; } function addAgentEverywhere(agent) { const overviewAgent = document.querySelector('#overview-agent'); addOptionIfMissing( overviewAgent, Number(agent.id_agent), `${agent.prenom} ${agent.nom} (${agent.matricule})` ); const body = document.querySelector('#agent-assignment-body'); if (body && !body.querySelector(`tr[data-agent-id="${Number(agent.id_agent)}"]`)) { const row = document.createElement('tr'); setAgentRowData(row, agent); row.innerHTML = agentRowHtml(agent); body.appendChild(row); } } function toggleDiplomaField(select, input) { if (!select || !input) return; const qualified = select.value === '1'; input.disabled = !qualified; if (!qualified) input.value = ''; } function openAgentProfileModal(row) { const modal = document.querySelector('#agent-profile-modal'); if (!modal || !row) return; document.querySelector('#edit-agent-profile-id').value = row.dataset.agentId || ''; document.querySelector('#agent-profile-modal-subtitle').textContent = row.querySelector('.agent-row-name')?.textContent?.trim() || ''; document.querySelector('#edit-agent-profile-email').value = row.dataset.email || ''; document.querySelector('#edit-agent-profile-phone').value = row.dataset.telephone || ''; document.querySelector('#edit-agent-profile-address').value = row.dataset.adresse || ''; document.querySelector('#edit-agent-profile-qualified').value = row.dataset.estDiplome === '1' ? '1' : '0'; document.querySelector('#edit-agent-profile-diploma').value = row.dataset.diplomeLibelle || ''; document.querySelector('#edit-agent-profile-contract-start').value = row.dataset.dateDebutContrat || ''; document.querySelector('#edit-agent-profile-contract-end').value = row.dataset.dateFinContrat || ''; document.querySelector('#edit-agent-profile-post').value = row.dataset.idPoste || ''; document.querySelector('#edit-agent-profile-contract-type').value = row.dataset.typeContrat || 'PERMANENT'; document.querySelector('#edit-agent-profile-training-planned').checked = row.dataset.formationRepartitionAnnuelle === '1'; document.querySelector('#edit-agent-profile-pta-comment').value = row.dataset.commentairePta || ''; document.querySelector('#edit-agent-profile-structure').value = row.dataset.structureId || ''; toggleDiplomaField(document.querySelector('#edit-agent-profile-qualified'), document.querySelector('#edit-agent-profile-diploma')); const message = document.querySelector('#agent-profile-message'); if (message) { message.className = 'message'; message.textContent = ''; } modal.hidden = false; } function closeAgentProfileModal() { const modal = document.querySelector('#agent-profile-modal'); if (modal) modal.hidden = true; } async function saveAgentProfile(event) { event.preventDefault(); const form = event.currentTarget; const message = document.querySelector('#agent-profile-message'); const submit = form.querySelector('button[type="submit"]'); const agentId = Number(document.querySelector('#edit-agent-profile-id').value); if (!agentId || !message || !submit) return; submit.disabled = true; message.className = 'message'; message.textContent = ''; try { const structureValue = document.querySelector('#edit-agent-profile-structure').value; const response = await fetch('api/update_agent.php', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ csrf_token: window.PTA_CONFIG.csrfToken, agent_id: agentId, email: document.querySelector('#edit-agent-profile-email').value, telephone: document.querySelector('#edit-agent-profile-phone').value, adresse: document.querySelector('#edit-agent-profile-address').value, est_diplome: document.querySelector('#edit-agent-profile-qualified').value === '1', diplome_libelle: document.querySelector('#edit-agent-profile-diploma').value, date_debut_contrat: document.querySelector('#edit-agent-profile-contract-start').value, date_fin_contrat: document.querySelector('#edit-agent-profile-contract-end').value, id_poste: Number(document.querySelector('#edit-agent-profile-post').value), type_contrat: document.querySelector('#edit-agent-profile-contract-type').value, formation_repartition_annuelle: document.querySelector('#edit-agent-profile-training-planned').checked, commentaire_pta: document.querySelector('#edit-agent-profile-pta-comment').value, structure_id: structureValue ? Number(structureValue) : null, }), }); const data = await readJsonResponse(response); if (!response.ok) throw new Error(apiErrorMessage(data, 'Impossible de modifier les informations de l’agent.')); const row = document.querySelector(`#agent-assignment-body tr[data-agent-id="${agentId}"]`); if (row) { setAgentRowData(row, data.agent); row.innerHTML = agentRowHtml({ ...data.agent, structure_nom: data.agent.structure_principale_nom, }); } message.className = 'message message-success'; message.textContent = data.message; if (structureSelect?.value) await PTA.modules.planning?.loadAgents?.(); if (document.querySelector('#overview-structure')?.value) await PTA.modules.structureOverview?.load?.(); if (document.querySelector('#overview-agent')?.value === String(agentId)) await PTA.modules.agentOverview?.load?.(); setTimeout(closeAgentProfileModal, 500); } catch (error) { message.className = 'message message-error'; message.textContent = error.message; } finally { submit.disabled = false; } } async function createStructure(event) { event.preventDefault(); const form = event.currentTarget; const message = document.querySelector('#create-structure-message'); const submit = form.querySelector('button[type="submit"]'); if (!message || !submit) return; message.className = 'message'; message.textContent = ''; submit.disabled = true; try { const response = await fetch('api/create_structure.php', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ csrf_token: window.PTA_CONFIG.csrfToken, code: document.querySelector('#new-structure-code').value, nom: document.querySelector('#new-structure-name').value, adresse: document.querySelector('#new-structure-address').value, type_affectation: document.querySelector('#new-structure-type').value, }), }); const data = await readJsonResponse(response); if (!response.ok) throw new Error(apiErrorMessage(data, 'Impossible de créer le lieu d’affectation.')); addStructureEverywhere(data.structure); addStructureSettingsRow(data.structure); form.reset(); document.querySelector('#new-structure-type').value = 'PERISCOLAIRE'; message.className = 'message message-success'; message.textContent = data.message; PTA.modules.coverage?.refresh?.({ silent: true }); } catch (error) { message.className = 'message message-error'; message.textContent = error.message; } finally { submit.disabled = false; } } async function createAgent(event) { event.preventDefault(); const form = event.currentTarget; const message = document.querySelector('#create-agent-message'); const submit = form.querySelector('button[type="submit"]'); if (!message || !submit) return; message.className = 'message'; message.textContent = ''; submit.disabled = true; try { const response = await fetch('api/create_agent.php', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ csrf_token: window.PTA_CONFIG.csrfToken, matricule: document.querySelector('#new-agent-matricule').value, nom: document.querySelector('#new-agent-name').value, prenom: document.querySelector('#new-agent-firstname').value, email: document.querySelector('#new-agent-email').value, telephone: document.querySelector('#new-agent-phone').value, adresse: document.querySelector('#new-agent-address').value, est_diplome: document.querySelector('#new-agent-qualified').value === '1', diplome_libelle: document.querySelector('#new-agent-diploma').value, structure_id: Number(document.querySelector('#new-agent-structure').value), quotite_travail: Number(document.querySelector('#new-agent-rate').value), date_debut_contrat: document.querySelector('#new-agent-contract-start').value, date_fin_contrat: document.querySelector('#new-agent-contract-end').value, id_poste: Number(document.querySelector('#new-agent-post').value), type_contrat: document.querySelector('#new-agent-contract-type').value, formation_repartition_annuelle: document.querySelector('#new-agent-training-planned').checked, commentaire_pta: document.querySelector('#new-agent-pta-comment').value, }), }); const data = await readJsonResponse(response); if (!response.ok) throw new Error(apiErrorMessage(data, 'Impossible de créer l’agent.')); addAgentEverywhere(data.agent); const createdStructureId = String(data.agent.id_structure); form.reset(); document.querySelector('#new-agent-rate').value = '100'; document.querySelector('#new-agent-contract-type').value = 'PERMANENT'; document.querySelector('#new-agent-training-planned').checked = false; document.querySelector('#new-agent-qualified').value = '0'; toggleDiplomaField(document.querySelector('#new-agent-qualified'), document.querySelector('#new-agent-diploma')); message.className = 'message message-success'; message.textContent = `${data.message} Quota annuel : ${formatDuration(Number(data.agent.quota_cible_minutes))}, suivi du 1er janvier au 31 décembre.`; if (structureSelect?.value === createdStructureId) { await PTA.modules.planning?.loadAgents?.(); } if (document.querySelector('#overview-structure')?.value === createdStructureId) { await PTA.modules.structureOverview?.load?.(); } } catch (error) { message.className = 'message message-error'; message.textContent = error.message; } finally { submit.disabled = false; } } function init() { document.querySelector('#agent-assignment-body')?.addEventListener('click', (event) => { const button = event.target.closest('.edit-agent-profile'); if (button) openAgentProfileModal(button.closest('tr[data-agent-id]')); }); document.querySelector('#structure-settings-body')?.addEventListener('click', (event) => { const button = event.target.closest('.save-structure-type'); if (button) saveStructureType(button); }); document.querySelector('#new-agent-qualified')?.addEventListener('change', (event) => { toggleDiplomaField(event.currentTarget, document.querySelector('#new-agent-diploma')); }); document.querySelector('#edit-agent-profile-qualified')?.addEventListener('change', (event) => { toggleDiplomaField(event.currentTarget, document.querySelector('#edit-agent-profile-diploma')); }); document.querySelector('#close-agent-profile-modal')?.addEventListener('click', closeAgentProfileModal); document.querySelector('#cancel-agent-profile')?.addEventListener('click', closeAgentProfileModal); document.querySelector('#agent-profile-modal')?.addEventListener('click', (event) => { if (event.target.id === 'agent-profile-modal') closeAgentProfileModal(); }); document.querySelector('#agent-profile-form')?.addEventListener('submit', saveAgentProfile); document.querySelector('#create-structure-form')?.addEventListener('submit', createStructure); document.querySelector('#create-agent-form')?.addEventListener('submit', createAgent); toggleDiplomaField(document.querySelector('#new-agent-qualified'), document.querySelector('#new-agent-diploma')); } PTA.modules.administration = { init, saveAgentStructure, saveStructureType, addStructureEverywhere, addAgentEverywhere, openAgentProfileModal, }; })();