From 48bf6f20745e65d93c9ab765e5fc448ed30a651c Mon Sep 17 00:00:00 2001 From: "matthias.lotz" Date: Wed, 15 Oct 2025 21:33:00 +0200 Subject: [PATCH] Initial Commit --- ERWEITERUNG.md | 552 + LICENSE | 20 +- README.md | 297 +- backend/.dockerignore | 3 + backend/.env.example | 1 + backend/.gitignore | 41 + backend/Dockerfile | 16 + backend/package.json | 30 + backend/src/constants.js | 16 + backend/src/database/DatabaseManager.js | 202 + backend/src/database/schema.sql | 48 + backend/src/index.js | 9 + backend/src/middlewares/cors.js | 13 + backend/src/middlewares/index.js | 12 + backend/src/models/uploadGroup.js | 52 + backend/src/repositories/GroupRepository.js | 340 + backend/src/routes/batchUpload.js | 108 + backend/src/routes/download.js | 10 + backend/src/routes/groups.js | 199 + backend/src/routes/index.js | 11 + backend/src/routes/migration.js | 75 + backend/src/routes/upload.js | 32 + backend/src/server.js | 35 + backend/src/services/MigrationService.js | 207 + backend/src/utils/groupStorage.js | 71 + backend/src/utils/initiate-resources.js | 24 + backend/src/utils/load-env.js | 3 + backend/src/utils/remove-images.js | 10 + docker-compose.yml | 41 + docs/images/example-video.gif | Bin 0 -> 877325 bytes docs/images/logo.png | Bin 0 -> 10936 bytes docs/images/screenshot.png | Bin 0 -> 6347 bytes docs/images/vallezw-Image-Uploader-dark.png | Bin 0 -> 69200 bytes docs/images/vallezw-Image-Uploader-light.png | Bin 0 -> 66007 bytes frontend/.env | 2 + frontend/.gitignore | 25 + frontend/Dockerfile | 38 + frontend/README.md | 70 + frontend/conf/conf.d/default.conf | 106 + frontend/conf/conf.d/gzip.conf | 24 + frontend/env-config 2.js | 4 + frontend/env.sh | 29 + frontend/htpasswd | 1 + frontend/package-lock.json | 33428 ++++++++++++++++ frontend/package.json | 49 + frontend/public/favicon.ico | Bin 0 -> 2238 bytes frontend/public/index.html | 36 + frontend/public/logo-16.png | Bin 0 -> 714 bytes frontend/public/logo-180.png | Bin 0 -> 5985 bytes frontend/public/logo-192.png | Bin 0 -> 6422 bytes frontend/public/logo-32.png | Bin 0 -> 1054 bytes frontend/public/logo-512.png | Bin 0 -> 17407 bytes frontend/public/logo.png | Bin 0 -> 13840 bytes frontend/public/manifest.json | 25 + frontend/public/robots.txt | 6 + frontend/src/App.css | 61 + frontend/src/App.js | 27 + .../ComponentUtils/Css/Background.css | 23 + .../Components/ComponentUtils/Css/Footer.css | 25 + .../Components/ComponentUtils/Css/Image.css | 109 + .../Components/ComponentUtils/Css/Image.scss | 48 + .../Components/ComponentUtils/Css/Navbar.css | 137 + .../src/Components/ComponentUtils/Footer.js | 13 + .../ComponentUtils/Headers/Navbar.js | 25 + .../ComponentUtils/ImageUploadCard.js | 73 + .../LoadingAnimation/Loading.js | 26 + .../LoadingAnimation/animation.json | 1 + .../MultiUpload/DescriptionInput.js | 164 + .../MultiUpload/ImagePreviewGallery.js | 142 + .../MultiUpload/MultiImageDropzone.js | 99 + .../MultiUpload/SimpleMultiImageDropzone.js | 142 + .../MultiUpload/UploadProgress.js | 79 + .../SocialMedia/Css/SocialMedia.css | 143 + .../SocialMedia/SocialMediaShareButtons.js | 24 + .../ComponentUtils/StyledDropzone.js | 96 + .../Components/ComponentUtils/UploadButton.js | 49 + .../ComponentUtils/UploadedImage.js | 43 + frontend/src/Components/Pages/404Page.js | 33 + frontend/src/Components/Pages/Css/404Page.css | 68 + .../Components/Pages/Css/ModerationPage.css | 360 + .../Pages/Css/UploadedImagePage.css | 19 + .../Components/Pages/GroupsOverviewPage.js | 349 + .../src/Components/Pages/ModerationPage.js | 346 + .../src/Components/Pages/MultiUploadPage.js | 284 + .../src/Components/Pages/SlideshowPage.js | 313 + frontend/src/Components/Pages/UploadPage.js | 103 + .../src/Components/Pages/UploadedImagePage.js | 38 + frontend/src/Images/404.png | Bin 0 -> 76563 bytes frontend/src/Images/404.svg | 1 + frontend/src/Images/404_blue.svg | 1 + frontend/src/Images/404_green.svg | 1 + frontend/src/Images/Backgrounds/bg1.svg | 3 + frontend/src/Images/Backgrounds/bg2.svg | 3 + frontend/src/Images/Backgrounds/bg3.svg | 3 + frontend/src/Images/Backgrounds/bg4.svg | 3 + frontend/src/Images/Backgrounds/bg5.svg | 3 + frontend/src/Images/Backgrounds/bg6.svg | 3 + frontend/src/Images/background.svg | 3 + frontend/src/Images/going_up.png | Bin 0 -> 67289 bytes frontend/src/Images/going_up.svg | 1 + frontend/src/Images/going_up_rm.png | Bin 0 -> 45099 bytes frontend/src/Images/logo.png | Bin 0 -> 4917 bytes frontend/src/Utils/batchUpload.js | 87 + frontend/src/Utils/sendRequest.js | 38 + frontend/src/index.js | 10 + prod.sh | 134 + scripts/README.md | 255 + scripts/batch_uploader.py | 682 + scripts/examples.sh | 75 + scripts/requirements.txt | 2 + .../Familie_Mueller/Weihnachten/README.md | 8 + .../Weihnachten/familienfoto.jpg | Bin 0 -> 8229 bytes .../Familie_Mueller/Weihnachten/geschenke.jpg | Bin 0 -> 6406 bytes .../Weihnachten/weihnachtsbaum.jpg | Bin 0 -> 8229 bytes .../2023/Thomas_Weber/Business_Trip/README.md | 8 + .../Thomas_Weber/Business_Trip/konferenz.jpg | Bin 0 -> 8229 bytes .../Thomas_Weber/Business_Trip/networking.jpg | Bin 0 -> 6261 bytes .../Anna_Schmidt/Architektur_Berlin/README.md | 8 + .../Architektur_Berlin/brandenburger_tor.jpg | Bin 0 -> 12469 bytes .../Architektur_Berlin/potsdamer_platz.jpg | Bin 0 -> 9290 bytes .../Architektur_Berlin/reichstag.jpg | Bin 0 -> 8227 bytes .../Max_Mustermann/Hochzeit_Anna/README.md | 8 + .../Max_Mustermann/Hochzeit_Anna/party.jpg | Bin 0 -> 8230 bytes .../Max_Mustermann/Hochzeit_Anna/torte.jpg | Bin 0 -> 6405 bytes .../Hochzeit_Anna/zeremonie.jpg | Bin 0 -> 12473 bytes .../Max_Mustermann/Urlaub_Mallorca/README.md | 8 + .../Urlaub_Mallorca/hotel_pool.jpg | Bin 0 -> 8229 bytes .../Urlaub_Mallorca/sonnenuntergang.jpg | Bin 0 -> 15630 bytes .../Urlaub_Mallorca/strand_spaziergang.jpg | Bin 0 -> 8229 bytes scripts/test_path_compatibility.py | 93 + scripts/test_setup.py | 163 + .../2023/Familie_Mueller/Urlaub/README.md | 36 + .../2023/Familie_Mueller/Urlaub/logo.png | Bin 0 -> 10936 bytes .../Familie_Mueller/Weihnachten/README.md | 36 + .../Weihnachten/screenshot.png | Bin 0 -> 6347 bytes .../2024/TestUser/TestProjekt/README.md | 36 + .../2024/TestUser/TestProjekt/logo.png | Bin 0 -> 10936 bytes .../TestUser/TestProjekt2/example-video.gif | Bin 0 -> 877325 bytes 138 files changed, 41489 insertions(+), 6 deletions(-) create mode 100644 ERWEITERUNG.md create mode 100644 backend/.dockerignore create mode 100644 backend/.env.example create mode 100644 backend/.gitignore create mode 100644 backend/Dockerfile create mode 100644 backend/package.json create mode 100644 backend/src/constants.js create mode 100644 backend/src/database/DatabaseManager.js create mode 100644 backend/src/database/schema.sql create mode 100644 backend/src/index.js create mode 100644 backend/src/middlewares/cors.js create mode 100644 backend/src/middlewares/index.js create mode 100644 backend/src/models/uploadGroup.js create mode 100644 backend/src/repositories/GroupRepository.js create mode 100644 backend/src/routes/batchUpload.js create mode 100644 backend/src/routes/download.js create mode 100644 backend/src/routes/groups.js create mode 100644 backend/src/routes/index.js create mode 100644 backend/src/routes/migration.js create mode 100644 backend/src/routes/upload.js create mode 100644 backend/src/server.js create mode 100644 backend/src/services/MigrationService.js create mode 100644 backend/src/utils/groupStorage.js create mode 100644 backend/src/utils/initiate-resources.js create mode 100644 backend/src/utils/load-env.js create mode 100644 backend/src/utils/remove-images.js create mode 100644 docker-compose.yml create mode 100644 docs/images/example-video.gif create mode 100644 docs/images/logo.png create mode 100644 docs/images/screenshot.png create mode 100644 docs/images/vallezw-Image-Uploader-dark.png create mode 100644 docs/images/vallezw-Image-Uploader-light.png create mode 100644 frontend/.env create mode 100644 frontend/.gitignore create mode 100644 frontend/Dockerfile create mode 100644 frontend/README.md create mode 100644 frontend/conf/conf.d/default.conf create mode 100644 frontend/conf/conf.d/gzip.conf create mode 100644 frontend/env-config 2.js create mode 100755 frontend/env.sh create mode 100644 frontend/htpasswd create mode 100644 frontend/package-lock.json create mode 100644 frontend/package.json create mode 100644 frontend/public/favicon.ico create mode 100644 frontend/public/index.html create mode 100644 frontend/public/logo-16.png create mode 100644 frontend/public/logo-180.png create mode 100644 frontend/public/logo-192.png create mode 100644 frontend/public/logo-32.png create mode 100644 frontend/public/logo-512.png create mode 100644 frontend/public/logo.png create mode 100644 frontend/public/manifest.json create mode 100644 frontend/public/robots.txt create mode 100644 frontend/src/App.css create mode 100644 frontend/src/App.js create mode 100644 frontend/src/Components/ComponentUtils/Css/Background.css create mode 100644 frontend/src/Components/ComponentUtils/Css/Footer.css create mode 100644 frontend/src/Components/ComponentUtils/Css/Image.css create mode 100644 frontend/src/Components/ComponentUtils/Css/Image.scss create mode 100644 frontend/src/Components/ComponentUtils/Css/Navbar.css create mode 100644 frontend/src/Components/ComponentUtils/Footer.js create mode 100644 frontend/src/Components/ComponentUtils/Headers/Navbar.js create mode 100644 frontend/src/Components/ComponentUtils/ImageUploadCard.js create mode 100644 frontend/src/Components/ComponentUtils/LoadingAnimation/Loading.js create mode 100644 frontend/src/Components/ComponentUtils/LoadingAnimation/animation.json create mode 100644 frontend/src/Components/ComponentUtils/MultiUpload/DescriptionInput.js create mode 100644 frontend/src/Components/ComponentUtils/MultiUpload/ImagePreviewGallery.js create mode 100644 frontend/src/Components/ComponentUtils/MultiUpload/MultiImageDropzone.js create mode 100644 frontend/src/Components/ComponentUtils/MultiUpload/SimpleMultiImageDropzone.js create mode 100644 frontend/src/Components/ComponentUtils/MultiUpload/UploadProgress.js create mode 100644 frontend/src/Components/ComponentUtils/SocialMedia/Css/SocialMedia.css create mode 100644 frontend/src/Components/ComponentUtils/SocialMedia/SocialMediaShareButtons.js create mode 100644 frontend/src/Components/ComponentUtils/StyledDropzone.js create mode 100644 frontend/src/Components/ComponentUtils/UploadButton.js create mode 100644 frontend/src/Components/ComponentUtils/UploadedImage.js create mode 100644 frontend/src/Components/Pages/404Page.js create mode 100644 frontend/src/Components/Pages/Css/404Page.css create mode 100644 frontend/src/Components/Pages/Css/ModerationPage.css create mode 100644 frontend/src/Components/Pages/Css/UploadedImagePage.css create mode 100644 frontend/src/Components/Pages/GroupsOverviewPage.js create mode 100644 frontend/src/Components/Pages/ModerationPage.js create mode 100644 frontend/src/Components/Pages/MultiUploadPage.js create mode 100644 frontend/src/Components/Pages/SlideshowPage.js create mode 100644 frontend/src/Components/Pages/UploadPage.js create mode 100644 frontend/src/Components/Pages/UploadedImagePage.js create mode 100644 frontend/src/Images/404.png create mode 100644 frontend/src/Images/404.svg create mode 100644 frontend/src/Images/404_blue.svg create mode 100644 frontend/src/Images/404_green.svg create mode 100644 frontend/src/Images/Backgrounds/bg1.svg create mode 100644 frontend/src/Images/Backgrounds/bg2.svg create mode 100644 frontend/src/Images/Backgrounds/bg3.svg create mode 100644 frontend/src/Images/Backgrounds/bg4.svg create mode 100644 frontend/src/Images/Backgrounds/bg5.svg create mode 100644 frontend/src/Images/Backgrounds/bg6.svg create mode 100644 frontend/src/Images/background.svg create mode 100644 frontend/src/Images/going_up.png create mode 100644 frontend/src/Images/going_up.svg create mode 100644 frontend/src/Images/going_up_rm.png create mode 100644 frontend/src/Images/logo.png create mode 100644 frontend/src/Utils/batchUpload.js create mode 100644 frontend/src/Utils/sendRequest.js create mode 100644 frontend/src/index.js create mode 100755 prod.sh create mode 100644 scripts/README.md create mode 100644 scripts/batch_uploader.py create mode 100755 scripts/examples.sh create mode 100644 scripts/requirements.txt create mode 100644 scripts/test_images/2023/Familie_Mueller/Weihnachten/README.md create mode 100644 scripts/test_images/2023/Familie_Mueller/Weihnachten/familienfoto.jpg create mode 100644 scripts/test_images/2023/Familie_Mueller/Weihnachten/geschenke.jpg create mode 100644 scripts/test_images/2023/Familie_Mueller/Weihnachten/weihnachtsbaum.jpg create mode 100644 scripts/test_images/2023/Thomas_Weber/Business_Trip/README.md create mode 100644 scripts/test_images/2023/Thomas_Weber/Business_Trip/konferenz.jpg create mode 100644 scripts/test_images/2023/Thomas_Weber/Business_Trip/networking.jpg create mode 100644 scripts/test_images/2024/Anna_Schmidt/Architektur_Berlin/README.md create mode 100644 scripts/test_images/2024/Anna_Schmidt/Architektur_Berlin/brandenburger_tor.jpg create mode 100644 scripts/test_images/2024/Anna_Schmidt/Architektur_Berlin/potsdamer_platz.jpg create mode 100644 scripts/test_images/2024/Anna_Schmidt/Architektur_Berlin/reichstag.jpg create mode 100644 scripts/test_images/2024/Max_Mustermann/Hochzeit_Anna/README.md create mode 100644 scripts/test_images/2024/Max_Mustermann/Hochzeit_Anna/party.jpg create mode 100644 scripts/test_images/2024/Max_Mustermann/Hochzeit_Anna/torte.jpg create mode 100644 scripts/test_images/2024/Max_Mustermann/Hochzeit_Anna/zeremonie.jpg create mode 100644 scripts/test_images/2024/Max_Mustermann/Urlaub_Mallorca/README.md create mode 100644 scripts/test_images/2024/Max_Mustermann/Urlaub_Mallorca/hotel_pool.jpg create mode 100644 scripts/test_images/2024/Max_Mustermann/Urlaub_Mallorca/sonnenuntergang.jpg create mode 100644 scripts/test_images/2024/Max_Mustermann/Urlaub_Mallorca/strand_spaziergang.jpg create mode 100644 scripts/test_path_compatibility.py create mode 100644 scripts/test_setup.py create mode 100644 test_photos/2023/Familie_Mueller/Urlaub/README.md create mode 100644 test_photos/2023/Familie_Mueller/Urlaub/logo.png create mode 100644 test_photos/2023/Familie_Mueller/Weihnachten/README.md create mode 100644 test_photos/2023/Familie_Mueller/Weihnachten/screenshot.png create mode 100644 test_photos/2024/TestUser/TestProjekt/README.md create mode 100644 test_photos/2024/TestUser/TestProjekt/logo.png create mode 100644 test_photos/2024/TestUser/TestProjekt2/example-video.gif diff --git a/ERWEITERUNG.md b/ERWEITERUNG.md new file mode 100644 index 0000000..eb0994f --- /dev/null +++ b/ERWEITERUNG.md @@ -0,0 +1,552 @@ +# Image-Uploader Erweiterung: Multi-Image Upload mit Beschreibung + +## 🎯 Ziel +Erweiterung der bestehenden Single-Image-Upload-FunktionalitĂ€t zu einem Multi-Image-Upload mit Beschreibungstext fĂŒr spĂ€tere Slideshow-Nutzung. + +## 📊 AufwandsschĂ€tzung +**GeschĂ€tzter Aufwand: 8-12 Stunden** (verteilt auf 2-3 Arbeitstage) + +### KomplexitĂ€tsbewertung: ⭐⭐⭐☆☆ (Mittel) + +## 🔄 ÄnderungsĂŒbersicht + +### Frontend Änderungen (5-7 Stunden) +- **Neue Multi-Upload-Komponente** +- **UI fĂŒr Beschreibungstext** +- **Vorschau-Galerie** +- **Upload-Progress fĂŒr mehrere Dateien** + +### Backend Änderungen (2-3 Stunden) +- **Neue API-Endpoints** +- **Datenbank/JSON-Struktur fĂŒr Upload-Gruppen** +- **Batch-Upload-Verarbeitung** + +### Integration & Testing (1-2 Stunden) +- **Frontend-Backend-Integration** +- **Error Handling** +- **UI/UX Tests** + +--- + +## đŸ—ïž Technische Umsetzung + +### 1. Backend-Erweiterungen + +#### 1.1 Neue Datenstruktur +```javascript +// Neue Upload-Group Struktur +{ + groupId: "unique-group-id", + description: "Benutzer-Beschreibung", + uploadDate: "2025-10-11T10:30:00Z", + images: [ + { + fileName: "abc123.jpg", + originalName: "foto1.jpg", + filePath: "/upload/abc123.jpg", + uploadOrder: 1 + }, + { + fileName: "def456.png", + originalName: "foto2.png", + filePath: "/upload/def456.png", + uploadOrder: 2 + } + ] +} +``` + +#### 1.2 Neue API-Endpoints +- `POST /api/upload/batch` - Multi-Image Upload +- `GET /api/groups/:groupId` - Upload-Gruppe abrufen +- `GET /api/groups` - Alle Upload-Gruppen auflisten +- `GET /api/slideshow/:groupId` - Slideshow-Daten + +#### 1.3 Dateien zu erstellen/Ă€ndern: +``` +backend/src/ +├── routes/ +│ ├── upload.js # ✏ Erweitern +│ ├── batch-upload.js # 🆕 Neu +│ └── groups.js # 🆕 Neu +├── models/ +│ └── uploadGroup.js # 🆕 Neu +├── utils/ +│ └── groupStorage.js # 🆕 Neu (JSON-basiert) +└── constants.js # ✏ Neue Endpoints hinzufĂŒgen +``` + +### 2. Frontend-Erweiterungen + +#### 2.1 Neue Komponenten +``` +frontend/src/Components/ +├── ComponentUtils/ +│ ├── MultiImageUpload.js # 🆕 Haupt-Upload-Komponente +│ ├── ImagePreviewGallery.js # 🆕 Vorschau der ausgewĂ€hlten Bilder +│ ├── DescriptionInput.js # 🆕 Textfeld fĂŒr Beschreibung +│ ├── UploadProgress.js # 🆕 Progress-Anzeige fĂŒr alle Dateien +│ └── Css/ +│ ├── MultiUpload.css # 🆕 Styling +│ └── ImageGallery.css # 🆕 Galerie-Styling +├── Pages/ +│ ├── MultiUploadPage.js # 🆕 Neue Seite fĂŒr Multi-Upload +│ ├── SlideshowPage.js # 🆕 Slideshow-Anzeige +│ └── GroupsOverviewPage.js # 🆕 Übersicht aller Upload-Gruppen +└── Utils/ + └── batchUpload.js # 🆕 Batch-Upload-Logik +``` + +#### 2.2 Routing-Erweiterungen +```javascript +// Neue Routen in App.js + + + +``` + +--- + +## 📋 Detaillierte Implementierungsschritte + +### Phase 1: Backend-Grundlage (2-3h) + +#### Schritt 1.1: Upload-Gruppen Datenmodell +```javascript +// backend/src/models/uploadGroup.js +class UploadGroup { + constructor(description) { + this.groupId = generateId(); + this.description = description; + this.uploadDate = new Date().toISOString(); + this.images = []; + } + + addImage(fileName, originalName, uploadOrder) { + this.images.push({ + fileName, + originalName, + filePath: `/upload/${fileName}`, + uploadOrder + }); + } +} +``` + +#### Schritt 1.2: JSON-basierte Speicherung +```javascript +// backend/src/utils/groupStorage.js +const fs = require('fs'); +const path = require('path'); + +const GROUPS_FILE = path.join(__dirname, '../data/upload-groups.json'); + +class GroupStorage { + static saveGroup(group) { + // JSON-Datei lesen, Gruppe hinzufĂŒgen, zurĂŒckschreiben + } + + static getGroup(groupId) { + // Gruppe aus JSON-Datei laden + } + + static getAllGroups() { + // Alle Gruppen laden + } +} +``` + +#### Schritt 1.3: Batch-Upload API +```javascript +// backend/src/routes/batch-upload.js +router.post('/api/upload/batch', (req, res) => { + const { description } = req.body; + const files = req.files.images; // Array von Dateien + + const group = new UploadGroup(description); + + // Alle Dateien verarbeiten + files.forEach((file, index) => { + const fileName = generateId() + '.' + getFileExtension(file.name); + file.mv(`upload/${fileName}`); + group.addImage(fileName, file.name, index + 1); + }); + + GroupStorage.saveGroup(group); + res.json({ groupId: group.groupId, message: 'Upload successful' }); +}); +``` + +### Phase 2: Frontend Multi-Upload UI (3-4h) + +#### Schritt 2.1: Multi-Image Dropzone +```javascript +// frontend/src/Components/ComponentUtils/MultiImageUpload.js +import { useDropzone } from 'react-dropzone'; + +function MultiImageUpload({ onImagesSelected }) { + const { getRootProps, getInputProps, acceptedFiles } = useDropzone({ + accept: 'image/*', + multiple: true, + onDrop: (files) => { + onImagesSelected(files); + } + }); + + return ( +
+ +

Ziehe mehrere Bilder hierher oder klicke zum AuswÀhlen

+

({acceptedFiles.length} Dateien ausgewÀhlt)

+
+ ); +} +``` + +#### Schritt 2.2: Bild-Vorschau Galerie +```javascript +// frontend/src/Components/ComponentUtils/ImagePreviewGallery.js +function ImagePreviewGallery({ images, onRemoveImage, onReorderImages }) { + return ( +
+ {images.map((image, index) => ( +
+ {`Preview + +
{index + 1}
+
+ ))} +
+ ); +} +``` + +#### Schritt 2.3: Beschreibungs-Input +```javascript +// frontend/src/Components/ComponentUtils/DescriptionInput.js +function DescriptionInput({ description, onDescriptionChange, maxLength = 500 }) { + return ( +
+ +