Add map view toggle for fullWidthMap mode
All checks were successful
Build Docker Image / build (push) Successful in 3m25s

- Add MapViewMode type (offers/hubs/suppliers) with cookie storage
- Add view toggle button group on full-width map
- Update clusterNodeType and mapPointColor based on selected view
- Add translations for view options
This commit is contained in:
Ruslan Bakiev
2026-01-22 18:41:38 +07:00
parent 2d86c79b06
commit 749f15131b
5 changed files with 74 additions and 4 deletions

View File

@@ -36,6 +36,32 @@
<div v-if="fullWidthMap" class="hidden lg:flex flex-1 min-h-0 py-4">
<div class="w-full">
<div class="sticky rounded-xl overflow-hidden shadow-lg" :style="mapStyle">
<!-- View mode toggle -->
<div class="absolute top-4 left-4 z-10">
<div class="btn-group shadow-lg bg-white/90 backdrop-blur rounded-lg">
<button
class="btn btn-sm"
:class="{ 'btn-active': mapViewMode === 'offers' }"
@click="setMapViewMode('offers')"
>
{{ $t('catalog.views.offers') }}
</button>
<button
class="btn btn-sm"
:class="{ 'btn-active': mapViewMode === 'hubs' }"
@click="setMapViewMode('hubs')"
>
{{ $t('catalog.views.hubs') }}
</button>
<button
class="btn btn-sm"
:class="{ 'btn-active': mapViewMode === 'suppliers' }"
@click="setMapViewMode('suppliers')"
>
{{ $t('catalog.views.suppliers') }}
</button>
</div>
</div>
<ClientOnly>
<CatalogMap
ref="mapRef"
@@ -217,6 +243,9 @@
<script setup lang="ts">
import type { MapBounds } from '~/components/catalog/CatalogMap.vue'
// Map view mode for full width map
const { mapViewMode, setMapViewMode } = useCatalogSearch()
interface MapItem {
uuid: string
latitude?: number | null

View File

@@ -1,6 +1,7 @@
import type { LocationQuery } from 'vue-router'
export type SelectMode = 'product' | 'supplier' | 'hub' | null
export type MapViewMode = 'offers' | 'hubs' | 'suppliers'
export type DisplayMode =
| 'map-default'
| 'grid-products'
@@ -214,6 +215,19 @@ export function useCatalogSearch() {
// Text search (for filtering within current grid) - shared via useState
const searchQuery = useState<string>('catalog-search-query', () => '')
// Map view mode preference (stored in cookie)
const mapViewCookie = useCookie<MapViewMode>('catalog-map-view', {
default: () => 'offers',
maxAge: 60 * 60 * 24 * 365 // 1 year
})
const mapViewMode = computed({
get: () => mapViewCookie.value,
set: (val: MapViewMode) => { mapViewCookie.value = val }
})
const setMapViewMode = (mode: MapViewMode) => {
mapViewCookie.value = mode
}
return {
// State
selectMode,
@@ -223,6 +237,7 @@ export function useCatalogSearch() {
hubId,
quantity,
searchQuery,
mapViewMode,
// Colors
entityColors,
@@ -239,6 +254,7 @@ export function useCatalogSearch() {
editFilter,
clearAll,
setLabel,
setMapViewMode,
// Labels cache
filterLabels

View File

@@ -87,7 +87,9 @@ const {
selectItem,
removeFilter,
editFilter,
setLabel
setLabel,
mapViewMode,
entityColors
} = useCatalogSearch()
// Composables for data
@@ -140,6 +142,12 @@ const useServerClustering = computed(() => {
})
const clusterNodeType = computed(() => {
// When in full width map mode, use mapViewMode preference
if (!selectMode.value) {
if (mapViewMode.value === 'offers') return 'offer'
if (mapViewMode.value === 'hubs') return 'logistics'
if (mapViewMode.value === 'suppliers') return 'supplier'
}
// For products/offers/default map show offer locations
if (['map-default', 'grid-products', 'grid-offers', 'grid-products-from-supplier', 'grid-products-in-hub'].includes(displayMode.value)) {
return 'offer'
@@ -148,10 +156,13 @@ const clusterNodeType = computed(() => {
return 'logistics'
})
// Import entity colors
const { entityColors } = useCatalogSearch()
const mapPointColor = computed(() => {
// When in full width map mode, use mapViewMode preference
if (!selectMode.value) {
if (mapViewMode.value === 'offers') return entityColors.offer // orange
if (mapViewMode.value === 'hubs') return entityColors.hub // green
if (mapViewMode.value === 'suppliers') return entityColors.supplier // blue
}
if (cardType.value === 'supplier') return entityColors.supplier // blue
if (cardType.value === 'hub') return entityColors.hub // green
if (cardType.value === 'offer') return entityColors.offer // orange