import React from 'react'; import { useNavigate } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; import { useQuery } from '@tanstack/react-query'; import { Check, Package as PackageIcon } 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 { OnboardingShell } from '../components/OnboardingShell'; import { MobileCard, CTAButton, PillBadge } from '../components/Primitives'; import { getPackages, getTenantPackagesOverview, Package, trackOnboarding } from '../../api'; import { ADMIN_WELCOME_BASE_PATH, ADMIN_WELCOME_EVENT_PATH, ADMIN_WELCOME_SUMMARY_PATH, adminPath } from '../../constants'; import { getSelectedPackageId, setSelectedPackageId } from '../lib/onboardingSelection'; import { useAdminTheme } from '../theme'; export default function WelcomePackagesPage() { const navigate = useNavigate(); const { t } = useTranslation('onboarding'); const { muted } = useAdminTheme(); const [selectedId, setSelectedId] = React.useState(() => getSelectedPackageId()); const { data: overview } = useQuery({ queryKey: ['mobile', 'onboarding', 'packages-overview'], queryFn: () => getTenantPackagesOverview({ force: true }), staleTime: 60_000, }); const { data: packages, isLoading, isError } = useQuery({ queryKey: ['mobile', 'onboarding', 'packages-list'], queryFn: () => getPackages('endcustomer'), staleTime: 60_000, }); const hasActivePackage = Boolean(overview?.activePackage) || Boolean(overview?.packages?.some((pkg) => pkg.active)); React.useEffect(() => { if (!hasActivePackage) { return; } setSelectedPackageId(null); navigate(ADMIN_WELCOME_EVENT_PATH, { replace: true }); }, [hasActivePackage, navigate]); const handleSelect = (pkg: Package) => { setSelectedId(pkg.id); setSelectedPackageId(pkg.id); void trackOnboarding('package_selected', { package_id: pkg.id, package_name: pkg.name }); }; return ( navigate(ADMIN_WELCOME_BASE_PATH)} onSkip={() => navigate(adminPath('/mobile/billing#packages'))} skipLabel={t('packages.cta.billing.button', 'Open billing')} > {isLoading ? ( {t('packages.state.loading', 'Loading packages …')} ) : isError ? ( {t('packages.state.errorTitle', 'Failed to load')} {t('packages.state.errorDescription', 'Please try again or contact support.')} ) : (packages?.length ?? 0) === 0 ? ( {t('packages.state.emptyTitle', 'Catalogue is empty')} {t('packages.state.emptyDescription', 'No packages are currently available. Reach out to support to enable new offers.')} ) : ( {packages?.map((pkg) => ( handleSelect(pkg)} /> ))} )} {t('packages.step.title', 'Activate the right plan')} {t('packages.step.description', 'Secure capacity for your next event. Upgrade at any time – only pay for what you need.')} navigate(ADMIN_WELCOME_SUMMARY_PATH)} disabled={!selectedId} fullWidth={false} /> navigate(adminPath('/mobile/billing#packages'))} fullWidth={false} /> ); } function PackageCard({ pkg, selected, onSelect, }: { pkg: Package; selected: boolean; onSelect: () => void; }) { const { t } = useTranslation('onboarding'); const { primary, border, accentSoft, muted } = useAdminTheme(); const badges = [ t('packages.card.badges.photos', { count: pkg.max_photos ?? 0, defaultValue: 'Unlimited photos' } as any), t('packages.card.badges.guests', { count: pkg.max_guests ?? 0, defaultValue: 'Unlimited guests' } as any), t('packages.card.badges.days', { count: pkg.gallery_days ?? 0, defaultValue: 'Unlimited days' } as any), ]; return ( {pkg.name} {t('packages.card.description', 'Ready for your next event right away.')} {selected ? t('packages.card.selected', 'Selected') : t('packages.card.select', 'Select package')} {badges.map((badge) => ( {badge as any} ))} {selected ? ( {t('packages.card.selected', 'Selected')} ) : null} ); }