upgrade to tamagui v2 and guest pwa overhaul

This commit is contained in:
Codex Agent
2026-02-02 13:01:20 +01:00
parent 2e78f3ab8d
commit 7c6e14ffe2
168 changed files with 47462 additions and 8914 deletions

View File

@@ -170,7 +170,7 @@ export default function MobileEventRecapPage() {
if (loading) {
return (
<MobileShell activeTab="home" title={t('events.recap.title', 'Event Recap')} onBack={back}>
<YStack space="$3">
<YStack gap="$3">
<SkeletonCard height={120} />
<SkeletonCard height={200} />
<SkeletonCard height={150} />
@@ -207,8 +207,8 @@ export default function MobileEventRecapPage() {
title={t('events.recap.title', 'Event Recap')}
onBack={back}
>
<YStack space="$4">
<XStack space="$2">
<YStack gap="$4">
<XStack gap="$2">
<TabButton
label={t('events.recap.tabs.overview', 'Overview')}
active={activeTab === 'overview'}
@@ -227,10 +227,10 @@ export default function MobileEventRecapPage() {
</XStack>
{activeTab === 'overview' ? (
<YStack space="$4">
<MobileCard space="$3">
<YStack gap="$4">
<MobileCard gap="$3">
<XStack alignItems="center" justifyContent="space-between">
<YStack space="$1">
<YStack gap="$1">
<Text fontSize="$xl" fontWeight="800" color={textStrong}>
{t('events.recap.completedTitle', 'Event abgeschlossen')}
</Text>
@@ -248,8 +248,8 @@ export default function MobileEventRecapPage() {
</XStack>
</MobileCard>
<MobileCard space="$3">
<XStack alignItems="center" space="$2">
<MobileCard gap="$3">
<XStack alignItems="center" gap="$2">
<Share2 size={18} color={primary} />
<Text fontSize="$md" fontWeight="800" color={textStrong}>
{t('events.recap.shareGuests', 'Gäste-Galerie teilen')}
@@ -260,7 +260,7 @@ export default function MobileEventRecapPage() {
</Text>
{guestLink ? (
<YStack space="$2" marginTop="$1">
<YStack gap="$2" marginTop="$1">
<XStack
backgroundColor={border}
padding="$3"
@@ -292,7 +292,7 @@ export default function MobileEventRecapPage() {
)}
{guestLink && activeInvite?.qr_code_data_url ? (
<YStack alignItems="center" space="$2" marginTop="$2">
<YStack alignItems="center" gap="$2" marginTop="$2">
<YStack
padding="$2"
backgroundColor="white"
@@ -315,15 +315,15 @@ export default function MobileEventRecapPage() {
) : null}
</MobileCard>
<MobileCard space="$3">
<XStack alignItems="center" space="$2">
<MobileCard gap="$3">
<XStack alignItems="center" gap="$2">
<Users size={18} color={primary} />
<Text fontSize="$md" fontWeight="800" color={textStrong}>
{t('events.recap.settings', 'Nachlauf-Optionen')}
</Text>
</XStack>
<YStack space="$1.5">
<YStack gap="$1.5">
<ToggleOption
label={t('events.recap.allowDownloads', 'Gäste dürfen Fotos laden')}
value={Boolean(event.settings?.guest_downloads_enabled)}
@@ -337,8 +337,8 @@ export default function MobileEventRecapPage() {
</YStack>
</MobileCard>
<MobileCard space="$3">
<XStack alignItems="center" space="$2">
<MobileCard gap="$3">
<XStack alignItems="center" gap="$2">
<Sparkles size={18} color={primary} />
<Text fontSize="$md" fontWeight="800" color={textStrong}>
{t('events.recap.addons', 'Galerie verlängern')}
@@ -348,7 +348,7 @@ export default function MobileEventRecapPage() {
{t('events.recap.addonBody', 'Die Online-Zeit deiner Galerie neigt sich dem Ende? Hier kannst du sie verlängern.')}
</Text>
<YStack space="$2">
<YStack gap="$2">
{addons
.filter((a) => a.key === 'gallery_extension')
.map((addon) => (
@@ -365,9 +365,9 @@ export default function MobileEventRecapPage() {
) : null}
{activeTab === 'engagement' ? (
<YStack space="$4">
<YStack gap="$4">
{engagementLoading ? (
<YStack space="$2">
<YStack gap="$2">
<SkeletonCard height={140} />
<SkeletonCard height={180} />
<SkeletonCard height={180} />
@@ -387,9 +387,9 @@ export default function MobileEventRecapPage() {
</Text>
</MobileCard>
) : (
<YStack space="$4">
<MobileCard space="$3">
<XStack alignItems="center" space="$2">
<YStack gap="$4">
<MobileCard gap="$3">
<XStack alignItems="center" gap="$2">
<TrendingUp size={18} color={primary} />
<Text fontSize="$md" fontWeight="800" color={textStrong}>
{t('events.recap.engagement.title', 'Guest engagement')}
@@ -418,8 +418,8 @@ export default function MobileEventRecapPage() {
</XStack>
</MobileCard>
<MobileCard space="$3">
<XStack alignItems="center" space="$2">
<MobileCard gap="$3">
<XStack alignItems="center" gap="$2">
<Trophy size={18} color={primary} />
<Text fontSize="$md" fontWeight="800" color={textStrong}>
{t('events.recap.engagement.leaderboards.uploadsTitle', 'Top contributors')}
@@ -430,7 +430,7 @@ export default function MobileEventRecapPage() {
{t('events.recap.engagement.leaderboards.uploadsEmpty', 'No uploads yet.')}
</Text>
) : (
<YStack space="$1.5" marginTop="$1">
<YStack gap="$1.5" marginTop="$1">
{engagement.leaderboards.uploads.slice(0, 5).map((entry, index) => (
<LeaderboardRow
key={`${entry.guest}-${entry.photos}-${index}`}
@@ -443,8 +443,8 @@ export default function MobileEventRecapPage() {
)}
</MobileCard>
<MobileCard space="$3">
<XStack alignItems="center" space="$2">
<MobileCard gap="$3">
<XStack alignItems="center" gap="$2">
<Heart size={18} color={primary} />
<Text fontSize="$md" fontWeight="800" color={textStrong}>
{t('events.recap.engagement.leaderboards.likesTitle', 'Most liked')}
@@ -455,7 +455,7 @@ export default function MobileEventRecapPage() {
{t('events.recap.engagement.leaderboards.likesEmpty', 'No likes yet.')}
</Text>
) : (
<YStack space="$1.5" marginTop="$1">
<YStack gap="$1.5" marginTop="$1">
{engagement.leaderboards.likes.slice(0, 5).map((entry, index) => (
<LeaderboardRow
key={`${entry.guest}-${entry.likes}-${index}`}
@@ -468,15 +468,15 @@ export default function MobileEventRecapPage() {
)}
</MobileCard>
<MobileCard space="$3">
<XStack alignItems="center" space="$2">
<MobileCard gap="$3">
<XStack alignItems="center" gap="$2">
<Sparkles size={18} color={primary} />
<Text fontSize="$md" fontWeight="800" color={textStrong}>
{t('events.recap.engagement.highlightsTitle', 'Highlights')}
</Text>
</XStack>
<YStack space="$2" marginTop="$1">
<XStack space="$2" alignItems="center">
<YStack gap="$2" marginTop="$1">
<XStack gap="$2" alignItems="center">
<YStack
width={72}
height={72}
@@ -519,7 +519,7 @@ export default function MobileEventRecapPage() {
</Text>
</XStack>
<YStack space="$1">
<YStack gap="$1">
<Text fontSize="$sm" fontWeight="600" color={textStrong}>
{t('events.recap.engagement.timeline', 'Uploads over time')}
</Text>
@@ -528,7 +528,7 @@ export default function MobileEventRecapPage() {
{t('events.recap.engagement.timelineEmpty', 'No timeline data yet.')}
</Text>
) : (
<YStack space="$1">
<YStack gap="$1">
{engagement.highlights.timeline.slice(-5).map((point) => (
<XStack key={point.date} alignItems="center" justifyContent="space-between">
<Text fontSize="$xs" color={muted}>
@@ -553,7 +553,7 @@ export default function MobileEventRecapPage() {
) : null}
{activeTab === 'compliance' ? (
<YStack space="$4">
<YStack gap="$4">
<DataExportsPanel variant="recap" event={event} />
</YStack>
) : null}
@@ -643,7 +643,7 @@ function LeaderboardRow({ rank, name, value }: { rank: number; name: string; val
borderColor={border}
backgroundColor={surfaceMuted}
>
<XStack alignItems="center" space="$2">
<XStack alignItems="center" gap="$2">
<Text fontSize="$xs" color={muted} fontWeight="700">
#{rank}
</Text>