'use client' import React from 'react' import { Card, CardHeader, CardTitle, CardContent, CardFooter } from '@/components/ui/card' import { Separator } from '@/components/ui/separator' import { Label } from '@/components/ui/label' import { Input } from '@/components/ui/input' import { Button } from '@/components/ui/button' import { Pencil, Trash2, UserPlus, ChevronRight, AlertCircle, Check } from 'lucide-react' import { Category, Product, CategorySelection } from '@/lib/types' import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from '@/components/ui/dialog' interface SummarySidebarProps { visibleCategories: Category[] selections: Record products: Product[] moduleQuantities: Record billingLabel: (interval: string) => string 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 licenseNumber: string setLicenseNumber: (num: string) => void addToBasket: () => void isNextStepDisabled: boolean hasActiveSelection: boolean nextStep: () => void prevStep: () => void } export function SummarySidebar({ visibleCategories, selections, products, moduleQuantities, billingLabel, oneTimeTotal, monthlyTotal, oneTimeNet, oneTimeTax, oneTimeGross, monthlyNet, monthlyTax, monthlyGross, updatePriceModifier, allCategoriesFilled, productValidationErrors, basketItems, editingIdx, editBasketItem, deleteBasketItem, deviceName, setDeviceName, licenseNumber, setLicenseNumber, addToBasket, isNextStepDisabled, hasActiveSelection, nextStep, prevStep, }: SummarySidebarProps) { const [isOpen, setIsOpen] = React.useState(false) const [selectedBasketIdx, setSelectedBasketIdx] = React.useState(null) // When editing a basket item via pencil, open the modal for that item const handleEditBasketItem = (idx: number) => { editBasketItem(idx) setIsOpen(true) } const fmt = (val: number) => new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(val) return (
Zusammenfassung {basketItems.length > 0 && ( {basketItems.length} {basketItems.length === 1 ? 'Kasse' : 'Kassen'} )} {/* Active Selections & Price - scrollable */}
{visibleCategories.map(cat => { const sel = selections[cat.id] const selectedProds: Product[] = [] if (cat.allow_multiselect && sel?.productIds) { sel.productIds.forEach(pId => { const p = products.find(prod => prod.id === pId) if (p) selectedProds.push(p) }) } else if (sel?.productId) { const p = products.find(prod => prod.id === sel.productId) if (p) selectedProds.push(p) } if (selectedProds.length === 0) return (
{cat.is_required ? ( ) : ( )} {cat.name}: {cat.is_required ? 'nicht gewählt' : 'nicht gewählt (optional)'}
) const sortedProds = [...selectedProds].sort((a, b) => a.base_price - b.base_price) const freeLimit = cat.allow_multiselect ? cat.free_items_limit : 0 return (

{cat.name}

{sortedProds.map((prod, idx) => { const isFree = idx < freeLimit const actualPrice = isFree ? 0 : prod.base_price return (
{prod.name} {isFree && (Frei)} {fmt(actualPrice)} {' '}{billingLabel(prod.billing_interval)}
{sel.moduleIds.map(mId => { const mod = prod.modules?.find(m => m.id === mId) const qty = moduleQuantities[mId] || 1 return mod ? (
+ {mod.name} {mod.has_quantity ? `(x${qty})` : ''} {fmt(mod.price * qty)}
) : null })}
) })}
) })} {/* Pricing block */} {oneTimeTotal > 0 && monthlyTotal > 0 ? (

Einmalig:

Netto: {fmt(oneTimeNet)}
zzgl. 19% MwSt.: {fmt(oneTimeTax)}
Brutto: {fmt(oneTimeGross)}

Monatlich:

Netto: {fmt(monthlyNet)} / mtl.
zzgl. 19% MwSt.: {fmt(monthlyTax)} / mtl.
Brutto: {fmt(monthlyGross)} / mtl.
) : oneTimeTotal > 0 ? (
Netto: {fmt(oneTimeNet)}
zzgl. 19% MwSt.: {fmt(oneTimeTax)}
Gesamt (brutto): {fmt(oneTimeGross)}
) : (
Netto: {fmt(monthlyNet)} / mtl.
zzgl. 19% MwSt.: {fmt(monthlyTax)} / mtl.
Gesamt (brutto): {fmt(monthlyGross)} / mtl.
)} {updatePriceModifier.label && (

Update-Rabatt aktiv

{updatePriceModifier.label}

)} {!allCategoriesFilled && (

Bitte aus jeder Pflichtkategorie einen Artikel wählen.

)} {productValidationErrors.map((err, errIdx) => (

{err}

))}
{/* Warenkorb List (Scrollable) */} {basketItems.length > 0 && (
Kassen ({basketItems.length}): Zum Bearbeiten anklicken
{basketItems.map((item, idx) => { const isEditing = idx === editingIdx return (
editBasketItem(idx)} className={`flex items-center justify-between p-2.5 rounded-xl border transition-all duration-200 text-left cursor-pointer group ${ isEditing ? 'border-primary bg-primary/15 text-white shadow-[0_0_12px_rgba(59,130,246,0.25)]' : 'border-white/10 bg-slate-900/60 text-slate-300 hover:border-white/20 hover:bg-slate-900' }`} >
{item.deviceName} {item.billingInterval === 'one_time' ? 'Kauf' : 'Abo'} {isEditing && ( Aktiv )}
{item.licenseNumber && (

Lizenz: {item.licenseNumber}

)}
) })}
)}
{editingIdx !== null ? 'Kasse bearbeiten' : 'Kasse anlegen'} Geben Sie den Namen und die Lizenznummer für diese Kasse ein.
setDeviceName(e.target.value)} className="bg-white/5 border-white/10 text-white text-xs h-9 rounded-lg" />
setLicenseNumber(e.target.value)} className="bg-white/5 border-white/10 text-white text-xs h-9 rounded-lg" />
) }