feat(admin): external media import modal + thumbnail fixes for reference events\n\n- Photos tab: replace inline external folder picker with a modal opened via "Import from External Folder" button next to "Upload Photos"; add info that all pictures in the selected folder will be imported.\n- Admin thumbnails: align list endpoint to /api/admin/photos/:eventId/photos and always return thumbnail_url to trigger on-demand generation; normalize external paths to avoid duplicated folder segments (e.g., individual/individual) that broke resolver; improve thumbnail logging.\n- Use authenticated image fetching on admin feedback pages to prevent 401s in automation.\n- i18n: add backup.external.warning strings; complete German backup/restore coverage; add common keys (notSet, of, up, select, selected).\n- Docs: add Local (npm) setup for EXTERNAL_MEDIA_ROOT in deployment guide.\n\nRefs #17 – gallery feature request: https://github.com/the-luap/picpeak/issues/17
Mirror to GitHub / mirror (push) Successful in 45s
Test and Lint / backend-test (push) Successful in 1m42s
Test and Lint / frontend-test (push) Failing after 1m50s
Version and Release / version-bump (push) Successful in 1m1s
Version and Release / trigger-drone (push) Successful in 3s

This commit is contained in:
2025-09-05 23:44:30 +02:00
parent 1d826accdc
commit 49c77785e7
13 changed files with 858 additions and 34 deletions
+11 -7
View File
@@ -606,8 +606,9 @@ router.get('/:eventId/photos/:photoId/download', adminAuth, async (req, res) =>
return res.status(404).json({ error: 'Photo not found' });
}
const storagePath = getStoragePath();
const filePath = path.join(storagePath, 'events/active', photo.path);
const { resolvePhotoFilePath } = require('../services/photoResolver');
const event = await db('events').where('id', eventId).first();
const filePath = resolvePhotoFilePath(event, photo);
// Check if file exists
try {
@@ -684,8 +685,10 @@ router.get('/:eventId/photos', adminAuth, async (req, res) => {
photos: photos.map(photo => ({
id: photo.id,
filename: photo.filename,
url: `/admin/events/${eventId}/photo/${photo.id}`,
thumbnail_url: photo.thumbnail_path ? `/admin/events/${eventId}/thumbnail/${photo.id}` : null,
// Use the correct admin photos router base for serving images
url: `/admin/photos/${eventId}/photo/${photo.id}`,
// Always expose a thumbnail URL; backend will generate on demand if missing
thumbnail_url: `/admin/photos/${eventId}/thumbnail/${photo.id}`,
type: photo.type,
category_id: photo.type,
category_name: photo.type === 'individual' ? 'Individual Photos' : 'Collages',
@@ -719,8 +722,9 @@ router.get('/:eventId/photo/:photoId', adminAuth, async (req, res) => {
return res.status(404).json({ error: 'Photo not found' });
}
const storagePath = getStoragePath();
const filePath = path.join(storagePath, 'events/active', photo.path);
const { resolvePhotoFilePath } = require('../services/photoResolver');
const event = await db('events').where('id', eventId).first();
const filePath = resolvePhotoFilePath(event, photo);
// Check if file exists
try {
@@ -802,4 +806,4 @@ router.get('/:eventId/debug', adminAuth, async (req, res) => {
}
});
module.exports = router;
module.exports = router;