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

@@ -588,8 +588,8 @@ export default function MobileEventTasksPage() {
}
const taskPanel = assignedTasks.length === 0 ? (
<YStack space="$2">
<MobileCard space="$2">
<YStack gap="$2">
<MobileCard gap="$2">
<Text fontSize={13} fontWeight="700" color={text}>
{t('events.tasks.emptyTitle', 'No photo tasks yet')}
</Text>
@@ -602,7 +602,7 @@ export default function MobileEventTasksPage() {
{limitReachedHint ? ` ${limitReachedHint}` : ''}
</Text>
) : null}
<XStack space="$2">
<XStack gap="$2">
<CTAButton
label={t('events.tasks.emptyActionTask', 'Add photo task')}
onPress={() => setShowTaskSheet(true)}
@@ -631,7 +631,7 @@ export default function MobileEventTasksPage() {
setShowTaskSheet(true);
}}
title={
<XStack alignItems="center" space="$2">
<XStack alignItems="center" gap="$2">
<YStack
width={28}
height={28}
@@ -669,7 +669,7 @@ export default function MobileEventTasksPage() {
setActiveTab('collections');
}}
title={
<XStack alignItems="center" space="$2">
<XStack alignItems="center" gap="$2">
<YStack
width={28}
height={28}
@@ -698,9 +698,9 @@ export default function MobileEventTasksPage() {
</YGroup>
</YStack>
) : (
<YStack space="$2">
<XStack alignItems="baseline" justifyContent="space-between" flexWrap="wrap" space="$2">
<XStack alignItems="baseline" space="$2" flexWrap="wrap">
<YStack gap="$2">
<XStack alignItems="baseline" justifyContent="space-between" flexWrap="wrap" gap="$2">
<XStack alignItems="baseline" gap="$2" flexWrap="wrap">
<Text fontSize="$sm" fontWeight="800" color={text}>
{t('events.tasks.assignedTitle', 'Task list')}
</Text>
@@ -718,11 +718,11 @@ export default function MobileEventTasksPage() {
) : null}
</XStack>
{selectionMode ? (
<MobileCard padding="$2.5" space="$2">
<MobileCard padding="$2.5" gap="$2">
<Text fontSize={12} fontWeight="700" color={text}>
{t('events.tasks.selectionCount', '{{count}} ausgewählt', { count: selectedTaskIds.size })}
</Text>
<XStack space="$2">
<XStack gap="$2">
<CTAButton
label={t('events.tasks.bulkRemove', 'Auswahl löschen')}
tone="danger"
@@ -751,7 +751,7 @@ export default function MobileEventTasksPage() {
onPointerLeave={cancelLongPress}
onPointerCancel={cancelLongPress}
title={
<XStack alignItems="center" space="$2">
<XStack alignItems="center" gap="$2">
{selectionMode ? (
<Checkbox
size="$3"
@@ -779,7 +779,7 @@ export default function MobileEventTasksPage() {
}
iconAfter={
selectionMode ? null : (
<XStack space="$2" alignItems="center">
<XStack gap="$2" alignItems="center">
{task.emotion ? (
<Tag label={task.emotion.name ?? ''} color={task.emotion.color ?? text} />
) : null}
@@ -811,7 +811,7 @@ export default function MobileEventTasksPage() {
);
const libraryPanel = (
<YStack space="$2">
<YStack gap="$2">
<XStack alignItems="center" justifyContent="space-between" flexWrap="wrap">
<Text fontSize="$sm" fontWeight="700" color={text}>
{t('events.tasks.tabs.library', 'Task Library')}
@@ -865,7 +865,7 @@ export default function MobileEventTasksPage() {
) : null
}
iconAfter={
<XStack space="$1.5" alignItems="center">
<XStack gap="$1.5" alignItems="center">
<Pressable
onPress={() => {
if (!canAddTasks) {
@@ -875,7 +875,7 @@ export default function MobileEventTasksPage() {
quickAssign(task.id);
}}
>
<XStack alignItems="center" space="$1">
<XStack alignItems="center" gap="$1">
<Plus size={14} color={canAddTasks ? primary : muted} />
<Text fontSize={12} fontWeight="600" color={canAddTasks ? primary : muted}>
{assigningId === task.id ? t('common.processing', '...') : t('events.tasks.add', 'Add')}
@@ -896,7 +896,7 @@ export default function MobileEventTasksPage() {
);
const collectionsPanel = (
<YStack space="$2">
<YStack gap="$2">
<Text fontSize="$xs" color={muted}>
{t('events.tasks.importHint', 'Use predefined packs for your event type.')}
</Text>
@@ -937,7 +937,7 @@ export default function MobileEventTasksPage() {
) : null
}
iconAfter={
<XStack space="$1.5" alignItems="center">
<XStack gap="$1.5" alignItems="center">
<Button
size="$2"
backgroundColor={withAlpha(primary, 0.12)}
@@ -969,7 +969,7 @@ export default function MobileEventTasksPage() {
);
const emotionsPanel = (
<YStack space="$2">
<YStack gap="$2">
<XStack alignItems="center" justifyContent="space-between" flexWrap="wrap">
<Text fontSize="$sm" fontWeight="700" color={text}>
{t('events.tasks.tabs.emotions', 'Emotions')}
@@ -1002,12 +1002,12 @@ export default function MobileEventTasksPage() {
hoverTheme
pressTheme
title={
<XStack alignItems="center" space="$2">
<XStack alignItems="center" gap="$2">
<Tag label={emotion.name ?? ''} color={emotion.color ?? border} />
</XStack>
}
iconAfter={
<XStack space="$2">
<XStack gap="$2">
<Pressable
onPress={() => {
setEditingEmotion(emotion);
@@ -1039,7 +1039,7 @@ export default function MobileEventTasksPage() {
title={t('events.tasks.title', 'Photo tasks for guests')}
onBack={back}
headerActions={
<XStack space="$2">
<XStack gap="$2">
<HeaderActionButton onPress={() => load()} ariaLabel={t('common.refresh', 'Refresh')}>
<RefreshCcw size={18} color={text} />
</HeaderActionButton>
@@ -1061,7 +1061,7 @@ export default function MobileEventTasksPage() {
) : null}
{loading ? (
<YStack space="$2">
<YStack gap="$2">
{Array.from({ length: 4 }).map((_, idx) => (
<SkeletonCard key={`tsk-${idx}`} height={70} />
))}
@@ -1074,7 +1074,7 @@ export default function MobileEventTasksPage() {
backgroundColor={surface}
padding="$3"
>
<YStack space="$3">
<YStack gap="$3">
<Card
borderRadius={18}
borderWidth={1}
@@ -1082,8 +1082,8 @@ export default function MobileEventTasksPage() {
backgroundColor={surfaceMuted}
padding="$3"
>
<YStack space="$2">
<XStack alignItems="center" justifyContent="space-between" space="$2">
<YStack gap="$2">
<XStack alignItems="center" justifyContent="space-between" gap="$2">
<Text fontSize="$xs" fontWeight="700" color={text}>
{t('events.tasks.toggle.title', 'Photo tasks for guests')}
</Text>
@@ -1121,7 +1121,7 @@ export default function MobileEventTasksPage() {
<Text fontSize="$xs" fontWeight="700" color={text}>
{t('events.tasks.toggle.switchLabel', 'Photo task mode')}
</Text>
<XStack alignItems="center" space="$1.5">
<XStack alignItems="center" gap="$1.5">
<Switch
size="$3"
checked={tasksEnabled}
@@ -1205,7 +1205,7 @@ export default function MobileEventTasksPage() {
<Tabs.Content value="assigned" paddingTop="$2">
<Card borderRadius={18} borderWidth={1} borderColor={border} backgroundColor={surface} padding="$3">
<YStack space="$2">
<YStack gap="$2">
<Card
borderRadius={16}
borderWidth={1}
@@ -1213,7 +1213,7 @@ export default function MobileEventTasksPage() {
backgroundColor={surfaceMuted}
padding="$2.5"
>
<XStack alignItems="center" space="$2">
<XStack alignItems="center" gap="$2">
<XStack flex={1}>
<MobileInput
type="search"
@@ -1226,7 +1226,7 @@ export default function MobileEventTasksPage() {
<Pressable onPress={() => setShowEmotionFilterSheet(true)}>
<XStack
alignItems="center"
space="$1.5"
gap="$1.5"
paddingVertical="$2"
paddingHorizontal="$3"
borderRadius={14}
@@ -1286,7 +1286,7 @@ export default function MobileEventTasksPage() {
/>
}
>
<YStack space="$2">
<YStack gap="$2">
{!canAddTasks ? (
<Text fontSize={12} fontWeight="600" color={dangerText}>
{limitReachedMessage}
@@ -1338,7 +1338,7 @@ export default function MobileEventTasksPage() {
/>
}
>
<YStack space="$2">
<YStack gap="$2">
{!canAddTasks ? (
<Text fontSize={12} fontWeight="600" color={dangerText}>
{limitReachedMessage}
@@ -1381,7 +1381,7 @@ export default function MobileEventTasksPage() {
/>
}
>
<YStack space="$2">
<YStack gap="$2">
<MobileField label={t('events.tasks.emotionName', 'Name')}>
<MobileInput
type="text"
@@ -1416,8 +1416,8 @@ export default function MobileEventTasksPage() {
setShowEmotionFilterSheet(false);
}}
>
<YStack space="$2">
<XStack alignItems="center" space="$2">
<YStack gap="$2">
<XStack alignItems="center" gap="$2">
<RadioGroup.Item value="">
<RadioGroup.Indicator />
</RadioGroup.Item>
@@ -1426,7 +1426,7 @@ export default function MobileEventTasksPage() {
</Text>
</XStack>
{emotions.map((emotion) => (
<XStack key={`emo-filter-${emotion.id}`} alignItems="center" space="$2">
<XStack key={`emo-filter-${emotion.id}`} alignItems="center" gap="$2">
<RadioGroup.Item value={String(emotion.id)}>
<RadioGroup.Indicator />
</RadioGroup.Item>
@@ -1458,7 +1458,7 @@ export default function MobileEventTasksPage() {
maxWidth={420}
width="90%"
>
<YStack space="$3">
<YStack gap="$3">
<AlertDialog.Title>
<Text fontSize="$md" fontWeight="800" color={text}>
{t('events.tasks.removeTitle', 'Remove photo task?')}
@@ -1471,7 +1471,7 @@ export default function MobileEventTasksPage() {
: t('events.tasks.removeBodyFallback', 'This will remove the photo task from the event.')}
</Text>
</AlertDialog.Description>
<XStack space="$2" justifyContent="flex-end">
<XStack gap="$2" justifyContent="flex-end">
<AlertDialog.Cancel asChild>
<CTAButton
label={t('common.cancel', 'Cancel')}
@@ -1513,7 +1513,7 @@ export default function MobileEventTasksPage() {
maxWidth={420}
width="90%"
>
<YStack space="$3">
<YStack gap="$3">
<AlertDialog.Title>
<Text fontSize="$md" fontWeight="800" color={text}>
{t('events.tasks.bulkRemoveTitle', 'Auswahl löschen')}
@@ -1524,7 +1524,7 @@ export default function MobileEventTasksPage() {
{t('events.tasks.bulkRemoveBody', 'This will remove the selected photo tasks from the event.')}
</Text>
</AlertDialog.Description>
<XStack space="$2" justifyContent="flex-end">
<XStack gap="$2" justifyContent="flex-end">
<AlertDialog.Cancel asChild>
<CTAButton
label={t('common.cancel', 'Cancel')}