// 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 (

{ShieldIcon && } Saisie déléguée

Mise à jour des informations du panneau

{Button && ( )}
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] */