diff --git a/frontend/src/App.css b/frontend/src/App.css index 62f742b..e378fee 100644 --- a/frontend/src/App.css +++ b/frontend/src/App.css @@ -1,5 +1,193 @@ /* Main shared styles for cards, buttons, modals used across pages */ +/* ============================================ + TYPOGRAPHY - Zentrale Schrift-Definitionen + ============================================ */ +body { + font-family: 'Open Sans', sans-serif; + color: #333333; + line-height: 1.6; +} + +h1, .h1 { + font-family: 'Open Sans', sans-serif; + font-weight: 500; + font-size: 28px; + color: #333333; + margin-bottom: 10px; +} + +h2, .h2 { + font-family: 'Open Sans', sans-serif; + font-weight: 500; + font-size: 24px; + color: #333333; + margin-bottom: 15px; +} + +h3, .h3 { + font-family: 'Open Sans', sans-serif; + font-weight: 500; + font-size: 20px; + color: #333333; + margin-bottom: 12px; +} + +p, .text-body { + font-family: 'Open Sans', sans-serif; + font-weight: 400; + font-size: 16px; + color: #666666; + margin-bottom: 16px; +} + +.text-subtitle { + font-family: 'Open Sans', sans-serif; + font-weight: 300; + font-size: 16px; + color: #666666; +} + +.text-small { + font-size: 14px; + color: #666666; +} + +.text-center { text-align: center; } +.text-left { text-align: left; } +.text-right { text-align: right; } + +/* ============================================ + LAYOUT & CONTAINERS + ============================================ */ +.container { + max-width: 1200px; + margin: 0 auto; + padding: 20px; +} + +.card { + background: white; + border-radius: 12px; + box-shadow: 0 4px 12px rgba(0,0,0,0.1); + padding: 20px; + margin-bottom: 20px; +} + +.card-content { + padding: 20px; +} + +/* ============================================ + PAGE HEADERS + ============================================ */ +.page-header { + text-align: center; + margin-bottom: 30px; +} + +.page-title { + font-family: 'Open Sans', sans-serif; + font-weight: 500; + font-size: 28px; + color: #333333; + text-align: center; + margin-bottom: 10px; +} + +.page-subtitle { + font-family: 'Open Sans', sans-serif; + font-weight: 300; + font-size: 16px; + color: #666666; + text-align: center; + margin-bottom: 30px; +} + +/* ============================================ + UTILITY CLASSES + ============================================ */ +.flex-center { + display: flex; + gap: 15px; + justify-content: center; + flex-wrap: wrap; + margin-top: 30px; +} + +.text-center-block { + text-align: center; + padding: 40px 0; +} + +/* Spacing utilities */ +.mt-1 { margin-top: 8px; } +.mt-2 { margin-top: 16px; } +.mt-3 { margin-top: 24px; } +.mt-4 { margin-top: 32px; } +.mb-1 { margin-bottom: 8px; } +.mb-2 { margin-bottom: 16px; } +.mb-3 { margin-bottom: 24px; } +.mb-4 { margin-bottom: 32px; } +.p-2 { padding: 16px; } +.p-3 { padding: 24px; } + +/* ============================================ + SUCCESS BOX (Upload Success) + ============================================ */ +.success-box { + margin-top: 32px; + padding: 24px; + border-radius: 12px; + background: linear-gradient(135deg, #4CAF50 0%, #45a049 100%); + color: white; + box-shadow: 0 4px 20px rgba(76, 175, 80, 0.4); + animation: slideIn 0.5s ease-out; +} + +@keyframes slideIn { + from { + opacity: 0; + transform: translateY(-20px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +.success-box h2 { + font-size: 28px; + font-weight: bold; + margin-bottom: 8px; + color: white; +} + +.success-box p { + font-size: 18px; + margin-bottom: 16px; + color: white; +} + +.info-box { + background: rgba(255,255,255,0.2); + border-radius: 8px; + padding: 16px; + margin-bottom: 16px; +} + +.info-box-highlight { + background: rgba(255,255,255,0.95); + border-radius: 8px; + padding: 20px; + margin-bottom: 16px; + border: 2px solid rgba(255,255,255,0.3); +} + +/* ============================================ + EXISTING STYLES BELOW + ============================================ */ + /* Page-specific styles for GroupsOverviewPage */ .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; } @@ -52,7 +240,7 @@ p { font-family: 'Open Sans', sans-serif; color:#555; line-height:1.6; } } /* 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 { padding:12px 30px; border:none; border-radius:6px; cursor:pointer; font-size:16px; transition:background-color 0.2s; min-width:80px; } .btn-secondary { background:#6c757d; color:white; } .btn-secondary:hover { background:#5a6268; } .btn-outline-secondary { background:transparent; border:1px solid #6c757d; color:#6c757d; } @@ -63,7 +251,6 @@ p { font-family: 'Open Sans', sans-serif; color:#555; line-height:1.6; } .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; } .btn:disabled { opacity:0.65; cursor:not-allowed; } /* Modal */ @@ -104,3 +291,32 @@ p { font-family: 'Open Sans', sans-serif; color:#555; line-height:1.6; } .admin-auth-card { width:100%; max-width:420px; box-shadow:0 8px 24px rgba(0,0,0,0.08); } .admin-auth-form { width:100%; } .admin-auth-error { max-width:420px; background:#fff3f3; border:1px solid #ffcdd2; padding:24px; border-radius:12px; text-align:center; color:#b71c1c; } + +/* ============================================ + MATERIAL-UI OVERRIDES - Globale Schriftart + ============================================ */ +/* TextField, Input, Textarea */ +.MuiTextField-root input, +.MuiTextField-root textarea, +.MuiInputBase-root, +.MuiInputBase-input, +.MuiOutlinedInput-input { + font-family: 'Open Sans', sans-serif !important; +} + +/* Labels */ +.MuiFormLabel-root, +.MuiInputLabel-root, +.MuiTypography-root { + font-family: 'Open Sans', sans-serif !important; +} + +/* Buttons */ +.MuiButton-root { + font-family: 'Open Sans', sans-serif !important; +} + +/* Checkbox Labels */ +.MuiFormControlLabel-label { + font-family: 'Open Sans', sans-serif !important; +} diff --git a/frontend/src/Components/ComponentUtils/Css/ImageGallery.css b/frontend/src/Components/ComponentUtils/Css/ImageGallery.css index 9b22860..5b207a7 100644 --- a/frontend/src/Components/ComponentUtils/Css/ImageGallery.css +++ b/frontend/src/Components/ComponentUtils/Css/ImageGallery.css @@ -111,7 +111,9 @@ background: #f8f9fa; display: flex; gap: 8px; - flex-wrap: wrap; + flex-wrap: wrap; + flex-direction: column; + margin-top: auto; } /* ImageGalleryCard - No preview state */ diff --git a/frontend/src/Components/ComponentUtils/GroupMetadataEditor.js b/frontend/src/Components/ComponentUtils/GroupMetadataEditor.js index 4e603b0..f74c22c 100644 --- a/frontend/src/Components/ComponentUtils/GroupMetadataEditor.js +++ b/frontend/src/Components/ComponentUtils/GroupMetadataEditor.js @@ -144,7 +144,7 @@ function GroupMetadataEditor({ > {/* Component Header */} - 📝 Projekt-Informationen + Projekt-Informationen - + {!isEditMode ? ( - + ) : ( - + )} ) : ( // Moderation mode actions (for existing groups) <> - + {isPending ? ( - + ) : ( - + )} - + ) ) : mode !== 'single-image' ? ( // Public view mode (only for group cards, not single images) - + ) : null} )} diff --git a/frontend/src/Components/ComponentUtils/MultiUpload/DescriptionInput.js b/frontend/src/Components/ComponentUtils/MultiUpload/DescriptionInput.js index fe0470d..87d8a79 100644 --- a/frontend/src/Components/ComponentUtils/MultiUpload/DescriptionInput.js +++ b/frontend/src/Components/ComponentUtils/MultiUpload/DescriptionInput.js @@ -17,7 +17,6 @@ function DescriptionInput({ const currentYear = new Date().getFullYear(); const fieldLabelSx = { - fontFamily: 'roboto', fontSize: '14px', color: '#555555', marginBottom: '8px', @@ -25,7 +24,6 @@ function DescriptionInput({ }; const sectionTitleSx = { - fontFamily: 'roboto', fontSize: '18px', color: '#333333', marginBottom: '15px', @@ -68,7 +66,7 @@ function DescriptionInput({ }; const requiredIndicatorSx = { color: '#E57373', fontSize: '16px' }; - const optionalIndicatorSx = { color: '#9E9E9E', fontSize: '12px', fontStyle: 'italic' }; + const optionalIndicatorSx = { color: '#9E9E9E', fontSize: '12px' }; return ( diff --git a/frontend/src/Components/ComponentUtils/MultiUpload/MultiImageDropzone.js b/frontend/src/Components/ComponentUtils/MultiUpload/MultiImageDropzone.js index a19244c..5cc1a6b 100644 --- a/frontend/src/Components/ComponentUtils/MultiUpload/MultiImageDropzone.js +++ b/frontend/src/Components/ComponentUtils/MultiUpload/MultiImageDropzone.js @@ -77,15 +77,13 @@ function MultiImageDropzone({ onImagesSelected, selectedImages = [] }) { const dropzoneTextSx = { fontSize: '18px', - fontFamily: 'roboto', color: '#666666', margin: '10px 0' }; const dropzoneSubtextSx = { fontSize: '14px', - color: '#999999', - fontFamily: 'roboto' + color: '#999999' }; const fileCountSx = { @@ -106,7 +104,7 @@ function MultiImageDropzone({ onImagesSelected, selectedImages = [] }) { onClick={handleClick} > - 📸 Mehrere Bilder hier hinziehen oder klicken zum Auswählen + Mehrere Bilder hier hinziehen oder klicken zum Auswählen diff --git a/frontend/src/Components/Pages/GroupsOverviewPage.js b/frontend/src/Components/Pages/GroupsOverviewPage.js index 4594f1f..9f852cc 100644 --- a/frontend/src/Components/Pages/GroupsOverviewPage.js +++ b/frontend/src/Components/Pages/GroupsOverviewPage.js @@ -1,13 +1,6 @@ import { useState, useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; import { Helmet } from 'react-helmet'; -import { - Container, - Card, - Typography, - Box, - CircularProgress -} from '@mui/material'; @@ -63,14 +56,14 @@ function GroupsOverviewPage() { return (
- -
- - - Slideshows werden geladen... - +
+
+
+
+

Slideshows werden geladen...

+
- +
); @@ -86,53 +79,39 @@ function GroupsOverviewPage() { - +
{/* Header */} - - - Alle Slideshows - - - Übersicht aller erstellten Slideshows. - - +
+

Alle Slideshows

+

Übersicht aller erstellten Slideshows.

+
{/* Groups Grid */} {error ? ( -
- - 😕 Fehler beim Laden - - - {error} - +
+

😕 Fehler beim Laden

+

{error}

) : groups.length === 0 ? ( -
- - 📸 Keine Slideshows vorhanden - - +
+

📸 Keine Slideshows vorhanden

+

Erstellen Sie Ihre erste Slideshow, indem Sie mehrere Bilder hochladen. - -

) : ( <> - - - 📊 {groups.length} Slideshow{groups.length !== 1 ? 's' : ''} gefunden - - +
+

+ {groups.length} Slideshow{groups.length !== 1 ? 's' : ''} gefunden +

+
handleViewGroup(group.groupId)} @@ -142,7 +121,7 @@ function GroupsOverviewPage() { /> )} - +
diff --git a/frontend/src/Components/Pages/ManagementPortalPage.js b/frontend/src/Components/Pages/ManagementPortalPage.js index acca180..8f2d066 100644 --- a/frontend/src/Components/Pages/ManagementPortalPage.js +++ b/frontend/src/Components/Pages/ManagementPortalPage.js @@ -1,6 +1,5 @@ import React, { useState, useEffect } from 'react'; import { useParams, useNavigate } from 'react-router-dom'; -import { Container, Card, CardContent, Typography, Box, Button } from '@mui/material'; import Swal from 'sweetalert2'; import NavbarUpload from '../ComponentUtils/Headers/NavbarUpload'; import Footer from '../ComponentUtils/Footer'; @@ -180,9 +179,9 @@ function ManagementPortalPage() { return (
- +
- +
); @@ -192,19 +191,15 @@ function ManagementPortalPage() { return (
- - - - {error} - - - {error} - - - - + +
+
); @@ -214,19 +209,17 @@ function ManagementPortalPage() {
- - - - - Mein Upload verwalten - - +
+
+
+

Mein Upload verwalten

+

Hier können Sie Ihre hochgeladenen Bilder verwalten, Metadaten bearbeiten und Einwilligungen ändern. - +

{/* Group Overview */} {group && ( - +
- - - Erteilte Einwilligungen: - +
+

Erteilte Einwilligungen:

- - +
+
)} {/* Add Images Dropzone */} - - - Weitere Bilder hinzufügen - +
+

Weitere Bilder hinzufügen

- +
{/* Image Descriptions Manager */} {group && group.images && group.images.length > 0 && ( - +
- +
)} {/* Group Metadata Editor */} {group && ( - +
- +
)} {/* Consent Manager */} {group && ( - +
- +
)} {/* Delete Group Button */} {group && ( - +
- +
)} - - - +
+
+
diff --git a/frontend/src/Components/Pages/ModerationGroupImagesPage.js b/frontend/src/Components/Pages/ModerationGroupImagesPage.js index 6402da2..2c20c45 100644 --- a/frontend/src/Components/Pages/ModerationGroupImagesPage.js +++ b/frontend/src/Components/Pages/ModerationGroupImagesPage.js @@ -1,6 +1,5 @@ import React, { useState, useEffect, useCallback } from 'react'; import { useParams, useNavigate } from 'react-router-dom'; -import { Container, Box } from '@mui/material'; // Services import { adminGet } from '../../services/adminApi'; @@ -81,7 +80,7 @@ const ModerationGroupImagesPage = () => {
- +
{/* Image Descriptions Manager */} { /> {/* Back Button */} - +
- - +
+
diff --git a/frontend/src/Components/Pages/ModerationGroupsPage.js b/frontend/src/Components/Pages/ModerationGroupsPage.js index fc3994a..45b59a9 100644 --- a/frontend/src/Components/Pages/ModerationGroupsPage.js +++ b/frontend/src/Components/Pages/ModerationGroupsPage.js @@ -1,7 +1,6 @@ import React, { useState, useEffect } from 'react'; import { Helmet } from 'react-helmet'; import { useNavigate } from 'react-router-dom'; -import { Container, Box, FormControl, FormLabel, FormGroup, FormControlLabel, Checkbox, Typography } from '@mui/material'; import FilterListIcon from '@mui/icons-material/FilterList'; import Swal from 'sweetalert2/dist/sweetalert2.js'; @@ -268,23 +267,14 @@ const ModerationGroupsPage = () => { - - - - Moderation - - +
+
+

Moderation

+
{user?.username && ( - +

Eingeloggt als {user.username} - +

)} - - +
+
@@ -314,79 +304,65 @@ const ModerationGroupsPage = () => {
{/* Filter und Export Controls */} - - - - +
+
+ + Consent-Filter - - - setConsentFilters({...consentFilters, workshop: e.target.checked})} - size="small" - /> - } - label="Werkstatt" - /> - setConsentFilters({...consentFilters, facebook: e.target.checked})} - size="small" - /> - } - label="Facebook" - /> - setConsentFilters({...consentFilters, instagram: e.target.checked})} - size="small" - /> - } - label="Instagram" - /> - setConsentFilters({...consentFilters, tiktok: e.target.checked})} - size="small" - /> - } - label="TikTok" - /> - - + +
+ + + + +
+
- +
{/* Wartende Gruppen */}
{
{ onDeleteImage={deleteImage} /> )} - +
); @@ -471,7 +447,7 @@ const ImageModal = ({ group, onClose, onDeleteImage }) => {
{image.originalName} @@ -231,14 +226,10 @@ function MultiUploadPage() { - +
)} @@ -254,85 +245,58 @@ function MultiUploadPage() { /> ) : ( - - +
+

✅ Upload erfolgreich! - - +

+

{uploadResult?.imageCount || 0} Bild{uploadResult?.imageCount === 1 ? '' : 'er'} {uploadResult?.imageCount === 1 ? 'wurde' : 'wurden'} hochgeladen. - +

- - +
+

Ihre Referenz-Nummer: - - +

+

{uploadResult?.groupId} - - +

+

Notieren Sie sich diese Nummer für spätere Anfragen an das Team. - - +

+
{uploadResult?.managementToken && ( - - +
+

🔗 Verwaltungslink für Ihren Upload - - +

+

Mit diesem Link können Sie später Ihre Bilder verwalten, Einwilligungen widerrufen oder die Gruppe löschen: - +

- - {window.location.origin}/manage/{uploadResult.managementToken} - +

-
+
- +

⚠️ Wichtig: Bewahren Sie diesen Link sicher auf! Jeder mit diesem Link kann Ihren Upload verwalten. - - +

+

ℹ️ Hinweis: Über diesen Link können Sie nur die Bilder in der Werkstatt verwalten. Bereits auf Social Media Plattformen veröffentlichte Bilder müssen separat dort gelöscht werden. - - +

+
)} - +

Die Bilder werden geprüft und nach Freigabe auf dem Werkstatt-Monitor angezeigt. {' '}Bei Social Media Einwilligung werden sie entsprechend veröffentlicht. - +

- +

Fragen oder Widerruf? Kontakt: it@hobbyhimmel.de - +

-
+
)}
)} - - - +
+
+