Files
fotospiel-app/resources/js/admin/mobile/components/EventSwitcherSheet.tsx
Codex Agent 45f0cea264
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (push) Has been cancelled
tests / ui (push) Has been cancelled
feat(mobile): implement event switcher sheet in header
- Replaced direct navigation with a bottom sheet for event switching
- Created reusable EventSwitcherSheet component
- Preserves context when switching events
2026-01-17 19:17:19 +01:00

87 lines
3.0 KiB
TypeScript

import React from 'react';
import { useTranslation } from 'react-i18next';
import { useNavigate } from 'react-router-dom';
import { YStack, XStack } from '@tamagui/stacks';
import { SizableText as Text } from '@tamagui/text';
import { Pressable } from '@tamagui/react-native-web-lite';
import { CheckCircle2, Circle } from 'lucide-react';
import { MobileSheet } from './Sheet';
import { useAdminTheme } from '../theme';
import { TenantEvent } from '../../api';
import { resolveEventDisplayName, formatEventDate } from '../../lib/events';
import { adminPath } from '../../constants';
export function EventSwitcherSheet({
open,
onClose,
events,
activeSlug,
}: {
open: boolean;
onClose: () => void;
events: TenantEvent[];
activeSlug: string | null;
}) {
const { t, i18n } = useTranslation(['management', 'mobile']);
const navigate = useNavigate();
const theme = useAdminTheme();
const locale = i18n.language;
const handleSelect = (slug: string) => {
onClose();
// Navigate to the dashboard of the selected event
navigate(adminPath(`/mobile/events/${slug}`));
};
return (
<MobileSheet
open={open}
title={t('mobile:header.eventSwitcher', 'Switch Event')}
onClose={onClose}
snapPoints={[65]}
>
<YStack space="$2">
{events.map((event) => {
const isActive = event.slug === activeSlug;
return (
<Pressable key={event.slug} onPress={() => handleSelect(event.slug)}>
<XStack
alignItems="center"
space="$3"
padding="$3"
borderRadius={14}
backgroundColor={isActive ? theme.surfaceMuted : 'transparent'}
borderWidth={1}
borderColor={isActive ? theme.border : 'transparent'}
>
<YStack flex={1}>
<Text fontSize="$sm" fontWeight="700" color={theme.textStrong}>
{resolveEventDisplayName(event)}
</Text>
<Text fontSize="$xs" color={theme.muted}>
{formatEventDate(event.event_date, locale)}
</Text>
</YStack>
{isActive ? (
<CheckCircle2 size={20} color={theme.primary} />
) : (
<Circle size={20} color={theme.border} />
)}
</XStack>
</Pressable>
);
})}
<Pressable onPress={() => { onClose(); navigate(adminPath('/mobile/events/new')); }}>
<XStack padding="$3" justifyContent="center">
<Text fontSize="$sm" fontWeight="700" color={theme.primary}>
{t('mobile:header.createEvent', 'Create Event')}
</Text>
</XStack>
</Pressable>
</YStack>
</MobileSheet>
);
}