import React, { useState, useEffect, useCallback } from 'react'; import { useNavigate } from 'react-router-dom'; import { makeStyles } from '@mui/styles'; import { Typography, Box, CircularProgress, IconButton } from '@mui/material'; import { Home as HomeIcon, ExitToApp as ExitIcon } from '@mui/icons-material'; // Utils import { fetchAllGroups } from '../../Utils/batchUpload'; const useStyles = makeStyles({ fullscreenContainer: { position: 'fixed', top: 0, left: 0, width: '100%', height: '100%', backgroundColor: '#000', display: 'flex', flexDirection: 'column', justifyContent: 'center', alignItems: 'center', zIndex: 9999, overflow: 'hidden' }, exitButton: { position: 'absolute', top: '20px', right: '20px', color: 'white', backgroundColor: 'rgba(0,0,0,0.5)', '&:hover': { backgroundColor: 'rgba(0,0,0,0.8)' } }, homeButton: { position: 'absolute', top: '20px', left: '20px', color: 'white', backgroundColor: 'rgba(0,0,0,0.5)', '&:hover': { backgroundColor: 'rgba(0,0,0,0.8)' } }, slideshowImage: { maxWidth: '100%', maxHeight: '100%', objectFit: 'contain', transition: 'opacity 0.5s ease-in-out' }, descriptionContainer: { position: 'fixed', left: 40, bottom: 40, backgroundColor: 'rgba(0,0,0,0.8)', padding: '25px 35px', borderRadius: '12px', maxWidth: '35vw', minWidth: '260px', textAlign: 'left', backdropFilter: 'blur(5px)', zIndex: 10001, boxShadow: '0 4px 24px rgba(0,0,0,0.4)' }, titleText: { color: 'white', fontSize: '28px', fontWeight: '500', margin: '0 0 8px 0', fontFamily: 'roboto' }, yearAuthorText: { color: '#FFD700', fontSize: '18px', fontWeight: '400', margin: '0 0 12px 0', fontFamily: 'roboto' }, descriptionText: { color: '#E0E0E0', fontSize: '16px', fontWeight: '300', margin: '0 0 12px 0', fontFamily: 'roboto', lineHeight: '1.4' }, metaText: { color: '#999', fontSize: '12px', marginTop: '8px', fontFamily: 'roboto' }, loadingContainer: { display: 'flex', flexDirection: 'column', alignItems: 'center', color: 'white' } }); function SlideshowPage() { const classes = useStyles(); const navigate = useNavigate(); const [allGroups, setAllGroups] = useState([]); const [currentGroupIndex, setCurrentGroupIndex] = useState(0); const [currentImageIndex, setCurrentImageIndex] = useState(0); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [fadeOut, setFadeOut] = useState(false); // Slideshow-Timing Konstanten const IMAGE_DISPLAY_TIME = 4000; // 4 Sekunden pro Bild const TRANSITION_TIME = 500; // 0.5 Sekunden für Fade-Effekt // Gruppen laden useEffect(() => { const loadAllGroups = async () => { try { setLoading(true); const groupsData = await fetchAllGroups(); if (groupsData.groups && groupsData.groups.length > 0) { // Mische die Gruppen zufällig const shuffledGroups = [...groupsData.groups].sort(() => Math.random() - 0.5); setAllGroups(shuffledGroups); setCurrentGroupIndex(0); setCurrentImageIndex(0); } else { setError('Keine Slideshows gefunden'); } } catch (err) { console.error('Fehler beim Laden der Gruppen:', err); setError('Fehler beim Laden der Slideshows'); } finally { setLoading(false); } }; loadAllGroups(); }, []); // Automatischer Slideshow-Wechsel const nextImage = useCallback(() => { if (allGroups.length === 0) return; const currentGroup = allGroups[currentGroupIndex]; if (!currentGroup || !currentGroup.images) return; setFadeOut(true); setTimeout(() => { if (currentImageIndex + 1 < currentGroup.images.length) { // Nächstes Bild in der aktuellen Gruppe setCurrentImageIndex(prev => prev + 1); } else { // Zur nächsten Gruppe wechseln (zufällig) const nextGroupIndex = Math.floor(Math.random() * allGroups.length); setCurrentGroupIndex(nextGroupIndex); setCurrentImageIndex(0); } setFadeOut(false); }, TRANSITION_TIME); }, [allGroups, currentGroupIndex, currentImageIndex]); // Timer für automatischen Wechsel useEffect(() => { if (loading || error || allGroups.length === 0) return; const timer = setInterval(nextImage, IMAGE_DISPLAY_TIME); return () => clearInterval(timer); }, [loading, error, allGroups, nextImage]); // Keyboard-Navigation useEffect(() => { const handleKeyPress = (event) => { switch (event.key) { case 'Escape': navigate('/'); break; case ' ': case 'ArrowRight': nextImage(); break; default: break; } }; document.addEventListener('keydown', handleKeyPress); return () => document.removeEventListener('keydown', handleKeyPress); }, [nextImage, navigate]); // Aktuelle Gruppe und Bild const currentGroup = allGroups[currentGroupIndex]; const currentImage = currentGroup?.images?.[currentImageIndex]; if (loading) { return ( Slideshow wird geladen... ); } if (error) { return ( {error} navigate('/')} title="Zur Startseite" > ); } if (!currentGroup || !currentImage) { return ( Keine Bilder verfügbar navigate('/')} title="Zur Startseite" > ); } return ( {/* Navigation Buttons */} navigate('/')} title="Zur Startseite" > navigate('/')} title="Slideshow beenden" > {/* Hauptbild */} {currentImage.originalName} {/* Beschreibung */} {/* Titel */} {currentGroup.title || 'Unbenanntes Projekt'} {/* Jahr und Name */} {currentGroup.year} {currentGroup.name && ` • ${currentGroup.name}`} {/* Beschreibung (wenn vorhanden) */} {currentGroup.description && ( {currentGroup.description} )} {/* Meta-Informationen */} Bild {currentImageIndex + 1} von {currentGroup.images.length} • Slideshow {currentGroupIndex + 1} von {allGroups.length} ); } export default SlideshowPage;