From 4598233cf45fc1495e0d888d135a3ba14d0bbf48 Mon Sep 17 00:00:00 2001 From: DanielS Date: Tue, 11 Aug 2026 23:01:04 +0200 Subject: [PATCH] feat(wizard): streamline step 3 with inline inputs and list/edit all devices in step 4 --- shop/components/order-wizard.tsx | 32 +++ shop/components/wizard/step-summary.tsx | 57 ++++- shop/components/wizard/summary-sidebar.tsx | 239 +++------------------ 3 files changed, 111 insertions(+), 217 deletions(-) diff --git a/shop/components/order-wizard.tsx b/shop/components/order-wizard.tsx index 572271e..bb60343 100644 --- a/shop/components/order-wizard.tsx +++ b/shop/components/order-wizard.tsx @@ -659,6 +659,24 @@ export function OrderWizard({ setSelections(resetSels) } + const resetFormForNewDevice = () => { + setEditingIdx(null) + setDeviceName('') + setLicenseNumber('') + setModuleQuantities({}) + const resetSels: Record = {} + categories.forEach(cat => { + const isVisible = selectedBillingInterval === 'one_time' ? cat.show_in_kauf !== false : cat.show_in_abo !== false + if (!isVisible || cat.allow_multiselect || cat.preselect === false) { + resetSels[cat.id] = { productId: null, productIds: [], moduleIds: [] } + } else { + const first = products.find(p => p.category_id === cat.id && (selectedBillingInterval === 'one_time' ? p.show_in_kauf !== false : p.show_in_abo !== false)) + resetSels[cat.id] = { productId: first?.id ?? null, productIds: first ? [first.id] : [], moduleIds: [] } + } + }) + setSelections(resetSels) + } + const editBasketItem = (idx: number) => { const item = basketItems[idx] if (!item) return @@ -671,6 +689,18 @@ export function OrderWizard({ setSelectedBillingInterval(item.billingInterval) } + const handleEditFromSummary = (idx: number) => { + editBasketItem(idx) + setDirection(-1) + setStep(3) + } + + const handleAddAnotherFromSummary = () => { + resetFormForNewDevice() + setDirection(-1) + setStep(3) + } + const deleteBasketItem = (idx: number) => { if (editingIdx === idx) { setEditingIdx(null) @@ -1097,6 +1127,8 @@ export function OrderWizard({ linkedFeeProducts={linkedFeeProducts} orderNotes={orderNotes} setOrderNotes={setOrderNotes} + onEditBasketItem={handleEditFromSummary} + onAddNewBasketItem={handleAddAnotherFromSummary} /> )} diff --git a/shop/components/wizard/step-summary.tsx b/shop/components/wizard/step-summary.tsx index e89eff9..de76dde 100644 --- a/shop/components/wizard/step-summary.tsx +++ b/shop/components/wizard/step-summary.tsx @@ -32,6 +32,8 @@ interface StepSummaryProps { linkedFeeProducts?: Product[] orderNotes: string setOrderNotes: (notes: string) => void + onEditBasketItem?: (idx: number) => void + onAddNewBasketItem?: () => void } function CategoryIcon({ icon, className }: { icon?: string | null; className?: string }) { @@ -63,6 +65,8 @@ export function StepSummary({ linkedFeeProducts = [], orderNotes, setOrderNotes, + onEditBasketItem, + onAddNewBasketItem, }: StepSummaryProps) { return (
@@ -152,11 +156,24 @@ export function StepSummary({
- - Zusammenfassung der Positionen - - {finalItemsToShow.length} {finalItemsToShow.length === 1 ? 'Kasse' : 'Kassen'} - + +
+ Zusammenfassung der Positionen + + {finalItemsToShow.length} {finalItemsToShow.length === 1 ? 'Kasse' : 'Kassen'} + +
+ {onAddNewBasketItem && ( + + )}
@@ -165,11 +182,31 @@ export function StepSummary({
{finalItemsToShow.map((item, itemIdx) => (
-
- Kasse: {item.deviceName} - - {item.billingInterval === 'one_time' ? 'Kauf' : 'Abo'} - +
onEditBasketItem && onEditBasketItem(itemIdx)} + className={`flex justify-between items-center bg-white/5 p-3 rounded-xl border border-white/10 ${onEditBasketItem ? 'cursor-pointer hover:border-primary/50 hover:bg-white/10 transition-all group' : ''}`} + > +
+ Kasse: {item.deviceName} + {item.licenseNumber && ( + ({item.licenseNumber}) + )} +
+
+ + {item.billingInterval === 'one_time' ? 'Kauf' : 'Abo'} + + {onEditBasketItem && ( + + )} +
{visibleCategories.map(cat => { diff --git a/shop/components/wizard/summary-sidebar.tsx b/shop/components/wizard/summary-sidebar.tsx index 252d376..8a846ae 100644 --- a/shop/components/wizard/summary-sidebar.tsx +++ b/shop/components/wizard/summary-sidebar.tsx @@ -80,35 +80,6 @@ export function SummarySidebar({ nextStep, prevStep, }: SummarySidebarProps) { - const [isOpen, setIsOpen] = React.useState(false) - const [isSavePromptOpen, setIsSavePromptOpen] = React.useState(false) - - const handleNextClick = () => { - if (hasActiveSelection) { - setIsSavePromptOpen(true) - } else { - nextStep() - } - } - - const handleSaveAndNext = async () => { - await addToBasket() - setIsSavePromptOpen(false) - nextStep() - } - - const handleDiscardAndNext = () => { - setIsSavePromptOpen(false) - nextStep() - } - 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 ( @@ -276,92 +247,43 @@ export function SummarySidebar({ {err}

))} -
{/* Warenkorb List (Scrollable) */} - {basketItems.length > 0 && ( -
-
- Kassen ({basketItems.length}): - Zum Bearbeiten anklicken +
{/* Kassenname & Lizenznummer Direkt-Eingabe */} +
+

+ {editingIdx !== null ? `Kasse ${editingIdx + 1} bearbeiten` : `Kassenbezeichnung`} +

+
+ + setDeviceName(e.target.value)} + className="bg-white/5 border-white/10 text-white text-xs h-8 rounded-lg" + />
-
- {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}

- )} -
-
- - -
-
- ) - })} +
+ + setLicenseNumber(e.target.value)} + className="bg-white/5 border-white/10 text-white text-xs h-8 rounded-lg" + />
- )} - + - @@ -370,103 +292,6 @@ export function SummarySidebar({ - - {/* Modal 1: Name & Lizenznummer beim manuellen Anlegen/Bearbeiten */} - - - - - {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" - /> -
-
- - - - -
-
- - {/* Modal 2: Abfrage beim Weiterklicken ohne gespeicherte Kasse */} - - - - - ⚠️ Kasse noch nicht gespeichert - - - Sie haben aktuell eine Kassen-Konfiguration ausgewählt. Möchten Sie diese Kasse speichern und mit zur Bestellung hinzufügen? - - - - - {basketItems.length > 0 && ( - - )} - - - -
) }