photobooth funktionen im event admin verlinkt, gäste pwa zeigt photobooth nur noch an, wenn diese aktiviert ist. kontaktformular optimiert. teilen-link mit iMessage und whatsapp erweitert.
This commit is contained in:
@@ -5,15 +5,27 @@ import { useTranslation } from '../i18n/useTranslation';
|
||||
|
||||
export type GalleryFilter = 'latest' | 'popular' | 'mine' | 'photobooth';
|
||||
|
||||
const filterConfig: Array<{ value: GalleryFilter; labelKey: string; icon: React.ReactNode }> = [
|
||||
type FilterConfig = Array<{ value: GalleryFilter; labelKey: string; icon: React.ReactNode }>;
|
||||
|
||||
const baseFilters: FilterConfig = [
|
||||
{ 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 }) {
|
||||
export default function FiltersBar({
|
||||
value,
|
||||
onChange,
|
||||
className,
|
||||
showPhotobooth = true,
|
||||
}: { value: GalleryFilter; onChange: (v: GalleryFilter) => void; className?: string; showPhotobooth?: boolean }) {
|
||||
const { t } = useTranslation();
|
||||
const filters: FilterConfig = React.useMemo(
|
||||
() => (showPhotobooth
|
||||
? [...baseFilters, { value: 'photobooth', labelKey: 'galleryPage.filters.photobooth', icon: <Camera className="h-4 w-4" aria-hidden /> }]
|
||||
: baseFilters),
|
||||
[showPhotobooth],
|
||||
);
|
||||
|
||||
return (
|
||||
<div
|
||||
@@ -22,7 +34,7 @@ export default function FiltersBar({ value, onChange, className }: { value: Gall
|
||||
className,
|
||||
)}
|
||||
>
|
||||
{filterConfig.map((filter) => (
|
||||
{filters.map((filter) => (
|
||||
<button
|
||||
key={filter.value}
|
||||
type="button"
|
||||
|
||||
@@ -28,10 +28,11 @@ export default function GalleryPreview({ token }: Props) {
|
||||
const { locale } = useTranslation();
|
||||
const { photos, loading } = usePollGalleryDelta(token, locale);
|
||||
const [mode, setMode] = React.useState<PreviewFilter>('latest');
|
||||
const typedPhotos = React.useMemo(() => photos as PreviewPhoto[], [photos]);
|
||||
const hasPhotobooth = React.useMemo(() => typedPhotos.some((p) => p.ingest_source === 'photobooth'), [typedPhotos]);
|
||||
|
||||
const items = React.useMemo(() => {
|
||||
const typed = photos as PreviewPhoto[];
|
||||
let arr = typed.slice();
|
||||
let arr = typedPhotos.slice();
|
||||
|
||||
// MyPhotos filter (requires session_id matching)
|
||||
if (mode === 'mine') {
|
||||
@@ -49,7 +50,13 @@ export default function GalleryPreview({ token }: Props) {
|
||||
}
|
||||
|
||||
return arr.slice(0, 4); // 2x2 = 4 items
|
||||
}, [photos, mode]);
|
||||
}, [typedPhotos, mode]);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (mode === 'photobooth' && !hasPhotobooth) {
|
||||
setMode('latest');
|
||||
}
|
||||
}, [mode, hasPhotobooth]);
|
||||
|
||||
// Helper function to generate photo title (must be before return)
|
||||
function getPhotoTitle(photo: PreviewPhoto): string {
|
||||
@@ -72,7 +79,7 @@ export default function GalleryPreview({ token }: Props) {
|
||||
{ value: 'latest', label: 'Newest' },
|
||||
{ value: 'popular', label: 'Popular' },
|
||||
{ value: 'mine', label: 'My Photos' },
|
||||
{ value: 'photobooth', label: 'Fotobox' },
|
||||
...(hasPhotobooth ? [{ value: 'photobooth', label: 'Fotobox' } as const] : []),
|
||||
];
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user