refactor(frontend): migrate SlideshowPage to MUI sx
This commit is contained in:
parent
182dcb228c
commit
5b4855a5f5
|
|
@ -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>
|
||||
);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user