import React from 'react'; import { useNavigate, useParams } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; import { Download, Share2, ChevronRight, RefreshCcw } 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 { MobileScaffold } from './components/Scaffold'; import { MobileCard, CTAButton, PillBadge } from './components/Primitives'; import { BottomNav } from './components/BottomNav'; import { TenantEvent, getEvent, getEventQrInvites, createQrInvite } from '../api'; import { isAuthError } from '../auth/tokens'; import { getApiErrorMessage } from '../lib/apiError'; import toast from 'react-hot-toast'; import { useMobileNav } from './hooks/useMobileNav'; import { MobileSheet } from './components/Sheet'; const LAYOUTS = [ { key: 'badges', title: 'Badges', subtitle: 'Standard, Staff' }, { key: 'tents', title: 'Table Tents', subtitle: 'A4, Letter' }, { key: 'posters', title: 'Posters', subtitle: 'A3, 11x17' }, { key: 'programs', title: 'Event Programs', subtitle: 'Folded, Booklet' }, ]; export default function MobileQrPrintPage() { const { slug: slugParam } = useParams<{ slug?: string }>(); const slug = slugParam ?? null; const navigate = useNavigate(); const { t } = useTranslation('management'); const [event, setEvent] = React.useState(null); const [error, setError] = React.useState(null); const [loading, setLoading] = React.useState(true); const [paperSize, setPaperSize] = React.useState('A4 (210 x 297 mm)'); const [qrUrl, setQrUrl] = React.useState(''); const { go } = useMobileNav(slug); const [showPaperSheet, setShowPaperSheet] = React.useState(false); const [showLayoutSheet, setShowLayoutSheet] = React.useState(false); React.useEffect(() => { if (!slug) return; (async () => { setLoading(true); try { const data = await getEvent(slug); const invites = await getEventQrInvites(slug); setEvent(data); const primaryInvite = invites.find((item) => item.is_active) ?? invites[0]; setQrUrl(primaryInvite?.url ?? data.public_url ?? ''); setError(null); } catch (err) { if (!isAuthError(err)) { setError(getApiErrorMessage(err, t('events.errors.loadFailed', 'QR-Daten konnten nicht geladen werden.'))); } } finally { setLoading(false); } })(); }, [slug, t]); return ( navigate(-1)} rightSlot={ window.location.reload()}> } footer={ } > {error ? ( {error} ) : null} {t('events.qr.heroTitle', 'Entrance QR Code')} {qrUrl ? ( QR ) : ( {t('events.qr.missing', 'Kein QR-Link vorhanden')} )} {t('events.qr.description', 'Scan to access the event guest app.')} { if (qrUrl) { toast.success(t('events.qr.downloadStarted', 'Download gestartet')); } else { toast.error(t('events.qr.missing', 'Kein QR-Link vorhanden')); } }} /> { try { await navigator.clipboard.writeText(qrUrl || event?.public_url || ''); toast.success(t('events.qr.shareSuccess', 'Link kopiert')); } catch { toast.error(t('events.qr.shareFailed', 'Konnte Link nicht kopieren')); } }} /> {t('events.qr.layouts', 'Print Layouts')} {LAYOUTS.map((layout) => ( setShowLayoutSheet(true)} > {layout.title} {layout.subtitle} ))} {t('events.qr.templates', 'Templates')} {t('events.qr.branding', 'Branding')} setShowPaperSheet(true)}> {t('events.qr.paper', 'Paper Size')} {paperSize} toast.success(t('events.qr.previewStarted', 'Preview gestartet (mock)'))} /> { if (!slug) return; try { const invite = await createQrInvite(slug, { label: 'Mobile Link' }); setQrUrl(invite.url); toast.success(t('events.qr.created', 'Neuer QR-Link erstellt')); } catch (err) { toast.error(getApiErrorMessage(err, t('events.qr.createFailed', 'Link konnte nicht erstellt werden.'))); } }} /> setShowPaperSheet(false)} title={t('events.qr.paper', 'Paper Size')} footer={null} > {['A4 (210 x 297 mm)', 'Letter (8.5 x 11 in)', 'A3 (297 x 420 mm)'].map((size) => ( { setPaperSize(size); setShowPaperSheet(false); }} > {size} {paperSize === size ? : null} ))} setShowLayoutSheet(false)} title={t('events.qr.layouts', 'Print Layouts')} footer={ toast.success(t('events.qr.previewStarted', 'Preview gestartet (mock)'))} /> } > {LAYOUTS.map((layout) => ( {layout.title} {layout.subtitle} {paperSize} ))} ); }