/** * ========================================================================= * PLATEFORME ECO-PANNEAU.FR - VERSION 1.0.0 * Composant : Modale du coffre-fort légal et upload des preuves * ========================================================================= */ const { useState } = React; window.ClientLegalVaultModal = ({ managingPanneau, setManagingPanneau, onClose, refreshData, showToast }) => { const LockIcon = window.LockIcon || (() => null); const ArrowUpIcon = window.ArrowUpIcon || (() => null); const Trash2Icon = window.Trash2Icon || (() => null); const LoaderIcon = window.LoaderIcon || (() => null); // COMPOSANTS GLOBAUX NETTOYÉS ET FACTORISÉS const Modal = window.Modal; const AlertBox = window.AlertBox; const ConfirmModal = window.ConfirmModal; const Button = window.Button; const VaultDocumentThumbnail = window.VaultDocumentThumbnail || (() => null); const VaultDocumentViewer = window.VaultDocumentViewer || (() => null); const UploadErrorsModal = window.UploadErrorsModal || (() => null); const [isSaving, setIsSaving] = useState(false); const [uploadStats, setUploadStats] = useState({ current: 0, total: 0 }); const [uploadDetail, setUploadDetail] = useState(''); const [vaultDragging, setVaultDragging] = useState(false); const [viewingDoc, setViewingDoc] = useState(null); const [confirmDialog, setConfirmDialog] = useState(null); const [uploadErrors, setUploadErrors] = useState([]); const handleVaultUpload = async (fileList) => { if (!fileList || fileList.length === 0) return; const files = Array.from(fileList); let currentTotalSize = managingPanneau.privateDocs?.reduce((acc, doc) => acc + (doc.size || 0), 0) || 0; setIsSaving(true); setUploadStats({ current: 1, total: files.length }); setUploadDetail('préparation'); let currentDocs = [...(managingPanneau.privateDocs || [])]; let hasChanges = false; let currentErrors = []; for (let i = 0; i < files.length; i++) { setUploadStats({ current: i + 1, total: files.length }); setUploadDetail('préparation'); const file = files[i]; if (file.size > 10 * 1024 * 1024) { currentErrors.push({ file: file.name, reason: "Taille > 10 Mo" }); continue; } if (currentTotalSize + file.size > 250 * 1024 * 1024) { currentErrors.push({ file: file.name, reason: "Dépassement du quota (250 Mo)" }); continue; } try { const type = file.type.includes('pdf') ? 'pdf' : (file.type.startsWith('image/') ? 'image' : null); if (!type) { currentErrors.push({ file: file.name, reason: "Format non supporté" }); continue; } // CORRECTION DE SIGNATURE : Suppression du 5ème argument redondant et passage propre des booléens publics/privés const fileId = await window.uploadFile(file, type, (msg) => setUploadDetail(msg), false, true, managingPanneau.client_uid, managingPanneau.id); const newDoc = { id: fileId.toString(), type, name: file.name, date: new Date().toLocaleDateString('fr-FR'), size: file.size, numPages: fileId.numPages || 1 }; currentDocs = [...currentDocs, newDoc]; currentTotalSize += file.size; hasChanges = true; // CORRECTION BDD : Mise à jour immédiate de la base de données et de l'UI const updatedPanneau = {...managingPanneau, privateDocs: currentDocs}; setManagingPanneau(updatedPanneau); await window.apiFetch('panneaux', { body: { id: updatedPanneau.id, status: updatedPanneau.status, offerType: updatedPanneau.offerType, physicalPanels: updatedPanneau.physicalPanels, details: updatedPanneau } }); } catch(err) { currentErrors.push({ file: file.name, reason: err.message || err || "Fichier invalide ou corrompu" }); } } if (hasChanges) refreshData(); setIsSaving(false); setUploadStats({ current: 0, total: 0 }); setUploadDetail(''); if (currentErrors.length > 0) { setUploadErrors(currentErrors); } }; return ( <>
Ces documents sont chiffrés et inaccessibles au public. Ils seront inclus dans l'archive D.O.E lors de la clôture du panneau.
{ e.preventDefault(); setVaultDragging(true); }} onDragLeave={(e) => { e.preventDefault(); setVaultDragging(false); }} onDragOver={(e) => e.preventDefault()} onDrop={(e) => { e.preventDefault(); setVaultDragging(false); handleVaultUpload(e.dataTransfer.files); }} className={`w-full min-h-[150px] border-2 border-dashed rounded-xl flex flex-col items-center justify-center p-6 transition relative ${vaultDragging ? 'border-emerald-500 bg-emerald-50/50' : 'border-slate-300 bg-slate-50 hover:bg-slate-100'}`} title="Vous pouvez également coller vos fichiers (Ctrl+V) directement sur cette fenêtre." > {isSaving ? (
Traitement en cours... Fichier {uploadStats.current}/{uploadStats.total} {uploadDetail ? `(${uploadDetail})` : ''}
) : ( <>
Glissez-déposez vos preuves ici (ou Ctrl+V) Images ou PDF (Max 10 Mo/fichier, 250 Mo au total) )}
{managingPanneau.privateDocs && managingPanneau.privateDocs.length > 0 ? (
{managingPanneau.privateDocs.map((doc, idx) => (
setViewingDoc(doc)}>

{doc.name}

{doc.date}
))}
) : (

Aucun document privé stocké.

)}
Total utilisé : {((managingPanneau.privateDocs?.reduce((acc, doc) => acc + (doc.size || 0), 0) || 0) / (1024*1024)).toFixed(2)} Mo / 250 Mo
{confirmDialog && ConfirmModal && ( setConfirmDialog(null)} zIndex="z-[350]" /> )}
{viewingDoc && VaultDocumentViewer && ( )} {uploadErrors.length > 0 && UploadErrorsModal && ( setUploadErrors([])} zIndex="z-[300]" /> )} ); }; /* EOF ========== [_react/_clients_modals_vault.jsx] */