fix: Link in Groups bei leeren Gruppen falsch
This commit is contained in:
parent
98b3616dc4
commit
6574ee0171
|
|
@ -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)
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -38,89 +38,25 @@ 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;
|
||||||
|
|
||||||
proxy_pass http://image-uploader-backend:5000/moderation/groups;
|
proxy_pass http://image-uploader-backend:5000/moderation/groups;
|
||||||
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;
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user