From 1c9ae2ec3158d4ca72cedd9bf83676262f53d504 Mon Sep 17 00:00:00 2001 From: DanielS Date: Mon, 10 Aug 2026 23:38:09 +0200 Subject: [PATCH] style: refine step 3 software select UI --- shop/components/wizard/step-software.tsx | 421 ++++++++++++----------- 1 file changed, 218 insertions(+), 203 deletions(-) diff --git a/shop/components/wizard/step-software.tsx b/shop/components/wizard/step-software.tsx index 61af183..2bbecc4 100644 --- a/shop/components/wizard/step-software.tsx +++ b/shop/components/wizard/step-software.tsx @@ -67,10 +67,10 @@ export function StepSoftware({ const selectedProduct = catProducts.find(p => p.id === sel?.productId) ?? null return ( - + - - + + Optionen wählen @@ -88,238 +88,253 @@ export function StepSoftware({ className="space-y-6" > {/* Category header */} -
+
-

{currentCategory.name}

+

{currentCategory.name}

{currentCategory.description && ( -

{currentCategory.description}

+

{currentCategory.description}

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

- Keine Produkte in dieser Kategorie im aktuellen Abrechnungsmodell vorhanden. -

- ) : currentCategory.allow_multiselect ? ( -
- {catProducts.map(product => { - const isChecked = sel?.productIds?.includes(product.id) ?? false - const disabled = isProductDisabled(product, currentCategory.id) - return ( -
- -
- ) - })} -
- ) : ( - selectProduct(currentCategory.id, id)} - className="grid gap-3" - > - {catProducts.map(product => { - const disabled = isProductDisabled(product, currentCategory.id) - return ( -
- + Keine Produkte in dieser Kategorie im aktuellen Abrechnungsmodell vorhanden. +

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

+ + Zusatzmodule für {selectedProduct.name} +

+
+ {selectedProduct.modules.map(module => { + const isExistingLicense = existingModuleIds.includes(module.id) + const disabled = isExistingLicense || isModuleDisabled(module, sel?.moduleIds ?? []) + const checked = isExistingLicense || (sel?.moduleIds.includes(module.id) ?? false) + return ( +
+
+ !isExistingLicense && toggleModule(currentCategory.id, module.id)} + disabled={disabled} + className="rounded border-white/20 data-[state=checked]:bg-primary" + /> +
-
- ) - })} - - )} - - {/* Modules */} - {selectedProduct?.modules && selectedProduct.modules.length > 0 && ( -
-

Zusatzmodule:

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

{module.description}

- )} - {!isExistingLicense && disabled && ( -

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

- )} -
-
- - {/* Scalable Quantity */} - {checked && !isExistingLicense && 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))} - -
+ {module.description && ( +

{module.description}

+ )} + {!isExistingLicense && disabled && ( +

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

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