/** * ========================================================================= * PLATEFORME ECO-PANNEAU.FR - VERSION 1.0.0 * Interface Admin - Onglet : Messagerie Globale * ========================================================================= */ // ========================================================================= // FACTORISATION : LOGIQUE MÉTIER DES MESSAGES ADMIN // ========================================================================= window.pano_buildAdminChatThreads = (interactions, panneaux, clients) => { const threadsMap = {}; interactions.forEach(m => { let threadId; let title = "Conversation"; let targetEmail = (m.author === 'Admin' || m.author === 'Système' || m.author === 'Systeme') ? m.target : m.author; let type = 'riverain'; let unread = (!m.resolved && m.author !== 'Admin' && m.author !== 'Système' && m.author !== 'Systeme') ? 1 : 0; let panneauData = null; if (m.panneauId === 'CONTACT_PUBLIC') { const visitorEmail = (m.author === 'Admin' || m.author === 'Système' || m.author === 'Systeme') ? m.target : m.author; threadId = `CONTACT_PUBLIC_${visitorEmail}`; title = `Contact Site : ${visitorEmail}`; targetEmail = visitorEmail; type = 'contact'; } else if (m.panneauId.startsWith('SUPPORT_')) { threadId = m.panneauId; const cUid = m.panneauId.split('_')[1]; const c = clients.find(cl => cl.id === cUid); title = `Support : ${c ? (c.company || c.name || c.full_name || c.email) : 'Client inconnu'}`; targetEmail = c ? c.email : 'Client'; type = 'support'; } else if (m.panneauId.startsWith('GROUP_')) { threadId = m.panneauId; const pId = m.panneauId.replace('GROUP_', ''); panneauData = panneaux.find(pan => pan.id === pId); title = `Équipe : ${panneauData ? panneauData.name : 'Panneau introuvable'}`; targetEmail = 'Groupe'; type = 'group'; } else { const riverainEmail = (m.author === 'Client' || m.author === 'Admin' || m.author === 'Système' || m.author === 'Systeme') ? m.target : m.author; threadId = `${m.panneauId}_${riverainEmail}`; panneauData = panneaux.find(pan => pan.id === m.panneauId); title = `Riverain : ${panneauData ? panneauData.name : 'Panneau'}`; targetEmail = riverainEmail; type = 'riverain'; } if (!threadsMap[threadId]) { threadsMap[threadId] = { id: threadId, panneauId: m.panneauId, title, targetEmail, type, messages: [], unread: 0, panneauData }; } threadsMap[threadId].messages.push(m); threadsMap[threadId].unread += unread; }); return Object.values(threadsMap).sort((a, b) => { const dateA = a.messages.length > 0 ? new Date(String(a.messages[a.messages.length - 1].created_at || '').replace(' ', 'T')).getTime() : 0; const dateB = b.messages.length > 0 ? new Date(String(b.messages[b.messages.length - 1].created_at || '').replace(' ', 'T')).getTime() : 0; return dateB - dateA; }); }; // ========================================================================= // COMPOSANT PRINCIPAL : MESSAGERIE ADMIN // ========================================================================= window.pano_AdminMessagesTab = ({ data, refreshData, showToast }) => { const { useState, useEffect } = React; const [forceRender, setForceRender] = useState(0); useEffect(() => { const handlePop = () => setForceRender(f => f + 1); window.addEventListener('popstate', handlePop); return () => window.removeEventListener('popstate', handlePop); }, []); const { UsersIcon, MessageSquareIcon, MessageCircleIcon, MailIcon } = window.pano_getIcons(); const IconBadge = window.pano_IconBadge || (() => null); const panneaux = data.panneaux || []; const clients = data.clients || []; const interactions = data.interactions || []; const threads = window.pano_buildAdminChatThreads(interactions, panneaux, clients); const openChat = (id) => { const u = new URL(window.location); u.searchParams.set('chat_id', id); window.history.pushState({ chat_id: id }, '', u); window.dispatchEvent(new Event('popstate')); if (refreshData) refreshData(); }; const getThreadIcon = (type) => { switch(type) { case 'support': return MessageSquareIcon; case 'group': return UsersIcon; case 'contact': return MailIcon; default: return MessageCircleIcon; } }; const getThreadVariant = (type) => { switch(type) { case 'support': return 'success'; case 'group': return 'info'; case 'contact': return 'warning'; default: return 'secondary'; } }; const getThreadTitleClass = (type) => { if (type === 'support') return 'font-black text-emerald-700'; if (type === 'group') return 'font-black text-blue-700'; if (type === 'contact') return 'font-black text-amber-700'; return 'font-bold text-slate-800'; }; return (

Messagerie Globale

Vue globale (Support, Groupes, Riverains, Contact public).

{threads.map(t => { const lastMsg = t.messages.length > 0 ? t.messages[t.messages.length - 1] : null; return (
openChat(t.id)} className="bg-white border border-slate-200 rounded-3xl p-5 cursor-pointer hover:border-emerald-300 hover:shadow-md transition flex flex-col gap-3 relative overflow-hidden group" > {t.unread > 0 && ( {t.unread} )}
{IconBadge && ( )}

{t.title}

{t.targetEmail}

0 ? 'text-slate-800 font-bold' : 'text-slate-600'}`}> {lastMsg ? lastMsg.detail.replace(/\[ATTACHMENT:[^\]]+\]/g, '[Pièce jointe]').replace(/<[^>]*>?/gm, '') : Nouvelle conversation...}

{t.type} {lastMsg ? new Date(String(lastMsg.created_at || '').replace(' ', 'T')).toLocaleString('fr-FR') : ''}
); })} {threads.length === 0 && (

Aucune conversation détectée sur la plateforme.

)}
); }; /* EOF ========== [_react/_admin_messages.jsx] */