import React, { useMemo } from "react"; import { useTranslation } from 'react-i18next'; import type { TFunction } from 'i18next'; import { Check, Package as PackageIcon } from "lucide-react"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; import { cn } from "@/lib/utils"; import { useCheckoutWizard } from "../WizardContext"; import type { CheckoutPackage } from "../types"; const currencyFormatter = new Intl.NumberFormat("de-DE", { style: "currency", currency: "EUR", minimumFractionDigits: 2, }); function translateFeature(feature: string, t: TFunction<'marketing'>) { const fallback = feature.replace(/_/g, ' '); return t(`packages.feature_${feature}`, { defaultValue: fallback }); } const DETAIL_LABEL_MAP: Record = { fotos: 'photos', photos: 'photos', gaeste: 'guests', gäste: 'guests', guests: 'guests', aufgaben: 'tasks', challenges: 'tasks', galerie: 'gallery', gallery: 'gallery', branding: 'branding', 'events_jahr': 'events_per_year', eventsjahr: 'events_per_year', }; function translateDetailLabel(label: string | undefined, t: TFunction<'marketing'>): string | undefined { if (!label) { return label; } const normalised = label .normalize('NFD') .replace(/\p{Diacritic}/gu, '') .toLowerCase() .replace(/[^a-z0-9]+/g, '_') .replace(/^_|_$/g, '') || label.toLowerCase(); const key = DETAIL_LABEL_MAP[normalised] ?? normalised; return t(`packages.detail_labels.${key}`, { defaultValue: label }); } function PackageSummary({ pkg, t }: { pkg: CheckoutPackage; t: TFunction<'marketing'> }) { const isFree = pkg.price === 0; const accentGradient = pkg.type === 'reseller' ? 'border-amber-100 bg-gradient-to-br from-amber-50/80 via-white to-amber-100/70 shadow-lg shadow-amber-100/60 dark:border-amber-500/40 dark:from-amber-900/40 dark:via-gray-900 dark:to-amber-900/20 dark:shadow-amber-900/40' : 'border-rose-100 bg-gradient-to-br from-rose-50/80 via-white to-rose-100/70 shadow-lg shadow-rose-100/60 dark:border-pink-500/40 dark:from-pink-900/40 dark:via-gray-900 dark:to-pink-900/10 dark:shadow-pink-900/40'; return ( {pkg.name} {pkg.description}
{pkg.price === 0 ? t('packages.free') : currencyFormatter.format(pkg.price)} {pkg.type === 'reseller' ? t('packages.subscription') : t('packages.one_time')}
{pkg.gallery_duration_label && (
{t('packages.gallery_days_label')}: {pkg.gallery_duration_label}
)} {Array.isArray(pkg.description_breakdown) && pkg.description_breakdown.length > 0 && (

{t('packages.breakdown_label')}

{pkg.description_breakdown.map((row, index) => (
{row.title && (

{translateDetailLabel(row.title, t)}

)}

{row.value}

))}
)} {Array.isArray(pkg.features) && pkg.features.length > 0 && (
    {pkg.features.map((feature, index) => (
  • {translateFeature(feature, t)}
  • ))}
)}
); } function PackageOption({ pkg, isActive, onSelect, t }: { pkg: CheckoutPackage; isActive: boolean; onSelect: () => void; t: TFunction<'marketing'> }) { const isFree = pkg.price === 0; const accentGradient = pkg.type === 'reseller' ? 'border-amber-100 bg-gradient-to-r from-amber-50/70 via-white to-amber-100/60 shadow-md shadow-amber-100/60 dark:border-amber-500/40 dark:from-amber-900/40 dark:via-gray-900 dark:to-amber-900/20 dark:shadow-amber-900/40' : 'border-rose-100 bg-gradient-to-r from-rose-50/70 via-white to-rose-100/60 shadow-md shadow-rose-100/60 dark:border-pink-500/40 dark:from-pink-900/40 dark:via-gray-900 dark:to-pink-900/10 dark:shadow-pink-900/40'; return ( ); } export const PackageStep: React.FC = () => { const { t } = useTranslation('marketing'); const { selectedPackage, packageOptions, setSelectedPackage, resetPaymentState } = useCheckoutWizard(); const comparablePackages = useMemo(() => { if (!selectedPackage) { return []; } // Filter by type and sort: free packages first, then by price ascending return packageOptions .filter((pkg: CheckoutPackage) => pkg.type === selectedPackage.type) .sort((a: CheckoutPackage, b: CheckoutPackage) => { // Free packages first if (a.price === 0 && b.price > 0) return -1; if (a.price > 0 && b.price === 0) return 1; // Then sort by price ascending return a.price - b.price; }); }, [packageOptions, selectedPackage]); const handlePackageChange = (pkg: CheckoutPackage) => { if (pkg.id === selectedPackage.id) { return; } setSelectedPackage(pkg); resetPaymentState(); }; if (!selectedPackage) { return (

{t('checkout.package_step.no_package_selected')}

); } return (
); };