feat: localize guest endpoints and caching
This commit is contained in:
@@ -3,6 +3,7 @@ import { useNavigate, useParams } from 'react-router-dom';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { ChevronRight } from 'lucide-react';
|
||||
import { cn } from '@/lib/utils';
|
||||
import { useTranslation } from '../i18n/useTranslation';
|
||||
|
||||
interface Emotion {
|
||||
id: number;
|
||||
@@ -33,6 +34,7 @@ export default function EmotionPicker({
|
||||
const [emotions, setEmotions] = useState<Emotion[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const { locale } = useTranslation();
|
||||
|
||||
// Fallback emotions (when API not available yet)
|
||||
const fallbackEmotions: Emotion[] = [
|
||||
@@ -53,7 +55,12 @@ export default function EmotionPicker({
|
||||
setError(null);
|
||||
|
||||
// Try API first
|
||||
const response = await fetch(`/api/v1/events/${encodeURIComponent(eventKey)}/emotions`);
|
||||
const response = await fetch(`/api/v1/events/${encodeURIComponent(eventKey)}/emotions?locale=${encodeURIComponent(locale)}`, {
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'X-Locale': locale,
|
||||
},
|
||||
});
|
||||
if (response.ok) {
|
||||
const data = await response.json();
|
||||
setEmotions(Array.isArray(data) ? data : fallbackEmotions);
|
||||
@@ -72,7 +79,7 @@ export default function EmotionPicker({
|
||||
}
|
||||
|
||||
fetchEmotions();
|
||||
}, [eventKey]);
|
||||
}, [eventKey, locale]);
|
||||
|
||||
const handleEmotionSelect = (emotion: Emotion) => {
|
||||
if (onSelect) {
|
||||
|
||||
@@ -1,17 +1,20 @@
|
||||
import React from 'react';
|
||||
import { cn } from '@/lib/utils';
|
||||
import { Sparkles, Flame, UserRound, Camera } from 'lucide-react';
|
||||
import { useTranslation } from '../i18n/useTranslation';
|
||||
|
||||
export type GalleryFilter = 'latest' | 'popular' | 'mine' | 'photobooth';
|
||||
|
||||
const filterConfig: Array<{ value: GalleryFilter; label: string; icon: React.ReactNode }> = [
|
||||
{ value: 'latest', label: 'Neueste', icon: <Sparkles className="h-4 w-4" aria-hidden /> },
|
||||
{ value: 'popular', label: 'Beliebt', icon: <Flame className="h-4 w-4" aria-hidden /> },
|
||||
{ value: 'mine', label: 'Meine', icon: <UserRound className="h-4 w-4" aria-hidden /> },
|
||||
{ value: 'photobooth', label: 'Fotobox', icon: <Camera className="h-4 w-4" aria-hidden /> },
|
||||
const filterConfig: Array<{ value: GalleryFilter; labelKey: string; icon: React.ReactNode }> = [
|
||||
{ value: 'latest', labelKey: 'galleryPage.filters.latest', icon: <Sparkles className="h-4 w-4" aria-hidden /> },
|
||||
{ value: 'popular', labelKey: 'galleryPage.filters.popular', icon: <Flame className="h-4 w-4" aria-hidden /> },
|
||||
{ value: 'mine', labelKey: 'galleryPage.filters.mine', icon: <UserRound className="h-4 w-4" aria-hidden /> },
|
||||
{ value: 'photobooth', labelKey: 'galleryPage.filters.photobooth', icon: <Camera className="h-4 w-4" aria-hidden /> },
|
||||
];
|
||||
|
||||
export default function FiltersBar({ value, onChange, className }: { value: GalleryFilter; onChange: (v: GalleryFilter) => void; className?: string }) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
@@ -32,7 +35,7 @@ export default function FiltersBar({ value, onChange, className }: { value: Gall
|
||||
)}
|
||||
>
|
||||
{filter.icon}
|
||||
{filter.label}
|
||||
{t(filter.labelKey)}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
|
||||
@@ -4,13 +4,15 @@ import { Card, CardContent } from '@/components/ui/card';
|
||||
import { getDeviceId } from '../lib/device';
|
||||
import { usePollGalleryDelta } from '../polling/usePollGalleryDelta';
|
||||
import { Heart } from 'lucide-react';
|
||||
import { useTranslation } from '../i18n/useTranslation';
|
||||
|
||||
type Props = { token: string };
|
||||
|
||||
type PreviewFilter = 'latest' | 'popular' | 'mine' | 'photobooth';
|
||||
|
||||
export default function GalleryPreview({ token }: Props) {
|
||||
const { photos, loading } = usePollGalleryDelta(token);
|
||||
const { locale } = useTranslation();
|
||||
const { photos, loading } = usePollGalleryDelta(token, locale);
|
||||
const [mode, setMode] = React.useState<PreviewFilter>('latest');
|
||||
|
||||
const items = React.useMemo(() => {
|
||||
|
||||
Reference in New Issue
Block a user