import React, { useCallback, useEffect, useMemo, useState } from "react"; import { Button } from "@/components/ui/button"; import { useCheckoutWizard } from "../WizardContext"; import { Trans, useTranslation } from 'react-i18next'; import { Badge } from "@/components/ui/badge"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { CalendarDays, CheckCircle2, ClipboardList, LoaderCircle, MailCheck, QrCode, ShieldCheck, Smartphone, Sparkles, XCircle } from "lucide-react"; import { cn } from "@/lib/utils"; interface ConfirmationStepProps { onViewProfile?: () => void; onGoToAdmin?: () => void; } const currencyFormatter = new Intl.NumberFormat("de-DE", { style: "currency", currency: "EUR", minimumFractionDigits: 2, }); export const ConfirmationStep: React.FC = ({ onViewProfile, onGoToAdmin }) => { const { t } = useTranslation('marketing'); const { selectedPackage, checkoutSessionId, setPaymentCompleted, clearCheckoutSessionId, } = useCheckoutWizard(); const [status, setStatus] = useState<'processing' | 'completed' | 'failed'>( checkoutSessionId ? 'processing' : 'completed', ); const [elapsedMs, setElapsedMs] = useState(0); const [checking, setChecking] = useState(false); const handleProfile = React.useCallback(() => { if (typeof onViewProfile === 'function') { onViewProfile(); return; } window.location.href = '/settings/profile'; }, [onViewProfile]); const handleAdmin = React.useCallback(() => { if (typeof onGoToAdmin === 'function') { onGoToAdmin(); return; } window.location.href = '/event-admin'; }, [onGoToAdmin]); const packageName = selectedPackage?.name ?? ''; const packagePrice = useMemo(() => { if (!selectedPackage) { return ''; } return selectedPackage.price === 0 ? t('packages.free') : currencyFormatter.format(selectedPackage.price); }, [selectedPackage, t]); const packageType = useMemo(() => { if (!selectedPackage) { return ''; } return selectedPackage.type === 'reseller' ? t('packages.subscription') : t('packages.one_time'); }, [selectedPackage, t]); const statusCopy = useMemo(() => { if (status === 'completed') { return { label: t('checkout.confirmation_step.status_state.completed'), body: t('checkout.confirmation_step.status_body_completed'), tone: 'text-emerald-600', icon: CheckCircle2, badge: 'bg-emerald-50 text-emerald-700 border-emerald-200', }; } if (status === 'failed') { return { label: t('checkout.confirmation_step.status_state.failed'), body: t('checkout.confirmation_step.status_body_failed'), tone: 'text-rose-600', icon: XCircle, badge: 'bg-rose-50 text-rose-700 border-rose-200', }; } return { label: t('checkout.confirmation_step.status_state.processing'), body: t('checkout.confirmation_step.status_body_processing'), tone: 'text-amber-600', icon: LoaderCircle, badge: 'bg-amber-50 text-amber-700 border-amber-200', }; }, [status, t]); const checkSessionStatus = useCallback(async (): Promise<'processing' | 'completed' | 'failed'> => { if (!checkoutSessionId) { return 'completed'; } try { const response = await fetch(`/checkout/session/${checkoutSessionId}/status`, { headers: { Accept: 'application/json', }, credentials: 'same-origin', }); if (!response.ok) { return 'processing'; } const payload = await response.json(); const remoteStatus = typeof payload?.status === 'string' ? payload.status : null; if (remoteStatus === 'completed') { setPaymentCompleted(true); clearCheckoutSessionId(); return 'completed'; } if (remoteStatus === 'failed' || remoteStatus === 'cancelled') { clearCheckoutSessionId(); return 'failed'; } } catch (error) { return 'processing'; } return 'processing'; }, [checkoutSessionId, clearCheckoutSessionId, setPaymentCompleted]); useEffect(() => { if (!checkoutSessionId) { setStatus('completed'); return; } let cancelled = false; let timeoutId: number | null = null; const poll = async () => { if (cancelled) { return; } const nextStatus = await checkSessionStatus(); if (cancelled) { return; } setStatus(nextStatus); if (nextStatus === 'processing' && typeof window !== 'undefined') { timeoutId = window.setTimeout(poll, 5000); } }; void poll(); return () => { cancelled = true; if (timeoutId && typeof window !== 'undefined') { window.clearTimeout(timeoutId); } }; }, [checkSessionStatus, checkoutSessionId]); useEffect(() => { if (status !== 'processing' || typeof window === 'undefined') { setElapsedMs(0); return; } const startedAt = Date.now(); const timer = window.setInterval(() => { setElapsedMs(Date.now() - startedAt); }, 1000); return () => { window.clearInterval(timer); }; }, [status]); const onboardingItems = [ { key: 'event', icon: CalendarDays, }, { key: 'invites', icon: QrCode, }, { key: 'tasks', icon: ClipboardList, }, ] as const; const statusItems = [ { key: 'payment', icon: CheckCircle2 }, { key: 'email', icon: MailCheck }, { key: 'access', icon: ShieldCheck }, ] as const; const statusProgress = useMemo(() => { if (status === 'completed') { return { payment: true, email: true, access: true }; } if (status === 'failed') { return { payment: false, email: false, access: false }; } return { payment: true, email: false, access: false }; }, [status]); const showManualActions = status === 'processing' && elapsedMs >= 30000; const StatusIcon = statusCopy.icon; const handleStatusRetry = useCallback(async () => { if (checking) { return; } setChecking(true); const nextStatus = await checkSessionStatus(); setStatus(nextStatus); setChecking(false); }, [checkSessionStatus, checking]); const handlePageRefresh = useCallback(() => { if (typeof window !== 'undefined') { window.location.reload(); } }, []); return (
{t('checkout.confirmation_step.hero_badge')}

{t('checkout.confirmation_step.hero_title')}

}} values={{ name: packageName }} />

{t('checkout.confirmation_step.hero_body')}

{t('checkout.confirmation_step.hero_next')}

{t('checkout.confirmation_step.status_title')} {statusCopy.body}
{statusCopy.label}
{statusItems.map(({ key, icon: Icon }) => { const active = statusProgress[key]; return (

{t(`checkout.confirmation_step.status_items.${key}.title`)}

{t(`checkout.confirmation_step.status_items.${key}.body`)}

); })}
{showManualActions && (

{t('checkout.confirmation_step.status_manual_hint')}

)}
{t('checkout.confirmation_step.onboarding_title')} {t('checkout.confirmation_step.onboarding_subtitle')}
{t('checkout.confirmation_step.onboarding_badge')}
{onboardingItems.map(({ key, icon: Icon }) => (

{t(`checkout.confirmation_step.onboarding_items.${key}.title`)}

{t(`checkout.confirmation_step.onboarding_items.${key}.body`)}

))}
); };