/** * ========================================================================= * PLATEFORME ECO-PANNEAU.FR - VERSION 1.0.0 * Interface Admin - Onglet : Gestion des Panneaux (Modération) * ========================================================================= */ window.pano_AdminPanelsTab = ({ data, refreshData, setManagingPanneau, setValidationErrors, openLocalModal, openLocalDialog, closeCurrentLayer, activeModal, activeDialog, targetId, showToast, setActiveTab }) => { const { useState, useEffect } = React; const routerActiveModal = activeModal || new URLSearchParams(window.location.search).get('modal'); const routerActiveDialog = activeDialog || new URLSearchParams(window.location.search).get('dialog'); const routerCloseLayer = closeCurrentLayer || (() => window.history.back()); const routerOpenModal = openLocalModal || ((type, id = null) => { const u = new URL(window.location); u.searchParams.set('modal', type); if(id) u.searchParams.set('targetId', id); window.history.pushState({ modal: type }, '', u); window.dispatchEvent(new Event('popstate')); }); const routerOpenDialog = openLocalDialog || ((type) => { const u = new URL(window.location); u.searchParams.set('dialog', type); window.history.pushState({ dialog: type }, '', u); window.dispatchEvent(new Event('popstate')); }); const [forceRender, setForceRender] = useState(0); useEffect(() => { if (!activeDialog && !activeModal) { const onPop = () => setForceRender(prev => prev + 1); window.addEventListener('popstate', onPop); return () => window.removeEventListener('popstate', onPop); } }, [activeDialog, activeModal]); const [moderationTarget, setModerationTarget] = useState(null); const [isSaving, setIsSaving] = useState(false); const [suspendTarget, setSuspendTarget] = useState(null); const [suspendReason, setSuspendReason] = useState(""); const [confirmConfig, setConfirmConfig] = useState(null); const Button = window.pano_Button || (() => null); const Modal = window.pano_Modal || (() => null); const ConfirmModal = window.pano_ConfirmModal || (() => null); const StatusBadge = window.pano_StatusBadge || (() => null); const PreviewModal = window.pano_PreviewModal || (() => null); const IconBadge = window.pano_IconBadge || (() => null); const BuildingIcon = window.pano_BuildingIcon || (() => null); const EyeIcon = window.pano_EyeIcon || (() => null); const EditIcon = window.pano_EditIcon || (() => null); const PowerIcon = window.pano_PowerIcon || (() => null); const Trash2Icon = window.pano_Trash2Icon || (() => null); const AlertTriangleIcon = window.pano_AlertTriangleIcon || (() => null); const CheckCircleIcon = window.pano_CheckCircleIcon || (() => null); const MessageSquareIcon = window.pano_MessageSquareIcon || (() => null); const checkPanelViolations = (p) => { const blacklist = (data.settings?.blacklist || '').split(',').map(s => s.trim().toLowerCase()).filter(Boolean); const greylist = (data.settings?.greylist || '').split(',').map(s => s.trim().toLowerCase()).filter(Boolean); let blackCount = 0; let greyCount = 0; const textToSearch = [p.name, p.location, p.description, p.maitreOuvrage].filter(Boolean).join(' ').toLowerCase(); const detected = { black: [], grey: [] }; blacklist.forEach(word => { if(textToSearch.includes(word)) { blackCount++; detected.black.push(word); } }); greylist.forEach(word => { if(textToSearch.includes(word)) { greyCount++; detected.grey.push(word); } }); return { isViolation: blackCount > 0 || greyCount > 2, detected }; }; const handleContactClient = (clientId) => { const u = new URL(window.location); u.searchParams.set('chat_id', 'SUPPORT_' + clientId); window.history.replaceState({}, '', u); setActiveTab('messages'); }; const handleSuspendSubmit = async (e) => { e.preventDefault(); if (!suspendReason.trim()) return; setIsSaving(true); const p = suspendTarget; const d1 = await window.pano_apiFetch('panneaux/status', { body: { id: p.id, status: 'Suspendu' }}); if (d1) { const message = `Le panneau "${p.name}" a été suspendu jusqu'à correction car il ne respecte pas les Conditions Générales de Vente du site.\n\nMotif du support :\n${suspendReason}\n\nVeuillez apporter les corrections nécessaires pour pouvoir le réactiver.`; await window.pano_apiFetch('interactions', { body: { panneauId: `SUPPORT_${p.clientName}`, detail: message, author: 'Admin', targetEmail: 'Client', type: 'message' } }); refreshData(); routerCloseLayer(); setTimeout(() => { setSuspendTarget(null); setSuspendReason(""); }, 300); } setIsSaving(false); }; const handleValidatePanel = async (id) => { const d = await window.pano_apiFetch('panneaux/mark_seen', { body: { id }, setLoading: setIsSaving, successMessage: "Panneau validé et marqué comme contrôlé." }); if (d) { refreshData(); routerCloseLayer(); } }; const toggleStatus = (id, currentStatus) => { const newStatus = currentStatus === 'Actif' ? 'Suspendu' : 'Actif'; setConfirmConfig({ title: `Passer en ${newStatus}`, message: `Voulez-vous vraiment passer ce panneau en statut "${newStatus}" ?`, confirmText: "Confirmer", type: newStatus === 'Suspendu' ? 'warning' : 'success', onConfirm: async () => { routerCloseLayer(); const d = await window.pano_apiFetch('panneaux/status', { body: { id, status: newStatus }, setLoading: setIsSaving }); if (d) refreshData(); } }); routerOpenDialog('confirm'); }; const handleDelete = (id) => { setConfirmConfig({ title: "Suppression forcée", message: "Attention : Cette action détruira immédiatement ce panneau et toutes ses données.", confirmText: "Détruire", isDestructive: true, onConfirm: async () => { routerCloseLayer(); const d = await window.pano_apiFetch('panneaux/delete', { body: { id, force_immediate: true }, setLoading: setIsSaving }); if (d) refreshData(); } }); routerOpenDialog('confirm'); }; const panneaux = data.panneaux || []; const clients = data.clients || []; const demoPanneau = panneaux.find(p => p.id === 'demo-panneau') || { id: 'demo-panneau', status: 'Actif', offerType: 'demo', name: 'Panneau de démonstration', location: 'Paris', themeColor: '#059669', hasNoAds: false }; const regularPanneaux = panneaux.filter(p => p.id !== 'demo-panneau' && p.status !== 'Brouillon'); const publishedPanels = regularPanneaux.filter(p => p.status === 'Actif'); const unseenPanels = publishedPanels.filter(p => !p.admin_seen); const seenPanels = publishedPanels.filter(p => p.admin_seen); const otherPanels = regularPanneaux.filter(p => p.status !== 'Actif'); const adminPreviewCible = routerActiveModal === 'preview_admin' ? panneaux.find(p => p.id === targetId) : null; return (
Modération et gestion de la base de données (version publiée uniquement).
Modifiez ce panneau pour mettre à jour la page d'accueil.
{p.name || 'Brouillon'}
{owner ? (owner.name || owner.email) : 'Client inconnu'}
{p.name || 'Brouillon'}
{owner ? (owner.name || owner.email) : 'Client inconnu'}
{p.name || 'Sans nom'}
{owner ? (owner.name || owner.email) : 'Client inconnu'}
Mots sensibles détectés dans le panneau : {moderationTarget.panneau.name}
{moderationTarget.detected.black.length > 0 && (Liste noire : {moderationTarget.detected.black.join(', ')}
)} {moderationTarget.detected.grey.length > 0 && (Liste grise : {moderationTarget.detected.grey.join(', ')}
)}Actions de modération rapides :