fix: Link in Groups bei leeren Gruppen falsch

This commit is contained in:
Matthias Lotz 2025-11-22 14:07:15 +01:00
parent 98b3616dc4
commit 6574ee0171
15 changed files with 85 additions and 146 deletions

View File

@ -10,14 +10,14 @@
## 🎯 Funktionale Anforderungen ## 🎯 Funktionale Anforderungen
### Must-Have ### Must-Have
- [ ] **Automatische Löschung**: Gruppen mit `approved = false` werden nach 7 Tagen ab Upload-Zeitpunkt gelöscht - [x] **Automatische Löschung**: Gruppen mit `approved = false` werden nach 7 Tagen ab Upload-Zeitpunkt gelöscht
- [ ] **Vollständige Löschung**: Datenbank-Einträge, Originalbilder und Preview-Bilder werden entfernt - [x] **Vollständige Löschung**: Datenbank-Einträge, Originalbilder und Preview-Bilder werden entfernt
- [ ] **Cron-Job**: Tägliche Ausführung um 10:00 Uhr morgens - [x] **Cron-Job**: Tägliche Ausführung um 10:00 Uhr morgens
- [ ] **Deletion Log**: Protokollierung gelöschter Gruppen in eigener Datenbanktabelle - [x] **Deletion Log**: Protokollierung gelöschter Gruppen in eigener Datenbanktabelle
- [ ] **Anonymisierung**: Keine personenbezogenen Daten (Titel, Name, Beschreibung) im Log - [x] **Anonymisierung**: Keine personenbezogenen Daten (Titel, Name, Beschreibung) im Log
- [ ] **Countdown-Anzeige**: In ModerationPage wird Restzeit bis zur Löschung angezeigt - [x] **Countdown-Anzeige**: In ModerationPage wird Restzeit bis zur Löschung angezeigt
- [ ] **Admin-Übersicht**: Geschützter Bereich in ModerationPage für Lösch-Historie - [x] **Admin-Übersicht**: Geschützter Bereich in ModerationPage für Lösch-Historie
- [ ] **Freigabe-Schutz**: Freigegebene Gruppen (`approved = true`) werden niemals automatisch gelöscht - [x] **Freigabe-Schutz**: Freigegebene Gruppen (`approved = true`) werden niemals automatisch gelöscht
### Nice-to-Have ### Nice-to-Have
- [ ] **Manuelle Verzögerung**: Admin kann Löschfrist verlängern (z.B. um weitere 7 Tage) - [ ] **Manuelle Verzögerung**: Admin kann Löschfrist verlängern (z.B. um weitere 7 Tage)

View File

