feat(multiselect): support multi-select categories and free items limits in category config and order wizard
All checks were successful
Staging Build / build (push) Successful in 2m38s

This commit is contained in:
DanielS
2026-07-07 16:56:24 +02:00
parent 00d1be3e4f
commit cc7445e4c5
9 changed files with 451 additions and 212 deletions

View File

@@ -43,6 +43,8 @@ const categorySchema = z.object({
icon: z.string().default('Package'),
sort_order: z.coerce.number().int().min(0).default(0),
is_required: z.boolean().default(true),
allow_multiselect: z.boolean().default(false),
free_items_limit: z.coerce.number().int().min(0).default(0),
})
type CategoryFormValues = z.infer<typeof categorySchema>
@@ -65,15 +67,17 @@ export function CategoryDialog({
icon: category?.icon || 'Package',
sort_order: category?.sort_order ?? 0,
is_required: category?.is_required ?? true,
allow_multiselect: category?.allow_multiselect ?? false,
free_items_limit: category?.free_items_limit ?? 0,
},
})
async function onSubmit(values: CategoryFormValues) {
try {
if (category) {
await updateCategory(category.id, values)
await updateCategory(category.id, values as any)
} else {
await createCategory(values)
await createCategory(values as any)
}
setOpen(false)
form.reset()
@@ -184,7 +188,7 @@ export function CategoryDialog({
</FormItem>
)}
/>
<FormField
<FormField
control={form.control}
name="is_required"
render={({ field }) => (
@@ -207,6 +211,52 @@ export function CategoryDialog({
</FormItem>
)}
/>
<FormField
control={form.control}
name="allow_multiselect"
render={({ field }) => (
<FormItem className="flex flex-row items-start space-x-3 space-y-0 rounded-lg border border-slate-200 dark:border-white/10 bg-slate-50 dark:bg-white/5 p-4">
<FormControl>
<Checkbox
checked={field.value}
onCheckedChange={field.onChange}
/>
</FormControl>
<div className="space-y-1 leading-none">
<FormLabel className="text-slate-900 dark:text-white font-semibold cursor-pointer">
Mehrfachauswahl erlauben
</FormLabel>
<p className="text-xs text-slate-500 dark:text-slate-400">
Erlaubt die Auswahl mehrerer Produkte/Module innerhalb dieser Kategorie.
</p>
</div>
</FormItem>
)}
/>
{form.watch('allow_multiselect') && (
<FormField
control={form.control}
name="free_items_limit"
render={({ field }) => (
<FormItem>
<FormLabel className="text-slate-900 dark:text-white">Inklusive Freie Artikel Limit</FormLabel>
<FormControl>
<Input
type="number"
min={0}
placeholder="z.B. 2"
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 />
<p className="text-xs text-slate-500 dark:text-slate-400">
Bis zu dieser Anzahl sind gewählte Artikel in dieser Kategorie kostenlos. Alle darüber hinausgehenden werden voll berechnet (günstigste Artikel zuerst frei).
</p>
</FormItem>
)}
/>
)}
</div>
</ScrollArea>
<DialogFooter className="pt-4">