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 */}
{/* 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;