Add navigation badges to offers and hubs catalog pages
All checks were successful
Build Docker Image / build (push) Successful in 3m52s
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:
@@ -34,16 +34,16 @@
|
|||||||
point-color="#10b981"
|
point-color="#10b981"
|
||||||
v-model:selected-id="selectedSourceUuid"
|
v-model:selected-id="selectedSourceUuid"
|
||||||
>
|
>
|
||||||
|
<template #searchBar>
|
||||||
|
<CatalogSearchBar
|
||||||
|
:active-filters="navigationFilters"
|
||||||
|
:show-counter="false"
|
||||||
|
@remove-filter="handleRemoveFilter"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
<template #header>
|
<template #header>
|
||||||
<Stack gap="3">
|
<Stack gap="3">
|
||||||
<!-- Breadcrumbs -->
|
|
||||||
<CatalogBreadcrumbs
|
|
||||||
:hub-id="hubId"
|
|
||||||
:hub-name="hub.name"
|
|
||||||
:product-id="productId"
|
|
||||||
:product-name="product.name"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- Product info -->
|
<!-- Product info -->
|
||||||
<div>
|
<div>
|
||||||
<Heading :level="1">{{ product.name }}</Heading>
|
<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 hubId = computed(() => route.params.id as string)
|
||||||
const productId = computed(() => route.params.productId 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)
|
// Mock price history generator (seeded by uuid for consistent results)
|
||||||
const getMockPriceHistory = (uuid: string): number[] => {
|
const getMockPriceHistory = (uuid: string): number[] => {
|
||||||
const seed = uuid.split('').reduce((acc, char) => acc + char.charCodeAt(0), 0)
|
const seed = uuid.split('').reduce((acc, char) => acc + char.charCodeAt(0), 0)
|
||||||
|
|||||||
@@ -11,8 +11,10 @@
|
|||||||
<template #searchBar="{ displayedCount, totalCount }">
|
<template #searchBar="{ displayedCount, totalCount }">
|
||||||
<CatalogSearchBar
|
<CatalogSearchBar
|
||||||
v-model:search-query="searchQuery"
|
v-model:search-query="searchQuery"
|
||||||
|
:active-filters="navigationFilters"
|
||||||
:displayed-count="displayedCount"
|
:displayed-count="displayedCount"
|
||||||
:total-count="totalCount"
|
:total-count="totalCount"
|
||||||
|
@remove-filter="handleRemoveFilter"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -33,9 +35,6 @@
|
|||||||
|
|
||||||
<!-- Content Header -->
|
<!-- Content Header -->
|
||||||
<Stack v-else gap="4">
|
<Stack v-else gap="4">
|
||||||
<!-- Breadcrumbs -->
|
|
||||||
<CatalogBreadcrumbs :hub-id="hubId" :hub-name="hub?.name" />
|
|
||||||
|
|
||||||
<!-- Header -->
|
<!-- Header -->
|
||||||
<div>
|
<div>
|
||||||
<Heading :level="1">{{ hub?.name }}</Heading>
|
<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)
|
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
|
// Search
|
||||||
const searchQuery = ref('')
|
const searchQuery = ref('')
|
||||||
|
|
||||||
|
|||||||
@@ -34,16 +34,16 @@
|
|||||||
point-color="#10b981"
|
point-color="#10b981"
|
||||||
v-model:selected-id="selectedSourceUuid"
|
v-model:selected-id="selectedSourceUuid"
|
||||||
>
|
>
|
||||||
|
<template #searchBar>
|
||||||
|
<CatalogSearchBar
|
||||||
|
:active-filters="navigationFilters"
|
||||||
|
:show-counter="false"
|
||||||
|
@remove-filter="handleRemoveFilter"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
<template #header>
|
<template #header>
|
||||||
<Stack gap="3">
|
<Stack gap="3">
|
||||||
<!-- Breadcrumbs -->
|
|
||||||
<OffersBreadcrumbs
|
|
||||||
:product-id="productId"
|
|
||||||
:product-name="product.name"
|
|
||||||
:hub-id="hubId"
|
|
||||||
:hub-name="hub.name"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- Product info -->
|
<!-- Product info -->
|
||||||
<div>
|
<div>
|
||||||
<Heading :level="1">{{ product.name }}</Heading>
|
<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 productId = computed(() => route.params.productId as string)
|
||||||
const hubId = computed(() => route.params.hubId 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)
|
// Mock price history generator (seeded by uuid for consistent results)
|
||||||
const getMockPriceHistory = (uuid: string): number[] => {
|
const getMockPriceHistory = (uuid: string): number[] => {
|
||||||
const seed = uuid.split('').reduce((acc, char) => acc + char.charCodeAt(0), 0)
|
const seed = uuid.split('').reduce((acc, char) => acc + char.charCodeAt(0), 0)
|
||||||
|
|||||||
@@ -15,8 +15,10 @@
|
|||||||
<template #searchBar="{ displayedCount, totalCount }">
|
<template #searchBar="{ displayedCount, totalCount }">
|
||||||
<CatalogSearchBar
|
<CatalogSearchBar
|
||||||
v-model:search-query="searchQuery"
|
v-model:search-query="searchQuery"
|
||||||
|
:active-filters="navigationFilters"
|
||||||
:displayed-count="displayedCount"
|
:displayed-count="displayedCount"
|
||||||
:total-count="totalCount"
|
:total-count="totalCount"
|
||||||
|
@remove-filter="handleRemoveFilter"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -37,9 +39,6 @@
|
|||||||
|
|
||||||
<!-- Content Header -->
|
<!-- Content Header -->
|
||||||
<Stack v-else gap="4">
|
<Stack v-else gap="4">
|
||||||
<!-- Breadcrumbs -->
|
|
||||||
<OffersBreadcrumbs :product-id="productId" :product-name="product?.name" />
|
|
||||||
|
|
||||||
<!-- Header -->
|
<!-- Header -->
|
||||||
<div>
|
<div>
|
||||||
<Heading :level="1">{{ product?.name }}</Heading>
|
<Heading :level="1">{{ product?.name }}</Heading>
|
||||||
@@ -96,6 +95,28 @@ const hoveredHubId = ref<string>()
|
|||||||
|
|
||||||
const productId = computed(() => route.params.productId 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 (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
|
// Search
|
||||||
const searchQuery = ref('')
|
const searchQuery = ref('')
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user