diff --git a/shop/components/wizard/step-billing.tsx b/shop/components/wizard/step-billing.tsx index fa4bf42..50b40ec 100644 --- a/shop/components/wizard/step-billing.tsx +++ b/shop/components/wizard/step-billing.tsx @@ -14,9 +14,7 @@ import { ChevronRight, RefreshCw, ShoppingBag, - ShieldCheck, CheckCircle2, - Info, } from 'lucide-react' import { motion, AnimatePresence } from 'framer-motion' @@ -34,197 +32,191 @@ interface StepBillingProps { export function StepBilling({ selectedBillingInterval, handleBillingIntervalChange, - customerMode, - selectedEndCustomerId, lastLicenseDate, setLastLicenseDate, prevStep, nextStep, }: StepBillingProps) { - // Optionale Validierung falls Datum bei Kauf Pflicht wäre, oder prüfen ob Modell gewählt ist const isOneTime = selectedBillingInterval === 'one_time' const isMonthly = selectedBillingInterval === 'monthly' + // Wenn Kauf gewählt ist, muss ein gültiges Datum vorliegen + const isNextDisabled = isOneTime && !lastLicenseDate + return ( {/* ─── 1. FIXED HEADER (shrink-0) ─── */} - +
- - + + Abrechnungsmodell wählen - + Wählen Sie zwischen monatlicher Miete (Abonnement) oder einmaligem Softwarekauf.
- + Schritt 2 von 4
- {/* ─── 2. SCROLLABLE MIDDLE CONTENT (flex-1 min-h-0 overflow-y-auto) ─── */} -
-
- {/* Abrechnungsmodell Cards */} -
- {/* Option 1: Miete / Abo */} -
handleBillingIntervalChange('monthly')} - className={`relative p-6 rounded-2xl border-2 cursor-pointer transition-all duration-300 flex flex-col justify-between min-h-[14rem] select-none ${ - isMonthly - ? 'border-primary bg-primary/10 shadow-[0_0_20px_rgba(59,130,246,0.2)] ring-1 ring-primary/50' - : 'border-white/5 bg-white/5 hover:border-white/20 hover:bg-white/[0.07]' - }`} - > -
-
-
- -
- {isMonthly && ( -
- -
- )} + {/* ─── 2. NO-SCROLL MIDDLE CONTENT (flex-1 flex flex-col justify-center items-center overflow-hidden p-4) ─── */} +
+
+ {/* Option 1: Miete / Abo */} +
handleBillingIntervalChange('monthly')} + className={`relative p-5 rounded-xl border-2 cursor-pointer transition-all duration-300 flex flex-col justify-between select-none ${ + isMonthly + ? 'border-primary bg-primary/10 shadow-[0_0_20px_rgba(59,130,246,0.2)] ring-1 ring-primary/50' + : 'border-white/5 bg-white/5 hover:border-white/20 hover:bg-white/[0.07]' + }`} + > +
+
+
+
- -
-
-

Miete / Abo

- - Empfohlen - + {isMonthly && ( +
+
-

- Fortlaufende monatliche Abrechnung -

-
+ )} +
-

- Maximale Flexibilität: Inklusive sämtlicher Software-Updates, Cloud-Dienste und technischem Support. Jederzeit kündbar oder anpassbar. +

+
+

Miete / Abo

+ + Empfohlen + +
+

+ Fortlaufende monatliche Abrechnung

-
- Zahlungsintervall: - monatlich -
+

+ Maximale Flexibilität: Inklusive sämtlicher Software-Updates, Cloud-Dienste und Support. Jederzeit kündbar oder anpassbar. +

- {/* Option 2: Kauf / Einmalkauf */} -
handleBillingIntervalChange('one_time')} - className={`relative p-6 rounded-2xl border-2 cursor-pointer transition-all duration-300 flex flex-col justify-between min-h-[14rem] select-none ${ - isOneTime - ? 'border-primary bg-primary/10 shadow-[0_0_20px_rgba(59,130,246,0.2)] ring-1 ring-primary/50' - : 'border-white/5 bg-white/5 hover:border-white/20 hover:bg-white/[0.07]' - }`} - > -
-
-
- -
- {isOneTime && ( -
- -
- )} -
- -
-
-

Kauf / Einmalkauf

- - Klassisch - -
-

- Einmalige Lizenzgebühr -

-
- -

- Dauerhafte Lizenzrechte für die gekaufte Version inklusive 12 Monate kostenfreier Updates. Keine laufenden monatlichen Mietgebühren. -

-
- -
- Zahlungsintervall: - einmalig -
+
+ Zahlungsintervall: + monatlich
- {/* Dynamische Stichtagsabfrage bei Kauf */} - - {isOneTime && ( - -
-
-
- -
-
- -

- Datum des letzten Kaufs zur automatischen Berechnung der Update-Staffel (z. B. 15% innerhalb 1 Jahr, 30% bis 2 Jahre, 50% bis 3 Jahre). -

-
-
- -
-
- - setLastLicenseDate(e.target.value)} - className="pl-9 bg-slate-950/80 border-white/10 text-white text-xs h-9 focus:border-primary" - /> -
- {lastLicenseDate && ( - - Stichtag gesetzt - - )} -
+ {/* Option 2: Kauf / Einmalkauf (mit integrierter Inline-Erweiterung) */} +
handleBillingIntervalChange('one_time')} + className={`relative p-5 rounded-xl border-2 cursor-pointer transition-all duration-300 flex flex-col justify-between select-none ${ + isOneTime + ? 'border-primary bg-primary/10 shadow-[0_0_20px_rgba(59,130,246,0.2)] ring-1 ring-primary/50' + : 'border-white/5 bg-white/5 hover:border-white/20 hover:bg-white/[0.07]' + }`} + > +
+
+
+
- - )} - + {isOneTime && ( +
+ +
+ )} +
+ +
+
+

