199 lines
6.8 KiB
JavaScript
199 lines
6.8 KiB
JavaScript
/**
|
|
* Module Hub Intervenant
|
|
* Gestion des RDV du jour et marquage présence/absence
|
|
*/
|
|
|
|
import { apiFetch } from './agenda-api.js';
|
|
import toastr from 'toastr';
|
|
|
|
/**
|
|
* Charge les RDV du jour de l'intervenant connecté
|
|
*/
|
|
export async function loadRdvToday() {
|
|
const container = document.getElementById('rdv-today-container');
|
|
const emptyMessage = document.getElementById('rdv-today-empty');
|
|
|
|
if (!container) {
|
|
console.error('Container rdv-today-container non trouvé');
|
|
return;
|
|
}
|
|
|
|
try {
|
|
if (window.CRVI_OVERLAY) { window.CRVI_OVERLAY.show(container); }
|
|
container.innerHTML = `
|
|
<div class="text-center py-4">
|
|
<div class="spinner-border text-primary" role="status">
|
|
<span class="visually-hidden">Chargement...</span>
|
|
</div>
|
|
<p class="mt-2 text-muted">Chargement des rendez-vous...</p>
|
|
</div>
|
|
`;
|
|
|
|
const rdvs = await apiFetch('intervenant/rdv-today');
|
|
|
|
if (!rdvs || rdvs.length === 0) {
|
|
container.style.display = 'none';
|
|
if (emptyMessage) {
|
|
emptyMessage.style.display = 'block';
|
|
}
|
|
return;
|
|
}
|
|
|
|
container.style.display = 'block';
|
|
if (emptyMessage) {
|
|
emptyMessage.style.display = 'none';
|
|
}
|
|
|
|
// Récupérer le template
|
|
const template = document.getElementById('rdv-item-template');
|
|
if (!template) {
|
|
console.error('Template rdv-item-template non trouvé');
|
|
return;
|
|
}
|
|
|
|
container.innerHTML = '';
|
|
|
|
rdvs.forEach(rdv => {
|
|
const clone = template.content.cloneNode(true);
|
|
|
|
// Formatage de l'heure
|
|
const heureDebut = formatTime(rdv.heure_rdv);
|
|
const heureFin = formatTime(rdv.heure_fin || rdv.heure_rdv);
|
|
|
|
// Remplir les données
|
|
const timeStartEl = clone.querySelector('[data-time-start]');
|
|
const timeEndEl = clone.querySelector('[data-time-end]');
|
|
const localEl = clone.querySelector('[data-local]');
|
|
const beneficiaireEl = clone.querySelector('[data-beneficiaire]');
|
|
const typeInterventionEl = clone.querySelector('[data-type-intervention]');
|
|
const presentBtn = clone.querySelector('button.mark-presence[data-statut="present"]');
|
|
const absentBtn = clone.querySelector('button.mark-presence[data-statut="absent"]');
|
|
|
|
if (timeStartEl) timeStartEl.textContent = heureDebut;
|
|
if (timeEndEl) timeEndEl.textContent = heureFin;
|
|
|
|
if (localEl && rdv.local) {
|
|
localEl.textContent = rdv.local.nom || 'Non assigné';
|
|
}
|
|
|
|
if (beneficiaireEl && rdv.beneficiaire) {
|
|
const nom = rdv.beneficiaire.prenom && rdv.beneficiaire.nom
|
|
? `${rdv.beneficiaire.prenom} ${rdv.beneficiaire.nom}`
|
|
: (rdv.beneficiaire.nom || 'Non assigné');
|
|
beneficiaireEl.textContent = nom;
|
|
}
|
|
|
|
if (typeInterventionEl) {
|
|
typeInterventionEl.textContent = rdv.type_intervention || '';
|
|
}
|
|
|
|
// Configurer les boutons présence/absence
|
|
if (presentBtn) {
|
|
presentBtn.setAttribute('data-event-id', rdv.id);
|
|
presentBtn.addEventListener('click', () => markPresence(rdv.id, 'present'));
|
|
}
|
|
|
|
if (absentBtn) {
|
|
absentBtn.setAttribute('data-event-id', rdv.id);
|
|
absentBtn.addEventListener('click', () => markPresence(rdv.id, 'absent'));
|
|
}
|
|
|
|
// Désactiver les boutons si le statut n'est plus "prevu"
|
|
if (rdv.statut !== 'prevu') {
|
|
if (presentBtn) presentBtn.disabled = true;
|
|
if (absentBtn) absentBtn.disabled = true;
|
|
}
|
|
|
|
container.appendChild(clone);
|
|
});
|
|
|
|
} catch (error) {
|
|
console.error('Erreur lors du chargement des RDV du jour:', error);
|
|
container.innerHTML = `
|
|
<div class="alert alert-danger">
|
|
<i class="fas fa-exclamation-triangle me-2"></i>
|
|
Erreur lors du chargement des rendez-vous : ${error.message}
|
|
</div>
|
|
`;
|
|
} finally {
|
|
if (window.CRVI_OVERLAY) { window.CRVI_OVERLAY.hide(container); }
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Formate une heure (format HH:MM:SS) en HH:MM
|
|
*/
|
|
function formatTime(timeStr) {
|
|
if (!timeStr) return '';
|
|
return timeStr.substring(0, 5); // Prendre HH:MM
|
|
}
|
|
|
|
/**
|
|
* Marque la présence ou l'absence pour un RDV
|
|
*/
|
|
async function markPresence(eventId, statut) {
|
|
const statutLabel = statut === 'present' ? 'présent' : 'absent';
|
|
|
|
// Demander confirmation pour l'absence
|
|
if (statut === 'absent') {
|
|
const confirmed = confirm(`Êtes-vous sûr de vouloir marquer ce rendez-vous comme absent ?`);
|
|
if (!confirmed) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
try {
|
|
// Désactiver les boutons pendant la requête
|
|
const buttons = document.querySelectorAll(`button[data-event-id="${eventId}"]`);
|
|
buttons.forEach(btn => btn.disabled = true);
|
|
const container = document.getElementById('rdv-today-container');
|
|
if (window.CRVI_OVERLAY && container) { window.CRVI_OVERLAY.show(container); }
|
|
|
|
await apiFetch('intervenant/mark-presence', {
|
|
method: 'POST',
|
|
body: JSON.stringify({
|
|
event_id: eventId,
|
|
statut: statut
|
|
})
|
|
});
|
|
|
|
toastr.success(
|
|
`Présence marquée comme ${statutLabel} avec succès`,
|
|
'Confirmation',
|
|
{ timeOut: 3000 }
|
|
);
|
|
|
|
// Recharger les RDV du jour
|
|
await loadRdvToday();
|
|
|
|
} catch (error) {
|
|
console.error('Erreur lors du marquage de présence:', error);
|
|
toastr.error(
|
|
error.message || `Erreur lors du marquage ${statutLabel}`,
|
|
'Erreur',
|
|
{ timeOut: 5000 }
|
|
);
|
|
|
|
// Réactiver les boutons en cas d'erreur
|
|
const buttons = document.querySelectorAll(`button[data-event-id="${eventId}"]`);
|
|
buttons.forEach(btn => btn.disabled = false);
|
|
} finally {
|
|
const container = document.getElementById('rdv-today-container');
|
|
if (window.CRVI_OVERLAY && container) { window.CRVI_OVERLAY.hide(container); }
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Initialise le module hub intervenant
|
|
*/
|
|
export function initializeIntervenantHub() {
|
|
console.log('Initialisation du hub intervenant...');
|
|
|
|
// Charger les RDV du jour au chargement
|
|
loadRdvToday();
|
|
|
|
// Recharger toutes les 5 minutes
|
|
setInterval(loadRdvToday, 5 * 60 * 1000);
|
|
}
|
|
|