'use client' import React from 'react' import { Card, CardHeader, CardTitle, CardDescription, CardContent } from '@/components/ui/card' import { Separator } from '@/components/ui/separator' import { Checkbox } from '@/components/ui/checkbox' import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group' import { Label } from '@/components/ui/label' import { Input } from '@/components/ui/input' import { Badge } from '@/components/ui/badge' import { ShoppingCart, Check, AlertCircle } from 'lucide-react' import * as Icons from 'lucide-react' import { Category, Product, CategorySelection } from '@/lib/types' import { SummarySidebar } from './summary-sidebar' interface StepSoftwareProps { visibleCategories: Category[] products: Product[] selections: Record selectProduct: (catId: string, prodId: string) => void isProductDisabled: (prod: Product, catId: string) => boolean isModuleDisabled: (mod: any, selectedModIds: string[]) => boolean toggleModule: (catId: string, modId: string) => void moduleQuantities: Record setModuleQuantities: React.Dispatch>> selectedBillingInterval: 'one_time' | 'monthly' billingLabel: (interval: string) => string billingBadgeClass: (interval: string) => string // Sidebar props oneTimeTotal: number monthlyTotal: number oneTimeNet: number oneTimeTax: number oneTimeGross: number monthlyNet: number monthlyTax: number monthlyGross: number updatePriceModifier: { label?: string } allCategoriesFilled: boolean productValidationErrors: string[] basketItems: any[] editingIdx: number | null editBasketItem: (idx: number) => void deleteBasketItem: (idx: number) => void deviceName: string setDeviceName: (name: string) => void addToBasket: () => void isNextStepDisabled: boolean hasActiveSelection: boolean nextStep: () => void prevStep: () => void } function CategoryIcon({ icon, className }: { icon?: string | null; className?: string }) { const LucideIcon = icon ? (Icons as any)[icon] : null if (!LucideIcon) return return } export function StepSoftware({ visibleCategories, products, selections, selectProduct, isProductDisabled, isModuleDisabled, toggleModule, moduleQuantities, setModuleQuantities, selectedBillingInterval, billingLabel, billingBadgeClass, oneTimeTotal, monthlyTotal, oneTimeNet, oneTimeTax, oneTimeGross, monthlyNet, monthlyTax, monthlyGross, updatePriceModifier, allCategoriesFilled, productValidationErrors, basketItems, editingIdx, editBasketItem, deleteBasketItem, deviceName, setDeviceName, addToBasket, isNextStepDisabled, hasActiveSelection, nextStep, prevStep, }: StepSoftwareProps) { return (
{/* Left: Category sections */}
Software wählen Wählen Sie pro Kategorie mindestens einen Artikel aus. {visibleCategories.map((cat, idx) => { const catProducts = products.filter(p => { if (p.category_id !== cat.id) return false return selectedBillingInterval === 'one_time' ? p.show_in_kauf !== false : p.show_in_abo !== false }) const sel = selections[cat.id] const selectedProduct = catProducts.find(p => p.id === sel?.productId) ?? null return (
{idx > 0 && } {/* Category header */}

{cat.name}

{cat.description && (

{cat.description}

)}
{sel?.productIds && sel.productIds.length > 0 ? ( {sel.productIds.length} Ausgewählt ) : sel?.productId ? ( Ausgewählt ) : cat.is_required ? ( Pflichtfeld ) : ( Optional )}
{catProducts.length === 0 ? (

Keine Produkte in dieser Kategorie im aktuellen Abrechnungsmodell vorhanden.

) : cat.allow_multiselect ? (
{catProducts.map(product => { const isChecked = sel?.productIds?.includes(product.id) ?? false const disabled = isProductDisabled(product, cat.id) return (
) })}
) : ( selectProduct(cat.id, id)} className="grid gap-3" > {catProducts.map(product => { const disabled = isProductDisabled(product, cat.id) return (
) })}
)} {/* Modules */} {selectedProduct?.modules && selectedProduct.modules.length > 0 && (

Zusatzmodule:

{selectedProduct.modules.map(module => { const disabled = isModuleDisabled(module, sel?.moduleIds ?? []) const checked = sel?.moduleIds.includes(module.id) ?? false return (
toggleModule(cat.id, module.id)} disabled={disabled} />
{module.description && (

{module.description}

)} {disabled && (

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

)}
{/* Scalable Quantity */} {checked && module.has_quantity && (
{ const val = Math.max(1, parseInt(e.target.value) || 1) setModuleQuantities(prev => ({ ...prev, [module.id]: val })) }} className="w-20 h-8 bg-white/5 border-white/10 text-white text-xs text-center rounded-lg" /> Gesamt: {new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR', }).format(module.price * (moduleQuantities[module.id] || 1))}
)}
) })}
)}
) })}
{/* Right: Summary sidebar */}
) }