import React, { useState, useEffect } from 'react'; import { Button, Card, CardContent, Typography, Container, Box } from '@mui/material'; import Swal from 'sweetalert2/dist/sweetalert2.js'; import 'sweetalert2/src/sweetalert2.scss'; // Components import Navbar from '../ComponentUtils/Headers/Navbar'; import Footer from '../ComponentUtils/Footer'; import MultiImageDropzone from '../ComponentUtils/MultiUpload/MultiImageDropzone'; import ImageGallery from '../ComponentUtils/ImageGallery'; import DescriptionInput from '../ComponentUtils/MultiUpload/DescriptionInput'; import UploadProgress from '../ComponentUtils/MultiUpload/UploadProgress'; import Loading from '../ComponentUtils/LoadingAnimation/Loading'; import ConsentCheckboxes from '../ComponentUtils/MultiUpload/ConsentCheckboxes'; // Utils import { uploadImageBatch } from '../../Utils/batchUpload'; // Styles import '../../App.css'; // Background.css is now globally imported in src/index.js // Styles migrated to MUI sx props in-place below function MultiUploadPage() { const [selectedImages, setSelectedImages] = useState([]); const [metadata, setMetadata] = useState({ year: new Date().getFullYear(), title: '', description: '', name: '' }); const [consents, setConsents] = useState({ workshopConsent: false, socialMediaConsents: [] }); const [uploading, setUploading] = useState(false); const [uploadProgress, setUploadProgress] = useState(0); const [uploadComplete, setUploadComplete] = useState(false); const [uploadResult, setUploadResult] = useState(null); const [isEditMode, setIsEditMode] = useState(false); const [imageDescriptions, setImageDescriptions] = useState({}); // Cleanup object URLs when component unmounts useEffect(() => { return () => { selectedImages.forEach(img => { if (img.url && img.url.startsWith('blob:')) { URL.revokeObjectURL(img.url); } }); }; }, [selectedImages]); const handleImagesSelected = (newImages) => { console.log('handleImagesSelected called with:', newImages); // Convert File objects to preview objects with URLs const imageObjects = newImages.map((file, index) => ({ id: `preview-${Date.now()}-${index}`, // Unique ID für Preview-Modus file: file, // Original File object for upload url: URL.createObjectURL(file), // Preview URL name: file.name, originalName: file.name, size: file.size, type: file.type })); setSelectedImages(prev => { const updated = [...prev, ...imageObjects]; return updated; }); }; const handleRemoveImage = (indexToRemove) => { setSelectedImages(prev => { const imageToRemove = prev[indexToRemove]; // Clean up the object URL to avoid memory leaks if (imageToRemove && imageToRemove.url && imageToRemove.url.startsWith('blob:')) { URL.revokeObjectURL(imageToRemove.url); } return prev.filter((_, index) => index !== indexToRemove); }); }; const handleClearAll = () => { // Clean up all object URLs selectedImages.forEach(img => { if (img.url && img.url.startsWith('blob:')) { URL.revokeObjectURL(img.url); } }); setSelectedImages([]); setMetadata({ year: new Date().getFullYear(), title: '', description: '', name: '' }); setConsents({ workshopConsent: false, socialMediaConsents: [] }); setImageDescriptions({}); setIsEditMode(false); }; // Handle drag-and-drop reordering (only updates local state, no API call) const handleReorder = (reorderedItems) => { console.log('Reordering images in preview:', reorderedItems); setSelectedImages(reorderedItems); }; // Handle edit mode toggle const handleEditMode = (enabled) => { setIsEditMode(enabled); }; // Handle description changes const handleDescriptionChange = (imageId, description) => { setImageDescriptions(prev => ({ ...prev, [imageId]: description.slice(0, 200) // Enforce max length })); }; const handleUpload = async () => { if (selectedImages.length === 0) { Swal.fire({ icon: 'warning', title: 'Keine Bilder ausgewählt', text: 'Bitte wählen Sie mindestens ein Bild zum Upload aus.', confirmButtonColor: '#4CAF50' }); return; } if (!metadata.year || !metadata.title.trim()) { Swal.fire({ icon: 'warning', title: 'Pflichtfelder fehlen', text: 'Bitte gebe das Jahr und den Titel an.', confirmButtonColor: '#4CAF50' }); return; } // GDPR: Validate workshop consent (mandatory) if (!consents.workshopConsent) { Swal.fire({ icon: 'error', title: 'Einwilligung erforderlich', text: 'Die Zustimmung zur Anzeige in der Werkstatt ist erforderlich.', confirmButtonColor: '#f44336' }); return; } setUploading(true); setUploadProgress(0); try { // Simuliere Progress (da wir noch keinen echten Progress haben) const progressInterval = setInterval(() => { setUploadProgress(prev => { if (prev >= 90) { clearInterval(progressInterval); return 90; } return prev + 10; }); }, 200); // Extract the actual File objects from our image objects const filesToUpload = selectedImages.map(img => img.file || img); // Prepare descriptions array for backend const descriptionsArray = selectedImages.map(img => ({ fileName: img.name, description: imageDescriptions[img.id] || '' })); const result = await uploadImageBatch(filesToUpload, metadata, descriptionsArray, consents); clearInterval(progressInterval); setUploadProgress(100); // Show success content setTimeout(() => { setUploadComplete(true); setUploadResult(result); }, 500); } catch (error) { setUploading(false); console.error('Upload error:', error); Swal.fire({ icon: 'error', title: 'Upload fehlgeschlagen', text: error.message || 'Ein Fehler ist beim Upload aufgetreten.', confirmButtonColor: '#f44336' }); } }; return (