diff --git a/shop/components/admin/create-product-dialog.tsx b/shop/components/admin/create-product-dialog.tsx index 48505e6..003e25e 100644 --- a/shop/components/admin/create-product-dialog.tsx +++ b/shop/components/admin/create-product-dialog.tsx @@ -78,8 +78,32 @@ export function CreateProductDialog({ products?: Product[] }) { const [open, setOpen] = useState(false) + const [step, setStep] = useState(1) const router = useRouter() + function handleOpenChange(isOpen: boolean) { + setOpen(isOpen) + if (isOpen) { + setStep(1) + } + } + + async function nextStep() { + let isValid = false + if (step === 1) { + isValid = await form.trigger(['name', 'category_id', 'base_price']) + } else if (step === 2) { + isValid = await form.trigger('billing_interval') + } else if (step === 3) { + isValid = await form.trigger(['show_in_kauf', 'show_in_abo']) + } else if (step === 4) { + isValid = await form.trigger(['requirements', 'exclusions']) + } + if (isValid || step === 5) { + setStep(prev => Math.min(prev + 1, 5)) + } + } + const otherProducts = products.filter(p => p.id !== product?.id) const form = useForm({ @@ -136,7 +160,7 @@ export function CreateProductDialog({ } return ( - + {children || ( )} - + {product ? 'Produkt bearbeiten' : 'Neues Produkt erstellen'} @@ -157,166 +181,201 @@ export function CreateProductDialog({
-
+ {/* Step Indicator */} +
+ {[ + { nr: 1, label: 'Allgemein' }, + { nr: 2, label: 'Abrechnung' }, + { nr: 3, label: 'Sichtbarkeit' }, + { nr: 4, label: 'Abhängigkeiten' }, + { nr: 5, label: 'Module' } + ].map(s => ( +
+
s.nr + ? 'bg-green-500 text-white' + : 'bg-slate-200 dark:bg-slate-800 text-slate-500' + }`}> + {s.nr} +
+ {s.label} +
+ ))} +
+ {step === 1 && ( +
+
+ ( + + Produktname + + + + + + )} + /> + ( + + Basispreis (€) + + + + + + )} + /> +
+ ( - Produktname - - - + Kategorie + )} /> + ( - Basispreis (€) + Beschreibung - + )} />
+ )} - ( - - Kategorie - - - - )} - /> - - ( - - Abrechnungsmodell -
- {[ - { value: 'one_time', label: 'Einmalig', icon: '💳' }, - { value: 'monthly', label: 'Monatlich', icon: '🔄' }, - ].map(opt => ( - - ))} -
- -
- )} - /> - -
- ( - - - - -
- In Kauf-Auswahl anzeigen - Produkt im Kauf-Zweig anzeigen -
-
- )} - /> - ( - - - - -
- In Abo-Auswahl anzeigen - Produkt im Abo-Zweig anzeigen
+
)} />
+ )} - {form.watch('billing_interval') === 'one_time' && ( - ( - - - - -
- Update-Rabatt erlauben - - Kunden erhalten für dieses Produkt den selektiven Update-Rabatt. - -
-
- )} - /> - )} + {step === 3 && ( +
+
+ ( + + + + +
+ In Kauf-Auswahl anzeigen + Produkt im Kauf-Zweig anzeigen +
+
+ )} + /> + ( + + + + +
+ In Abo-Auswahl anzeigen + Produkt im Abo-Zweig anzeigen +
+
+ )} + /> +
- - ( - - Beschreibung - - - - - + {form.watch('billing_interval') === 'one_time' && ( + ( + + + + +
+ Update-Rabatt erlauben + + Kunden erhalten für dieses Produkt den selektiven Update-Rabatt. + +
+
+ )} + /> )} - /> +
+ )} + {step === 4 && (
{/* Product Requirements */} )} - - )} />
+ )} - - + {step === 5 && (

Module

-
{fields.map((field, index) => { @@ -449,79 +488,90 @@ export function CreateProductDialog({ .filter((_, idx) => idx !== index) return ( -
- - -
- ( - - Modulname - - - - - - )} - /> - ( - - Aufpreis (€) - - - - - - )} - /> +
+
+
+ ( + + Modulname + + + + + + )} + /> + ( + + Preis (€/Monat) + + + + + + )} + /> +
+
-
- {/* Requirements Selection Matrix */} - ( -
- Benötigt Module - - {otherModules.length === 0 ? ( -

Keine anderen Module vorhanden.

- ) : ( -
+ ( + + Beschreibung + + + + + + )} + /> + + {otherModules.length > 0 && ( +
+ ( + + Erfordert Module + +
{otherModules.map(other => { - const checked = (reqField.value || []).includes(other.id) + const checked = (mReqField.value || []).includes(other.id) return (
{ - const currentVal = reqField.value || [] + const currentVal = mReqField.value || [] if (checkedState) { - reqField.onChange([...currentVal, other.id]) + mReqField.onChange([...currentVal, other.id]) } else { - reqField.onChange(currentVal.filter(id => id !== other.id)) + mReqField.onChange(currentVal.filter(id => id !== other.id)) } }} /> @@ -529,44 +579,38 @@ export function CreateProductDialog({ ) })}
- )} - -
- )} - /> +
+
+ )} + /> - {/* Exclusions Selection Matrix */} - ( -
- Schließt aus - - {otherModules.length === 0 ? ( -

Keine anderen Module vorhanden.

- ) : ( -
+ ( + + Schließt Module aus + +
{otherModules.map(other => { - const checked = (exclField.value || []).includes(other.id) + const checked = (mExclField.value || []).includes(other.id) return (
{ - const currentVal = exclField.value || [] + const currentVal = mExclField.value || [] if (checkedState) { - exclField.onChange([...currentVal, other.id]) + mExclField.onChange([...currentVal, other.id]) } else { - exclField.onChange(currentVal.filter(id => id !== other.id)) + mExclField.onChange(currentVal.filter(id => id !== other.id)) } }} /> @@ -574,12 +618,12 @@ export function CreateProductDialog({ ) })}
- )} - -
- )} - /> -
+
+ + )} + /> +
+ )}
) })} - + {fields.length === 0 && (
Noch keine Module hinzugefügt.
)} + +
+ +
+ )}
- - - + +
+ {step > 1 ? ( + + ) : ( + + )} +
+
+ {step < 5 ? ( + + ) : ( + + )} +