import React, { useState, useEffect, useCallback } from 'react'; import { Head, useForm, usePage, router } from '@inertiajs/react'; import { useTranslation } from 'react-i18next'; import { Elements } from '@stripe/react-stripe-js'; import { loadStripe } from '@stripe/stripe-js'; import { Steps } from '@/components/ui/Steps'; // Correct casing for Shadcn Steps import { Check } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; import { Progress } from '@/components/ui/progress'; import { Loader2 } from 'lucide-react'; import MarketingLayout from '@/layouts/marketing/MarketingLayout'; import RegisterForm from '../auth/RegisterForm'; // Extract Register form to separate component import LoginForm from '../auth/LoginForm'; // Extract Login form import PaymentForm from './PaymentForm'; // New component for Stripe payment import SuccessStep from './SuccessStep'; // New component for success interface Package { id: number; name: string; description: string; price: number; features: string[]; type?: 'endcustomer' | 'reseller'; trial_days?: number; // Add other fields as needed } interface UserData { id: number; email: string; pending_purchase?: boolean; } interface PurchaseWizardProps { package: Package; stripePublishableKey: string; privacyHtml: string; } const steps = [ { 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, privacyHtml }: PurchaseWizardProps) { const STORAGE_KEY = 'fotospiel_wizard_state'; const STORAGE_TTL = 30 * 60 * 1000; // 30 minutes in ms const [currentStep, setCurrentStep] = useState(0); const [isAuthenticated, setIsAuthenticated] = useState(false); const [authCompleted, setAuthCompleted] = useState(false); const [authType, setAuthType] = useState<'register' | 'login'>('register'); // Toggle for auth step const [wizardData, setWizardData] = useState<{ package: Package; user: UserData | null }>({ package: initialPackage, user: null }); const { t } = useTranslation(['marketing', 'auth']); const { props } = usePage(); const { auth } = props as any; // Load state from sessionStorage on mount useEffect(() => { const saved = sessionStorage.getItem(STORAGE_KEY); if (saved) { try { const parsed = JSON.parse(saved); const { currentStep: savedCurrentStep, wizardData: savedWizardData, isAuthenticated: savedIsAuthenticated, authType: savedAuthType, timestamp } = parsed; if (Date.now() - timestamp < STORAGE_TTL && savedWizardData?.package?.id === initialPackage.id) { setCurrentStep(savedCurrentStep || 0); setWizardData(savedWizardData || { package: initialPackage, user: null }); setIsAuthenticated(savedIsAuthenticated || false); setAuthType(savedAuthType || 'register'); // If in payment step and pending purchase, reload client_secret if needed if ((savedCurrentStep || 0) === 2 && savedWizardData?.user?.pending_purchase) { // Optional: router.reload() or API call to refresh payment intent } } else { sessionStorage.removeItem(STORAGE_KEY); } } catch (e) { console.error('Failed to load wizard state:', e); sessionStorage.removeItem(STORAGE_KEY); } } }, [initialPackage.id]); // Save state to sessionStorage on changes const saveState = useCallback(() => { const state = { currentStep, wizardData: { package: wizardData.package, user: wizardData.user ? { id: wizardData.user.id, email: wizardData.user.email, pending_purchase: wizardData.user.pending_purchase } : null, }, isAuthenticated, authType, timestamp: Date.now(), }; sessionStorage.setItem(STORAGE_KEY, JSON.stringify(state)); }, [currentStep, wizardData, isAuthenticated, authType]); useEffect(() => { saveState(); }, [saveState]); // Cleanup on unmount or success useEffect(() => { return () => { if (currentStep === 3) { sessionStorage.removeItem(STORAGE_KEY); } }; }, [currentStep]); useEffect(() => { if (auth.user) { setIsAuthenticated(true); // Do not skip step, handle in render // Update wizardData with auth.user if pending_purchase if (auth.user.pending_purchase) { setWizardData(prev => ({ ...prev, user: auth.user })); } } }, [auth]); const stripePromise = loadStripe(stripePublishableKey); const nextStep = () => { if (currentStep < steps.length - 1) { setCurrentStep((prev) => prev + 1); } }; const prevStep = () => { if (currentStep > 0) { setCurrentStep((prev) => prev - 1); } }; const handleAuthSuccess = (userData: any) => { setWizardData((prev) => ({ ...prev, user: userData })); setIsAuthenticated(true); setAuthCompleted(true); // Show success message briefly then proceed setTimeout(() => { nextStep(); setAuthCompleted(false); }, 2000); }; const handlePaymentSuccess = () => { // Call API to assign package router.post('/api/purchase/complete', { package_id: initialPackage.id }, { onSuccess: () => nextStep(), }); }; const renderStepContent = () => { switch (steps[currentStep].id) { case 'package': return ( {initialPackage.name} {initialPackage.description}

Preis: {initialPackage.price === 0 ? 'Kostenlos' : `${initialPackage.price} €`}

); case 'auth': if (isAuthenticated) { if (authCompleted) { return (

{t('auth.login_success')}

Sie sind nun eingeloggt und werden weitergeleitet...

); } else { return (

{t('auth.already_logged_in')}

); } } return (
{authType === 'register' ? ( ) : ( )}
); case 'payment': if (initialPackage.price === 0) { // Skip for free, assign directly router.post('/api/purchase/free', { package_id: initialPackage.id }); return
Free package assigned! Redirecting...
; } return ( ); case 'success': return ; default: return null; } }; return (
{renderStepContent()} {currentStep > 0 && currentStep < 3 && (
{currentStep < 3 && }
)}
); }