feat(categories): add branch visibility selection
All checks were successful
Staging Build / build (push) Successful in 2m43s

This commit is contained in:
DanielS
2026-07-09 14:26:56 +02:00
parent 07c7d8c656
commit 071e669b71
4 changed files with 76 additions and 8 deletions

View File

@@ -195,8 +195,17 @@ export function OrderWizard({
}
}, [lastLicenseMonths, selectedBillingInterval])
const visibleCategories = useMemo(() => {
return categories.filter(cat =>
selectedBillingInterval === 'one_time'
? cat.show_in_kauf !== false
: cat.show_in_abo !== false
)
}, [categories, selectedBillingInterval])
// Per-category selection map: categoryId -> { productId, productIds, moduleIds }
const [selections, setSelections] = useState<Record<string, CategorySelection>>(() => {
const initInterval = initialOrder?.order_data?.billing_cycle ?? 'monthly'
const init: Record<string, CategorySelection> = {}
categories.forEach(cat => {
if (initialOrder) {
@@ -211,10 +220,11 @@ export function OrderWizard({
return
}
}
if (cat.allow_multiselect || cat.preselect === false) {
const isVisible = initInterval === 'one_time' ? cat.show_in_kauf !== false : cat.show_in_abo !== false
if (!isVisible || 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)
const first = products.find(p => p.category_id === cat.id && (initInterval === 'one_time' ? p.show_in_kauf !== false : p.show_in_abo !== false))
init[cat.id] = { productId: first?.id ?? null, productIds: first ? [first.id] : [], moduleIds: [] }
}
})
@@ -223,7 +233,7 @@ export function OrderWizard({
// Only REQUIRED categories must have a product selected (which must be filtered by selected branch)
const allCategoriesFilled = useMemo(() => {
return categories
return visibleCategories
.filter(cat => cat.is_required)
.every(cat => {
const sel = selections[cat.id]
@@ -243,7 +253,7 @@ export function OrderWizard({
? prod.show_in_kauf !== false
: prod.show_in_abo !== false
})
}, [categories, selections, products, selectedBillingInterval])
}, [visibleCategories, selections, products, selectedBillingInterval])
// Product validation errors (requirements and exclusions)
const productValidationErrors = useMemo(() => {
@@ -459,7 +469,8 @@ export function OrderWizard({
}
const newSelections: Record<string, CategorySelection> = {}
categories.forEach(cat => {
if (cat.allow_multiselect || cat.preselect === false) {
const isVisible = val === 'one_time' ? cat.show_in_kauf !== false : cat.show_in_abo !== false
if (!isVisible || cat.allow_multiselect || cat.preselect === false) {
newSelections[cat.id] = { productId: null, productIds: [], moduleIds: [] }
} else {
const matchingProd = products.find(p =>
@@ -870,7 +881,7 @@ export function OrderWizard({
</CardDescription>
</CardHeader>
<CardContent className="space-y-8">
{categories.map((cat, idx) => {
{visibleCategories.map((cat, idx) => {
const otherSelectedProductIds = Object.entries(selections)
.filter(([cId]) => cId !== cat.id)
.map(([, s]) => s.productId)
@@ -1122,7 +1133,7 @@ export function OrderWizard({
<CardTitle className="text-white">Zusammenfassung</CardTitle>
</CardHeader>
<CardContent className="space-y-4">
{categories.map(cat => {
{visibleCategories.map(cat => {
const sel = selections[cat.id]
const selectedProds: Product[] = []
if (cat.allow_multiselect && sel?.productIds) {
@@ -1311,7 +1322,7 @@ export function OrderWizard({
</CardHeader>
<CardContent className="space-y-6 text-left">
<div className="p-4 rounded-lg bg-white/5 space-y-4">
{categories.map(cat => {
{visibleCategories.map(cat => {
const sel = selections[cat.id]
const selectedProds: Product[] = []
if (cat.allow_multiselect && sel?.productIds) {