import React, { useState, useEffect } from 'react'; import { useParams, useNavigate } from 'react-router-dom'; import { Container, Card, CardContent, Typography, Box, Button } from '@mui/material'; import Swal from 'sweetalert2'; import NavbarUpload from '../ComponentUtils/Headers/NavbarUpload'; import Footer from '../ComponentUtils/Footer'; import Loading from '../ComponentUtils/LoadingAnimation/Loading'; import ImageGalleryCard from '../ComponentUtils/ImageGalleryCard'; import ConsentBadges from '../ComponentUtils/ConsentBadges'; import MultiImageDropzone from '../ComponentUtils/MultiUpload/MultiImageDropzone'; import ImageDescriptionManager from '../ComponentUtils/ImageDescriptionManager'; import GroupMetadataEditor from '../ComponentUtils/GroupMetadataEditor'; import ConsentManager from '../ComponentUtils/ConsentManager'; import DeleteGroupButton from '../ComponentUtils/DeleteGroupButton'; /** * ManagementPortalPage - Self-service management for uploaded groups * * Modulare Struktur mit individuellen Komponenten: * - ImageDescriptionManager: Bildbeschreibungen bearbeiten * - GroupMetadataEditor: Gruppenmetadaten bearbeiten * - ConsentManager: Einwilligungen verwalten * - DeleteGroupButton: Gruppe löschen */ function ManagementPortalPage() { const { token } = useParams(); const navigate = useNavigate(); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [group, setGroup] = useState(null); // Load group data const loadGroup = async () => { try { setLoading(true); setError(null); const res = await fetch(`/api/manage/${token}`); if (res.status === 404) { setError('Ungültiger oder abgelaufener Verwaltungslink'); return; } if (res.status === 429) { setError('Zu viele Anfragen. Bitte versuchen Sie es später erneut.'); return; } if (!res.ok) { throw new Error('Fehler beim Laden der Gruppe'); } const response = await res.json(); const data = response.data || response; // Transform data const transformedData = { ...data, displayInWorkshop: data.displayInWorkshop || data.display_in_workshop, consentTimestamp: data.consentTimestamp || data.consent_timestamp, consents: { workshopConsent: (data.displayInWorkshop === 1 || data.display_in_workshop === 1), socialMediaConsents: (data.socialMediaConsents || []) .filter(c => c.consented === 1 && c.revoked === 0) .map(c => ({ platformId: c.platform_id, consented: true })) }, metadata: { year: data.year || new Date().getFullYear(), title: data.title || '', description: data.description || '', name: data.name || '' }, images: (data.images || []).map(img => ({ ...img, remoteUrl: `/download/${img.fileName}`, originalName: img.originalName || img.fileName, id: img.id, imageDescription: img.imageDescription || '' })) }; setGroup(transformedData); } catch (e) { console.error('Error loading group:', e); setError('Fehler beim Laden der Gruppe'); } finally { setLoading(false); } }; useEffect(() => { if (token) { loadGroup(); } }, [token]); // eslint-disable-line react-hooks/exhaustive-deps // Handle adding new images const handleImagesSelected = async (newImages) => { try { const formData = new FormData(); newImages.forEach(file => { formData.append('images', file); }); const res = await fetch(`/api/manage/${token}/images`, { method: 'POST', body: formData }); if (!res.ok) { const body = await res.json().catch(() => ({})); throw new Error(body.error || 'Fehler beim Hochladen'); } await Swal.fire({ icon: 'success', title: 'Bilder hinzugefügt', text: `${newImages.length} Bild(er) wurden erfolgreich hinzugefügt.`, timer: 2000, showConfirmButton: false }); // Reload group data await loadGroup(); } catch (error) { console.error('Error adding images:', error); Swal.fire({ icon: 'error', title: 'Fehler', text: error.message || 'Bilder konnten nicht hinzugefügt werden' }); } }; const handleReorder = async (newOrder) => { if (!group || !group.groupId) { console.error('No groupId available for reordering'); return; } try { const imageIds = newOrder.map(img => img.id); // Use token-based management API const response = await fetch(`/api/manage/${token}/reorder`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ imageIds: imageIds }) }); if (!response.ok) { throw new Error('Reihenfolge konnte nicht gespeichert werden'); } await Swal.fire({ icon: 'success', title: 'Gespeichert', text: 'Die neue Reihenfolge wurde gespeichert.', timer: 1500, showConfirmButton: false }); await loadGroup(); } catch (error) { console.error('Error reordering images:', error); Swal.fire({ icon: 'error', title: 'Fehler', text: error.message || 'Reihenfolge konnte nicht gespeichert werden' }); } }; if (loading) { return (