fix: wire admin photo feedback filters into grid query (#293)

The Has Likes / Has Favorites / Has Comments checkboxes in the admin
Event > Photos tab updated local state but never affected the visible
photo grid, because the feedbackFilters state was only wired to the
export menu and the backend /admin/photos/:eventId/photos endpoint had
no support for these params.

Fixes:
- backend/src/routes/adminPhotos.js: extend GET /:eventId/photos to
  accept has_likes, has_favorites, has_comments, min_rating, and logic
  (AND/OR) query params and apply them via where-clause groups using
  the existing denormalized like_count/favorite_count/comment_count/
  average_rating columns.
- frontend/src/services/photos.service.ts: add hasLikes, hasFavorites,
  hasComments, minRating, logic to the PhotoFilters interface and
  append them as query params in getEventPhotos.
- frontend/src/pages/admin/EventDetailsPage.tsx: merge feedbackFilters
  into combinedPhotoFilters (via useMemo) and key the admin-event-photos
  query on it, so toggling any checkbox refetches with the new params.

Verified end-to-end against local Docker: seeded event with a known
feedback distribution and confirmed
- Has Likes → 4 photos
- Has Favorites → 3 photos
- Likes AND Favorites → 1 photo
- Likes OR Favorites → 6 photos
- Has Comments → 2 photos
- network requests carry the exact query params
This commit is contained in:
Paul Nothaft
2026-04-11 07:46:32 +02:00
parent fe46e4268d
commit d4b4dc628f
3 changed files with 67 additions and 8 deletions
+13 -2
View File
@@ -294,10 +294,21 @@ export const EventDetailsPage: React.FC = () => {
// Statistics are now fetched with the event details from the admin API
// Merge feedback filters into photo query params so the grid reflects
// the Has Likes / Has Favorites / Has Comments / min rating checkboxes.
const combinedPhotoFilters: PhotoFilterParams = useMemo(() => ({
...photoFilters,
hasLikes: feedbackFilters.hasLikes || undefined,
hasFavorites: feedbackFilters.hasFavorites || undefined,
hasComments: feedbackFilters.hasComments || undefined,
minRating: feedbackFilters.minRating ?? undefined,
logic: feedbackFilters.logic,
}), [photoFilters, feedbackFilters]);
// Fetch photos (needed for both photos tab and hero photo selector)
const { data: photos = [], isLoading: photosLoading, refetch: refetchPhotos } = useQuery({
queryKey: ['admin-event-photos', id, photoFilters],
queryFn: () => photosService.getEventPhotos(parseInt(id!), photoFilters),
queryKey: ['admin-event-photos', id, combinedPhotoFilters],
queryFn: () => photosService.getEventPhotos(parseInt(id!), combinedPhotoFilters),
enabled: !!id && (activeTab === 'photos' || isEditing),
});