// ECO-PANNEAU.FR - __react/socle/_socle_editeur_infos.jsx window.pano_PanneauEditorInfos = ({ panneau, setPanneau, lockedFields = [], validationErrors = [], settings, uiPrefs = {} }) => { // 1. - SÉCURITÉ ANTI-FUITE DE MÉMOIRE (Memory Leak) ET CORRUPTION D'ÉTAT const isMounted = React.useRef(true); React.useEffect(() => { return () => { isMounted.current = false; }; }, []); // 2. - Composants et Icônes const { AlertBox, Button } = window.pano_getComponents(); const { InfoIcon, LockIcon, MapPinIcon, CalendarIcon, UploadCloudIcon, CheckCircleIcon, Trash2Icon, PlusIcon } = window.pano_getIcons(); // 3. - Logique de verrouillage const isFieldLocked = (fieldId) => lockedFields.includes(fieldId); // 4. - Actions métier const handleFileUpload = async (e, type) => { const file = e.target.files[0]; if (e.target) e.target.value = null; if (!file) return; const uploadImage = (urlField, idField) => { const reader = new FileReader(); reader.onload = async (event) => { if (!isMounted.current) return; const base64Url = event.target.result; setPanneau(prev => ({ ...prev, [urlField]: base64Url })); try { const fileObj = await window.pano_uploadFile(file, 'image', null, false, false, panneau.client_uid, panneau.id); if (!isMounted.current) return; setPanneau(prev => ({ ...prev, [idField]: fileObj.id || fileObj })); } catch (err) { if (!isMounted.current) return; if (window.pano_showToast) window.pano_showToast(err, "error"); else if (window.pano_logFallback) window.pano_logFallback("Erreur d'upload d'image ignorée."); setPanneau(prev => ({ ...prev, [urlField]: '' })); } }; reader.readAsDataURL(file); }; if (type === 'image') { uploadImage('imageUrl', 'imageId'); } else if (type === 'logo') { uploadImage('maitreOuvrageLogoUrl', 'maitreOuvrageLogoId'); } else if (type === 'logo_architecte') { uploadImage('architecteLogoUrl', 'architecteLogoId'); } else if (type === 'pdf') { try { const fileObj = await window.pano_uploadFile(file, 'pdf', null, false, false, panneau.client_uid, panneau.id); if (!isMounted.current) return; setPanneau(prev => ({ ...prev, pdfId: fileObj.id || fileObj, pdfNumPages: fileObj.numPages || 1 })); } catch (err) { if (!isMounted.current) return; if (window.pano_showToast) window.pano_showToast(err, "error"); else if (window.pano_logFallback) window.pano_logFallback("Erreur d'upload PDF ignorée."); } } }; // 4.1 - Gestion des arrêtés modificatifs const addModificatif = () => { if (isFieldLocked('permitNumber')) return; const currentArr = panneau.modificatifs || []; const newUid = 'mod_' + Date.now() + '_' + Math.floor(Math.random() * 1000); const newPanneau = { ...panneau, modificatifs: [...currentArr, { _uid: newUid, label: '', date: '', id: '', numPages: 1 }] }; delete newPanneau.modifiedPermits; setPanneau(newPanneau); }; const updateModificatif = (uid, field, value) => { if (isFieldLocked('permitNumber')) return; const currentArr = panneau.modificatifs || []; const newArr = currentArr.map((p, i) => { const pUid = p._uid || p.id || i; return pUid === uid ? { ...p, [field]: value } : p; }); const newPanneau = { ...panneau, modificatifs: newArr }; delete newPanneau.modifiedPermits; setPanneau(newPanneau); }; const removeModificatif = (uid) => { if (isFieldLocked('permitNumber')) return; const currentArr = panneau.modificatifs || []; const newArr = currentArr.filter((p, i) => (p._uid || p.id || i) !== uid); const newPanneau = { ...panneau, modificatifs: newArr }; delete newPanneau.modifiedPermits; setPanneau(newPanneau); }; const handleModificatifUpload = async (e, uid) => { const file = e.target.files[0]; if (e.target) e.target.value = null; if (!file) return; try { const fileObj = await window.pano_uploadFile(file, 'pdf', null, false, false, panneau.client_uid, panneau.id); if (!isMounted.current) return; const currentArr = panneau.modificatifs || []; const newArr = currentArr.map((p, i) => { const pUid = p._uid || p.id || i; return pUid === uid ? { ...p, id: fileObj.id || fileObj, numPages: fileObj.numPages || 1 } : p; }); const newPanneau = { ...panneau, modificatifs: newArr }; delete newPanneau.modifiedPermits; setPanneau(newPanneau); } catch (err) { if (!isMounted.current) return; if (window.pano_showToast) window.pano_showToast(err, "error"); else if (window.pano_logFallback) window.pano_logFallback("Erreur d'upload modificatif ignorée."); } }; const showContactRow = uiPrefs.simp_opt_schedule !== false || uiPrefs.simp_opt_emergency !== false || uiPrefs.simp_opt_link !== false; // 5. - Rendu UI return (