feat(gallery/filters): add Rated and Commented filters (UI + backend).\n\n- UI: add star (Rated) and message (Commented) buttons to feedback filter bars (desktop + mobile)\n- Backend: support filter=rated, commented, and combinations via aggregate counts/queries

This commit is contained in:
2025-09-16 10:11:08 +02:00
parent 526dcd8dfc
commit b03760ab01
3 changed files with 90 additions and 11 deletions
@@ -1,9 +1,9 @@
import React from 'react';
import { Heart, Star } from 'lucide-react';
import { Heart, Star, Bookmark, MessageSquare } from 'lucide-react';
import { Button } from '../common';
import { useTranslation } from 'react-i18next';
export type FilterType = 'all' | 'liked' | 'favorited';
export type FilterType = 'all' | 'liked' | 'favorited' | 'rated' | 'commented';
interface GalleryFilterProps {
currentFilter: FilterType;
@@ -150,14 +150,34 @@ export const GalleryFilter: React.FC<GalleryFilterProps> = ({
onClick={() => onFilterChange('favorited')}
className="text-xs sm:text-sm flex items-center gap-1"
>
<Star className="w-3 h-3 sm:w-4 sm:h-4" />
<span className="hidden sm:inline">{t('gallery.favorited', 'Favorites')}</span>
<Bookmark className="w-3 h-3 sm:w-4 sm:h-4" />
<span className="hidden sm:inline">{t('gallery.favorites', 'Favorites')}</span>
{favoriteCount > 0 && (
<span className="bg-primary-100 text-primary-700 px-1.5 rounded">
{favoriteCount}
</span>
)}
</Button>
<Button
variant={currentFilter === 'rated' ? 'primary' : 'outline'}
size="sm"
onClick={() => onFilterChange('rated')}
className="text-xs sm:text-sm flex items-center gap-1"
>
<Star className="w-3 h-3 sm:w-4 sm:h-4" />
<span className="hidden sm:inline">{t('gallery.rated', 'Rated')}</span>
</Button>
<Button
variant={currentFilter === 'commented' ? 'primary' : 'outline'}
size="sm"
onClick={() => onFilterChange('commented')}
className="text-xs sm:text-sm flex items-center gap-1"
>
<MessageSquare className="w-3 h-3 sm:w-4 sm:h-4" />
<span className="hidden sm:inline">{t('gallery.commented', 'Commented')}</span>
</Button>
</div>
</div>
)}
@@ -1,5 +1,5 @@
import React, { useState } from 'react';
import { Search, SortAsc, Grid, Heart, Star } from 'lucide-react';
import { Search, SortAsc, Grid, Heart, Star, Bookmark, MessageSquare } from 'lucide-react';
import { useTranslation } from 'react-i18next';
import { Button, Input } from '../common';
import type { FilterType } from './GalleryFilter';
@@ -205,9 +205,27 @@ export const PhotoFilterBar: React.FC<PhotoFilterBarProps> = ({
onClick={() => onFilterChange('favorited')}
className="p-1 w-8 h-8 flex items-center justify-center"
aria-label={t('feedback.favorites', 'Favorites')}
>
<Bookmark className="w-3.5 h-3.5" />
</Button>
<Button
variant={currentFilter === 'rated' ? 'primary' : 'outline'}
size="sm"
onClick={() => onFilterChange('rated')}
className="p-1 w-8 h-8 flex items-center justify-center"
aria-label={t('gallery.rated', 'Rated')}
>
<Star className="w-3.5 h-3.5" />
</Button>
<Button
variant={currentFilter === 'commented' ? 'primary' : 'outline'}
size="sm"
onClick={() => onFilterChange('commented')}
className="p-1 w-8 h-8 flex items-center justify-center"
aria-label={t('gallery.commented', 'Commented')}
>
<MessageSquare className="w-3.5 h-3.5" />
</Button>
</div>
</div>
)}
@@ -249,9 +267,27 @@ export const PhotoFilterBar: React.FC<PhotoFilterBarProps> = ({
onClick={() => onFilterChange('favorited')}
className="p-1 w-8 h-8 flex items-center justify-center"
aria-label={t('feedback.favorites', 'Favorites')}
>
<Bookmark className="w-3.5 h-3.5" />
</Button>
<Button
variant={currentFilter === 'rated' ? 'primary' : 'outline'}
size="sm"
onClick={() => onFilterChange('rated')}
className="p-1 w-8 h-8 flex items-center justify-center"
aria-label={t('gallery.rated', 'Rated')}
>
<Star className="w-3.5 h-3.5" />
</Button>
<Button
variant={currentFilter === 'commented' ? 'primary' : 'outline'}
size="sm"
onClick={() => onFilterChange('commented')}
className="p-1 w-8 h-8 flex items-center justify-center"
aria-label={t('gallery.commented', 'Commented')}
>
<MessageSquare className="w-3.5 h-3.5" />
</Button>
</div>
</div>
)}