upgrade to tamagui v2 and guest pwa overhaul
This commit is contained in:
@@ -89,7 +89,7 @@ function SectionHeader({
|
||||
const subtitleSize = compact ? '$xs' : '$sm';
|
||||
const spacing = compact ? '$1' : '$1.5';
|
||||
return (
|
||||
<YStack space={spacing}>
|
||||
<YStack gap={spacing}>
|
||||
<XStack alignItems="center" justifyContent="space-between">
|
||||
<Text fontSize={titleSize} fontWeight="800" color={theme.textStrong}>
|
||||
{title}
|
||||
@@ -222,7 +222,7 @@ export default function MobileDashboardPage() {
|
||||
return (
|
||||
<MobileShell activeTab="home" title={t('mobileDashboard.title', 'Dashboard')}>
|
||||
<DashboardCard padding="$0">
|
||||
<YStack padding="$3" space="$2">
|
||||
<YStack padding="$3" gap="$2">
|
||||
<SectionHeader
|
||||
title={t('dashboard:overview.title', 'At a glance')}
|
||||
showSeparator={false}
|
||||
@@ -231,7 +231,7 @@ export default function MobileDashboardPage() {
|
||||
/>
|
||||
</YStack>
|
||||
<Separator backgroundColor={theme.border} opacity={0.6} />
|
||||
<YStack padding="$3" space="$2.5">
|
||||
<YStack padding="$3" gap="$2.5">
|
||||
{/* 1. LIFECYCLE HERO */}
|
||||
<LifecycleHero
|
||||
event={activeEvent}
|
||||
@@ -326,7 +326,7 @@ function LifecycleHero({
|
||||
|
||||
if (phase === 'live') {
|
||||
return (
|
||||
<YStack space="$2">
|
||||
<YStack gap="$2">
|
||||
<Header />
|
||||
<DashboardCard
|
||||
variant={cardVariant}
|
||||
@@ -335,10 +335,10 @@ function LifecycleHero({
|
||||
borderColor="transparent"
|
||||
style={{ backgroundImage: 'linear-gradient(135deg, #4F46E5 0%, #4338CA 100%)' }}
|
||||
>
|
||||
<YStack space={isEmbedded ? '$2.5' : '$3'}>
|
||||
<YStack gap={isEmbedded ? '$2.5' : '$3'}>
|
||||
<XStack alignItems="center" justifyContent="space-between">
|
||||
<YStack space="$1">
|
||||
<XStack alignItems="center" space="$2">
|
||||
<YStack gap="$1">
|
||||
<XStack alignItems="center" gap="$2">
|
||||
<YStack width={8} height={8} borderRadius={4} backgroundColor="#22C55E" />
|
||||
<Text color="white" fontWeight="700" fontSize="$xs" textTransform="uppercase" letterSpacing={1}>
|
||||
{t('dashboard:liveNow.status', 'Happening Now')}
|
||||
@@ -404,11 +404,11 @@ function LifecycleHero({
|
||||
|
||||
if (phase === 'post') {
|
||||
return (
|
||||
<YStack space="$2">
|
||||
<YStack gap="$2">
|
||||
<Header />
|
||||
<DashboardCard variant={cardVariant} padding={cardPadding}>
|
||||
<YStack space={isEmbedded ? '$2.5' : '$3'}>
|
||||
<XStack alignItems="center" space="$2.5">
|
||||
<YStack gap={isEmbedded ? '$2.5' : '$3'}>
|
||||
<XStack alignItems="center" gap="$2.5">
|
||||
<YStack width={40} height={40} borderRadius={20} backgroundColor={theme.successText} alignItems="center" justifyContent="center">
|
||||
<CheckCircle2 size={20} color="white" />
|
||||
</YStack>
|
||||
@@ -427,7 +427,7 @@ function LifecycleHero({
|
||||
height={48}
|
||||
borderRadius={16}
|
||||
>
|
||||
<XStack alignItems="center" space="$2">
|
||||
<XStack alignItems="center" gap="$2">
|
||||
<Download size={16} color="white" />
|
||||
<Text fontSize="$sm" fontWeight="800" color="white">
|
||||
{t('events.recap.downloadAll', 'Download photos')}
|
||||
@@ -443,7 +443,7 @@ function LifecycleHero({
|
||||
height={48}
|
||||
borderRadius={16}
|
||||
>
|
||||
<XStack alignItems="center" space="$2">
|
||||
<XStack alignItems="center" gap="$2">
|
||||
<Text fontSize="$sm" fontWeight="800" color={theme.textStrong}>
|
||||
{t('events.recap.openRecap', 'Open recap')}
|
||||
</Text>
|
||||
@@ -458,7 +458,7 @@ function LifecycleHero({
|
||||
|
||||
// SETUP
|
||||
return (
|
||||
<YStack space="$2">
|
||||
<YStack gap="$2">
|
||||
<Header />
|
||||
{showQuickControls ? (
|
||||
<XStack
|
||||
@@ -472,7 +472,7 @@ function LifecycleHero({
|
||||
paddingVertical="$2"
|
||||
>
|
||||
<Pressable onPress={() => navigate(adminPath(`/mobile/events/${event.slug}/edit`))}>
|
||||
<XStack alignItems="center" space="$1.5">
|
||||
<XStack alignItems="center" gap="$1.5">
|
||||
<Settings size={16} color={theme.primary} />
|
||||
<Text fontSize="$sm" fontWeight="700" color={theme.textStrong}>
|
||||
{t('dashboard:readiness.quickSettings', 'Event settings')}
|
||||
@@ -480,8 +480,8 @@ function LifecycleHero({
|
||||
</XStack>
|
||||
</Pressable>
|
||||
|
||||
<XStack alignItems="center" space="$3">
|
||||
<YStack alignItems="center" space="$1">
|
||||
<XStack alignItems="center" gap="$3">
|
||||
<YStack alignItems="center" gap="$1">
|
||||
<Text fontSize="$xs" color={theme.muted} textTransform="uppercase" letterSpacing={0.8}>
|
||||
{t('dashboard:readiness.publishToggle', 'Live')}
|
||||
</Text>
|
||||
@@ -499,13 +499,13 @@ function LifecycleHero({
|
||||
</XStack>
|
||||
) : null}
|
||||
<DashboardCard variant={cardVariant} padding={cardPadding}>
|
||||
<YStack space={isEmbedded ? '$2.5' : '$3'}>
|
||||
<YStack gap={isEmbedded ? '$2.5' : '$3'}>
|
||||
<XStack alignItems="center" justifyContent="space-between">
|
||||
<YStack>
|
||||
<Text fontSize="$xs" color={theme.muted} fontWeight="700" textTransform="uppercase">
|
||||
{t('dashboard:upcoming.status.planning', 'Countdown')}
|
||||
</Text>
|
||||
<Text fontSize="$2xl" fontWeight="900" color={theme.primary}>
|
||||
<Text fontSize="$xxl" fontWeight="900" color={theme.primary}>
|
||||
{daysToGo}{' '}
|
||||
<Text fontSize="$sm" color={theme.muted} fontWeight="500">
|
||||
{t('management:galleryStatus.daysLabel', 'days')}
|
||||
@@ -518,7 +518,7 @@ function LifecycleHero({
|
||||
</XStack>
|
||||
|
||||
{showNextStep && nextStep ? (
|
||||
<YStack space="$2">
|
||||
<YStack gap="$2">
|
||||
<Text fontSize="$xs" fontWeight="700" color={theme.muted} textTransform="uppercase" letterSpacing={1}>
|
||||
{t('dashboard:readiness.nextStepTitle', 'Next step')}
|
||||
</Text>
|
||||
@@ -531,7 +531,7 @@ function LifecycleHero({
|
||||
paddingHorizontal="$3"
|
||||
onPress={() => navigate(adminPath(nextStep.targetPath))}
|
||||
title={
|
||||
<XStack alignItems="center" space="$2">
|
||||
<XStack alignItems="center" gap="$2">
|
||||
<Circle size={18} color={theme.primary} strokeWidth={2.5} />
|
||||
<Text fontSize="$sm" fontWeight="700" color={theme.textStrong}>
|
||||
{nextStep.label}
|
||||
@@ -546,7 +546,7 @@ function LifecycleHero({
|
||||
) : undefined
|
||||
}
|
||||
iconAfter={
|
||||
<XStack alignItems="center" space="$1">
|
||||
<XStack alignItems="center" gap="$1">
|
||||
<PillBadge tone="success">{nextStep.ctaLabel}</PillBadge>
|
||||
<ChevronRight size={16} color={theme.muted} />
|
||||
</XStack>
|
||||
@@ -665,7 +665,7 @@ function UnifiedToolGrid({ event, navigate, permissions, isMember, isCompleted }
|
||||
|
||||
return (
|
||||
<DashboardCard padding="$0">
|
||||
<YStack padding="$3.5" space="$2">
|
||||
<YStack padding="$3.5" gap="$2">
|
||||
<SectionHeader
|
||||
title={t('dashboard:quickActions.title', 'Quick actions')}
|
||||
subtitle={t('dashboard:quickActions.description', 'Jump straight to the most important actions.')}
|
||||
@@ -674,9 +674,9 @@ function UnifiedToolGrid({ event, navigate, permissions, isMember, isCompleted }
|
||||
/>
|
||||
</YStack>
|
||||
<Separator backgroundColor={theme.border} opacity={0.6} />
|
||||
<YStack padding="$3.5" space="$3">
|
||||
<YStack padding="$3.5" gap="$3">
|
||||
{sections.map((section) => (
|
||||
<YStack key={section.title} space="$2">
|
||||
<YStack key={section.title} gap="$2">
|
||||
<Text fontSize="$xs" fontWeight="700" color={theme.muted} textTransform="uppercase" letterSpacing={1}>
|
||||
{section.title}
|
||||
</Text>
|
||||
@@ -692,7 +692,7 @@ function UnifiedToolGrid({ event, navigate, permissions, isMember, isCompleted }
|
||||
paddingHorizontal="$3"
|
||||
onPress={() => navigate(adminPath(item.path))}
|
||||
title={
|
||||
<XStack alignItems="center" space="$2.5">
|
||||
<XStack alignItems="center" gap="$2.5">
|
||||
<XStack
|
||||
width={32}
|
||||
height={32}
|
||||
@@ -729,7 +729,7 @@ function RecentPhotosSection({ photos, navigate, slug }: { photos: TenantPhoto[]
|
||||
|
||||
return (
|
||||
<DashboardCard>
|
||||
<YStack space="$2">
|
||||
<YStack gap="$2">
|
||||
<XStack alignItems="center" justifyContent="space-between">
|
||||
<Text fontSize="$xs" fontWeight="700" color={theme.muted} textTransform="uppercase" letterSpacing={1}>
|
||||
{t('photos.recentTitle', 'Latest Uploads')}
|
||||
@@ -749,7 +749,7 @@ function RecentPhotosSection({ photos, navigate, slug }: { photos: TenantPhoto[]
|
||||
|
||||
<Separator backgroundColor={theme.border} opacity={0.6} />
|
||||
|
||||
<XStack space="$2" overflow="scroll" paddingVertical="$1">
|
||||
<XStack gap="$2" overflow="scroll" paddingVertical="$1">
|
||||
{photos.map((photo) => (
|
||||
<Pressable key={photo.id} onPress={() => navigate(adminPath(`/mobile/events/${slug}/control-room`))}>
|
||||
<YStack
|
||||
@@ -762,7 +762,7 @@ function RecentPhotosSection({ photos, navigate, slug }: { photos: TenantPhoto[]
|
||||
borderColor={theme.border}
|
||||
>
|
||||
{photo.thumbnail_url ? (
|
||||
<Image source={{ uri: photo.thumbnail_url }} width={80} height={80} resizeMode="cover" />
|
||||
<Image src={photo.thumbnail_url} width={80} height={80} objectFit="cover" />
|
||||
) : (
|
||||
<YStack flex={1} alignItems="center" justifyContent="center">
|
||||
<ImageIcon size={20} color={theme.muted} />
|
||||
@@ -785,12 +785,12 @@ function AlertsSection({ event, stats, t }: any) {
|
||||
|
||||
return (
|
||||
<DashboardCard>
|
||||
<YStack space="$2">
|
||||
<YStack gap="$2">
|
||||
<Text fontSize="$xs" fontWeight="700" color={theme.muted} textTransform="uppercase" letterSpacing={1}>
|
||||
{t('management:alertsTitle', 'Alerts')}
|
||||
</Text>
|
||||
<Separator backgroundColor={theme.border} opacity={0.6} />
|
||||
<YStack space="$2">
|
||||
<YStack gap="$2">
|
||||
{limitWarnings.map((w: any, idx: number) => {
|
||||
const isDanger = w.tone === 'danger';
|
||||
const bg = isDanger ? theme.dangerBg : theme.warningBg;
|
||||
@@ -807,7 +807,7 @@ function AlertsSection({ event, stats, t }: any) {
|
||||
borderWidth={1}
|
||||
borderColor={border}
|
||||
alignItems="center"
|
||||
space="$2"
|
||||
gap="$2"
|
||||
>
|
||||
<Icon size={16} color={text} />
|
||||
<Text fontSize="$sm" color={text} fontWeight="600">
|
||||
@@ -826,7 +826,7 @@ function EmptyState({ canManage, onCreate }: any) {
|
||||
const theme = useAdminTheme();
|
||||
const { t } = useTranslation(['management', 'mobile']);
|
||||
return (
|
||||
<YStack flex={1} alignItems="center" justifyContent="center" space="$4">
|
||||
<YStack flex={1} alignItems="center" justifyContent="center" gap="$4">
|
||||
<Sparkles size={48} color={theme.primary} />
|
||||
<Text fontSize="$lg" fontWeight="800" color={theme.textStrong} textAlign="center">
|
||||
{t('mobile:header.appName', 'Event Admin')}
|
||||
|
||||
Reference in New Issue
Block a user