diff --git a/app/components/catalog/CatalogConfigurator.vue b/app/components/catalog/CatalogConfigurator.vue index 3aeaef7..214f7ae 100644 --- a/app/components/catalog/CatalogConfigurator.vue +++ b/app/components/catalog/CatalogConfigurator.vue @@ -4,7 +4,7 @@ import { ClientProductsDocument, type ClientProductsQuery } from '~/composables/ import { useClientCart } from '~/composables/useClientCart'; type ProductNode = ClientProductsQuery['clientProducts'][number]; -type ParamFieldKey = 'widthMm' | 'lengthM' | 'thicknessMicron' | 'sleeveBrand'; +type ParamFieldKey = 'widthMm' | 'lengthM' | 'thicknessMicron' | 'sleeveBrand' | 'quantityPerBox'; type ParamValue = number | string; type ParsedProduct = ProductNode & { @@ -23,15 +23,17 @@ type GroupState = { lengthM: number | null; thicknessMicron: number | null; sleeveBrand: string | null; + quantityPerBox: string | null; isExpanded: boolean; }; -const PARAM_KEYS: ParamFieldKey[] = ['widthMm', 'lengthM', 'thicknessMicron', 'sleeveBrand']; +const PARAM_KEYS: ParamFieldKey[] = ['widthMm', 'lengthM', 'thicknessMicron', 'sleeveBrand', 'quantityPerBox']; const parameterFields: Array<{ key: ParamFieldKey; label: string }> = [ { key: 'widthMm', label: 'Ширина' }, { key: 'lengthM', label: 'Длина' }, { key: 'thicknessMicron', label: 'Толщина' }, { key: 'sleeveBrand', label: 'Втулка' }, + { key: 'quantityPerBox', label: 'Короб' }, ]; const coverPresets = [ @@ -177,6 +179,13 @@ function getAllFieldOptions(group: ProductGroup, field: ParamFieldKey) { const values = new Set(); for (const product of group.products) { + if (field === 'quantityPerBox') { + for (const option of product.quantityPerBoxOptions) { + values.add(option); + } + continue; + } + const value = product[field]; if (value !== null && value !== undefined) { values.add(value); @@ -202,6 +211,7 @@ function createGroupState(group: ProductGroup): GroupState { lengthM: firstProduct?.lengthM ?? null, thicknessMicron: firstProduct?.thicknessMicron ?? null, sleeveBrand: firstProduct?.sleeveBrand ?? null, + quantityPerBox: firstProduct?.quantityPerBoxOptions[0] ?? null, isExpanded: false, }; } @@ -230,7 +240,17 @@ function getGroupState(group: ProductGroup) { } function matchesProductState(product: ParsedProduct, state: GroupState, keys: ParamFieldKey[]) { - return keys.every((key) => state[key] === null || product[key] === state[key]); + return keys.every((key) => { + if (state[key] === null) { + return true; + } + + if (key === 'quantityPerBox') { + return product.quantityPerBoxOptions.includes(String(state[key])); + } + + return product[key] === state[key]; + }); } function matchingProducts(group: ProductGroup) { @@ -254,22 +274,6 @@ function selectedProduct(group: ProductGroup) { return matches.length === 1 ? matches[0] : null; } -function boxQuantityLabel(group: ProductGroup) { - const product = selectedProduct(group); - if (product?.quantityPerBoxOptions.length) { - return product.quantityPerBoxOptions.join(' / '); - } - - const values = new Set(); - for (const item of group.products) { - for (const option of item.quantityPerBoxOptions) { - values.add(option); - } - } - - return sortParamValues([...values]).join(' / ') || '—'; -} - function formatOptionLabel(field: ParamFieldKey, value: ParamValue) { if (field === 'widthMm') { return `${value} мм`; @@ -311,6 +315,7 @@ function updateField(group: ProductGroup, field: ParamFieldKey, value: ParamValu state.lengthM = fallback.lengthM ?? null; state.thicknessMicron = fallback.thicknessMicron ?? null; state.sleeveBrand = fallback.sleeveBrand ?? null; + state.quantityPerBox = fallback.quantityPerBoxOptions[0] ?? null; } function articleLabel(group: ProductGroup) { @@ -439,15 +444,13 @@ function decrementSelected(group: ProductGroup) {