// ECO-PANNEAU.FR - _react/clients/_clients_modals_newsletter.jsx const { useState } = React; window.pano_ClientNewsletterModal = ({ managingPanneau, myClientData, onClose, showToast }) => { // ZÉRO-DETTE : Utilisation de notre Hook abstrait ! const { isMounted, safeFetch } = window.pano_useSafeFetch(); // 1. - Composants et Icônes const { MailIcon, UsersIcon, SendIcon, AlertTriangleIcon, LoaderIcon, CheckCircleIcon } = window.pano_getIcons(); const { Modal, Button, FormInput, FormTextarea, AlertBox } = window.pano_getComponents(); // 2. - États locaux const [isSending, setIsSending] = useState(false); const [isSent, setIsSent] = useState(false); const [moderationPrompt, setModerationPrompt] = useState(false); const [newsletterData, setNewsletterData] = useState({ subject: '', message: '' }); // 3. - Calcul des droits (UID et Email Hash) const isOwner = managingPanneau.client_uid === myClientData.id; const isMe = (uid) => uid === myClientData.id || uid === myClientData.email_hash; const myCollab = !isOwner ? managingPanneau.collaborators?.find(c => isMe(c.uid)) : null; const canEdit = isOwner || myCollab?.rights?.can_edit; if (!canEdit) { return (

Vous n'avez pas les droits nécessaires pour envoyer une information aux riverains.

); } const subscriberCount = managingPanneau?.newsletterSubscribers || 0; // 4. - Actions métier const handleSendNewsletter = async (e, requestModeration = false) => { if (e) e.preventDefault(); if (!newsletterData.subject.trim() || !newsletterData.message.trim()) { showToast("Veuillez remplir tous les champs.", "error"); return; } const d = await safeFetch('newsletter/send', { body: { panneau_id: managingPanneau.id, subject: newsletterData.subject, message: newsletterData.message, request_moderation: requestModeration }, setLoading: setIsSending }); if (!isMounted.current) return; // SÉCURITÉ : Coupe-circuit if (d && d.data) { if (d.data.requires_moderation) { setModerationPrompt(true); } else if (d.data.moderation_submitted) { showToast(d.message || "Demande de modération transmise.", "success"); setModerationPrompt(false); setIsSent(true); setTimeout(() => { if (isMounted.current) onClose(); }, 3000); } else { showToast(d.message || "Information envoyée avec succès !", "success"); setIsSent(true); setTimeout(() => { if (isMounted.current) onClose(); }, 3000); } } else if (d) { showToast(d.message || "Information envoyée avec succès !", "success"); setIsSent(true); setTimeout(() => { if (isMounted.current) onClose(); }, 3000); } }; // 5. - Rendu UI : Avertissement de modération if (moderationPrompt) { return ( setModerationPrompt(false)} actions={(close) => ( <> )} >
{AlertTriangleIcon && }

Termes non autorisés détectés

Votre message contient des termes non autorisés et a été bloqué par notre filtre de modération.

Souhaitez-vous demander une modération humaine ?

); } // 6. - Rendu UI Principal return ( 0) ? (close) => ( <> ) : null} >

{UsersIcon && } Riverains abonnés

Personnes souhaitant être tenues informées de l'avancée de ce chantier.

{subscriberCount}
{isSent ? (
{CheckCircleIcon && }

Message envoyé !

Votre actualité a bien été transmise {window.pano_formatPlural(subscriberCount, "à 1 abonné", `aux ${subscriberCount} abonnés`)}.

) : subscriberCount === 0 ? (
{MailIcon && }

Aucun abonné pour le moment

Les riverains peuvent s'inscrire directement depuis la page publique de votre panneau en scannant le QR Code.

) : (
handleSendNewsletter(e, false)} className="space-y-5 animate-in fade-in min-w-0">

Rédiger votre message

{FormInput && ( setNewsletterData({...newsletterData, subject: e.target.value})} placeholder="Ex: Fermeture temporaire de la rue..." required disabled={isSending} className="min-w-0" /> )} {FormTextarea && ( setNewsletterData({...newsletterData, message: e.target.value})} placeholder="Bonjour, nous vous informons que les travaux de terrassement débuteront ce lundi..." rows={6} required disabled={isSending} hint="Un lien de désinscription sera automatiquement ajouté en bas de cet e-mail pour respecter le RGPD." className="min-w-0" /> )}
{AlertTriangleIcon && }

Ce message sera envoyé par e-mail {window.pano_formatPlural(subscriberCount, "à l'unique riverain inscrit à ce jour", `à tous les riverains inscrits à ce jour (${subscriberCount} personnes)`)}. Les filtres de modération s'appliquent à ce contenu.

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