diff --git a/resources/js/admin/mobile/components/EventSwitcherSheet.tsx b/resources/js/admin/mobile/components/EventSwitcherSheet.tsx new file mode 100644 index 0000000..52b7088 --- /dev/null +++ b/resources/js/admin/mobile/components/EventSwitcherSheet.tsx @@ -0,0 +1,86 @@ +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 ( + + + {events.map((event) => { + const isActive = event.slug === activeSlug; + return ( + handleSelect(event.slug)}> + + + + {resolveEventDisplayName(event)} + + + {formatEventDate(event.event_date, locale)} + + + {isActive ? ( + + ) : ( + + )} + + + ); + })} + + { onClose(); navigate(adminPath('/mobile/events/new')); }}> + + + {t('mobile:header.createEvent', 'Create Event')} + + + + + + ); +} diff --git a/resources/js/admin/mobile/components/MobileShell.tsx b/resources/js/admin/mobile/components/MobileShell.tsx index 17358e2..8a702d3 100644 --- a/resources/js/admin/mobile/components/MobileShell.tsx +++ b/resources/js/admin/mobile/components/MobileShell.tsx @@ -21,6 +21,7 @@ import { loadPhotoQueue } from '../lib/photoModerationQueue'; import { countQueuedPhotoActions } from '../lib/queueStatus'; import { useAdminTheme } from '../theme'; import { useAuth } from '../../auth/context'; +import { EventSwitcherSheet } from './EventSwitcherSheet'; type MobileShellProps = { title?: string; @@ -55,6 +56,7 @@ export function MobileShell({ title, subtitle, children, activeTab, onBack, head const [loadingEvents, setLoadingEvents] = React.useState(false); const [attemptedFetch, setAttemptedFetch] = React.useState(false); const [queuedPhotoCount, setQueuedPhotoCount] = React.useState(0); + const [switcherOpen, setSwitcherOpen] = React.useState(false); const effectiveEvents = events.length ? events : fallbackEvents; const effectiveActive = activeEvent ?? (effectiveEvents.length === 1 ? effectiveEvents[0] : null); @@ -136,7 +138,7 @@ export function MobileShell({ title, subtitle, children, activeTab, onBack, head } return ( - navigate(ADMIN_EVENTS_PATH)}> + setSwitcherOpen(true)}> + + setSwitcherOpen(false)} + events={effectiveEvents} + activeSlug={effectiveActive?.slug ?? null} + /> ); } @@ -364,4 +373,4 @@ export function HeaderActionButton({ {children} ); -} \ No newline at end of file +}