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 React, { useState, useEffect, useCallback } from 'react';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { makeStyles } from '@mui/styles';
|
|
||||||
import {
|
import {
|
||||||
Typography,
|
Typography,
|
||||||
Box,
|
Box,
|
||||||
|
|
@ -15,99 +14,9 @@ import {
|
||||||
// Utils
|
// Utils
|
||||||
import { fetchAllGroups } from '../../Utils/batchUpload';
|
import { fetchAllGroups } from '../../Utils/batchUpload';
|
||||||
|
|
||||||
const useStyles = makeStyles({
|
// Styles moved inline to sx props below
|
||||||
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() {
|
function SlideshowPage() {
|
||||||
const classes = useStyles();
|
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
const [allGroups, setAllGroups] = useState([]);
|
const [allGroups, setAllGroups] = useState([]);
|
||||||
|
|
@ -203,27 +112,54 @@ function SlideshowPage() {
|
||||||
const currentGroup = allGroups[currentGroupIndex];
|
const currentGroup = allGroups[currentGroupIndex];
|
||||||
const currentImage = currentGroup?.images?.[currentImageIndex];
|
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) {
|
if (loading) {
|
||||||
return (
|
return (
|
||||||
<Box className={classes.fullscreenContainer}>
|
<Box sx={fullscreenSx}>
|
||||||
<Box className={classes.loadingContainer}>
|
<Box sx={loadingContainerSx}>
|
||||||
<CircularProgress style={{ color: 'white', marginBottom: '20px' }} />
|
<CircularProgress sx={{ color: 'white', mb: 2 }} />
|
||||||
<Typography style={{ color: 'white' }}>Slideshow wird geladen...</Typography>
|
<Typography sx={{ color: 'white' }}>Slideshow wird geladen...</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
</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) {
|
if (error) {
|
||||||
return (
|
return (
|
||||||
<Box className={classes.fullscreenContainer}>
|
<Box sx={fullscreenSx}>
|
||||||
<Box className={classes.loadingContainer}>
|
<Box sx={loadingContainerSx}>
|
||||||
<Typography style={{ color: 'white', fontSize: '24px' }}>{error}</Typography>
|
<Typography sx={{ color: 'white', fontSize: '24px' }}>{error}</Typography>
|
||||||
<IconButton
|
<IconButton sx={homeButtonSx} onClick={() => navigate('/')} title="Zur Startseite">
|
||||||
className={classes.homeButton}
|
|
||||||
onClick={() => navigate('/')}
|
|
||||||
title="Zur Startseite"
|
|
||||||
>
|
|
||||||
<HomeIcon />
|
<HomeIcon />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
@ -233,16 +169,10 @@ function SlideshowPage() {
|
||||||
|
|
||||||
if (!currentGroup || !currentImage) {
|
if (!currentGroup || !currentImage) {
|
||||||
return (
|
return (
|
||||||
<Box className={classes.fullscreenContainer}>
|
<Box sx={fullscreenSx}>
|
||||||
<Box className={classes.loadingContainer}>
|
<Box sx={loadingContainerSx}>
|
||||||
<Typography style={{ color: 'white', fontSize: '24px' }}>
|
<Typography sx={{ color: 'white', fontSize: '24px' }}>Keine Bilder verfügbar</Typography>
|
||||||
Keine Bilder verfügbar
|
<IconButton sx={homeButtonSx} onClick={() => navigate('/')} title="Zur Startseite">
|
||||||
</Typography>
|
|
||||||
<IconButton
|
|
||||||
className={classes.homeButton}
|
|
||||||
onClick={() => navigate('/')}
|
|
||||||
title="Zur Startseite"
|
|
||||||
>
|
|
||||||
<HomeIcon />
|
<HomeIcon />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Box>
|
</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 (
|
return (
|
||||||
<Box className={classes.fullscreenContainer}>
|
<Box sx={fullscreenSx}>
|
||||||
{/* Navigation Buttons */}
|
{/* Navigation Buttons */}
|
||||||
<IconButton
|
<IconButton sx={homeButtonSx} onClick={() => navigate('/')} title="Zur Startseite">
|
||||||
className={classes.homeButton}
|
|
||||||
onClick={() => navigate('/')}
|
|
||||||
title="Zur Startseite"
|
|
||||||
>
|
|
||||||
<HomeIcon />
|
<HomeIcon />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
|
|
||||||
<IconButton
|
<IconButton sx={exitButtonSx} onClick={() => navigate('/')} title="Slideshow beenden">
|
||||||
className={classes.exitButton}
|
|
||||||
onClick={() => navigate('/')}
|
|
||||||
title="Slideshow beenden"
|
|
||||||
>
|
|
||||||
<ExitIcon />
|
<ExitIcon />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
|
|
||||||
{/* Hauptbild */}
|
{/* Hauptbild */}
|
||||||
<img
|
<Box component="img" src={`/api${currentImage.filePath}`} alt={currentImage.originalName} sx={{ ...slideshowImageSx, opacity: fadeOut ? 0 : 1 }} />
|
||||||
src={`/api${currentImage.filePath}`}
|
|
||||||
alt={currentImage.originalName}
|
|
||||||
className={classes.slideshowImage}
|
|
||||||
style={{
|
|
||||||
opacity: fadeOut ? 0 : 1,
|
|
||||||
transition: `opacity ${TRANSITION_TIME}ms ease-in-out`
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{/* Beschreibung */}
|
{/* Beschreibung */}
|
||||||
<Box className={classes.descriptionContainer}>
|
<Box sx={descriptionContainerSx}>
|
||||||
{/* Titel */}
|
{/* Titel */}
|
||||||
<Typography className={classes.titleText}>
|
<Typography sx={titleTextSx}>{currentGroup.title || 'Unbenanntes Projekt'}</Typography>
|
||||||
{currentGroup.title || 'Unbenanntes Projekt'}
|
|
||||||
</Typography>
|
|
||||||
|
|
||||||
{/* Jahr und Name */}
|
{/* Jahr und Name */}
|
||||||
<Typography className={classes.yearAuthorText}>
|
<Typography sx={yearAuthorTextSx}>{currentGroup.year}{currentGroup.name && ` • ${currentGroup.name}`}</Typography>
|
||||||
{currentGroup.year}
|
|
||||||
{currentGroup.name && ` • ${currentGroup.name}`}
|
|
||||||
</Typography>
|
|
||||||
|
|
||||||
{/* Beschreibung (wenn vorhanden) */}
|
{/* Beschreibung (wenn vorhanden) */}
|
||||||
{currentGroup.description && (
|
{currentGroup.description && <Typography sx={descriptionTextSx}>{currentGroup.description}</Typography>}
|
||||||
<Typography className={classes.descriptionText}>
|
|
||||||
{currentGroup.description}
|
|
||||||
</Typography>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* Meta-Informationen */}
|
{/* Meta-Informationen */}
|
||||||
<Typography className={classes.metaText}>
|
<Typography sx={metaTextSx}>Bild {currentImageIndex + 1} von {currentGroup.images.length} • Slideshow {currentGroupIndex + 1} von {allGroups.length}</Typography>
|
||||||
Bild {currentImageIndex + 1} von {currentGroup.images.length} •
|
|
||||||
Slideshow {currentGroupIndex + 1} von {allGroups.length}
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user