// ECO-PANNEAU.FR - __react/socle/_socle_messagerie_ui.jsx const { memo, useEffect } = React; // 1. - UTILITAIRES ET MODALES TRANSVERSES window.pano_ModerationModal = ({ word, onModify, onRequestControl }) => { const { ShieldIcon } = window.pano_getIcons(); const { Button, Modal } = window.pano_getComponents(); return ( (
)} >
À cause de l'utilisation de l'expression "{word}", vous devez modifier votre message.

Vous avez également la possibilité de faire contrôler votre message par le support technique avant envoi au destinataire.
); }; window.pano_checkForBlacklist = (text, settings) => { if (!settings || !settings.blacklist) return null; const words = settings.blacklist.split(',') .map(w => w.trim().toLowerCase()) .filter(w => w); const lowerText = text.toLowerCase(); for (let w of words) { if (lowerText.includes(w)) return w; } return null; }; // 2. - COMPOSANT : BULLE DE MESSAGE (MÉMORISÉE POUR PERFORMANCES) window.pano_MessageBubble = memo(({ msg, isMe, displayAuthor, onImageLoad, onViewAttachment, isAdmin, onModerate, themeColor = '#059669', onAction, canDeleteAttachment, onDeleteAttachment }) => { const { AlertTriangleIcon, LoaderIcon, FileTextIcon, EditIcon, CheckCircleIcon, Trash2Icon } = window.pano_getIcons(); const { Button, PdfThumbnail } = window.pano_getComponents(); useEffect(() => { if (!window.DOMPurify && window.pano_logFallback) { window.pano_logFallback("DOMPurify introuvable dans MessageBubble. Utilisation du fallback regex pour la sécurisation HTML."); } }, []); const attachments = []; const deletedAttachments = []; // Capture des pièces jointes valides const regex = /\[ATTACHMENT:([a-zA-Z0-9_.\/-]+):(image|pdf)(?::(\d+))?\]/g; let match; while ((match = regex.exec(msg.detail || '')) !== null) { attachments.push({ id: match[1], type: match[2], numPages: match[3] ? parseInt(match[3], 10) : 1 }); } // Capture robuste des pièces jointes supprimées const delRegex = /\[DELETED_ATTACHMENT(?::(image|pdf))?\]/g; let delMatch; while ((delMatch = delRegex.exec(msg.detail || '')) !== null) { deletedAttachments.push({ type: delMatch[1] || 'fichier' }); } // Nettoyage complet du texte const textContent = (msg.detail || '').replace(regex, '').replace(delRegex, '').trim(); const isHtmlAllowed = msg.authorType === 'Admin' || msg.authorType === 'Système' || msg.authorType === 'Systeme' || msg.authorType === 'System'; const suspendRegex = /Le panneau "([^"]+)" a été (?:suspendu|rejeté)/i; const suspendMatch = textContent.match(suspendRegex); const isTemp = msg.id.toString().startsWith('temp_'); const handleCorrigerClick = (e) => { e.preventDefault(); // Délégation propre de l'action au composant parent if (onAction && suspendMatch) { onAction('correct_panel', suspendMatch[1]); } }; const handleHtmlClick = (e) => { const grantBtn = e.target.closest('[data-action="grant_access"]'); if (grantBtn) { e.preventDefault(); e.stopPropagation(); window.dispatchEvent(new CustomEvent('chat_grant_access')); } }; return (
{msg.isAlert === 2 && (
En attente de contrôle {isAdmin && onModerate && (
)}
)}
{textContent && ( isHtmlAllowed ? (
/g, '>').replace(/"/g, '"').replace(/'/g, ''') }} className="text-sm leading-relaxed whitespace-pre-wrap admin-html break-words" /> ) : (

{textContent}

) )} {suspendMatch && msg.authorType === 'Admin' && !isMe && (
)} {attachments.length > 0 && (
{attachments.map((att, i) => ( {att.type === 'image' && (
onViewAttachment(att)} className="cursor-pointer"> {/* ZÉRO-DETTE : Utilisation de preview=1 pour les images */} Pièce jointe
{canDeleteAttachment && onDeleteAttachment && (
)} {att.type === 'pdf' && PdfThumbnail && (
onViewAttachment(att)} className={`cursor-pointer rounded-xl border flex flex-col text-left transition-transform hover:scale-[1.02] h-full ${isMe ? 'border-white/20 bg-black/10' : 'border-slate-200 bg-white'}`}>
Aperçu PDF
{canDeleteAttachment && onDeleteAttachment && (
)}
))}
)} {/* Affichage des pièces jointes supprimées */} {deletedAttachments.length > 0 && (
0 ? 'pt-2 border-t border-white/10' : ''}`}> {deletedAttachments.map((att, i) => (
Fichier supprimé par l'utilisateur pour libérer de l'espace.
))}
)}
{/* CORRECTION UX : Modification de l'horodatage pour l'envoi en cours */} {displayAuthor} • {isTemp ? Envoi en cours... : new Date(String(msg.created_at || '').replace(' ', 'T')).toLocaleString('fr-FR')} {isTemp && }
); }, (prevProps, nextProps) => { return prevProps.msg.id === nextProps.msg.id && prevProps.msg.resolved === nextProps.msg.resolved && prevProps.msg.isAlert === nextProps.msg.isAlert && prevProps.isAdmin === nextProps.isAdmin && prevProps.themeColor === nextProps.themeColor; }); /* EOF ========== [__react/socle/_socle_messagerie_ui.jsx] */