/**
* =========================================================================
* PLATEFORME ECO-PANNEAU.FR - VERSION 1.0.0
* Composant Vue Riverains (Interface publique scannée via QR Code)
* Design Mobile-First, gère l'affichage légal et la messagerie publique.
* =========================================================================
*/
const { useState, useEffect, useRef } = React;
const {
MapPin, Building, Phone, FileDigit, Users, MessageSquare,
AlertTriangle, ExternalLink, Clock, Info, Shield, Download,
PublicContactForm, ChatBox
} = window;
/**
* Vue principale encapsulée pour le riverain.
* S'affiche en plein écran sur mobile, ou confinée dans un mock-up iPhone sur l'espace client.
*/
window.RiverainView = ({ chantier, showToast, interactions = [], refreshData, isPreview = false, initialTab = 'home' }) => {
const [activeTab, setActiveTab] = useState(initialTab);
// Synchronisation si la prop initialTab change à la volée (ex: clic sur lien magique)
useEffect(() => {
setActiveTab(initialTab);
}, [initialTab]);
// Défilement automatique vers le haut au changement d'onglet
const contentRef = useRef(null);
useEffect(() => {
if (contentRef.current) contentRef.current.scrollTo({ top: 0, behavior: 'smooth' });
}, [activeTab]);
if (!chantier) {
return (
Panneau introuvable
Ce panneau n'est plus actif ou l'URL est invalide.
);
}
const isPublicContact = chantier.id === 'CONTACT_PUBLIC';
const isDemo = chantier.id === 'demo-chantier';
const themeColor = chantier.themeColor || '#059669';
const displayImageUrl = chantier.imageUrl || (chantier.imageId ? `?api=file/download&type=image&id=${chantier.imageId}` : null);
const displayMoaLogoUrl = chantier.maitreOuvrageLogoUrl || (chantier.maitreOuvrageLogoId ? `?api=file/download&type=image&id=${chantier.maitreOuvrageLogoId}` : null);
// Fonction d'envoi de réponse au sein du fil de discussion existant
const handleChatSend = async (text) => {
// On récupère l'email du riverain depuis l'historique ou le cache
const threadEmail = interactions.find(m => m.author !== 'Admin' && m.author !== 'Client')?.author || localStorage.getItem('eco_riverain_email') || 'Visiteur anonyme';
if (threadEmail !== 'Visiteur anonyme') localStorage.setItem('eco_riverain_email', threadEmail);
const data = { chantierId: chantier.id, detail: text, author: threadEmail, isAlert: 0 };
try {
await fetch(window.ECO_CONFIG.apiBaseUrl + 'interactions', { method: 'POST', body: JSON.stringify(data) });
if (refreshData) refreshData();
} catch (e) {
if(showToast) showToast("Erreur lors de l'envoi", "error");
}
};
// On formate les messages pour que le ChatBox (qui se base sur le rôle "public") identifie bien le riverain
const chatMessages = interactions.map(m => ({
...m,
author: (m.author !== 'Admin' && m.author !== 'Client') ? 'Riverain' : m.author
}));
// Compteur de messages non lus destinés au riverain (venant du client ou de l'admin)
const unreadCount = interactions.filter(m => !m.resolved && (m.author === 'Admin' || m.author === 'Client')).length;
return (
{/* --- EN-TÊTE DYNAMIQUE (HERO) --- */}
{displayImageUrl && (
<>
>
)}
{!displayImageUrl && (
)}
{(!isPublicContact && !isDemo) && (
Panneau en cours
)}
{chantier.name}
{/* --- CONTENU PRINCIPAL --- */}
{/* ONGLET 1 : INFORMATIONS (HOME) */}
{activeTab === 'home' && (
{/* Localisation */}
Localisation
{chantier.location}
{/* Maître d'Ouvrage */}
{(chantier.maitreOuvrage || displayMoaLogoUrl) && (
Maître d'ouvrage
{displayMoaLogoUrl ? (
) : (
)}
{chantier.maitreOuvrage &&
{chantier.maitreOuvrage}
}
)}
{/* Arrêté Légal PDF */}
{chantier.pdfId && (
)}
{/* Description & Horaires */}
{chantier.description && (
Description des travaux
{chantier.description}
)}
{(chantier.noiseSchedule || chantier.promoterLink) && (
{chantier.noiseSchedule && (
Horaires autorisés
{chantier.noiseSchedule}
)}
{chantier.promoterLink && (
Site web
Visiter le site
)}
)}
)}
{/* ONGLET 2 : L'ÉQUIPE (TEAM) */}
{activeTab === 'team' && (
{(!chantier.intervenants?.length && !chantier.lots?.length) ? (
L'équipe du panneau n'a pas encore été renseignée.
) : (
<>
{/* Intervenants principaux */}
{chantier.intervenants?.length > 0 && (
Intervenants principaux
{chantier.intervenants.map((inter, idx) => (
{inter.logoId ? (
) : (
)}
{inter.name}
{inter.role}
{(inter.phone || inter.email) && (
)}
))}
)}
{/* Sous-traitants par Lots */}
{chantier.lots?.length > 0 && (
Entreprises sous-traitantes
{chantier.lots.map((lot, idx) => (
{lot.entreprises?.map((ent, eIdx) => (
{ent.logoId &&
}
{ent.name}
{ent.role &&
{ent.role}
}
))}
{(!lot.entreprises || lot.entreprises.length === 0) && (
En cours d'attribution
)}
))}
)}
>
)}
)}
{/* ONGLET 3 : CONTACT & MESSAGERIE */}
{activeTab === 'contact' && (
{chantier.emergencyPhone && (
Numéro d'urgence
{chantier.emergencyPhone}
)}
Échanger avec le responsable
{interactions.length > 0 ? "Historique de vos échanges confidentiels :" : "Posez une question ou signalez une nuisance. Le responsable vous répondra en toute confidentialité."}
{interactions.length === 0 ? (
{
const emailInput = document.querySelector('input[name="email"]');
if(emailInput) localStorage.setItem('eco_riverain_email', emailInput.value);
if(refreshData) refreshData();
}}
/>
) : (
)}
)}
{/* --- NAVIGATION INFERIEURE (FIXED BOTTOM) --- */}
setActiveTab('home')} className={`flex flex-col items-center justify-center w-full h-full space-y-1 transition ${activeTab === 'home' ? 'text-slate-900' : 'text-slate-400 hover:text-slate-600'}`}>
Le panneau
setActiveTab('team')} className={`flex flex-col items-center justify-center w-full h-full space-y-1 transition ${activeTab === 'team' ? 'text-slate-900' : 'text-slate-400 hover:text-slate-600'}`}>
L'équipe
setActiveTab('contact')} className={`flex flex-col items-center justify-center w-full h-full space-y-1 transition relative ${activeTab === 'contact' ? 'text-slate-900' : 'text-slate-400 hover:text-slate-600'}`}>
{unreadCount > 0 && (
)}
Contact
);
};
/* EOF ===== [_riverains.jsx] =============== */