Kauf / Einmalkauf

+ + Klassisch + +
+

+ Einmalige Lizenzgebühr +

+
+ +

+ Dauerhafte Lizenzrechte für die gekaufte Version inklusive 12 Monate kostenfreier Updates. +

+ + {/* Inline-Erweiterung für Kaufdatum / Stichtag */} + + {isOneTime && ( + e.stopPropagation()} + > +
+
+ +
+ +

+ Zur automatischen Berechnung der Update-Staffel (15% / 30% / 50%). +

+
+
+ +
+ setLastLicenseDate(e.target.value)} + className="bg-slate-900 border-white/10 text-white text-xs h-8 focus:border-primary w-full" + /> +
+ + {lastLicenseDate && ( +
+ Stichtag erfasst +
+ )} +
+
+ )} +
+
+ +
+ Zahlungsintervall: + einmalig +
+
{/* ─── 3. FIXED BOTTOM ACTION BAR (shrink-0) ─── */} -
+
{/* Back Button */} {/* Selected Model Status Chip */} -
+
Gewähltes Modell: - Weiter zu Schritt 3 + Weiter zu Schritt 3
) } + diff --git a/shop/components/wizard/step-customer.tsx b/shop/components/wizard/step-customer.tsx index 9786a1d..bbd6326 100644 --- a/shop/components/wizard/step-customer.tsx +++ b/shop/components/wizard/step-customer.tsx @@ -180,44 +180,44 @@ export function StepCustomer({ <> {/* ─── 1. FIXED HEADER (shrink-0) ─── */} - -
+ +
- - + + Für wen bestellen Sie? - + Wählen Sie den Endkunden für die Lizenzierung aus oder legen Sie schnell einen neuen Datensatz an.
{/* ─── 2. SCROLLABLE MIDDLE CONTENT (flex-1 min-h-0 overflow-hidden) ─── */} -
-
+
+
{/* ─── 2A. ADMIN PARTNER SELECTION ─── */} {isAdmin && ( -
-
+
+
-
- + Admin Modus
@@ -225,7 +225,7 @@ export function StepCustomer({ {/* Partner Search & Page Size */}
- + {/* Partner Card List (Scrollable) */} -
+
{/* Reserved Fixed Card: Alle Partner */}
{ setSelectedCompanyId('all') setSelectedEndCustomerId(null) }} - className={`flex items-center justify-between p-2.5 rounded-xl border cursor-pointer transition-all select-none ${ + className={`flex items-center justify-between p-2 rounded-lg border cursor-pointer transition-all select-none ${ selectedCompanyId === 'all' || !selectedCompanyId ? 'border-primary bg-primary/10 shadow-sm shadow-primary/10' : 'border-white/5 bg-white/5 hover:bg-white/10' }`} > -
-
- +
+
+
-

+

Alle Partner (Firmenübergreifend)

-

+

{endCustomers.filter((c) => !c.is_anonymized).length} Kunden gesamt

{(selectedCompanyId === 'all' || !selectedCompanyId) && ( - + )}
@@ -288,20 +288,20 @@ export function StepCustomer({ setSelectedCompanyId(c.id) setSelectedEndCustomerId(null) }} - className={`flex items-center justify-between p-2.5 rounded-xl border cursor-pointer transition-all select-none ${ + className={`flex items-center justify-between p-2 rounded-lg border cursor-pointer transition-all select-none ${ isSelected ? 'border-primary bg-primary/10 shadow-sm shadow-primary/10' : 'border-white/5 bg-white/5 hover:bg-white/10' }`} > -
-
- +
+
+
-

{c.name}

+

{c.name}

{(c.street || c.zip || c.city) && ( -

+

{[c.street, [c.zip, c.city].filter(Boolean).join(' ')].filter(Boolean).join(', ')}

)} @@ -311,7 +311,7 @@ export function StepCustomer({
0 ? 'border-green-500/30 text-green-400 bg-green-500/10' : 'border-white/10 text-slate-500 bg-white/5' @@ -319,21 +319,21 @@ export function StepCustomer({ > {customerCount} - {isSelected && } + {isSelected && }
) })} {filteredCompanies.length === 0 && ( -
+
Keine Partner gefunden.
)}
{/* Partner Pagination Footer */} -
+
{Math.min(partnerCurrentPage * partnerPageSize, totalPartnerCount)} / {totalPartnerCount} Partner
@@ -343,20 +343,20 @@ export function StepCustomer({ size="sm" onClick={() => setPartnerCurrentPage(1)} disabled={partnerCurrentPage === 1} - className="h-6 px-1.5 text-slate-400 hover:text-white" + className="h-5 px-1 text-slate-400 hover:text-white" > - + - + {partnerCurrentPage} / {totalPartnerPages}
@@ -383,14 +383,14 @@ export function StepCustomer({ )} {/* ─── 2B. CUSTOMER SELECTION LIST (Scrollable Panel) ─── */} -
-
+
+
-