feat(admin): make product dialog wider and improve module additions layout
Some checks failed
Staging Build / build (push) Failing after 26s
Some checks failed
Staging Build / build (push) Failing after 26s
This commit is contained in:
@@ -78,8 +78,32 @@ export function CreateProductDialog({
|
|||||||
products?: Product[]
|
products?: Product[]
|
||||||
}) {
|
}) {
|
||||||
const [open, setOpen] = useState(false)
|
const [open, setOpen] = useState(false)
|
||||||
|
const [step, setStep] = useState(1)
|
||||||
const router = useRouter()
|
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 otherProducts = products.filter(p => p.id !== product?.id)
|
||||||
|
|
||||||
const form = useForm<ProductFormValues>({
|
const form = useForm<ProductFormValues>({
|
||||||
@@ -136,7 +160,7 @@ export function CreateProductDialog({
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog open={open} onOpenChange={setOpen}>
|
<Dialog open={open} onOpenChange={handleOpenChange}>
|
||||||
<DialogTrigger asChild>
|
<DialogTrigger asChild>
|
||||||
{children || (
|
{children || (
|
||||||
<Button className="bg-primary hover:bg-primary/90">
|
<Button className="bg-primary hover:bg-primary/90">
|
||||||
@@ -144,7 +168,7 @@ export function CreateProductDialog({
|
|||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
</DialogTrigger>
|
</DialogTrigger>
|
||||||
<DialogContent className="sm:max-w-[700px] max-h-[90vh] overflow-hidden flex flex-col bg-white dark:bg-slate-950 border-slate-200 dark:border-white/10 text-slate-900 dark:text-white shadow-2xl">
|
<DialogContent className="sm:max-w-[900px] max-h-[90vh] overflow-hidden flex flex-col bg-white dark:bg-slate-950 border-slate-200 dark:border-white/10 text-slate-900 dark:text-white shadow-2xl">
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<DialogTitle className="text-2xl font-bold">
|
<DialogTitle className="text-2xl font-bold">
|
||||||
{product ? 'Produkt bearbeiten' : 'Neues Produkt erstellen'}
|
{product ? 'Produkt bearbeiten' : 'Neues Produkt erstellen'}
|
||||||
@@ -157,6 +181,31 @@ export function CreateProductDialog({
|
|||||||
<Form {...form}>
|
<Form {...form}>
|
||||||
<form onSubmit={form.handleSubmit(onSubmit)} className="flex flex-col gap-4 overflow-hidden flex-1 min-h-0">
|
<form onSubmit={form.handleSubmit(onSubmit)} className="flex flex-col gap-4 overflow-hidden flex-1 min-h-0">
|
||||||
<div className="flex-1 overflow-y-auto pr-4 space-y-6 py-4 min-h-0">
|
<div className="flex-1 overflow-y-auto pr-4 space-y-6 py-4 min-h-0">
|
||||||
|
{/* Step Indicator */}
|
||||||
|
<div className="flex justify-between items-center mb-6 border-b border-slate-100 dark:border-white/5 pb-4">
|
||||||
|
{[
|
||||||
|
{ nr: 1, label: 'Allgemein' },
|
||||||
|
{ nr: 2, label: 'Abrechnung' },
|
||||||
|
{ nr: 3, label: 'Sichtbarkeit' },
|
||||||
|
{ nr: 4, label: 'Abhängigkeiten' },
|
||||||
|
{ nr: 5, label: 'Module' }
|
||||||
|
].map(s => (
|
||||||
|
<div key={s.nr} className="flex flex-col items-center gap-1 flex-1">
|
||||||
|
<div className={`w-8 h-8 rounded-full flex items-center justify-center font-bold text-sm transition-colors ${
|
||||||
|
step === s.nr
|
||||||
|
? 'bg-primary text-white'
|
||||||
|
: step > s.nr
|
||||||
|
? 'bg-green-500 text-white'
|
||||||
|
: 'bg-slate-200 dark:bg-slate-800 text-slate-500'
|
||||||
|
}`}>
|
||||||
|
{s.nr}
|
||||||
|
</div>
|
||||||
|
<span className="text-[10px] text-slate-500 dark:text-slate-400 font-medium">{s.label}</span>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
{step === 1 && (
|
||||||
|
<div className="space-y-6">
|
||||||
<div className="grid grid-cols-2 gap-4">
|
<div className="grid grid-cols-2 gap-4">
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
@@ -209,6 +258,24 @@ export function CreateProductDialog({
|
|||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="description"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel className="text-slate-900 dark:text-white">Beschreibung</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Input placeholder="Kurze Beschreibung des Produkts" className="bg-slate-50 dark:bg-white/5 border-slate-200 dark:border-white/10 text-slate-900 dark:text-white placeholder:text-slate-500" {...field} />
|
||||||
|
</FormControl>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{step === 2 && (
|
||||||
|
<div className="space-y-6">
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
name="billing_interval"
|
name="billing_interval"
|
||||||
@@ -239,7 +306,11 @@ export function CreateProductDialog({
|
|||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{step === 3 && (
|
||||||
|
<div className="space-y-6">
|
||||||
<div className="grid grid-cols-2 gap-4">
|
<div className="grid grid-cols-2 gap-4">
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
@@ -301,22 +372,10 @@ export function CreateProductDialog({
|
|||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="description"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel className="text-slate-900 dark:text-white">Beschreibung</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder="Kurze Beschreibung des Produkts" className="bg-slate-50 dark:bg-white/5 border-slate-200 dark:border-white/10 text-slate-900 dark:text-white placeholder:text-slate-500" {...field} />
|
|
||||||
</FormControl>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
)}
|
||||||
/>
|
|
||||||
|
|
||||||
|
{step === 4 && (
|
||||||
<div className="grid grid-cols-2 gap-4">
|
<div className="grid grid-cols-2 gap-4">
|
||||||
{/* Product Requirements */}
|
{/* Product Requirements */}
|
||||||
<FormField
|
<FormField
|
||||||
@@ -405,38 +464,18 @@ export function CreateProductDialog({
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</ScrollArea>
|
</ScrollArea>
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
<Separator className="bg-slate-200 dark:bg-white/10" />
|
{step === 5 && (
|
||||||
|
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<h3 className="text-lg font-semibold flex items-center gap-2">
|
<h3 className="text-lg font-semibold flex items-center gap-2">
|
||||||
<PlusCircle className="w-5 h-5 text-primary" />
|
<PlusCircle className="w-5 h-5 text-primary" />
|
||||||
Module
|
Module
|
||||||
</h3>
|
</h3>
|
||||||
<Button
|
|
||||||
type="button"
|
|
||||||
variant="outline"
|
|
||||||
size="sm"
|
|
||||||
className="border-primary/50 text-primary hover:bg-primary/10"
|
|
||||||
onClick={() => append({
|
|
||||||
id: typeof crypto !== 'undefined' && crypto.randomUUID ? crypto.randomUUID() : Math.random().toString(36).substring(2, 15),
|
|
||||||
name: '',
|
|
||||||
price: 0,
|
|
||||||
is_required: false,
|
|
||||||
has_quantity: false,
|
|
||||||
description: '',
|
|
||||||
requirements: [],
|
|
||||||
exclusions: []
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
<Plus className="w-4 h-4 mr-2" /> Modul hinzufügen
|
|
||||||
</Button>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{fields.map((field, index) => {
|
{fields.map((field, index) => {
|
||||||
@@ -449,26 +488,17 @@ export function CreateProductDialog({
|
|||||||
.filter((_, idx) => idx !== index)
|
.filter((_, idx) => idx !== index)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div key={field.id} className="p-4 rounded-lg bg-slate-50 dark:bg-white/5 border border-slate-200 dark:border-white/10 space-y-4 relative group">
|
<div key={field.id} className="p-4 border border-slate-200 dark:border-white/10 rounded-xl bg-slate-50 dark:bg-white/5 space-y-4">
|
||||||
<Button
|
<div className="flex items-start justify-between gap-4">
|
||||||
type="button"
|
<div className="flex-1 grid grid-cols-2 gap-4">
|
||||||
variant="ghost"
|
|
||||||
size="icon"
|
|
||||||
className="absolute top-2 right-2 h-8 w-8 text-muted-foreground hover:text-destructive opacity-0 group-hover:opacity-100 transition-opacity"
|
|
||||||
onClick={() => remove(index)}
|
|
||||||
>
|
|
||||||
<X className="h-4 w-4" />
|
|
||||||
</Button>
|
|
||||||
|
|
||||||
<div className="grid grid-cols-2 gap-4">
|
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
name={`modules.${index}.name`}
|
name={`modules.${index}.name`}
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel className="text-slate-900 dark:text-white">Modulname</FormLabel>
|
<FormLabel className="text-slate-900 dark:text-white text-xs">Modulname</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Input placeholder="z.B. Cloud Storage" className="bg-slate-100 dark:bg-white/10 border-slate-200 dark:border-white/10 text-slate-900 dark:text-white placeholder:text-slate-500" {...field} />
|
<Input placeholder="z.B. Zusatzlizenz" className="bg-white dark:bg-slate-900 border-slate-200 dark:border-white/10 text-slate-900 dark:text-white text-xs" {...field} />
|
||||||
</FormControl>
|
</FormControl>
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
@@ -479,49 +509,69 @@ export function CreateProductDialog({
|
|||||||
name={`modules.${index}.price`}
|
name={`modules.${index}.price`}
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel className="text-slate-900 dark:text-white">Aufpreis (€)</FormLabel>
|
<FormLabel className="text-slate-900 dark:text-white text-xs">Preis (€/Monat)</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Input type="number" step="0.01" className="bg-slate-100 dark:bg-white/10 border-slate-200 dark:border-white/10 text-slate-900 dark:text-white placeholder:text-slate-500" {...field} />
|
<Input type="number" step="0.01" className="bg-white dark:bg-slate-900 border-slate-200 dark:border-white/10 text-slate-900 dark:text-white text-xs" {...field} />
|
||||||
</FormControl>
|
</FormControl>
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
variant="ghost"
|
||||||
|
size="sm"
|
||||||
|
className="text-red-500 hover:text-red-700 hover:bg-red-50 dark:hover:bg-red-950/20 mt-6"
|
||||||
|
onClick={() => remove(index)}
|
||||||
|
>
|
||||||
|
<Trash2 className="w-4 h-4" />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="grid grid-cols-2 gap-4 border border-slate-200 dark:border-white/10 rounded-lg p-3 bg-slate-100 dark:bg-black/20">
|
<FormField
|
||||||
{/* Requirements Selection Matrix */}
|
control={form.control}
|
||||||
|
name={`modules.${index}.description`}
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel className="text-slate-900 dark:text-white text-xs">Beschreibung</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Input placeholder="Kurze Beschreibung" className="bg-white dark:bg-slate-900 border-slate-200 dark:border-white/10 text-slate-900 dark:text-white text-xs" {...field} />
|
||||||
|
</FormControl>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{otherModules.length > 0 && (
|
||||||
|
<div className="grid grid-cols-2 gap-4">
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
name={`modules.${index}.requirements`}
|
name={`modules.${index}.requirements`}
|
||||||
render={({ field: reqField }) => (
|
render={({ field: mReqField }) => (
|
||||||
<div className="space-y-2">
|
<FormItem className="flex flex-col gap-1">
|
||||||
<FormLabel className="text-slate-900 dark:text-white text-xs font-semibold">Benötigt Module</FormLabel>
|
<FormLabel className="text-slate-900 dark:text-white text-[11px] font-medium">Erfordert Module</FormLabel>
|
||||||
<ScrollArea className="h-28 border border-slate-200 dark:border-white/5 rounded p-2 bg-slate-50 dark:bg-white/5">
|
<ScrollArea className="h-24 border border-slate-200 dark:border-white/10 rounded p-2 bg-white dark:bg-slate-900">
|
||||||
{otherModules.length === 0 ? (
|
<div className="space-y-1">
|
||||||
<p className="text-[10px] text-slate-500 italic">Keine anderen Module vorhanden.</p>
|
|
||||||
) : (
|
|
||||||
<div className="space-y-1.5">
|
|
||||||
{otherModules.map(other => {
|
{otherModules.map(other => {
|
||||||
const checked = (reqField.value || []).includes(other.id)
|
const checked = (mReqField.value || []).includes(other.id)
|
||||||
return (
|
return (
|
||||||
<div key={other.id} className="flex items-center space-x-2">
|
<div key={other.id} className="flex items-center space-x-2">
|
||||||
<Checkbox
|
<Checkbox
|
||||||
id={`req-${index}-${other.id}`}
|
id={`mod-req-${index}-${other.id}`}
|
||||||
checked={checked}
|
checked={checked}
|
||||||
onCheckedChange={(checkedState) => {
|
onCheckedChange={(checkedState) => {
|
||||||
const currentVal = reqField.value || []
|
const currentVal = mReqField.value || []
|
||||||
if (checkedState) {
|
if (checkedState) {
|
||||||
reqField.onChange([...currentVal, other.id])
|
mReqField.onChange([...currentVal, other.id])
|
||||||
} else {
|
} else {
|
||||||
reqField.onChange(currentVal.filter(id => id !== other.id))
|
mReqField.onChange(currentVal.filter(id => id !== other.id))
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<label
|
<label
|
||||||
htmlFor={`req-${index}-${other.id}`}
|
htmlFor={`mod-req-${index}-${other.id}`}
|
||||||
className="text-xs text-slate-700 dark:text-slate-300 cursor-pointer select-none truncate block max-w-[180px]"
|
className="text-[10px] text-slate-650 dark:text-slate-350 cursor-pointer truncate block"
|
||||||
title={other.name}
|
|
||||||
>
|
>
|
||||||
{other.name}
|
{other.name}
|
||||||
</label>
|
</label>
|
||||||
@@ -529,44 +579,38 @@ export function CreateProductDialog({
|
|||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
)}
|
|
||||||
</ScrollArea>
|
</ScrollArea>
|
||||||
</div>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* Exclusions Selection Matrix */}
|
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
name={`modules.${index}.exclusions`}
|
name={`modules.${index}.exclusions`}
|
||||||
render={({ field: exclField }) => (
|
render={({ field: mExclField }) => (
|
||||||
<div className="space-y-2">
|
<FormItem className="flex flex-col gap-1">
|
||||||
<FormLabel className="text-slate-900 dark:text-white text-xs font-semibold">Schließt aus</FormLabel>
|
<FormLabel className="text-slate-900 dark:text-white text-[11px] font-medium">Schließt Module aus</FormLabel>
|
||||||
<ScrollArea className="h-28 border border-slate-200 dark:border-white/5 rounded p-2 bg-slate-50 dark:bg-white/5">
|
<ScrollArea className="h-24 border border-slate-200 dark:border-white/10 rounded p-2 bg-white dark:bg-slate-900">
|
||||||
{otherModules.length === 0 ? (
|
<div className="space-y-1">
|
||||||
<p className="text-[10px] text-slate-500 italic">Keine anderen Module vorhanden.</p>
|
|
||||||
) : (
|
|
||||||
<div className="space-y-1.5">
|
|
||||||
{otherModules.map(other => {
|
{otherModules.map(other => {
|
||||||
const checked = (exclField.value || []).includes(other.id)
|
const checked = (mExclField.value || []).includes(other.id)
|
||||||
return (
|
return (
|
||||||
<div key={other.id} className="flex items-center space-x-2">
|
<div key={other.id} className="flex items-center space-x-2">
|
||||||
<Checkbox
|
<Checkbox
|
||||||
id={`excl-${index}-${other.id}`}
|
id={`mod-excl-${index}-${other.id}`}
|
||||||
checked={checked}
|
checked={checked}
|
||||||
onCheckedChange={(checkedState) => {
|
onCheckedChange={(checkedState) => {
|
||||||
const currentVal = exclField.value || []
|
const currentVal = mExclField.value || []
|
||||||
if (checkedState) {
|
if (checkedState) {
|
||||||
exclField.onChange([...currentVal, other.id])
|
mExclField.onChange([...currentVal, other.id])
|
||||||
} else {
|
} else {
|
||||||
exclField.onChange(currentVal.filter(id => id !== other.id))
|
mExclField.onChange(currentVal.filter(id => id !== other.id))
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<label
|
<label
|
||||||
htmlFor={`excl-${index}-${other.id}`}
|
htmlFor={`mod-excl-${index}-${other.id}`}
|
||||||
className="text-xs text-slate-700 dark:text-slate-300 cursor-pointer select-none truncate block max-w-[180px]"
|
className="text-[10px] text-slate-650 dark:text-slate-350 cursor-pointer truncate block"
|
||||||
title={other.name}
|
|
||||||
>
|
>
|
||||||
{other.name}
|
{other.name}
|
||||||
</label>
|
</label>
|
||||||
@@ -574,12 +618,12 @@ export function CreateProductDialog({
|
|||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
)}
|
|
||||||
</ScrollArea>
|
</ScrollArea>
|
||||||
</div>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
<div className="flex items-center gap-6">
|
<div className="flex items-center gap-6">
|
||||||
<FormField
|
<FormField
|
||||||
@@ -623,12 +667,54 @@ export function CreateProductDialog({
|
|||||||
Noch keine Module hinzugefügt.
|
Noch keine Module hinzugefügt.
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
<div className="flex justify-end pt-2">
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
variant="outline"
|
||||||
|
size="sm"
|
||||||
|
className="border-primary/50 text-primary hover:bg-primary/10"
|
||||||
|
onClick={() => append({
|
||||||
|
id: typeof crypto !== 'undefined' && crypto.randomUUID ? crypto.randomUUID() : Math.random().toString(36).substring(2, 15),
|
||||||
|
name: '',
|
||||||
|
price: 0,
|
||||||
|
is_required: false,
|
||||||
|
has_quantity: false,
|
||||||
|
description: '',
|
||||||
|
requirements: [],
|
||||||
|
exclusions: []
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
<Plus className="w-4 h-4 mr-2" /> Modul hinzufügen
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
<DialogFooter className="pt-4 border-t border-slate-200 dark:border-white/10">
|
<DialogFooter className="pt-4 border-t border-slate-200 dark:border-white/10 flex justify-between items-center sm:justify-between">
|
||||||
<Button type="button" variant="ghost" onClick={() => setOpen(false)} className="text-slate-500 hover:text-slate-900 dark:text-slate-400 dark:hover:text-white">Abbrechen</Button>
|
<div className="flex gap-2">
|
||||||
<Button type="submit" className="bg-primary hover:bg-primary/90 text-white">Speichern</Button>
|
{step > 1 ? (
|
||||||
|
<Button type="button" variant="outline" onClick={() => setStep(prev => prev - 1)}>
|
||||||
|
Zurück
|
||||||
|
</Button>
|
||||||
|
) : (
|
||||||
|
<Button type="button" variant="ghost" onClick={() => setOpen(false)} className="text-slate-500 hover:text-slate-900 dark:text-slate-400 dark:hover:text-white">
|
||||||
|
Abbrechen
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="flex gap-2">
|
||||||
|
{step < 5 ? (
|
||||||
|
<Button type="button" onClick={nextStep} className="bg-primary hover:bg-primary/90 text-white">
|
||||||
|
Weiter
|
||||||
|
</Button>
|
||||||
|
) : (
|
||||||
|
<Button type="submit" className="bg-primary hover:bg-primary/90 text-white">
|
||||||
|
Speichern
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</DialogFooter>
|
</DialogFooter>
|
||||||
</form>
|
</form>
|
||||||
</Form>
|
</Form>
|
||||||
|
|||||||
Reference in New Issue
Block a user