Files
fotospiel-app/resources/js/admin/mobile/welcome/WelcomeEventPage.tsx
Codex Agent 5f521d055f Änderungen (relevant):
- Add‑on Checkout auf Transactions + Transaction‑ID speichern: app/Services/Addons/EventAddonCheckoutService.php
  - Paket/Marketing Checkout auf Transactions: app/Services/Paddle/PaddleCheckoutService.php
  - Gift‑Voucher Checkout: Customer anlegen/finden + Transactions: app/Services/GiftVouchers/
    GiftVoucherCheckoutService.php
  - Tests aktualisiert: tests/Feature/Tenant/EventAddonCheckoutTest.php, tests/Unit/PaddleCheckoutServiceTest.php,
tests/Unit/GiftVoucherCheckoutServiceTest.php
2025-12-29 18:04:28 +01:00

133 lines
4.8 KiB
TypeScript

import React from 'react';
import { useNavigate } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import { useQuery } from '@tanstack/react-query';
import { CalendarDays, Sparkles, Users } from 'lucide-react';
import { YStack, XStack } from '@tamagui/stacks';
import { SizableText as Text } from '@tamagui/text';
import { OnboardingShell } from '../components/OnboardingShell';
import { MobileCard, CTAButton } from '../components/Primitives';
import { ADMIN_HOME_PATH, ADMIN_WELCOME_BASE_PATH, ADMIN_WELCOME_PACKAGES_PATH, ADMIN_WELCOME_SUMMARY_PATH, adminPath } from '../../constants';
import { getTenantPackagesOverview, trackOnboarding } from '../../api';
import { getSelectedPackageId } from '../lib/onboardingSelection';
export default function WelcomeEventPage() {
const navigate = useNavigate();
const { t } = useTranslation('onboarding');
const selectedId = getSelectedPackageId();
const { data: overview } = useQuery({
queryKey: ['mobile', 'onboarding', 'packages-overview'],
queryFn: () => getTenantPackagesOverview({ force: true }),
staleTime: 60_000,
});
const hasActivePackage =
Boolean(overview?.activePackage) || Boolean(overview?.packages?.some((pkg) => pkg.active));
const handleSkip = React.useCallback(() => {
void trackOnboarding('dismissed');
navigate(ADMIN_HOME_PATH);
}, [navigate]);
const backTarget = selectedId
? ADMIN_WELCOME_SUMMARY_PATH
: hasActivePackage
? ADMIN_WELCOME_BASE_PATH
: ADMIN_WELCOME_PACKAGES_PATH;
return (
<OnboardingShell
eyebrow={t('eventSetup.layout.eyebrow', 'Step 4')}
title={t('eventSetup.layout.title', 'Prepare your first event')}
subtitle={t(
'eventSetup.layout.subtitle',
'Fill in a few details, invite co-hosts, and open your guest gallery for the big day.',
)}
onBack={() => navigate(backTarget)}
onSkip={handleSkip}
skipLabel={t('layout.jumpToDashboard', 'Jump to dashboard')}
>
<MobileCard space="$3">
<Text fontSize="$sm" fontWeight="800">
{t('eventSetup.step.title', 'Event setup in minutes')}
</Text>
<Text fontSize="$sm" color="#6b7280">
{t(
'eventSetup.step.description',
'We guide you through name, date, mood, and tasks. Afterwards you can moderate photos and support guests live.',
)}
</Text>
<YStack space="$2">
<FeatureRow
icon={Sparkles}
title={t('eventSetup.tiles.story.title', 'Story & mood')}
body={t('eventSetup.tiles.story.copy', 'Pick imagery, colours, and emotion cards for your event.')}
/>
<FeatureRow
icon={Users}
title={t('eventSetup.tiles.team.title', 'Organise your team')}
body={t('eventSetup.tiles.team.copy', 'Invite moderators or photographers and assign roles.')}
/>
<FeatureRow
icon={CalendarDays}
title={t('eventSetup.tiles.launch.title', 'Prepare go-live')}
body={t('eventSetup.tiles.launch.copy', 'Create QR codes, test the gallery, and align the run of show.')}
/>
</YStack>
</MobileCard>
<MobileCard space="$2">
<Text fontSize="$sm" fontWeight="800">
{t('eventSetup.cta.heading', 'Ready for your first event?')}
</Text>
<Text fontSize="$sm" color="#6b7280">
{t(
'eventSetup.cta.description',
"You're switching to the event manager. Assign tasks, invite members, and test the gallery. You can always return to the welcome journey.",
)}
</Text>
<CTAButton label={t('eventSetup.cta.button', 'Create event')} onPress={() => navigate(adminPath('/mobile/events/new'))} />
</MobileCard>
<YStack space="$2">
<CTAButton
label={t('eventSetup.actions.dashboard.button', 'Open dashboard')}
tone="ghost"
onPress={() => navigate(ADMIN_HOME_PATH)}
/>
<CTAButton
label={t('eventSetup.actions.events.button', 'Open event list')}
tone="ghost"
onPress={() => navigate(adminPath('/mobile/events'))}
/>
</YStack>
</OnboardingShell>
);
}
function FeatureRow({
icon: Icon,
title,
body,
}: {
icon: React.ComponentType<{ size?: number; color?: string }>;
title: string;
body: string;
}) {
return (
<XStack alignItems="center" space="$2">
<XStack width={34} height={34} borderRadius={12} backgroundColor="#e0f2fe" alignItems="center" justifyContent="center">
<Icon size={16} color="#0284c7" />
</XStack>
<YStack>
<Text fontSize="$sm" fontWeight="700">
{title}
</Text>
<Text fontSize="$xs" color="#6b7280">
{body}
</Text>
</YStack>
</XStack>
);
}