import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { Head, usePage } from '@inertiajs/react'; import { useTranslation } from 'react-i18next'; import { loadStripe } from '@stripe/stripe-js'; import { Steps } from '@/components/ui/steps'; import { Button } from '@/components/ui/button'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; import { Progress } from '@/components/ui/progress'; import { Alert, AlertDescription } from '@/components/ui/alert'; import MarketingLayout from '@/layouts/marketing/MarketingLayout'; import RegisterForm from '../auth/RegisterForm'; import LoginForm from '../auth/LoginForm'; import PaymentForm from './PaymentForm'; import SuccessStep from './SuccessStep'; interface Package { id: number; name: string; description: string; price: number; features: string[]; } interface PurchaseWizardProps { package: Package; stripePublishableKey: string; paypalClientId?: string | null; privacyHtml: string; } type StepId = 'package' | 'auth' | 'payment' | 'success'; interface WizardUser { id: number; email: string; name?: string; pending_purchase?: boolean; email_verified?: boolean; } interface AuthSuccessPayload { status: 'authenticated' | 'registered'; user?: WizardUser; next_step?: StepId | 'verification'; needs_verification?: boolean; package?: { id: number; name: string; price: number; type: string; } | null; } const steps: Array<{ id: StepId; title: string; description: string }> = [ { id: 'package', title: 'Paket auswählen', description: 'Bestätigen Sie Ihr gewähltes Paket' }, { id: 'auth', title: 'Anmelden oder Registrieren', description: 'Erstellen oder melden Sie sich an' }, { id: 'payment', title: 'Zahlung', description: 'Sichern Sie Ihr Paket ab' }, { id: 'success', title: 'Erfolg', description: 'Willkommen!' }, ]; export default function PurchaseWizard({ package: initialPackage, stripePublishableKey, paypalClientId, privacyHtml, }: PurchaseWizardProps) { const { t } = useTranslation(['marketing', 'auth']); const { props } = usePage(); const serverUser = (props as any)?.auth?.user ?? null; const [currentStepIndex, setCurrentStepIndex] = useState(0); const [authType, setAuthType] = useState<'register' | 'login'>('register'); const [wizardUser, setWizardUser] = useState(serverUser); const [authNotice, setAuthNotice] = useState(null); const isAuthenticated = Boolean(wizardUser); useEffect(() => { if (serverUser) { setWizardUser(serverUser); } }, [serverUser ? serverUser.id : null]); const stripePromise = useMemo(() => loadStripe(stripePublishableKey), [stripePublishableKey]); const goToStep = useCallback((stepId: StepId) => { const idx = steps.findIndex((step) => step.id === stepId); if (idx >= 0) { setCurrentStepIndex(idx); } }, []); const handleContinue = useCallback(() => { let nextIndex = Math.min(currentStepIndex + 1, steps.length - 1); if (steps[nextIndex]?.id === 'auth' && isAuthenticated) { nextIndex = Math.min(nextIndex + 1, steps.length - 1); } setCurrentStepIndex(nextIndex); }, [currentStepIndex, isAuthenticated]); const handleBack = useCallback(() => { let nextIndex = Math.max(currentStepIndex - 1, 0); if (steps[nextIndex]?.id === 'auth' && isAuthenticated) { nextIndex = Math.max(nextIndex - 1, 0); } setCurrentStepIndex(nextIndex); }, [currentStepIndex, isAuthenticated]); const handleAuthSuccess = useCallback( (payload: AuthSuccessPayload) => { if (payload?.user) { setWizardUser(payload.user); } if (payload?.needs_verification) { setAuthNotice(t('auth:verify_notice', { defaultValue: 'Bitte bestätige deine E-Mail-Adresse, um fortzufahren.' })); } else { setAuthNotice(null); } const next = payload?.next_step; if (next === 'success') { goToStep('success'); } else { goToStep('payment'); } }, [goToStep, t], ); const handlePaymentSuccess = useCallback(() => { goToStep('success'); }, [goToStep]); const renderPackageStep = () => ( {initialPackage.name} {initialPackage.description}

{t('marketing:payment.price_label', { defaultValue: 'Preis' })}: {' '} {initialPackage.price === 0 ? t('marketing:payment.free', { defaultValue: 'Kostenlos' }) : new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(initialPackage.price)}

    {initialPackage.features.map((feature, index) => (
  • {feature}
  • ))}
); const renderAuthStep = () => { if (isAuthenticated) { return ( {t('auth:already_authenticated', { defaultValue: 'Bereits angemeldet' })} {t('auth:logged_in_as', { defaultValue: 'Du bist angemeldet als {{email}}.', email: wizardUser?.email ?? wizardUser?.name ?? t('auth:user', { defaultValue: 'aktueller Nutzer' }), })} {authNotice && ( {authNotice} )} ); } return (
{authNotice && ( {authNotice} )} {authType === 'register' ? ( ) : ( )}
); }; const renderPaymentStep = () => (
{isAuthenticated && ( {t('marketing:payment.authenticated_notice', { defaultValue: 'Angemeldet als {{email}}. Zahlungsmethode auswählen.', email: wizardUser?.email ?? wizardUser?.name ?? t('auth:user', { defaultValue: 'aktueller Nutzer' }), })} )} {authNotice && ( {authNotice} )}
); const renderSuccessStep = () => ; const currentStep = steps[currentStepIndex]; const renderStepContent = () => { switch (currentStep.id) { case 'package': return renderPackageStep(); case 'auth': return renderAuthStep(); case 'payment': return renderPaymentStep(); case 'success': return renderSuccessStep(); default: return null; } }; return (
{renderStepContent()} {currentStep.id !== 'success' && currentStep.id !== 'package' && (
)}
); }