Add navigation badges to offers and hubs catalog pages
All checks were successful
Build Docker Image / build (push) Successful in 3m52s

- /catalog/offers/[productId] - badge "Товар: Name"
- /catalog/offers/[productId]/[hubId] - badges "Товар", "Хаб"
- /catalog/hubs/[id] - badge "Хаб: Name"
- /catalog/hubs/[id]/[productId] - badges "Хаб", "Товар"

Removed breadcrumb components, replaced with search bar badges
This commit is contained in:
Ruslan Bakiev
2026-01-19 11:33:36 +07:00
parent 5b715ef46f
commit da29a354ff
4 changed files with 128 additions and 22 deletions

View File

@@ -34,16 +34,16 @@
point-color="#10b981"
v-model:selected-id="selectedSourceUuid"
>
<template #searchBar>
<CatalogSearchBar
:active-filters="navigationFilters"
:show-counter="false"
@remove-filter="handleRemoveFilter"
/>
</template>
<template #header>
<Stack gap="3">
<!-- Breadcrumbs -->
<CatalogBreadcrumbs
:hub-id="hubId"
:hub-name="hub.name"
:product-id="productId"
:product-name="product.name"
/>
<!-- Product info -->
<div>
<Heading :level="1">{{ product.name }}</Heading>
@@ -117,6 +117,38 @@ const offersData = ref<Map<string, any>>(new Map())
const hubId = computed(() => route.params.id as string)
const productId = computed(() => route.params.productId as string)
// Navigation filters for search bar badges
const navigationFilters = computed(() => {
const filters: Array<{ id: string; label: string; key: string }> = []
if (hub.value?.name) {
filters.push({
id: 'hub',
key: 'Хаб',
label: hub.value.name
})
}
if (product.value?.name) {
filters.push({
id: 'product',
key: 'Товар',
label: product.value.name
})
}
return filters
})
// Handle removing navigation filter (navigate back)
const handleRemoveFilter = (filterId: string) => {
if (filterId === 'product') {
navigateTo(localePath(`/catalog/hubs/${hubId.value}`))
} else if (filterId === 'hub') {
navigateTo(localePath('/catalog/hubs'))
}
}
// Mock price history generator (seeded by uuid for consistent results)
const getMockPriceHistory = (uuid: string): number[] => {
const seed = uuid.split('').reduce((acc, char) => acc + char.charCodeAt(0), 0)

View File

@@ -11,8 +11,10 @@
<template #searchBar="{ displayedCount, totalCount }">
<CatalogSearchBar
v-model:search-query="searchQuery"
:active-filters="navigationFilters"
:displayed-count="displayedCount"
:total-count="totalCount"
@remove-filter="handleRemoveFilter"
/>
</template>
@@ -33,9 +35,6 @@
<!-- Content Header -->
<Stack v-else gap="4">
<!-- Breadcrumbs -->
<CatalogBreadcrumbs :hub-id="hubId" :hub-name="hub?.name" />
<!-- Header -->
<div>
<Heading :level="1">{{ hub?.name }}</Heading>
@@ -78,6 +77,28 @@ const products = ref<Array<{ uuid: string; name: string }>>([])
const hubId = computed(() => route.params.id as string)
// Navigation filters for search bar badges
const navigationFilters = computed(() => {
const filters: Array<{ id: string; label: string; key: string }> = []
if (hub.value?.name) {
filters.push({
id: 'hub',
key: 'Хаб',
label: hub.value.name
})
}
return filters
})
// Handle removing navigation filter (navigate back)
const handleRemoveFilter = (filterId: string) => {
if (filterId === 'hub') {
navigateTo(localePath('/catalog/hubs'))
}
}
// Search
const searchQuery = ref('')

View File

@@ -34,16 +34,16 @@
point-color="#10b981"
v-model:selected-id="selectedSourceUuid"
>
<template #searchBar>
<CatalogSearchBar
:active-filters="navigationFilters"
:show-counter="false"
@remove-filter="handleRemoveFilter"
/>
</template>
<template #header>
<Stack gap="3">
<!-- Breadcrumbs -->
<OffersBreadcrumbs
:product-id="productId"
:product-name="product.name"
:hub-id="hubId"
:hub-name="hub.name"
/>
<!-- Product info -->
<div>
<Heading :level="1">{{ product.name }}</Heading>
@@ -117,6 +117,38 @@ const offersData = ref<Map<string, any>>(new Map())
const productId = computed(() => route.params.productId as string)
const hubId = computed(() => route.params.hubId as string)
// Navigation filters for search bar badges
const navigationFilters = computed(() => {
const filters: Array<{ id: string; label: string; key: string }> = []
if (product.value?.name) {
filters.push({
id: 'product',
key: 'Товар',
label: product.value.name
})
}
if (hub.value?.name) {
filters.push({
id: 'hub',
key: 'Хаб',
label: hub.value.name
})
}
return filters
})
// Handle removing navigation filter (navigate back)
const handleRemoveFilter = (filterId: string) => {
if (filterId === 'hub') {
navigateTo(localePath(`/catalog/offers/${productId.value}`))
} else if (filterId === 'product') {
navigateTo(localePath('/catalog/offers'))
}
}
// Mock price history generator (seeded by uuid for consistent results)
const getMockPriceHistory = (uuid: string): number[] => {
const seed = uuid.split('').reduce((acc, char) => acc + char.charCodeAt(0), 0)

View File

@@ -15,8 +15,10 @@
<template #searchBar="{ displayedCount, totalCount }">
<CatalogSearchBar
v-model:search-query="searchQuery"
:active-filters="navigationFilters"
:displayed-count="displayedCount"
:total-count="totalCount"
@remove-filter="handleRemoveFilter"
/>
</template>
@@ -37,9 +39,6 @@
<!-- Content Header -->
<Stack v-else gap="4">
<!-- Breadcrumbs -->
<OffersBreadcrumbs :product-id="productId" :product-name="product?.name" />
<!-- Header -->
<div>
<Heading :level="1">{{ product?.name }}</Heading>
@@ -96,6 +95,28 @@ const hoveredHubId = ref<string>()
const productId = computed(() => route.params.productId as string)
// Navigation filters for search bar badges
const navigationFilters = computed(() => {
const filters: Array<{ id: string; label: string; key: string }> = []
if (product.value?.name) {
filters.push({
id: 'product',
key: 'Товар',
label: product.value.name
})
}
return filters
})
// Handle removing navigation filter (navigate back)
const handleRemoveFilter = (filterId: string) => {
if (filterId === 'product') {
navigateTo(localePath('/catalog/offers'))
}
}
// Search
const searchQuery = ref('')