feat(catalog): add search to all catalog pages
All checks were successful
Build Docker Image / build (push) Successful in 4m55s

Add CatalogSearchBar component with filtering to:
- /catalog/offers - search by product name
- /catalog/offers/[productId] - search by hub name/country
- /catalog/hubs/[id] - search by product name
- /catalog/suppliers/[supplierId] - search by product name
- /catalog/suppliers/[supplierId]/[productId] - search by hub name/country
This commit is contained in:
Ruslan Bakiev
2026-01-16 02:19:41 +07:00
parent 45ec9923e3
commit d9d05a4c21
5 changed files with 107 additions and 5 deletions

View File

@@ -1,7 +1,8 @@
<template>
<CatalogPage
:items="hubs"
:items="filteredHubs"
:loading="isLoading"
:total-count="hubs.length"
with-map
map-id="supplier-product-hubs-map"
point-color="#10b981"
@@ -9,6 +10,14 @@
@update:hovered-id="hoveredHubId = $event"
@select="onSelectHub"
>
<template #searchBar="{ displayedCount, totalCount }">
<CatalogSearchBar
v-model:search-query="searchQuery"
:displayed-count="displayedCount"
:total-count="totalCount"
/>
</template>
<template #header>
<!-- Not Found -->
<Card v-if="!isLoading && (!supplier || !product)" padding="lg">
@@ -109,6 +118,18 @@ const hoveredHubId = ref<string>()
const supplierId = computed(() => routeRef.params.supplierId as string)
const productId = computed(() => routeRef.params.productId as string)
// Search
const searchQuery = ref('')
const filteredHubs = computed(() => {
if (!searchQuery.value.trim()) return hubs.value
const q = searchQuery.value.toLowerCase()
return hubs.value.filter(hub =>
hub.name?.toLowerCase().includes(q) ||
hub.country?.toLowerCase().includes(q)
)
})
// Handle hub selection
const onSelectHub = (hub: any) => {
navigateTo(localePath(`/catalog/suppliers/${supplierId.value}/${productId.value}/${hub.uuid}`))

View File

@@ -1,12 +1,21 @@
<template>
<CatalogPage
:items="products"
:items="filteredProducts"
:map-items="mapItems"
:loading="isLoading"
:total-count="products.length"
with-map
map-id="supplier-products-map"
point-color="#3b82f6"
>
<template #searchBar="{ displayedCount, totalCount }">
<CatalogSearchBar
v-model:search-query="searchQuery"
:displayed-count="displayedCount"
:total-count="totalCount"
/>
</template>
<template #header>
<!-- Supplier Not Found -->
<Card v-if="!isLoading && !supplier" padding="lg">
@@ -91,6 +100,17 @@ const offers = ref<any[]>([])
const supplierId = computed(() => route.params.supplierId as string)
// Search
const searchQuery = ref('')
const filteredProducts = computed(() => {
if (!searchQuery.value.trim()) return products.value
const q = searchQuery.value.toLowerCase()
return products.value.filter(item =>
item.name?.toLowerCase().includes(q)
)
})
// Map items - show supplier location
const mapItems = computed(() => {
if (!supplier.value?.latitude || !supplier.value?.longitude) return []