CSS Anpassungen, noch nicht gut

This commit is contained in:
Matthias Lotz 2025-10-19 21:59:37 +02:00
parent e06625ba97
commit bf4ff75ce5
9 changed files with 109 additions and 332 deletions

View File

@ -0,0 +1,76 @@
/* Main shared styles for cards, buttons, modals used across pages */
/* Group Card */
.group-card {
background: white;
border-radius: 12px;
overflow: hidden;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
transition: transform 0.2s, box-shadow 0.2s;
}
/* Make cards use column layout so image + content align and cards stretch uniformly */
.group-card { display: flex; flex-direction: column; }
.group-card:hover { transform: translateY(-2px); box-shadow: 0 4px 16px rgba(0,0,0,0.15); }
.group-card.pending { border-left: 5px solid #ffc107; }
.group-card.approved { border-left: 5px solid #28a745; }
.group-preview { position: relative; height: 200px; background: #f8f9fa; }
.preview-image { width: 100%; height: 100%; object-fit: cover; }
/* Support legacy class used by GroupsOverviewPage (CardMedia with class 'group-image') */
.group-card .group-image { width: 100%; height: 200px; object-fit: cover; display: block; }
/* Ensure content area expands to fill remaining space */
.group-content { flex-grow: 1; display: flex; flex-direction: column; }
/* Utility classes to replace inline styles for consistent sizing */
.grid-item-stretch { display: flex; }
.card-stretch { display: flex; flex-direction: column; height: 100%; }
.no-preview { display:flex; align-items:center; justify-content:center; height:100%; color:#6c757d; font-style:italic; }
.image-count { position:absolute; top:10px; right:10px; background:rgba(0,0,0,0.7); color:white; padding:4px 8px; border-radius:12px; font-size:0.8rem; }
.group-info { padding:15px; }
.group-info h3 { margin:0 0 10px 0; color:#333; }
.group-meta { color:#007bff; font-weight:500; margin:5px 0; }
.group-description { color:#6c757d; font-size:0.9rem; margin:8px 0; line-height:1.4; }
.upload-date { color:#6c757d; font-size:0.8rem; margin:10px 0 0 0; }
.group-actions { padding:15px; background:#f8f9fa; display:flex; gap:8px; flex-wrap:wrap; }
/* Buttons */
.btn { padding:8px 12px; border:none; border-radius:6px; cursor:pointer; font-size:0.85rem; transition:background-color 0.2s; flex:1; min-width:80px; }
.btn-secondary { background:#6c757d; color:white; }
.btn-secondary:hover { background:#5a6268; }
.btn-success { background:#28a745; color:white; }
.btn-success:hover { background:#218838; }
.btn-warning { background:#ffc107; color:#212529; }
.btn-warning:hover { background:#e0a800; }
.btn-danger { background:#dc3545; color:white; }
.btn-danger:hover { background:#c82333; }
.btn-sm { padding:4px 8px; font-size:0.75rem; min-width:auto; }
/* Modal */
.image-modal-overlay { position:fixed; top:0; left:0; right:0; bottom:0; background:rgba(0,0,0,0.8); display:flex; align-items:center; justify-content:center; z-index:1000; padding:20px; }
.image-modal { background:white; border-radius:12px; max-width:90vw; max-height:90vh; overflow:hidden; display:flex; flex-direction:column; }
.modal-header { display:flex; justify-content:space-between; align-items:center; padding:20px; border-bottom:1px solid #e9ecef; background:#f8f9fa; }
.modal-header h2 { margin:0; color:#333; }
.close-btn { background:none; border:none; font-size:2rem; cursor:pointer; color:#6c757d; padding:0; width:40px; height:40px; display:flex; align-items:center; justify-content:center; }
.close-btn:hover { color:#333; }
.modal-body { padding:20px; overflow-y:auto; }
.group-details { background:#f8f9fa; padding:15px; border-radius:8px; margin-bottom:20px; }
.group-details p { margin:5px 0; }
.images-grid { display:grid; grid-template-columns:repeat(auto-fit, minmax(200px, 1fr)); gap:15px; }
.image-item { background:#f8f9fa; border-radius:8px; overflow:hidden; position:relative; }
.modal-image { width:100%; height:150px; object-fit:cover; display:block; }
.image-actions { padding:10px; display:flex; justify-content:space-between; align-items:center; background:white; }
.image-name { font-size:0.8rem; color:#6c757d; flex:1; margin-right:10px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
@media (max-width:768px) {
.moderation-stats { flex-direction:column; gap:20px; }
.groups-grid { grid-template-columns:1fr; }
.group-actions { flex-direction:column; }
.btn { width:100%; }
.image-modal { max-width:95vw; max-height:95vh; }
.images-grid { grid-template-columns:repeat(auto-fit, minmax(150px,1fr)); }
}
/* Standard groups grid used by moderation and overview pages */
.groups-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 20px; }

View File

@ -96,21 +96,18 @@ function ImagePreviewGallery({ images, onRemoveImage, onReorderImages }) {
Vorschau ({images.length} Bild{images.length !== 1 ? 'er' : ''})
</Typography>
<Grid container spacing={2}>
<Grid container spacing={2} alignItems="stretch">
{images.map((image, index) => (
<Grid item xs={12} sm={6} md={4} lg={3} key={index}>
<Card className={classes.imageCard}>
<CardMedia
component="img"
className={classes.imageMedia}
image={
// If image is a File-like object, create an object URL.
// If it's a remote image descriptor, use its remoteUrl or url field.
image && image.remoteUrl ? image.remoteUrl : image && image.url ? image.url : URL.createObjectURL(image)
}
alt={`Vorschau ${index + 1}`}
/>
<Grid item xs={12} sm={6} md={4} lg={3} key={index} className="grid-item-stretch">
<Card className={`group-card ${classes.imageCard} card-stretch`}>
<div className="group-preview">
<img
className="preview-image"
src={image && image.remoteUrl ? image.remoteUrl : image && image.url ? image.url : URL.createObjectURL(image)}
alt={`Vorschau ${index + 1}`}
/>
</div>
<IconButton
className={classes.removeButton}
size="small"
@ -119,7 +116,7 @@ function ImagePreviewGallery({ images, onRemoveImage, onReorderImages }) {
>
<CloseIcon fontSize="small" />
</IconButton>
<IconButton
className={classes.dragHandle}
size="small"
@ -127,11 +124,11 @@ function ImagePreviewGallery({ images, onRemoveImage, onReorderImages }) {
>
<DragIcon fontSize="small" />
</IconButton>
<div className={classes.imageOrder}>
{index + 1}
</div>
<div className={classes.fileName} title={`${image.name || image.originalName || ''} ${image.size ? ' • ' + formatFileSize(image.size) : ''}`}>
{image.name || image.originalName || 'Bild'}{image.size ? ' • ' + formatFileSize(image.size) : ''}
</div>

View File

@ -11,3 +11,10 @@ body { margin: 0; font-family: Roboto, Arial, sans-serif; background: #fff; }
/* Reset common element spacing to keep consistent top spacing */
h1, h2, h3, h4, h5 { margin-top: 0; }
/* Unified page container used by all pages */
.page-container {
padding-top: 20px;
padding-bottom: 40px;
min-height: 80vh;
}

View File

@ -1,6 +1,3 @@
/* Copied from ComponentUtils/Css/GroupImagesPage.css and moved to Pages/Css */
.group-images-container { padding-top: 20px; padding-bottom: 40px; min-height: 80vh; }
.group-card { border-radius: 12px; box-shadow: 0 4px 12px rgba(0,0,0,0.1); padding: 20px; margin-bottom: 20px; }
.header-text { font-family: roboto; font-weight: 400; font-size: 28px; text-align: center; margin-bottom: 10px; color: #333333; }
.subheader-text { font-family: roboto; font-weight: 300; font-size: 16px; color: #666666; text-align: center; margin-bottom: 30px; }
.action-buttons { display: flex; gap: 15px; justify-content: center; margin-top: 20px; flex-wrap: wrap; }

View File

@ -1,20 +1,6 @@
/* Copied from ComponentUtils/Css/GroupsOverviewPage.css and moved to Pages/Css */
.groups-overview-container { padding-top: 20px; padding-bottom: 40px; min-height: 80vh; }
.header-card { border-radius: 12px; box-shadow: 0 4px 12px rgba(0,0,0,0.1); margin-bottom: 30px; text-align: center; padding: 20px; }
.header-title { font-family: roboto; font-weight: 500; font-size: 28px; color: #333333; margin-bottom: 10px; }
.header-subtitle { font-family: roboto; font-size: 16px; color: #666666; margin-bottom: 20px; }
.group-card { border-radius: 12px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); transition: all 0.3s ease; height: 100%; display: flex; flex-direction: column; }
.group-card:hover { transform: translateY(-4px); box-shadow: 0 8px 20px rgba(0,0,0,0.15); }
.group-image { height: 180px; object-fit: cover; }
.group-content { flex-grow: 1; display: flex; flex-direction: column; }
.group-title { font-family: roboto; font-weight: 500; font-size: 16px; color: #333333; margin-bottom: 8px; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.group-meta { font-size: 12px; color: #999999; margin-bottom: 15px; }
.group-actions { margin-top: auto; display: flex; gap: 8px; justify-content: space-between; }
.view-button { border-radius: 20px; text-transform: none; font-size: 12px; padding: 6px 16px; background: linear-gradient(45deg, #4CAF50 30%, #45a049 90%); color: white; }
.view-button:hover { background: linear-gradient(45deg, #45a049 30%, #4CAF50 90%); }
.action-buttons { display:flex; gap:15px; justify-content:center; flex-wrap: wrap; margin-top:20px; }
.primary-button { border-radius: 25px; padding: 12px 30px; font-size:16px; font-weight:500; text-transform:none; background: linear-gradient(45deg, #2196F3 30%, #1976D2 90%); color:white; }
.home-button { border-radius:25px; padding:12px 30px; font-size:16px; font-weight:500; text-transform:none; border:2px solid #4CAF50; color:#4CAF50; background-color: transparent; }
.empty-state { text-align:center; padding:60px 20px; }
.loading-container { text-align:center; padding:60px 20px; }
@media (max-width:800px) { .nav__links, .cta { display:none; } }

View File

@ -73,288 +73,4 @@
display: grid;
grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
gap: 20px;
}
/* Group Card */
.group-card {
background: white;
border-radius: 12px;
overflow: hidden;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
transition: transform 0.2s, box-shadow 0.2s;
}
.group-card:hover {
transform: translateY(-2px);
box-shadow: 0 4px 16px rgba(0,0,0,0.15);
}
.group-card.pending {
border-left: 5px solid #ffc107;
}
.group-card.approved {
border-left: 5px solid #28a745;
}
.group-preview {
position: relative;
height: 200px;
background: #f8f9fa;
}
.preview-image {
width: 100%;
height: 100%;
object-fit: cover;
}
.no-preview {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
color: #6c757d;
font-style: italic;
}
.image-count {
position: absolute;
top: 10px;
right: 10px;
background: rgba(0,0,0,0.7);
color: white;
padding: 4px 8px;
border-radius: 12px;
font-size: 0.8rem;
}
.group-info {
padding: 15px;
}
.group-info h3 {
margin: 0 0 10px 0;
color: #333;
}
.group-meta {
color: #007bff;
font-weight: 500;
margin: 5px 0;
}
.group-description {
color: #6c757d;
font-size: 0.9rem;
margin: 8px 0;
line-height: 1.4;
}
.upload-date {
color: #6c757d;
font-size: 0.8rem;
margin: 10px 0 0 0;
}
.group-actions {
padding: 15px;
background: #f8f9fa;
display: flex;
gap: 8px;
flex-wrap: wrap;
}
/* Buttons */
.btn {
padding: 8px 12px;
border: none;
border-radius: 6px;
cursor: pointer;
font-size: 0.85rem;
transition: background-color 0.2s;
flex: 1;
min-width: 80px;
}
.btn-secondary {
background: #6c757d;
color: white;
}
.btn-secondary:hover {
background: #5a6268;
}
.btn-success {
background: #28a745;
color: white;
}
.btn-success:hover {
background: #218838;
}
.btn-warning {
background: #ffc107;
color: #212529;
}
.btn-warning:hover {
background: #e0a800;
}
.btn-danger {
background: #dc3545;
color: white;
}
.btn-danger:hover {
background: #c82333;
}
.btn-sm {
padding: 4px 8px;
font-size: 0.75rem;
min-width: auto;
}
/* Image Modal */
.image-modal-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0,0,0,0.8);
display: flex;
align-items: center;
justify-content: center;
z-index: 1000;
padding: 20px;
}
.image-modal {
background: white;
border-radius: 12px;
max-width: 90vw;
max-height: 90vh;
overflow: hidden;
display: flex;
flex-direction: column;
}
.modal-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 20px;
border-bottom: 1px solid #e9ecef;
background: #f8f9fa;
}
.modal-header h2 {
margin: 0;
color: #333;
}
.close-btn {
background: none;
border: none;
font-size: 2rem;
cursor: pointer;
color: #6c757d;
padding: 0;
width: 40px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
}
.close-btn:hover {
color: #333;
}
.modal-body {
padding: 20px;
overflow-y: auto;
}
.group-details {
background: #f8f9fa;
padding: 15px;
border-radius: 8px;
margin-bottom: 20px;
}
.group-details p {
margin: 5px 0;
}
.images-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 15px;
}
.image-item {
background: #f8f9fa;
border-radius: 8px;
overflow: hidden;
position: relative;
}
.modal-image {
width: 100%;
height: 150px;
object-fit: cover;
display: block;
}
.image-actions {
padding: 10px;
display: flex;
justify-content: space-between;
align-items: center;
background: white;
}
.image-name {
font-size: 0.8rem;
color: #6c757d;
flex: 1;
margin-right: 10px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* Responsive */
@media (max-width: 768px) {
.moderation-stats {
flex-direction: column;
gap: 20px;
}
.groups-grid {
grid-template-columns: 1fr;
}
.group-actions {
flex-direction: column;
}
.btn {
width: 100%;
}
.image-modal {
max-width: 95vw;
max-height: 95vh;
}
.images-grid {
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}
}

View File

@ -135,7 +135,7 @@ const GroupImagesPage = () => {
<div className="allContainer">
<Navbar />
<Container maxWidth="lg" className="group-images-container">
<Container maxWidth="lg" className="page-container">
<Card className="group-card">
<CardContent>
<Typography className="header-text">Gruppe bearbeiten</Typography>

View File

@ -81,7 +81,7 @@ function GroupsOverviewPage() {
return (
<div className="allContainer">
<Navbar />
<Container maxWidth="lg" className="groups-overview-container">
<Container maxWidth="lg" className="page-container">
<div className="loading-container">
<CircularProgress size={60} color="primary" />
<Typography variant="h6" style={{ marginTop: '20px', color: '#666666' }}>
@ -104,7 +104,7 @@ function GroupsOverviewPage() {
</Helmet>
<Navbar />
<Container maxWidth="lg" className="groups-overview-container">
<Container maxWidth="lg" className="page-container">
{/* Header */}
<Card className="header-card">
<Typography className="header-title">
@ -172,19 +172,16 @@ function GroupsOverviewPage() {
</Typography>
</Box>
<Grid container spacing={3}>
<div className="groups-grid">
{groups.map((group) => (
<Grid item xs={12} sm={6} md={4} key={group.groupId}>
<Card className="group-card">
<Grid item xs={12} sm={6} md={4} key={group.groupId} className="grid-item-stretch">
<Card className="group-card card-stretch">
{group.images && group.images.length > 0 && (
<CardMedia
component="img"
className="group-image"
image={group.images[0].filePath}
alt={group.description || 'Slideshow Vorschau'}
/>
<div className="group-preview">
<img className="preview-image" src={group.images[0].filePath} alt={group.description || 'Slideshow Vorschau'} />
</div>
)}
<CardContent className="group-content">
<Typography className="group-title">
{group.description || 'Unbenannte Slideshow'}
@ -208,7 +205,7 @@ function GroupsOverviewPage() {
</Card>
</Grid>
))}
</Grid>
</div>
</>
)}
</Container>

View File

@ -2,6 +2,7 @@ import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import './Components/Pages/Css/Background.css';
import './Components/ComponentUtils/Css/main.css';
ReactDOM.render(
<React.StrictMode>