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
+}