From 0f7787de36270e6acdcd69f4232ca0279892f3ed Mon Sep 17 00:00:00 2001 From: Ruslan Bakiev <572431+veikab@users.noreply.github.com> Date: Fri, 3 Apr 2026 08:50:24 +0700 Subject: [PATCH] Refine catalog cart controls and show cart badge in header --- app/components/ui/AppHeader.vue | 4 ++++ app/composables/useClientCart.ts | 20 ++++++++++++++++---- app/pages/products.vue | 24 +++++++++++++++++++----- 3 files changed, 39 insertions(+), 9 deletions(-) diff --git a/app/components/ui/AppHeader.vue b/app/components/ui/AppHeader.vue index a3c7384..96e1297 100644 --- a/app/components/ui/AppHeader.vue +++ b/app/components/ui/AppHeader.vue @@ -6,6 +6,7 @@ type NavItem = { }; const route = useRoute(); +const { totalItems } = useClientCart(); const leftCapsule: NavItem[] = [ { to: '/profile', label: 'Профиль', icon: 'user' }, @@ -83,6 +84,9 @@ function isActive(path: string) { {{ item.label }} + + {{ totalItems }} + diff --git a/app/composables/useClientCart.ts b/app/composables/useClientCart.ts index 702b459..288136f 100644 --- a/app/composables/useClientCart.ts +++ b/app/composables/useClientCart.ts @@ -12,8 +12,8 @@ export type ClientCartItem = { }; function normalizeQuantity(value: number) { - if (!Number.isFinite(value) || value < 1) { - return 1; + if (!Number.isFinite(value) || value < 0) { + return 0; } return Math.floor(value); @@ -64,7 +64,13 @@ export function useClientCart() { return; } - existing.quantity = normalizeQuantity(quantity); + const normalizedQuantity = normalizeQuantity(quantity); + if (normalizedQuantity === 0) { + removeProduct(productId); + return; + } + + existing.quantity = normalizedQuantity; } function incrementQuantity(productId: string) { @@ -82,7 +88,13 @@ export function useClientCart() { return; } - existing.quantity = normalizeQuantity(existing.quantity - 1); + const normalizedQuantity = normalizeQuantity(existing.quantity - 1); + if (normalizedQuantity === 0) { + removeProduct(productId); + return; + } + + existing.quantity = normalizedQuantity; } function removeProduct(productId: string) { diff --git a/app/pages/products.vue b/app/pages/products.vue index 0a4eb8f..e34c10c 100644 --- a/app/pages/products.vue +++ b/app/pages/products.vue @@ -6,7 +6,7 @@ import { useClientCart } from '~/composables/useClientCart'; const { result, loading, error } = useQuery(ClientProductsDocument); const search = ref(''); const stockFilter = ref<'ALL' | 'CUSTOM' | 'STANDARD'>('ALL'); -const { addProduct, getQuantity, totalItems } = useClientCart(); +const { addProduct, getQuantity, totalItems, incrementQuantity, decrementQuantity } = useClientCart(); const coverPresets = [ ['#e9fbe5', '#acfcd5', '#7be9aa'], @@ -65,6 +65,14 @@ function addProductToCart(product: ClientProductsQuery['clientProducts'][number] isCustomizable: product.isCustomizable, }); } + +function incrementProduct(productId: string) { + incrementQuantity(productId); +} + +function decrementProduct(productId: string) { + decrementQuantity(productId); +} @@ -137,14 +145,20 @@ function addProductToCart(product: ClientProductsQuery['clientProducts'][number] {{ product.name }} SKU: {{ product.sku }} - - В корзине: {{ getQuantity(product.id) }} + - + + В корзину + + + - + {{ getQuantity(product.id) }} + + +
SKU: {{ product.sku }}