@ -506,94 +506,94 @@ export const uploadImageBatch = async (files, metadata, descriptions = []) => {
### Manuelle Tests ### Manuelle Tests
- [ ] Upload mehrerer Bilder mit verschiedenen Beschreibungen - [x] Upload mehrerer Bilder mit verschiedenen Beschreibungen
- [ ] Upload ohne Beschreibungen - [x] Upload ohne Beschreibungen
- [ ] Bearbeiten bestehender Gruppen - [x] Bearbeiten bestehender Gruppen
- [ ] Slideshow mit Beschreibungen testen - [x] Slideshow mit Beschreibungen testen
- [ ] Mobile-Ansicht testen - [ ] Mobile-Ansicht testen
- [ ] Performance mit vielen Bildern testen - [x] Performance mit vielen Bildern testen
--- ---
## 📝 Implementation TODO ## 📝 Implementation TODO
### Phase 1: Backend Foundation ✅ ### Phase 1: Backend Foundation ✅
- [ ] **Task 1.1:** Datenbank-Migration erstellen - [x] **Task 1.1:** Datenbank-Migration erstellen
- [ ] `004_add_image_description.sql` erstellen - [x] `004_add_image_description.sql` erstellen
- [ ] Migration in `DatabaseManager.js` registrieren - [x] Migration in `DatabaseManager.js` registrieren
- [ ] Lokale DB testen - [ x Lokale DB testen
- [ ] **Task 1.2:** Repository-Layer erweitern - [x] **Task 1.2:** Repository-Layer erweitern
- [ ] `updateImageDescription()` in `GroupRepository.js` - [x] `updateImageDescription()` in `GroupRepository.js`
- [ ] `updateBatchImageDescriptions()` in `GroupRepository.js` - [x] `updateBatchImageDescriptions()` in `GroupRepository.js`
- [ ] `getImagesByGroupId()` erweitern für `image_description` - [x] `getImagesByGroupId()` erweitern für `image_description`
- [ ] **Task 1.3:** API-Routes implementieren - [x] **Task 1.3:** API-Routes implementieren
- [ ] `PATCH /groups/:groupId/images/:imageId` in `routes/groups.js` - [x] `PATCH /groups/:groupId/images/:imageId` in `routes/groups.js`
- [ ] `PATCH /groups/:groupId/images/batch-description` in `routes/groups.js` - [x] `PATCH /groups/:groupId/images/batch-description` in `routes/groups.js`
- [ ] Validierung hinzufügen (max 200 Zeichen) - [x] Validierung hinzufügen (max 200 Zeichen)
- [ ] GET Routes erweitern (image_description returnen) - [x] GET Routes erweitern (image_description returnen)
- [ ] **Task 1.4:** Upload-Route erweitern - [x] **Task 1.4:** Upload-Route erweitern
- [ ] `batchUpload.js` Route akzeptiert `descriptions` Parameter - [x] `batchUpload.js` Route akzeptiert `descriptions` Parameter
- [ ] Speichere Beschreibungen beim Upload - [x] Speichere Beschreibungen beim Upload
- [ ] Backward-Kompatibilität testen - [x] Backward-Kompatibilität testen
### Phase 2: Frontend Core Components ✅ ### Phase 2: Frontend Core Components ✅
- [ ] **Task 2.1:** ImageGalleryCard.js anpassen - [x] **Task 2.1:** ImageGalleryCard.js anpassen
- [ ] "Sort" Button durch "Edit" Button ersetzen - [x] "Sort" Button durch "Edit" Button ersetzen
- [ ] Edit-Modus UI implementieren (Textarea) - [x] Edit-Modus UI implementieren (Textarea)
- [ ] Props hinzufügen: `isEditMode`, `onEditMode`, `imageDescription`, `onDescriptionChange` - [x] Props hinzufügen: `isEditMode`, `onEditMode`, `imageDescription`, `onDescriptionChange`
- [ ] Zeichenzähler implementieren - [x] Zeichenzähler implementieren
- [ ] Validierung (max 200 Zeichen) - [x] Validierung (max 200 Zeichen)
- [ ] **Task 2.2:** ImageGallery.js erweitern - [x] **Task 2.2:** ImageGallery.js erweitern
- [ ] Neue Props durchreichen - [x] Neue Props durchreichen
- [ ] Edit-Modus State-Management - [x] Edit-Modus State-Management
- [ ] **Task 2.3:** CSS-Styles hinzufügen - [x] **Task 2.3:** CSS-Styles hinzufügen
- [ ] `ImageGallery.css` erweitern - [x] `ImageGallery.css` erweitern
- [ ] Textarea-Styles - [x] Textarea-Styles
- [ ] Zeichenzähler-Styles - [x] Zeichenzähler-Styles
- [ ] Edit-Button-Styles - [x] Edit-Button-Styles
- [ ] Mobile-Optimierung - [x] Mobile-Optimierung
### Phase 3: Upload Flow Integration ✅ ### Phase 3: Upload Flow Integration ✅
- [ ] **Task 3.1:** MultiUploadPage.js erweitern - [x] **Task 3.1:** MultiUploadPage.js erweitern
- [ ] State für Edit-Modus hinzufügen - [x] State für Edit-Modus hinzufügen
- [ ] State für Beschreibungen hinzufügen - [x] State für Beschreibungen hinzufügen
- [ ] Handler für Edit-Modus implementieren - [x] Handler für Edit-Modus implementieren
- [ ] Handler für Beschreibungsänderungen implementieren - [x] Handler für Beschreibungsänderungen implementieren
- [ ] Upload-Logik erweitern (Beschreibungen mitschicken) - [x] Upload-Logik erweitern (Beschreibungen mitschicken)
- [ ] Edit-Mode Toggle UI hinzufügen - [x] Edit-Mode Toggle UI hinzufügen
- [ ] **Task 3.2:** batchUpload.js erweitern - [x] **Task 3.2:** batchUpload.js erweitern
- [ ] Funktionssignatur anpassen (descriptions Parameter) - [x] Funktionssignatur anpassen (descriptions Parameter)
- [ ] FormData um Beschreibungen erweitern - [x] FormData um Beschreibungen erweitern
- [ ] Error-Handling - [x] Error-Handling
### Phase 4: Moderation Integration ✅ ### Phase 4: Moderation Integration ✅
- [ ] **Task 4.1:** ModerationGroupImagesPage.js erweitern - [x] **Task 4.1:** ModerationGroupImagesPage.js erweitern
- [ ] State für Edit-Modus hinzufügen - [x] State für Edit-Modus hinzufügen
- [ ] State für Beschreibungen hinzufügen - [x] State für Beschreibungen hinzufügen
- [ ] `loadGroup()` erweitern (Beschreibungen laden) - [x] `loadGroup()` erweitern (Beschreibungen laden)
- [ ] Handler für Beschreibungsänderungen implementieren - [x] Handler für Beschreibungsänderungen implementieren
- [ ] `handleSaveDescriptions()` implementieren - [x] `handleSaveDescriptions()` implementieren
- [ ] Edit-Mode Toggle UI hinzufügen - [x] Edit-Mode Toggle UI hinzufügen
- [ ] Optimistic Updates - [x] Optimistic Updates
### Phase 5: Slideshow Integration ✅ ### Phase 5: Slideshow Integration ✅
- [ ] **Task 5.1:** SlideshowPage.js erweitern - [x] **Task 5.1:** SlideshowPage.js erweitern
- [ ] Beschreibungs-Anzeige UI implementieren - [x] Beschreibungs-Anzeige UI implementieren
- [ ] CSS für Slideshow-Beschreibung - [x] CSS für Slideshow-Beschreibung
- [ ] Responsive Design - [x] Responsive Design
- [ ] Conditional Rendering (nur wenn Beschreibung vorhanden) - [x] Conditional Rendering (nur wenn Beschreibung vorhanden)
- [ ] **Task 5.2:** Slideshow-Styles - [x] **Task 5.2:** Slideshow-Styles
- [ ] `.slideshow-description` CSS - [x] `.slideshow-description` CSS
- [ ] Overlay-Styling - [x] Overlay-Styling
- [ ] Animation (optional) - [x] Animation (optional)
- [ ] Mobile-Ansicht - [x] Mobile-Ansicht
### Phase 6: Groups Overview Integration ✅ ### Phase 6: Groups Overview Integration ✅
- [ ] **Task 6.1:** GroupsOverviewPage.js erweitern - [ ] **Task 6.1:** GroupsOverviewPage.js erweitern

View File

@ -16,6 +16,8 @@ services:
environment: environment:
- API_URL=http://backend:5000 - API_URL=http://backend:5000
- CLIENT_URL=http://localhost - CLIENT_URL=http://localhost
- REACT_APP_ADMIN_API_KEY=${ADMIN_API_KEY}
networks: networks:
- npm-nw - npm-nw
- prod-internal - prod-internal
@ -34,6 +36,7 @@ services:
- prod-internal - prod-internal
environment: environment:
- NODE_ENV=production - NODE_ENV=production
- ADMIN_API_KEY=${ADMIN_API_KEY}
networks: networks:
npm-nw: npm-nw:

View File

@ -38,85 +38,21 @@ http {
# Allow large uploads (50MB) # Allow large uploads (50MB)
client_max_body_size 50M; client_max_body_size 50M;
# API proxy to image-uploader-backend service # Generic API proxy for all backend endpoints under /api/
location /upload { # This mirrors the dev setup: forward everything under /api/ to the backend service
location /api/ {
proxy_pass http://image-uploader-backend:5000; proxy_pass http://image-uploader-backend:5000;
proxy_set_header Host $host; proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Proto $scheme;
# Allow large uploads for API too # Allow large uploads for batch upload endpoints
client_max_body_size 50M;
}
# API routes for new multi-upload features
location /api/upload {
proxy_pass http://image-uploader-backend:5000/upload;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Allow large uploads for batch upload
client_max_body_size 100M; client_max_body_size 100M;
} }
# API - Download original images
location /api/download {
proxy_pass http://image-uploader-backend:5000/download;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# API - Preview/thumbnail images (optimized for gallery views)
location /api/previews {
proxy_pass http://image-uploader-backend:5000/previews;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# API - Groups (NO PASSWORD PROTECTION)
location /api/groups {
proxy_pass http://image-uploader-backend:5000/groups;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# API - Social Media Consent Management (NO PASSWORD PROTECTION)
location /api/social-media {
proxy_pass http://image-uploader-backend:5000/api/social-media;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# API - Management Portal (NO PASSWORD PROTECTION - Token-based auth)
location /api/manage {
proxy_pass http://image-uploader-backend:5000/api/manage;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Admin API routes (NO password protection - protected by /moderation page access)
location /api/admin {
proxy_pass http://image-uploader-backend:5000/api/admin;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Protected API - Moderation API routes (password protected) - must come before /groups # Protected API - Moderation API routes (password protected) - must come before /groups
# Keep this route protected and proxy to backend if moderation endpoints exist there.
location /moderation/groups { location /moderation/groups {
auth_basic "Restricted Area - Moderation API"; auth_basic "Restricted Area - Moderation API";
auth_basic_user_file /etc/nginx/.htpasswd; auth_basic_user_file /etc/nginx/.htpasswd;

View File

@ -55,7 +55,7 @@ function GroupsOverviewPage() {
}; };
const handleCreateNew = () => { const handleCreateNew = () => {
navigate('/multi-upload'); navigate('/');
}; };
// removed unused local helpers (formatDate, handleGoHome) to clear ESLint warnings // removed unused local helpers (formatDate, handleGoHome) to clear ESLint warnings