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

@@ -389,7 +389,7 @@ export default function MobileBrandingPage() {
return (
<>
<MobileCard space="$3">
<MobileCard gap="$3">
<Text fontSize="$sm" fontWeight="700" color={textStrong}>
{t('events.watermark.previewTitle', 'Watermark Preview')}
</Text>
@@ -421,7 +421,7 @@ export default function MobileBrandingPage() {
/>
) : null}
<MobileCard space="$3">
<MobileCard gap="$3">
<Text fontSize="$md" fontWeight="800" color={textStrong}>
{t('events.watermark.title', 'Wasserzeichen')}
</Text>
@@ -449,14 +449,14 @@ export default function MobileBrandingPage() {
</MobileField>
{resolvedMode === 'custom' && !controlsLocked ? (
<YStack space="$2">
<YStack gap="$2">
<Text fontSize="$sm" fontWeight="700" color={textStrong}>
{t('events.watermark.upload', 'Wasserzeichen hochladen')}
</Text>
<Pressable onPress={() => document.getElementById('watermark-upload-input')?.click()}>
<XStack
alignItems="center"
space="$2"
gap="$2"
paddingHorizontal="$3.5"
paddingVertical="$2.5"
borderRadius={12}
@@ -520,7 +520,7 @@ export default function MobileBrandingPage() {
) : null}
</MobileCard>
<MobileCard space="$3">
<MobileCard gap="$3">
<Text fontSize="$md" fontWeight="800" color={textStrong}>
{t('events.watermark.placement', 'Position & Größe')}
</Text>
@@ -603,8 +603,8 @@ export default function MobileBrandingPage() {
<ContextHelpLink slug="event-branding-assets" />
</XStack>
<MobileCard space="$2">
<XStack space="$2">
<MobileCard gap="$2">
<XStack gap="$2">
<TabButton label={t('events.branding.titleShort', 'Branding')} active={activeTab === 'branding'} onPress={() => setActiveTab('branding')} />
<TabButton label={t('events.watermark.tab', 'Wasserzeichen')} active={activeTab === 'watermark'} onPress={() => setActiveTab('watermark')} />
</XStack>
@@ -612,20 +612,20 @@ export default function MobileBrandingPage() {
{activeTab === 'branding' ? (
<>
<MobileCard space="$3">
<MobileCard gap="$3">
<Text fontSize="$sm" fontWeight="700" color={textStrong}>
{t('events.branding.previewTitle', 'Guest App Preview')}
</Text>
<YStack borderRadius={16} borderWidth={1} borderColor={previewBorder} backgroundColor={previewBackground} padding="$3" space="$2" alignItems="center">
<YStack borderRadius={16} borderWidth={1} borderColor={previewBorder} backgroundColor={previewBackground} padding="$3" gap="$2" alignItems="center">
<YStack width="100%" borderRadius={12} backgroundColor={previewSurface} borderWidth={1} borderColor={previewBorder} overflow="hidden">
<YStack
height={64}
style={{ background: `linear-gradient(135deg, ${previewForm.primary}, ${previewForm.accent})` }}
/>
<YStack padding="$3" space="$2">
<YStack padding="$3" gap="$2">
<XStack
alignItems="center"
space="$2"
gap="$2"
flexDirection={previewForm.logoPosition === 'center' ? 'column' : previewForm.logoPosition === 'right' ? 'row-reverse' : 'row'}
justifyContent={previewForm.logoPosition === 'center' ? 'center' : 'flex-start'}
>
@@ -665,7 +665,7 @@ export default function MobileBrandingPage() {
</Text>
</YStack>
</XStack>
<XStack space="$2" marginTop="$1">
<XStack gap="$2" marginTop="$1">
<ColorSwatch color={previewForm.primary} label={t('events.branding.primary', 'Primary')} borderColor={previewBorder} />
<ColorSwatch color={previewForm.accent} label={t('events.branding.accent', 'Accent')} borderColor={previewBorder} />
<ColorSwatch color={previewBackground} label={t('events.branding.background', 'Background')} borderColor={previewBorder} />
@@ -701,11 +701,11 @@ export default function MobileBrandingPage() {
) : null}
<>
<MobileCard space="$3">
<MobileCard gap="$3">
<Text fontSize="$md" fontWeight="800" color={textStrong}>
{t('events.branding.mode', 'Theme')}
</Text>
<XStack space="$2">
<XStack gap="$2">
<ModeButton
label={t('events.branding.modeLight', 'Light')}
active={form.mode === 'light'}
@@ -727,7 +727,7 @@ export default function MobileBrandingPage() {
</XStack>
</MobileCard>
<MobileCard space="$3">
<MobileCard gap="$3">
<Text fontSize="$md" fontWeight="800" color={textStrong}>
{t('events.branding.colors', 'Colors')}
</Text>
@@ -757,7 +757,7 @@ export default function MobileBrandingPage() {
/>
</MobileCard>
<MobileCard space="$3">
<MobileCard gap="$3">
<Text fontSize="$md" fontWeight="800" color={textStrong}>
{t('events.branding.fonts', 'Fonts')}
</Text>
@@ -786,7 +786,7 @@ export default function MobileBrandingPage() {
<Text fontSize="$sm" fontWeight="700" color={textStrong}>
{t('events.branding.fontSize', 'Font Size')}
</Text>
<XStack space="$2">
<XStack gap="$2">
<ModeButton
label={t('events.branding.fontSizeSmall', 'S')}
active={form.fontSize === 's'}
@@ -808,14 +808,14 @@ export default function MobileBrandingPage() {
</XStack>
</MobileCard>
<MobileCard space="$3">
<MobileCard gap="$3">
<Text fontSize="$md" fontWeight="800" color={textStrong}>
{t('events.branding.logo', 'Logo')}
</Text>
<Text fontSize="$sm" color={muted}>
{t('events.branding.logoHint', 'Upload a logo or use an emoji for the guest header.')}
</Text>
<XStack space="$2">
<XStack gap="$2">
<ModeButton
label={t('events.branding.logoModeUpload', 'Upload')}
active={form.logoMode === 'upload'}
@@ -847,7 +847,7 @@ export default function MobileBrandingPage() {
padding="$3"
alignItems="center"
justifyContent="center"
space="$2"
gap="$2"
>
{form.logoDataUrl ? (
<>
@@ -856,7 +856,7 @@ export default function MobileBrandingPage() {
alt={t('events.branding.logoAlt', 'Logo')}
style={{ maxHeight: 80, maxWidth: '100%', objectFit: 'contain' }}
/>
<XStack space="$2">
<XStack gap="$2">
<CTAButton
label={t('events.branding.replaceLogo', 'Replace logo')}
onPress={() => document.getElementById('branding-logo-input')?.click()}
@@ -868,7 +868,7 @@ export default function MobileBrandingPage() {
>
<XStack
alignItems="center"
space="$1.5"
gap="$1.5"
paddingHorizontal="$3"
paddingVertical="$2"
borderRadius={12}
@@ -892,7 +892,7 @@ export default function MobileBrandingPage() {
>
<XStack
alignItems="center"
space="$2"
gap="$2"
paddingHorizontal="$3.5"
paddingVertical="$2.5"
borderRadius={12}
@@ -939,7 +939,7 @@ export default function MobileBrandingPage() {
<Text fontSize="$sm" fontWeight="700" color={textStrong}>
{t('events.branding.logoPosition', 'Position')}
</Text>
<XStack space="$2">
<XStack gap="$2">
<ModeButton
label={t('events.branding.positionLeft', 'Left')}
active={form.logoPosition === 'left'}
@@ -962,7 +962,7 @@ export default function MobileBrandingPage() {
<Text fontSize="$sm" fontWeight="700" color={textStrong}>
{t('events.branding.logoSize', 'Size')}
</Text>
<XStack space="$2">
<XStack gap="$2">
<ModeButton
label={t('events.branding.logoSizeSmall', 'S')}
active={form.logoSize === 's'}
@@ -984,14 +984,14 @@ export default function MobileBrandingPage() {
</XStack>
</MobileCard>
<MobileCard space="$3">
<MobileCard gap="$3">
<Text fontSize="$md" fontWeight="800" color={textStrong}>
{t('events.branding.buttons', 'Buttons & Links')}
</Text>
<Text fontSize="$sm" color={muted}>
{t('events.branding.buttonsHint', 'Style, radius, and link color for CTA buttons.')}
</Text>
<XStack space="$2">
<XStack gap="$2">
<ModeButton
label={t('events.branding.buttonFilled', 'Filled')}
active={form.buttonStyle === 'filled'}
@@ -1039,7 +1039,7 @@ export default function MobileBrandingPage() {
renderWatermarkTab()
)}
<YStack space="$2">
<YStack gap="$2">
<CTAButton label={saving ? t('events.branding.saving', 'Saving...') : t('events.branding.save', 'Save Branding')} onPress={() => handleSave()} />
<Pressable disabled={loading || saving} onPress={handleReset}>
<XStack
@@ -1050,7 +1050,7 @@ export default function MobileBrandingPage() {
backgroundColor={surface}
borderWidth={1}
borderColor={border}
space="$2"
gap="$2"
>
<RefreshCcw size={16} color={textStrong} />
<Text fontSize="$sm" color={textStrong} fontWeight="700">
@@ -1067,7 +1067,7 @@ export default function MobileBrandingPage() {
footer={null}
bottomOffsetPx={120}
>
<YStack space="$2">
<YStack gap="$2">
{fontsLoading ? (
Array.from({ length: 4 }).map((_, idx) => <SkeletonCard key={`font-sk-${idx}`} height={48} />)
) : fonts.length === 0 ? (
@@ -1228,11 +1228,11 @@ function ColorField({
}) {
const { textStrong, muted } = useAdminTheme();
return (
<YStack space="$2" opacity={disabled ? 0.6 : 1}>
<YStack gap="$2" opacity={disabled ? 0.6 : 1}>
<Text fontSize="$sm" fontWeight="700" color={textStrong}>
{label}
</Text>
<XStack alignItems="center" space="$2">
<XStack alignItems="center" gap="$2">
<MobileColorInput
value={value}
onChange={(event) => onChange(event.target.value)}
@@ -1249,7 +1249,7 @@ function ColorField({
function ColorSwatch({ color, label, borderColor }: { color: string; label: string; borderColor?: string }) {
const { border, muted } = useAdminTheme();
return (
<YStack alignItems="center" space="$1">
<YStack alignItems="center" gap="$1">
<YStack width={40} height={40} borderRadius={12} borderWidth={1} borderColor={borderColor ?? border} backgroundColor={color} />
<Text fontSize="$xs" color={muted}>
{label}
@@ -1276,7 +1276,7 @@ function InputField({
const { primary } = useAdminTheme();
return (
<MobileField label={label}>
<XStack alignItems="center" space="$2">
<XStack alignItems="center" gap="$2">
<MobileInput
value={value}
placeholder={placeholder}
@@ -1316,7 +1316,7 @@ function LabeledSlider({
}) {
const { textStrong, muted, primary, border, surface } = useAdminTheme();
return (
<YStack space="$1.5">
<YStack gap="$1.5">
<XStack alignItems="center" justifyContent="space-between">
<Text fontSize="$sm" fontWeight="700" color={textStrong}>
{label}
@@ -1367,7 +1367,7 @@ function PositionGrid({
];
return (
<YStack space="$2">
<YStack gap="$2">
<Text fontSize="$sm" fontWeight="700" color={textStrong}>
Position
</Text>
@@ -1503,8 +1503,8 @@ function InfoBadge({ icon, text, tone = 'info' }: { icon?: React.ReactNode; text
const color = tone === 'danger' ? dangerText : textStrong;
return (
<MobileCard space="$2" backgroundColor={background} borderColor={border}>
<XStack space="$2" alignItems="center">
<MobileCard gap="$2" backgroundColor={background} borderColor={border}>
<XStack gap="$2" alignItems="center">
{icon}
<Text fontSize="$sm" color={color}>
{text}
@@ -1529,7 +1529,7 @@ function UpgradeCard({
return (
<MobileCard
space="$4"
gap="$4"
padding="$6"
alignItems="center"
justifyContent="center"
@@ -1547,7 +1547,7 @@ function UpgradeCard({
>
<Lock size={32} color={primary} />
</YStack>
<YStack space="$2" alignItems="center">
<YStack gap="$2" alignItems="center">
<Text fontSize="$xl" fontWeight="900" color={textStrong} textAlign="center">
{title}
</Text>