feat(categories): allow disabling preselection
All checks were successful
Staging Build / build (push) Successful in 2m45s
All checks were successful
Staging Build / build (push) Successful in 2m45s
This commit is contained in:
@@ -45,6 +45,7 @@ const categorySchema = z.object({
|
||||
is_required: z.boolean().default(true),
|
||||
allow_multiselect: z.boolean().default(false),
|
||||
free_items_limit: z.coerce.number().int().min(0).default(0),
|
||||
preselect: z.boolean().default(true),
|
||||
})
|
||||
|
||||
type CategoryFormValues = z.infer<typeof categorySchema>
|
||||
@@ -69,6 +70,7 @@ export function CategoryDialog({
|
||||
is_required: category?.is_required ?? true,
|
||||
allow_multiselect: category?.allow_multiselect ?? false,
|
||||
free_items_limit: category?.free_items_limit ?? 0,
|
||||
preselect: category?.preselect ?? true,
|
||||
},
|
||||
})
|
||||
|
||||
@@ -219,7 +221,12 @@ export function CategoryDialog({
|
||||
<FormControl>
|
||||
<Checkbox
|
||||
checked={field.value}
|
||||
onCheckedChange={field.onChange}
|
||||
onCheckedChange={(checked) => {
|
||||
field.onChange(checked);
|
||||
if (checked) {
|
||||
form.setValue('preselect', false);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</FormControl>
|
||||
<div className="space-y-1 leading-none">
|
||||
@@ -233,6 +240,30 @@ export function CategoryDialog({
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
{!form.watch('allow_multiselect') && (
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="preselect"
|
||||
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">
|
||||
Vorauswahl aktivieren
|
||||
</FormLabel>
|
||||
<p className="text-xs text-slate-500 dark:text-slate-400">
|
||||
Wenn aktiv, wird beim Öffnen des Wizards automatisch das erste Produkt dieser Kategorie ausgewählt.
|
||||
</p>
|
||||
</div>
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
{form.watch('allow_multiselect') && (
|
||||
<FormField
|
||||
control={form.control}
|
||||
|
||||
@@ -211,7 +211,7 @@ export function OrderWizard({
|
||||
return
|
||||
}
|
||||
}
|
||||
if (cat.allow_multiselect) {
|
||||
if (cat.allow_multiselect || cat.preselect === false) {
|
||||
init[cat.id] = { productId: null, productIds: [], moduleIds: [] }
|
||||
} else {
|
||||
const first = products.find(p => p.category_id === cat.id && p.show_in_abo !== false)
|
||||
@@ -459,11 +459,19 @@ export function OrderWizard({
|
||||
}
|
||||
const newSelections: Record<string, CategorySelection> = {}
|
||||
categories.forEach(cat => {
|
||||
if (cat.allow_multiselect || cat.preselect === false) {
|
||||
newSelections[cat.id] = { productId: null, productIds: [], moduleIds: [] }
|
||||
} else {
|
||||
const matchingProd = products.find(p =>
|
||||
p.category_id === cat.id &&
|
||||
(val === 'one_time' ? p.show_in_kauf !== false : p.show_in_abo !== false)
|
||||
)
|
||||
newSelections[cat.id] = { productId: matchingProd?.id ?? null, moduleIds: [] }
|
||||
newSelections[cat.id] = {
|
||||
productId: matchingProd?.id ?? null,
|
||||
productIds: matchingProd ? [matchingProd.id] : [],
|
||||
moduleIds: []
|
||||
}
|
||||
}
|
||||
})
|
||||
setSelections(newSelections)
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ export type Category = {
|
||||
is_required: boolean
|
||||
allow_multiselect: boolean
|
||||
free_items_limit: number
|
||||
preselect: boolean
|
||||
created_at: string
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
-- Add preselect column to categories table
|
||||
ALTER TABLE public.categories ADD COLUMN IF NOT EXISTS preselect BOOLEAN DEFAULT true NOT NULL;
|
||||
Reference in New Issue
Block a user