import React, { useState, useEffect } from 'react'; import { Helmet } from 'react-helmet'; import { useNavigate } from 'react-router-dom'; import { Container, Box, FormControl, InputLabel, Select, MenuItem } from '@mui/material'; import FilterListIcon from '@mui/icons-material/FilterList'; import Swal from 'sweetalert2/dist/sweetalert2.js'; // Services import { adminGet, adminRequest, adminDownload } from '../../services/adminApi'; import { handleAdminError } from '../../services/adminErrorHandler'; // Components import Navbar from '../ComponentUtils/Headers/Navbar'; import Footer from '../ComponentUtils/Footer'; import ImageGallery from '../ComponentUtils/ImageGallery'; import DeletionLogSection from '../ComponentUtils/DeletionLogSection'; import ConsentBadges from '../ComponentUtils/ConsentBadges'; import { getImageSrc } from '../../Utils/imageUtils'; const ModerationGroupsPage = () => { const [groups, setGroups] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [selectedGroup, setSelectedGroup] = useState(null); const [showImages, setShowImages] = useState(false); const [consentFilter, setConsentFilter] = useState('all'); const [platforms, setPlatforms] = useState([]); const navigate = useNavigate(); useEffect(() => { loadModerationGroups(); loadPlatforms(); }, []); useEffect(() => { loadModerationGroups(); }, [consentFilter]); const loadPlatforms = async () => { try { const data = await adminGet('/api/admin/social-media/platforms'); setPlatforms(data); } catch (error) { await handleAdminError(error, 'Plattformen laden'); } }; const loadModerationGroups = async () => { try { setLoading(true); // Build URL with filter params let url = '/api/admin/groups'; const params = new URLSearchParams(); if (consentFilter !== 'all') { if (consentFilter === 'workshop-only') { params.append('workshopOnly', 'true'); } else { // Platform filter (facebook, instagram, tiktok) params.append('platform', consentFilter); } } if (params.toString()) { url += '?' + params.toString(); } const data = await adminGet(url); setGroups(data.groups); } catch (error) { await handleAdminError(error, 'Moderations-Gruppen laden'); setError('Fehler beim Laden der Gruppen'); } finally { setLoading(false); } }; const approveGroup = async (groupId, approved) => { try { await adminRequest( `/api/admin/groups/${groupId}/approve`, 'PATCH', { approved: approved } ); // Update local state setGroups(groups.map(group => group.groupId === groupId ? { ...group, approved: approved } : group )); // Success feedback await Swal.fire({ icon: 'success', title: approved ? 'Gruppe freigegeben' : 'Freigabe zurückgezogen', text: approved ? 'Die Gruppe ist jetzt öffentlich sichtbar.' : 'Die Gruppe wurde zurück in "Wartend" verschoben.', timer: 2000, showConfirmButton: false }); } catch (error) { await handleAdminError(error, 'Gruppe freigeben'); await Swal.fire({ icon: 'error', title: 'Fehler', text: 'Fehler beim Freigeben der Gruppe: ' + error.message }); } }; const deleteImage = async (groupId, imageId) => { console.log('deleteImage called with:', { groupId, imageId }); console.log('API_URL:', window._env_.API_URL); try { // Use admin API endpoint const url = `/api/admin/groups/${groupId}/images/${imageId}`; console.log('DELETE request to:', url); await adminRequest(url, 'DELETE'); // Remove image from selectedGroup if (selectedGroup && selectedGroup.groupId === groupId) { const updatedImages = selectedGroup.images.filter(img => img.id !== imageId); setSelectedGroup({ ...selectedGroup, images: updatedImages, imageCount: updatedImages.length }); } // Update group image count setGroups(groups.map(group => group.groupId === groupId ? { ...group, imageCount: group.imageCount - 1 } : group )); } catch (error) { await handleAdminError(error, 'Bild löschen'); } }; const deleteGroup = async (groupId) => { if (!window.confirm('Gruppe wirklich löschen? Diese Aktion kann nicht rückgängig gemacht werden.')) { return; } try { await adminRequest(`/api/admin/groups/${groupId}`, 'DELETE'); setGroups(groups.filter(group => group.groupId !== groupId)); if (selectedGroup && selectedGroup.groupId === groupId) { setSelectedGroup(null); setShowImages(false); } } catch (error) { await handleAdminError(error, 'Gruppe löschen'); } }; // Navigate to the dedicated group images page const viewGroupImages = (group) => { navigate(`/moderation/groups/${group.groupId}`); }; const exportConsentData = async () => { try { const blob = await adminDownload('/api/admin/consents/export?format=csv'); const url = window.URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = `consent-export-${new Date().toISOString().split('T')[0]}.csv`; document.body.appendChild(a); a.click(); document.body.removeChild(a); window.URL.revokeObjectURL(url); await Swal.fire({ icon: 'success', title: 'Export erfolgreich', text: 'Consent-Daten wurden als CSV heruntergeladen.', timer: 2000, showConfirmButton: false }); } catch (error) { await handleAdminError(error, 'Consent-Export'); }); } }; if (loading) { return
Lade Gruppen...
; } if (error) { return
{error}
; } const pendingGroups = groups.filter(g => !g.approved); const approvedGroups = groups.filter(g => g.approved); return (
Moderation - Interne Verwaltung

Moderation

{pendingGroups.length} Wartend
{approvedGroups.length} Freigegeben
{groups.length} Gesamt
{/* Filter und Export Controls */} Consent-Filter {/* Wartende Gruppen */}
{/* Freigegebene Gruppen */}
{/* Lösch-Historie */}
{/* Bilder-Modal */} {showImages && selectedGroup && ( { setShowImages(false); setSelectedGroup(null); }} onDeleteImage={deleteImage} /> )}
); }; // `GroupCard` has been extracted to `../ComponentUtils/GroupCard` const ImageModal = ({ group, onClose, onDeleteImage }) => { return (
e.stopPropagation()}>

{group.title}

Jahr: {group.year}

Ersteller: {group.name}

{group.description && (

Beschreibung: {group.description}

)}

Bilder: {group.images.length}

{group.images.map(image => (
{image.originalName}
{image.originalName}
))}
); }; export default ModerationGroupsPage;