import React from 'react';
import { useNavigate } from 'react-router-dom';
import { ChevronDown, ChevronLeft, Bell, QrCode } from 'lucide-react';
import { YStack, XStack } from '@tamagui/stacks';
import { SizableText as Text } from '@tamagui/text';
import { Pressable } from '@tamagui/react-native-web-lite';
import { useTranslation } from 'react-i18next';
import { useEventContext } from '../../context/EventContext';
import { BottomNav, NavKey } from './BottomNav';
import { useMobileNav } from '../hooks/useMobileNav';
import { adminPath } from '../../constants';
import { MobileSheet } from './Sheet';
import { MobileCard, PillBadge } from './Primitives';
import { useAlertsBadge } from '../hooks/useAlertsBadge';
import { formatEventDate, resolveEventDisplayName } from '../../lib/events';
import { TenantEvent } from '../../api';
type MobileShellProps = {
title?: string;
subtitle?: string;
children: React.ReactNode;
activeTab: NavKey;
onBack?: () => void;
headerActions?: React.ReactNode;
};
export function MobileShell({ title, subtitle, children, activeTab, onBack, headerActions }: MobileShellProps) {
const { events, activeEvent, hasMultipleEvents, hasEvents, selectEvent } = useEventContext();
const { go } = useMobileNav(activeEvent?.slug);
const navigate = useNavigate();
const { t, i18n } = useTranslation('mobile');
const { count: alertCount } = useAlertsBadge();
const [pickerOpen, setPickerOpen] = React.useState(false);
const locale = i18n.language?.startsWith('en') ? 'en-GB' : 'de-DE';
const eventTitle = title ?? (activeEvent ? resolveEventDisplayName(activeEvent) : t('header.appName', 'Event Admin'));
const subtitleText =
subtitle ??
(activeEvent?.event_date
? formatEventDate(activeEvent.event_date, locale) ?? ''
: hasEvents
? t('header.selectEvent', 'Select an event to continue')
: t('header.empty', 'Create your first event to get started'));
const showEventSwitcher = hasMultipleEvents;
const showQr = Boolean(activeEvent?.slug);
return (
{onBack ? (
{t('actions.back', 'Back')}
) : null}
setPickerOpen(true)}
style={{ alignItems: 'flex-start' }}
>
{eventTitle}
{subtitleText ? (
{subtitleText}
) : null}
{showEventSwitcher ? : null}
navigate(adminPath('/mobile/alerts'))}>
{alertCount > 0 ? (
{alertCount > 9 ? '9+' : alertCount}
) : null}
{showQr ? (
navigate(adminPath(`/mobile/events/${activeEvent?.slug}/qr`))}>
{t('header.quickQr', 'Quick QR')}
) : null}
{headerActions ?? null}
{children}
setPickerOpen(false)}
title={t('header.eventSwitcher', 'Choose an event')}
footer={null}
bottomOffsetPx={110}
>
{events.length === 0 ? (
{t('header.noEventsTitle', 'Create your first event')}
{t('header.noEventsBody', 'Start an event to access tasks, uploads, QR posters and more.')}
navigate(adminPath('/mobile/events/new'))}>
{t('header.createEvent', 'Create event')}
) : (
events.map((event) => (
{
selectEvent(event.slug ?? null);
setPickerOpen(false);
}}
>
{resolveEventDisplayName(event)}
{formatEventDate(event.event_date, locale) ?? t('header.noDate', 'Date tbd')}
{event.slug === activeEvent?.slug
? t('header.active', 'Active')
: (event.status ?? '—')}
))
)}
{activeEvent ? (
{
selectEvent(null);
setPickerOpen(false);
}}
>
{t('header.clearSelection', 'Clear selection')}
) : null}
);
}
export function renderEventLocation(event?: TenantEvent | null): string {
if (!event) return 'Location';
const settings = (event.settings ?? {}) as Record;
const candidate =
(settings.location as string | undefined) ??
(settings.address as string | undefined) ??
(settings.city as string | undefined);
if (candidate && candidate.trim()) {
return candidate;
}
return 'Location';
}