refactor(frontend): migrate SlideshowPage to MUI sx

This commit is contained in:
Matthias Lotz 2025-10-29 21:41:02 +01:00
parent 182dcb228c
commit 5b4855a5f5

View File

@ -1,6 +1,5 @@
import React, { useState, useEffect, useCallback } from 'react';
import { useNavigate } from 'react-router-dom';
import { makeStyles } from '@mui/styles';
import {
Typography,
Box,
@ -15,99 +14,9 @@ import {
// 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'
}
});
// Styles moved inline to sx props below
function SlideshowPage() {
const classes = useStyles();
const navigate = useNavigate();
const [allGroups, setAllGroups] = useState([]);
@ -203,27 +112,54 @@ function SlideshowPage() {
const currentGroup = allGroups[currentGroupIndex];
const currentImage = currentGroup?.images?.[currentImageIndex];
const fullscreenSx = {
position: 'fixed',
top: 0,
left: 0,
width: '100%',
height: '100%',
backgroundColor: '#000',
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
zIndex: 9999,
overflow: 'hidden'
};
const loadingContainerSx = {
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
color: 'white'
};
if (loading) {
return (
<Box className={classes.fullscreenContainer}>
<Box className={classes.loadingContainer}>
<CircularProgress style={{ color: 'white', marginBottom: '20px' }} />
<Typography style={{ color: 'white' }}>Slideshow wird geladen...</Typography>
<Box sx={fullscreenSx}>
<Box sx={loadingContainerSx}>
<CircularProgress sx={{ color: 'white', mb: 2 }} />
<Typography sx={{ color: 'white' }}>Slideshow wird geladen...</Typography>
</Box>
</Box>
);
}
const homeButtonSx = {
position: 'absolute',
top: '20px',
left: '20px',
color: 'white',
backgroundColor: 'rgba(0,0,0,0.5)',
'&:hover': { backgroundColor: 'rgba(0,0,0,0.8)' }
};
if (error) {
return (
<Box className={classes.fullscreenContainer}>
<Box className={classes.loadingContainer}>
<Typography style={{ color: 'white', fontSize: '24px' }}>{error}</Typography>
<IconButton
className={classes.homeButton}
onClick={() => navigate('/')}
title="Zur Startseite"
>
<Box sx={fullscreenSx}>
<Box sx={loadingContainerSx}>
<Typography sx={{ color: 'white', fontSize: '24px' }}>{error}</Typography>
<IconButton sx={homeButtonSx} onClick={() => navigate('/')} title="Zur Startseite">
<HomeIcon />
</IconButton>
</Box>
@ -233,16 +169,10 @@ function SlideshowPage() {
if (!currentGroup || !currentImage) {
return (
<Box className={classes.fullscreenContainer}>
<Box className={classes.loadingContainer}>
<Typography style={{ color: 'white', fontSize: '24px' }}>
Keine Bilder verfügbar
</Typography>
<IconButton
className={classes.homeButton}
onClick={() => navigate('/')}
title="Zur Startseite"
>
<Box sx={fullscreenSx}>
<Box sx={loadingContainerSx}>
<Typography sx={{ color: 'white', fontSize: '24px' }}>Keine Bilder verfügbar</Typography>
<IconButton sx={homeButtonSx} onClick={() => navigate('/')} title="Zur Startseite">
<HomeIcon />
</IconButton>
</Box>
@ -250,61 +180,69 @@ function SlideshowPage() {
);
}
const exitButtonSx = {
position: 'absolute',
top: '20px',
right: '20px',
color: 'white',
backgroundColor: 'rgba(0,0,0,0.5)',
'&:hover': { backgroundColor: 'rgba(0,0,0,0.8)' }
};
const slideshowImageSx = {
maxWidth: '100%',
maxHeight: '100%',
objectFit: 'contain',
transition: `opacity ${TRANSITION_TIME}ms ease-in-out`
};
const descriptionContainerSx = {
position: 'fixed',
left: 40,
bottom: 40,
backgroundColor: 'rgba(0,0,0,0.8)',
p: '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)'
};
const titleTextSx = { color: 'white', fontSize: '28px', fontWeight: 500, mb: 1, fontFamily: 'roboto' };
const yearAuthorTextSx = { color: '#FFD700', fontSize: '18px', fontWeight: 400, mb: 1, fontFamily: 'roboto' };
const descriptionTextSx = { color: '#E0E0E0', fontSize: '16px', fontWeight: 300, mb: 1, fontFamily: 'roboto', lineHeight: 1.4 };
const metaTextSx = { color: '#999', fontSize: '12px', mt: 1, fontFamily: 'roboto' };
return (
<Box className={classes.fullscreenContainer}>
<Box sx={fullscreenSx}>
{/* Navigation Buttons */}
<IconButton
className={classes.homeButton}
onClick={() => navigate('/')}
title="Zur Startseite"
>
<IconButton sx={homeButtonSx} onClick={() => navigate('/')} title="Zur Startseite">
<HomeIcon />
</IconButton>
<IconButton
className={classes.exitButton}
onClick={() => navigate('/')}
title="Slideshow beenden"
>
<IconButton sx={exitButtonSx} onClick={() => navigate('/')} title="Slideshow beenden">
<ExitIcon />
</IconButton>
{/* Hauptbild */}
<img
src={`/api${currentImage.filePath}`}
alt={currentImage.originalName}
className={classes.slideshowImage}
style={{
opacity: fadeOut ? 0 : 1,
transition: `opacity ${TRANSITION_TIME}ms ease-in-out`
}}
/>
<Box component="img" src={`/api${currentImage.filePath}`} alt={currentImage.originalName} sx={{ ...slideshowImageSx, opacity: fadeOut ? 0 : 1 }} />
{/* Beschreibung */}
<Box className={classes.descriptionContainer}>
<Box sx={descriptionContainerSx}>
{/* Titel */}
<Typography className={classes.titleText}>
{currentGroup.title || 'Unbenanntes Projekt'}
</Typography>
<Typography sx={titleTextSx}>{currentGroup.title || 'Unbenanntes Projekt'}</Typography>
{/* Jahr und Name */}
<Typography className={classes.yearAuthorText}>
{currentGroup.year}
{currentGroup.name && `${currentGroup.name}`}
</Typography>
<Typography sx={yearAuthorTextSx}>{currentGroup.year}{currentGroup.name && `${currentGroup.name}`}</Typography>
{/* Beschreibung (wenn vorhanden) */}
{currentGroup.description && (
<Typography className={classes.descriptionText}>
{currentGroup.description}
</Typography>
)}
{currentGroup.description && <Typography sx={descriptionTextSx}>{currentGroup.description}</Typography>}
{/* Meta-Informationen */}
<Typography className={classes.metaText}>
Bild {currentImageIndex + 1} von {currentGroup.images.length}
Slideshow {currentGroupIndex + 1} von {allGroups.length}
</Typography>
<Typography sx={metaTextSx}>Bild {currentImageIndex + 1} von {currentGroup.images.length} Slideshow {currentGroupIndex + 1} von {allGroups.length}</Typography>
</Box>
</Box>
);