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
+9 -10
View File
@@ -20,6 +20,7 @@ import { toast } from 'react-toastify';
import { format } from 'date-fns';
import { Button, Card, Loading } from '../../components/common';
import { AdminAuthenticatedImage } from '../../components/admin/AdminAuthenticatedImage';
import { FeedbackSettings } from '../../components/admin';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { eventsService } from '../../services/events.service';
@@ -251,15 +252,13 @@ export const EventFeedbackPage: React.FC = () => {
<Card key={item.id} className="overflow-hidden">
<div className="p-4 flex items-start gap-4">
{item.photo_id && (
<img
src={`/api/admin/photos/${eventId}/thumbnail/${item.photo_id}`}
alt={item.filename || 'Photo'}
className="w-16 h-16 object-cover rounded"
onError={(e) => {
// Hide image if thumbnail fails to load
(e.target as HTMLImageElement).style.display = 'none';
}}
/>
<div className="w-16 h-16 overflow-hidden rounded">
<AdminAuthenticatedImage
src={`/api/admin/photos/${eventId}/thumbnail/${item.photo_id}`}
alt={item.filename || 'Photo'}
className="w-16 h-16 object-cover rounded"
/>
</div>
)}
<div className="flex-1">
<div className="flex items-start justify-between">
@@ -528,4 +527,4 @@ export const EventFeedbackPage: React.FC = () => {
)}
</div>
);
};
};