'use client' import { useState, useMemo } from 'react' import { motion, AnimatePresence } from 'framer-motion' import { Product, ProductModule, Profile } from '@/lib/types' import { Card, CardContent, CardDescription, CardHeader, CardTitle, CardFooter } from '@/components/ui/card' import { Button } from '@/components/ui/button' import { Checkbox } from '@/components/ui/checkbox' import { Input } from '@/components/ui/input' import { Label } from '@/components/ui/label' import { Separator } from '@/components/ui/separator' import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group' import { Check, ChevronRight, ChevronLeft, ShoppingCart, User, CreditCard, ShieldCheck, Cloud, Utensils, HardDrive, Package } from 'lucide-react' import { submitOrder } from '@/lib/actions/orders' import { Category } from '@/lib/types' import { Tabs, TabsList, TabsTrigger } from '@/components/ui/tabs' import { Badge } from '@/components/ui/badge' export function OrderWizard({ products, categories, initialProfile }: { products: Product[], categories: Category[], initialProfile: Profile | null }) { const [step, setStep] = useState(1) const [activeCategory, setActiveCategory] = useState(categories[0]?.id || 'all') const [customerData, setCustomerData] = useState>(initialProfile || { company_name: '', vat_id: '', first_name: '', last_name: '', address: '', city: '', zip_code: '' }) const filteredProducts = useMemo(() => { if (activeCategory === 'all') return products return products.filter(p => p.category_id === activeCategory) }, [products, activeCategory]) const [selectedProduct, setSelectedProduct] = useState(filteredProducts[0] || null) const [selectedModules, setSelectedModules] = useState([]) const totalPrice = useMemo(() => { if (!selectedProduct) return 0 let total = Number(selectedProduct.base_price) selectedModules.forEach(modId => { const mod = selectedProduct.modules?.find(m => m.id === modId) if (mod) total += Number(mod.price) }) return total }, [selectedProduct, selectedModules]) const nextStep = () => setStep(s => s + 1) const prevStep = () => setStep(s => s - 1) const toggleModule = (id: string) => { const module = selectedProduct?.modules?.find(m => m.id === id) if (!module) return setSelectedModules(prev => { const isSelected = prev.includes(id) if (isSelected) { // When deselecting, we might need to deselect others that depend on this one const newSelection = prev.filter(m => m !== id) return newSelection.filter(mId => { const m = selectedProduct?.modules?.find(mod => mod.id === mId) return !m?.requirements || m.requirements.every(reqId => newSelection.includes(reqId) || reqId === id) }).filter(mId => mId !== id) } else { // When selecting, check exclusions if (module.exclusions && module.exclusions.some(exId => prev.includes(exId))) { return prev // Should be disabled anyway, but safety check } return [...prev, id] } }) } const isModuleDisabled = (module: ProductModule) => { // 1. Check requirements: all required modules must be selected const requirementsMet = !module.requirements || module.requirements.length === 0 || module.requirements.every(reqId => selectedModules.includes(reqId)) // 2. Check exclusions: no excluded module must be selected const isExcluded = module.exclusions && module.exclusions.some(exId => selectedModules.includes(exId)) return !requirementsMet || isExcluded } const handleSubmit = async () => { if (!selectedProduct) return try { await submitOrder({ product_id: selectedProduct.id, selected_modules: selectedModules, total_amount: totalPrice, customer_details: customerData }) alert('Bestellung erfolgreich aufgegeben!') window.location.href = '/' } catch (error) { console.error(error) alert('Fehler bei der Bestellung.') } } return (
{/* Progress Stepper */}
{[1, 2, 3].map((s) => (
= s ? 'bg-primary text-white scale-110 shadow-[0_0_15px_rgba(var(--primary),0.5)]' : 'bg-slate-800 text-slate-400' }`} > {step > s ? : s}
))}
{step === 1 && (
Software wählen Wählen Sie Ihr Basispaket und optionale Erweiterungen. {/* Category Tabs */}
{ setActiveCategory(val) // Auto-select first product in new category const firstInCat = products.find(p => val === 'all' || p.category_id === val) if (firstInCat) { setSelectedProduct(firstInCat) setSelectedModules([]) } }}> Alle {categories.map(cat => { const Icon = cat.icon === 'Cloud' ? Cloud : cat.icon === 'Utensils' ? Utensils : cat.icon === 'HardDrive' ? HardDrive : Package return ( {cat.name} ) })}
{ const p = products.find(prod => prod.id === id) if (p) { setSelectedProduct(p) setSelectedModules([]) // Reset modules when product changes } }} className="grid gap-4" > {filteredProducts.map(product => (
))}
{selectedProduct && selectedProduct.modules && selectedProduct.modules.length > 0 && (
{selectedProduct.modules.map(module => (
toggleModule(module.id)} disabled={isModuleDisabled(module)} />

{module.description}

{isModuleDisabled(module) && (

{module.requirements && module.requirements.some(reqId => !selectedModules.includes(reqId)) ? "Benötigt weitere Module" : "Nicht kombinierbar mit aktueller Auswahl"}

)}
))}
)}
Zusammenfassung
Basispreis: {new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(selectedProduct?.base_price || 0)}
{selectedModules.map(modId => { const mod = selectedProduct?.modules?.find(m => m.id === modId) return (
{mod?.name}: +{new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(mod?.price || 0)}
) })}
Gesamt: {new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(totalPrice)}
)} {step === 2 && ( Kundendaten Wir benötigen Ihre Daten für die Rechnungsstellung.
setCustomerData({...customerData, company_name: e.target.value})} placeholder="GmbH / Einzelunternehmen" className="bg-white/5 border-white/10" />
setCustomerData({...customerData, vat_id: e.target.value})} placeholder="DE123456789" className="bg-white/5 border-white/10" />
setCustomerData({...customerData, first_name: e.target.value})} className="bg-white/5 border-white/10" />
setCustomerData({...customerData, last_name: e.target.value})} className="bg-white/5 border-white/10" />
setCustomerData({...customerData, address: e.target.value})} className="bg-white/5 border-white/10" />
setCustomerData({...customerData, zip_code: e.target.value})} className="bg-white/5 border-white/10" />
setCustomerData({...customerData, city: e.target.value})} className="bg-white/5 border-white/10" />
)} {step === 3 && (
Bestellung prüfen Fast fertig! Bitte überprüfen Sie Ihre Auswahl.
{selectedProduct?.name} {new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(totalPrice)} / Monat

Inklusive: {selectedModules.length > 0 ? selectedModules.map(id => selectedProduct?.modules?.find(m => m.id === id)?.name).join(', ') : 'Keine Zusatzmodule'}

{customerData.company_name}

{customerData.address}, {customerData.zip_code} {customerData.city}

Mit dem Klick auf "Kostenpflichtig bestellen" akzeptieren Sie unsere AGB und die Datenschutzerklärung.

)}
) }