64 lines
2.2 KiB
TypeScript
64 lines
2.2 KiB
TypeScript
import React from 'react';
|
|
import { Link } from 'react-router-dom';
|
|
import { Card, CardContent } from '@/components/ui/card';
|
|
import { Button } from '@/components/ui/button';
|
|
import { usePollGalleryDelta } from '../polling/usePollGalleryDelta';
|
|
|
|
type Props = { slug: string };
|
|
|
|
export default function GalleryPreview({ slug }: Props) {
|
|
const { photos, loading } = usePollGalleryDelta(slug);
|
|
const [mode, setMode] = React.useState<'latest' | 'popular'>('latest');
|
|
|
|
const items = React.useMemo(() => {
|
|
const arr = photos.slice();
|
|
if (mode === 'popular') {
|
|
arr.sort((a: any, b: any) => (b.likes_count ?? 0) - (a.likes_count ?? 0));
|
|
} else {
|
|
arr.sort((a: any, b: any) => new Date(b.created_at ?? 0).getTime() - new Date(a.created_at ?? 0).getTime());
|
|
}
|
|
return arr.slice(0, 6);
|
|
}, [photos, mode]);
|
|
|
|
return (
|
|
<div>
|
|
<div className="mb-2 flex items-center gap-2">
|
|
<div className="inline-flex rounded-md border p-1 text-xs">
|
|
<button
|
|
onClick={() => setMode('latest')}
|
|
className={`px-2 py-1 ${mode === 'latest' ? 'rounded-sm bg-muted font-medium' : ''}`}
|
|
>Neueste</button>
|
|
<button
|
|
onClick={() => setMode('popular')}
|
|
className={`px-2 py-1 ${mode === 'popular' ? 'rounded-sm bg-muted font-medium' : ''}`}
|
|
>Beliebt</button>
|
|
</div>
|
|
<div className="grow" />
|
|
<Link to={`../gallery`}><Button variant="link" className="px-0">Alle ansehen →</Button></Link>
|
|
</div>
|
|
|
|
{loading && <p className="text-sm text-muted-foreground">Lädt…</p>}
|
|
{!loading && items.length === 0 && (
|
|
<Card>
|
|
<CardContent className="p-3 text-sm text-muted-foreground">
|
|
Noch keine Fotos. Starte mit deinem ersten Upload!
|
|
</CardContent>
|
|
</Card>
|
|
)}
|
|
<div className="grid grid-cols-3 gap-2">
|
|
{items.map((p: any) => (
|
|
<Link key={p.id} to={`../photo/${p.id}`} state={{ photo: p }}>
|
|
<img
|
|
src={p.thumbnail_path || p.file_path}
|
|
alt="Foto"
|
|
className="aspect-square w-full rounded object-cover"
|
|
loading="lazy"
|
|
/>
|
|
</Link>
|
|
))}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|