/** * ========================================================================= * PLATEFORME ECO-PANNEAU.FR - VERSION 1.0.0 * Socle Riverains (3/4) - Onglet Contact et Messagerie * ========================================================================= */ const { useState, useEffect } = React; window.pano_RiverainContactTab = ({ panneau, themeColor, interactions, settings, refreshData, showToast, isPreview, handleExternalLink }) => { const { activeDialog, openDialog, closeCurrentLayer } = window.pano_useUrlModal(); const [contactSuccess, setContactSuccess] = useState(false); const [mountTime] = useState(Math.floor(Date.now() / 1000)); const { PhoneIcon, MessageSquareIcon, Trash2Icon, MailIcon, InfoIcon } = window.pano_getIcons(); const Button = window.pano_Button || (() => null); const PublicContactForm = window.pano_PublicContactForm || (() => null); const ChatBox = window.pano_ChatBox || (() => null); const ConfirmModal = window.pano_ConfirmModal || (() => null); const isPublicContact = panneau.id === 'CONTACT_PUBLIC'; const isSimulated = isPreview || panneau.id === 'demo-panneau'; const panelInteractions = (interactions || []).filter(i => i.panneauId === panneau.id); const handleChatSend = async (text) => { if (isSimulated) { openDialog('demo_warning', 'chat'); return; } // CORRECTION ZÉRO-TRUST : pano_riverain_email let threadEmail = panelInteractions.find(m => m.author !== 'Admin' && m.author !== 'Client')?.author || localStorage.getItem('pano_riverain_email') || 'Visiteur anonyme'; if (threadEmail !== 'Visiteur anonyme') { localStorage.setItem('pano_riverain_email', threadEmail); } const data = { panneauId: panneau.id, detail: text, author: threadEmail, isAlert: 0, hp_time: mountTime }; try { await fetch(window.pano_CONFIG.apiBaseUrl + 'interactions', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data) }); if (refreshData) refreshData(); } catch (e) { if (showToast) showToast("Erreur lors de l'envoi", "error"); } }; const confirmDeleteThread = async () => { let threadEmail = panelInteractions.find(m => m.author !== 'Admin' && m.author !== 'Client')?.author || localStorage.getItem('pano_riverain_email'); const token = localStorage.getItem('pano_riverain_token_' + threadEmail); if (!token || !threadEmail) { if(showToast) showToast("Vous n'êtes pas authentifié pour effectuer cette action.", "error"); closeCurrentLayer(); return; } const data = { thread_id: panneau.id, email: threadEmail, verification_token: token }; try { const res = await fetch(window.pano_CONFIG.apiBaseUrl + 'interactions/delete_thread', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data) }); const d = await res.json(); if (d.status === 'success') { if (showToast) showToast("Votre conversation a été effacée.", "success"); if (refreshData) refreshData(); } else { if (showToast) showToast(d.message || "Action non autorisée.", "error"); } } catch (e) { if (showToast) showToast("Erreur réseau.", "error"); } closeCurrentLayer(); }; const fakeDemoInteractions = [ { id: 'fake_1', panneauId: panneau.id, author: 'Riverain (Voisin)', authorType: 'Riverain', target: 'Client', detail: "Bonjour, j'habite la maison voisine. Pouvez-vous me dire quand les travaux de démolition vont commencer ?", created_at: new Date(Date.now() - 172800000).toISOString(), resolved: true, isAlert: 0 }, { id: 'fake_2', panneauId: panneau.id, author: 'Responsable', authorType: 'Client', target: 'Riverain', detail: "Bonjour. La démolition est prévue pour la première semaine du mois prochain. Nous ferons le maximum pour limiter les nuisances sonores.", created_at: new Date(Date.now() - 86400000).toISOString(), resolved: true, isAlert: 0 } ]; const effectiveInteractions = isSimulated ? fakeDemoInteractions : panelInteractions; const chatMessages = effectiveInteractions.map(m => ({ ...m, author: (m.author !== 'Admin' && m.author !== 'Client') ? (isSimulated ? m.author : 'Riverain') : m.author })); const isChatActive = effectiveInteractions.length > 0; return (
{panneau.emergencyPhone && (

Numéro de contact

{panneau.emergencyPhone}

)}

Échanger avec {isPublicContact ? "le service client" : "le responsable"}

{isChatActive && !isSimulated && (
{isSimulated && (
{ e.preventDefault(); e.stopPropagation(); openDialog('demo_warning', 'chat'); }} onDrop={(e) => { e.preventDefault(); e.stopPropagation(); openDialog('demo_warning', 'chat'); }} onDragOver={(e) => { e.preventDefault(); e.stopPropagation(); }} title="Messagerie désactivée" >
)} {effectiveInteractions.length === 0 ? ( contactSuccess ? (

Message envoyé !

Votre demande a été transmise au responsable du chantier en toute confidentialité.

Étape suivante

Un e-mail contenant votre lien d'accès sécurisé vient de vous être envoyé. Veuillez utiliser ce lien pour lire la réponse et poursuivre la conversation.

{Button && ( )}
) : ( { setContactSuccess(true); if (refreshData) refreshData(); }} /> ) ) : (
)}
{activeDialog === 'confirm_delete_thread' && ConfirmModal && ( )}
); }; /* EOF ========== [_react/_riverains_contact.jsx] */