// ECO-PANNEAU.FR - _react/delegate/_delegate_view.jsx
// 1. - COMPOSANT PRINCIPAL : SAISIE DÉLÉGUÉE
window.pano_DelegateView = ({ token, showToast }) => {
const { useState, useEffect } = React;
// ZÉRO-DETTE : Utilisation de notre Hook abstrait !
const { isMounted, safeFetch } = window.pano_useSafeFetch();
const [panneau, setPanneau] = useState(null);
const [loading, setLoading] = useState(true);
const [isSaving, setIsSaving] = useState(false);
const [error, setError] = useState(null);
const [editingEntity, setEditingEntity] = useState(null);
const [confirmDialog, setConfirmDialog] = useState(null);
// 2. - Composants et Icônes
const { LoaderIcon, AlertTriangleIcon, ShieldIcon, CheckCircleIcon } = window.pano_getIcons();
const { ConfirmModal, Button, PanneauEditorForm, EntityEditorModal } = window.pano_getComponents();
// 3. - Cycle de vie et requêtes
useEffect(() => {
// Fetch natif conservé ici car il s'agit d'une initialisation sans jeton d'authentification classique
fetch(window.pano_CONFIG.apiBaseUrl + 'panneaux/delegated_access&token=' + encodeURIComponent(token) + '&_t=' + Date.now())
.then(r => r.json())
.then(d => {
if (!isMounted.current) return; // SÉCURITÉ : Coupe-circuit
if (d.status === 'success') {
setPanneau(d.data);
} else {
setError(d.message);
}
setLoading(false);
})
.catch((e) => {
if (!isMounted.current) return; // SÉCURITÉ : Coupe-circuit
if (window.pano_logFallback) window.pano_logFallback("Erreur fetch delegation: " + e.message);
setError("Erreur réseau");
setLoading(false);
});
}, [token, isMounted]);
const handleSave = async () => {
const d = await safeFetch('panneaux/delegated_update', {
body: { token, ...panneau },
setLoading: setIsSaving,
successMessage: "Informations enregistrées avec succès."
});
// La gestion de isMounted pour setIsSaving est déjà incluse dans safeFetch
};
// 4. - Rendu UI : États de chargement et erreurs
if (loading) {
return (
{LoaderIcon &&
}
Vérification de l'accès...
);
}
if (error) {
return (
{AlertTriangleIcon &&
}
Accès refusé
{error}
);
}
// 5. - Rendu UI : Éditeur délégué
return (
Vous avez été invité à compléter les informations légales de ce panneau (intervenants, sous-traitants, PDF de l'arrêté). Vos modifications seront directement répercutées sur l'affichage public.
{PanneauEditorForm && (
window.location.href = '?'}
onPublish={handleSave}
onEditEntity={(loc, data) => setEditingEntity({location: loc, data})}
deleteEntity={(loc) => {
setConfirmDialog({
title: "Supprimer l'élément",
message: "Êtes-vous sûr de vouloir supprimer cet élément de l'équipe ?",
confirmText: "Supprimer",
type: "error",
isDestructive: true,
onConfirm: () => {
let newInter = [...(panneau.intervenants || [])];
let newLots = JSON.parse(JSON.stringify(panneau.lots || []));
if (loc.type === 'intervenant') {
newInter.splice(loc.index, 1);
} else if (loc.type === 'lot') {
newLots.splice(loc.index, 1);
} else {
newLots[loc.lotIndex].entreprises.splice(loc.index, 1);
}
setPanneau({ ...panneau, intervenants: newInter, lots: newLots });
setConfirmDialog(null);
},
onCancel: () => setConfirmDialog(null)
});
}}
isSaving={isSaving}
currentUserRole="delegate"
lockedFields={panneau.lockedFields || []}
showToast={showToast}
/>
)}
{editingEntity && EntityEditorModal && (
{
let newInter = [...(panneau.intervenants || [])];
let newLots = JSON.parse(JSON.stringify(panneau.lots || []));
const loc = editingEntity.location;
// CORRECTION SÉCURITÉ : Utilisation du générateur d'ID avec fallback
if (loc.type === 'intervenant') {
if (loc.index !== undefined) {
newInter[loc.index] = editingEntity.data;
} else {
newInter.push({...editingEntity.data, id: window.pano_generateID()});
}
} else if (loc.type === 'lot') {
if (loc.index !== undefined) {
newLots[loc.index] = {...newLots[loc.index], ...editingEntity.data};
} else {
newLots.push({...editingEntity.data, id: window.pano_generateID(), entreprises: []});
}
} else if (loc.type === 'entreprise') {
if (loc.index !== undefined) {
newLots[loc.lotIndex].entreprises[loc.index] = editingEntity.data;
} else {
newLots[loc.lotIndex].entreprises.push({...editingEntity.data, id: window.pano_generateID()});
}
}
setPanneau({ ...panneau, intervenants: newInter, lots: newLots });
setEditingEntity(null);
}}
clientUid={panneau?.client_uid}
panneauId={panneau?.id}
onClose={() => setEditingEntity(null)}
showToast={showToast}
/>
)}
{confirmDialog && ConfirmModal && (
setConfirmDialog(null)} />
)}
);
};
/* EOF ========== [_react/delegate/_delegate_view.jsx] */