From 796204b3cd56546cf0bcb34238805942ba5db56e Mon Sep 17 00:00:00 2001 From: Ruslan Bakiev <572431+veikab@users.noreply.github.com> Date: Thu, 22 Jan 2026 08:54:31 +0700 Subject: [PATCH] Add grid layout for catalog cards + hover shadow - CatalogPage: added gridColumns prop (1/2/3 columns) - Card: added hover:shadow-lg on interactive cards - Products, hubs, suppliers pages now use 3-column grid - Offers remain full-width (gridColumns=1 default) --- app/components/page/CatalogPage.vue | 24 +++++++++++++------ app/components/ui/Card.vue | 4 +++- app/pages/catalog/hubs/index.vue | 1 + .../catalog/offers/[productId]/index.vue | 1 + app/pages/catalog/offers/index.vue | 1 + app/pages/catalog/suppliers/index.vue | 1 + 6 files changed, 24 insertions(+), 8 deletions(-) diff --git a/app/components/page/CatalogPage.vue b/app/components/page/CatalogPage.vue index d2783c4..11038a8 100644 --- a/app/components/page/CatalogPage.vue +++ b/app/components/page/CatalogPage.vue @@ -40,7 +40,7 @@ - +
- +
@@ -96,7 +96,7 @@ - +
- +
@@ -169,7 +169,7 @@ - +
- +
@@ -217,6 +217,7 @@ const props = withDefaults(defineProps<{ hoveredId?: string hasSubNav?: boolean totalCount?: number // Total count for search bar counter (can differ from items.length with pagination) + gridColumns?: number // Number of columns for card grid (1 = stack, 2/3 = grid) }>(), { loading: false, withMap: true, @@ -225,7 +226,16 @@ const props = withDefaults(defineProps<{ mapId: 'catalog-map', pointColor: '#3b82f6', hasSubNav: true, - totalCount: 0 + totalCount: 0, + gridColumns: 1 +}) + +// Grid class based on gridColumns prop +const gridClass = computed(() => { + if (props.gridColumns === 1) return 'flex flex-col gap-3' + if (props.gridColumns === 2) return 'grid grid-cols-2 gap-3' + if (props.gridColumns === 3) return 'grid grid-cols-3 gap-3' + return 'flex flex-col gap-3' }) // Smooth scroll collapse - pixel values for smooth animation diff --git a/app/components/ui/Card.vue b/app/components/ui/Card.vue index 8057391..aa9e816 100644 --- a/app/components/ui/Card.vue +++ b/app/components/ui/Card.vue @@ -35,7 +35,9 @@ const toneMap: Record = { const cardClass = computed(() => { const paddingClass = paddingMap[props.padding] || paddingMap.medium const toneClass = toneMap[props.tone] || toneMap.default - const interactiveClass = props.interactive ? 'cursor-pointer' : '' + const interactiveClass = props.interactive + ? 'cursor-pointer hover:shadow-lg transition-shadow duration-200' + : '' const baseClass = 'card' return [baseClass, paddingClass, toneClass, interactiveClass].filter(Boolean).join(' ') }) diff --git a/app/pages/catalog/hubs/index.vue b/app/pages/catalog/hubs/index.vue index 58ef641..91ed8aa 100644 --- a/app/pages/catalog/hubs/index.vue +++ b/app/pages/catalog/hubs/index.vue @@ -3,6 +3,7 @@ :items="displayItems" :map-items="itemsWithCoords" :loading="isLoading" + :grid-columns="3" with-map use-server-clustering map-id="hubs-map" diff --git a/app/pages/catalog/offers/[productId]/index.vue b/app/pages/catalog/offers/[productId]/index.vue index 905c16d..06871bc 100644 --- a/app/pages/catalog/offers/[productId]/index.vue +++ b/app/pages/catalog/offers/[productId]/index.vue @@ -3,6 +3,7 @@ :items="filteredHubs" :loading="isLoading" :total-count="hubs.length" + :grid-columns="3" with-map use-server-clustering cluster-node-type="logistics" diff --git a/app/pages/catalog/offers/index.vue b/app/pages/catalog/offers/index.vue index 95c465c..4347049 100644 --- a/app/pages/catalog/offers/index.vue +++ b/app/pages/catalog/offers/index.vue @@ -3,6 +3,7 @@ :items="filteredProducts" :loading="isLoading" :total-count="products.length" + :grid-columns="3" with-map use-server-clustering cluster-node-type="offer" diff --git a/app/pages/catalog/suppliers/index.vue b/app/pages/catalog/suppliers/index.vue index d2c9cd8..b4b3166 100644 --- a/app/pages/catalog/suppliers/index.vue +++ b/app/pages/catalog/suppliers/index.vue @@ -3,6 +3,7 @@ :items="displayItems" :map-items="itemsWithCoords" :loading="isLoading" + :grid-columns="3" with-map map-id="suppliers-map" point-color="#3b82f6"