Refactor catalog layout: mode toggle to top right, view toggle to top left
All checks were successful
Build Docker Image / build (push) Successful in 3m35s
All checks were successful
Build Docker Image / build (push) Successful in 3m35s
- Move Explore/Quote mode toggle to top right corner - Add view toggle (Offers/Hubs/Suppliers) to top left in Explore mode - Panel shows only in Quote mode when showPanel prop is true - Simplified panel slot structure
This commit is contained in:
@@ -28,8 +28,8 @@
|
||||
</ClientOnly>
|
||||
</div>
|
||||
|
||||
<!-- Mode tabs (top left overlay) -->
|
||||
<div class="absolute top-4 left-4 z-20">
|
||||
<!-- Mode tabs (top RIGHT overlay) -->
|
||||
<div class="absolute top-4 right-4 z-20 hidden lg:block">
|
||||
<div class="tabs tabs-boxed bg-white/95 backdrop-blur shadow-lg">
|
||||
<button
|
||||
class="tab"
|
||||
@@ -50,43 +50,85 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Left overlay panel -->
|
||||
<div
|
||||
class="absolute top-20 left-4 bottom-4 z-10 w-80 max-w-[calc(100vw-2rem)] hidden lg:block"
|
||||
>
|
||||
<div class="bg-white/95 backdrop-blur rounded-xl shadow-lg p-4 h-full overflow-hidden flex flex-col">
|
||||
<!-- Explore mode panel -->
|
||||
<template v-if="catalogMode === 'explore'">
|
||||
<slot name="explore-panel">
|
||||
<ExplorePanel
|
||||
:selected-item="selectedMapItem"
|
||||
@close-selected="selectedMapItem = null"
|
||||
@view-details="onViewDetails"
|
||||
/>
|
||||
</slot>
|
||||
</template>
|
||||
|
||||
<!-- Quote mode panel -->
|
||||
<template v-else>
|
||||
<slot name="quote-panel" />
|
||||
</template>
|
||||
<!-- View toggle (top LEFT overlay) - for Explore mode -->
|
||||
<div v-if="catalogMode === 'explore'" class="absolute top-4 left-4 z-20 hidden lg:block">
|
||||
<div class="join bg-white/95 backdrop-blur shadow-lg rounded-lg">
|
||||
<button
|
||||
class="btn btn-sm join-item"
|
||||
:class="{ 'btn-active': mapViewMode === 'offers' }"
|
||||
@click="setMapViewMode('offers')"
|
||||
>
|
||||
{{ $t('catalog.views.offers') }}
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-sm join-item"
|
||||
:class="{ 'btn-active': mapViewMode === 'hubs' }"
|
||||
@click="setMapViewMode('hubs')"
|
||||
>
|
||||
{{ $t('catalog.views.hubs') }}
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-sm join-item"
|
||||
:class="{ 'btn-active': mapViewMode === 'suppliers' }"
|
||||
@click="setMapViewMode('suppliers')"
|
||||
>
|
||||
{{ $t('catalog.views.suppliers') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Mobile bottom sheet (simplified) -->
|
||||
<!-- Left overlay panel (shown when showPanel is true) -->
|
||||
<div
|
||||
v-if="showPanel"
|
||||
class="absolute top-4 left-4 bottom-4 z-10 w-96 max-w-[calc(100vw-2rem)] hidden lg:block"
|
||||
:class="catalogMode === 'explore' ? 'top-16' : 'top-4'"
|
||||
>
|
||||
<div class="bg-white/95 backdrop-blur rounded-xl shadow-lg p-4 h-full overflow-hidden flex flex-col">
|
||||
<slot name="panel" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Mobile bottom sheet -->
|
||||
<div class="lg:hidden absolute bottom-0 left-0 right-0 z-20">
|
||||
<!-- Mobile mode toggle -->
|
||||
<div class="flex justify-center mb-2">
|
||||
<!-- Mobile toggles -->
|
||||
<div class="flex justify-between items-center px-4 mb-2">
|
||||
<!-- View toggle (Explore mode only) -->
|
||||
<div v-if="catalogMode === 'explore'" class="join bg-white/95 backdrop-blur shadow-lg rounded-lg">
|
||||
<button
|
||||
class="btn btn-xs join-item"
|
||||
:class="{ 'btn-active': mapViewMode === 'offers' }"
|
||||
@click="setMapViewMode('offers')"
|
||||
>
|
||||
{{ $t('catalog.views.offers') }}
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-xs join-item"
|
||||
:class="{ 'btn-active': mapViewMode === 'hubs' }"
|
||||
@click="setMapViewMode('hubs')"
|
||||
>
|
||||
{{ $t('catalog.views.hubs') }}
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-xs join-item"
|
||||
:class="{ 'btn-active': mapViewMode === 'suppliers' }"
|
||||
@click="setMapViewMode('suppliers')"
|
||||
>
|
||||
{{ $t('catalog.views.suppliers') }}
|
||||
</button>
|
||||
</div>
|
||||
<div v-else />
|
||||
|
||||
<!-- Mode toggle -->
|
||||
<div class="tabs tabs-boxed bg-white/95 backdrop-blur shadow-lg tabs-sm">
|
||||
<button
|
||||
class="tab"
|
||||
class="tab tab-sm"
|
||||
:class="{ 'tab-active': catalogMode === 'explore' }"
|
||||
@click="setCatalogMode('explore')"
|
||||
>
|
||||
{{ $t('catalog.modes.explore') }}
|
||||
</button>
|
||||
<button
|
||||
class="tab"
|
||||
class="tab tab-sm"
|
||||
:class="{ 'tab-active': catalogMode === 'quote' }"
|
||||
@click="setCatalogMode('quote')"
|
||||
>
|
||||
@@ -95,8 +137,9 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Mobile panel (collapsible) -->
|
||||
<!-- Mobile panel (collapsible) - only when showPanel is true -->
|
||||
<div
|
||||
v-if="showPanel"
|
||||
class="bg-white/95 backdrop-blur rounded-t-xl shadow-lg transition-all duration-300"
|
||||
:class="mobilePanelExpanded ? 'h-[60vh]' : 'h-auto'"
|
||||
>
|
||||
@@ -109,21 +152,7 @@
|
||||
</div>
|
||||
|
||||
<div class="px-4 pb-4 overflow-y-auto" :class="mobilePanelExpanded ? 'h-[calc(60vh-2rem)]' : 'max-h-48'">
|
||||
<!-- Explore mode panel -->
|
||||
<template v-if="catalogMode === 'explore'">
|
||||
<slot name="explore-panel">
|
||||
<ExplorePanel
|
||||
:selected-item="selectedMapItem"
|
||||
@close-selected="selectedMapItem = null"
|
||||
@view-details="onViewDetails"
|
||||
/>
|
||||
</slot>
|
||||
</template>
|
||||
|
||||
<!-- Quote mode panel -->
|
||||
<template v-else>
|
||||
<slot name="quote-panel" />
|
||||
</template>
|
||||
<slot name="panel" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -133,7 +162,7 @@
|
||||
<script setup lang="ts">
|
||||
import type { MapBounds } from '~/components/catalog/CatalogMap.vue'
|
||||
|
||||
const { mapViewMode, catalogMode, setCatalogMode } = useCatalogSearch()
|
||||
const { mapViewMode, setMapViewMode, catalogMode, setCatalogMode } = useCatalogSearch()
|
||||
|
||||
interface MapItem {
|
||||
uuid: string
|
||||
@@ -152,13 +181,15 @@ const props = withDefaults(defineProps<{
|
||||
pointColor?: string
|
||||
hoveredId?: string
|
||||
items?: MapItem[]
|
||||
showPanel?: boolean
|
||||
}>(), {
|
||||
loading: false,
|
||||
useServerClustering: true,
|
||||
clusterNodeType: 'offer',
|
||||
mapId: 'catalog-map',
|
||||
pointColor: '#f97316',
|
||||
items: () => []
|
||||
items: () => [],
|
||||
showPanel: false
|
||||
})
|
||||
|
||||
const emit = defineEmits<{
|
||||
|
||||
@@ -6,10 +6,11 @@
|
||||
map-id="unified-catalog-map"
|
||||
:point-color="mapPointColor"
|
||||
:items="[]"
|
||||
:show-panel="showPanel"
|
||||
@select="onMapSelect"
|
||||
>
|
||||
<!-- Quote panel slot -->
|
||||
<template #quote-panel>
|
||||
<!-- Panel slot - shows Quote form or selection list -->
|
||||
<template #panel>
|
||||
<QuotePanel
|
||||
:product-id="productId"
|
||||
:product-label="getFilterLabel('product', productId)"
|
||||
@@ -140,6 +141,9 @@ const showQuoteResults = ref(false)
|
||||
// Loading state
|
||||
const isLoading = computed(() => offersLoading.value)
|
||||
|
||||
// Show panel when in Quote mode
|
||||
const showPanel = computed(() => catalogMode.value === 'quote')
|
||||
|
||||
// Get filter label from cache
|
||||
const getFilterLabel = (type: string, id: string | undefined): string | undefined => {
|
||||
if (!id) return undefined
|
||||
|
||||
Reference in New Issue
Block a user