Fix: offers map coords, map position, orders filter, select-location layout
All checks were successful
Build Docker Image / build (push) Successful in 3m38s

This commit is contained in:
Ruslan Bakiev
2026-01-08 13:01:54 +07:00
parent 8d1b7c6dc7
commit 53904ead05
4 changed files with 88 additions and 95 deletions

View File

@@ -47,7 +47,7 @@
<!-- Right: Map (fixed position) --> <!-- Right: Map (fixed position) -->
<div class="w-3/5 relative"> <div class="w-3/5 relative">
<div class="fixed top-28 right-6 w-[calc(60%-3rem)] h-[calc(100vh-8rem)] rounded-lg overflow-hidden"> <div class="fixed top-32 right-6 w-[calc(60%-3rem)] h-[calc(100vh-9rem)] rounded-lg overflow-hidden">
<ClientOnly> <ClientOnly>
<CatalogMap <CatalogMap
ref="mapRef" ref="mapRef"

View File

@@ -7,11 +7,11 @@ export function useTeamOrders() {
const { execute } = useGraphQL() const { execute } = useGraphQL()
const filters = computed(() => [ const filters = computed(() => [
{ key: 'all', label: t('ordersList.filters.all') }, { id: 'all', label: t('ordersList.filters.all') },
{ key: 'pending', label: t('ordersList.filters.pending') }, { id: 'pending', label: t('ordersList.filters.pending') },
{ key: 'processing', label: t('ordersList.filters.processing') }, { id: 'processing', label: t('ordersList.filters.processing') },
{ key: 'in_transit', label: t('ordersList.filters.in_transit') }, { id: 'in_transit', label: t('ordersList.filters.in_transit') },
{ key: 'delivered', label: t('ordersList.filters.delivered') } { id: 'delivered', label: t('ordersList.filters.delivered') }
]) ])
const selectedFilter = ref('all') const selectedFilter = ref('all')

View File

@@ -1,6 +1,6 @@
<template> <template>
<CatalogPage <CatalogPage
:items="items" :items="itemsForMap"
:loading="isLoading || productsLoading" :loading="isLoading || productsLoading"
map-id="offers-map" map-id="offers-map"
point-color="#f59e0b" point-color="#f59e0b"
@@ -64,6 +64,13 @@ const {
setProductUuid setProductUuid
} = useCatalogOffers() } = useCatalogOffers()
// Map items with correct coordinate field names
const itemsForMap = computed(() => items.value.map(offer => ({
...offer,
latitude: offer.locationLatitude,
longitude: offer.locationLongitude
})))
// Product filter options // Product filter options
const productFilters = computed(() => { const productFilters = computed(() => {
const all = [{ id: 'all', label: t('catalogOffersSection.filters.all_products') }] const all = [{ id: 'all', label: t('catalogOffersSection.filters.all_products') }]

View File

@@ -1,86 +1,78 @@
<template> <template>
<div class="container mx-auto px-4 py-8"> <CatalogPage
<PageHeader :title="t('common.selectLocation')"> :items="itemsWithCoords"
<template #actions> :loading="isLoading"
<button class="btn btn-ghost" @click="router.back()"> map-id="select-location-map"
<Icon name="lucide:x" size="20" /> point-color="#10b981"
</button> :selected-id="selectedHubId"
</template> v-model:hovered-id="hoveredHubId"
</PageHeader> @select="selectHub"
>
<Stack gap="8" class="mt-6"> <template #header>
<!-- My addresses -->
<Stack v-if="isAuthenticated && teamAddresses?.length" gap="4">
<Heading :level="3">{{ t('profileAddresses.header.title') }}</Heading>
<Grid :cols="1" :md="2" :gap="4">
<Card
v-for="addr in teamAddresses"
:key="addr.uuid"
padding="small"
interactive
:class="{ 'ring-2 ring-primary': isSelected('address', addr.uuid) }"
@click="selectAddress(addr)"
>
<Stack gap="2">
<Stack direction="row" align="center" gap="2">
<Icon name="lucide:map-pin" size="18" class="text-primary" />
<Text size="base" weight="semibold">{{ addr.name }}</Text>
<Pill v-if="addr.isDefault" variant="outline" size="sm">Default</Pill>
</Stack>
<Text tone="muted" size="sm">{{ addr.address }}</Text>
</Stack>
</Card>
</Grid>
</Stack>
<!-- Hubs -->
<Stack gap="4"> <Stack gap="4">
<Heading :level="3">{{ t('catalogMap.hubsTab') }}</Heading> <!-- Back button -->
<div class="flex justify-between items-center">
<NuxtLink :to="localePath('/select-location/map')" class="block h-48 rounded-lg overflow-hidden cursor-pointer"> <Heading :level="2">{{ t('common.selectLocation') }}</Heading>
<ClientOnly> <button class="btn btn-ghost btn-sm" @click="router.back()">
<MapboxGlobe <Icon name="lucide:x" size="20" />
map-id="select-location-map" </button>
:locations="itemsWithCoords"
:height="192"
/>
</ClientOnly>
</NuxtLink>
<CatalogFilters :filters="filters" v-model="selectedFilter" />
<div v-if="isLoading" class="flex items-center justify-center p-8">
<span class="loading loading-spinner loading-lg" />
</div> </div>
<EmptyState <!-- My addresses section -->
v-else-if="!items?.length" <Stack v-if="isAuthenticated && teamAddresses?.length" gap="3">
:title="t('catalogMap.noHubs')" <Text weight="semibold">{{ t('profileAddresses.header.title') }}</Text>
/> <Stack gap="2">
<Card
v-for="addr in teamAddresses"
:key="addr.uuid"
padding="sm"
interactive
:class="{ 'ring-2 ring-primary': isSelected('address', addr.uuid) }"
@click="selectAddress(addr)"
>
<Stack gap="1">
<Stack direction="row" align="center" gap="2">
<Icon name="lucide:map-pin" size="16" class="text-primary" />
<Text size="sm" weight="semibold">{{ addr.name }}</Text>
<Pill v-if="addr.isDefault" variant="outline" size="sm">Default</Pill>
</Stack>
<Text tone="muted" size="xs">{{ addr.address }}</Text>
</Stack>
</Card>
</Stack>
</Stack>
<template v-else> <!-- Hubs section header -->
<Grid :cols="1" :md="2" :gap="4"> <Text weight="semibold">{{ t('catalogMap.hubsTab') }}</Text>
<HubCard
v-for="hub in items"
:key="hub.uuid"
:hub="hub"
selectable
:is-selected="isSelected('hub', hub.uuid)"
@select="selectHub(hub)"
/>
</Grid>
<PaginationLoadMore
:shown="items.length"
:total="total"
:can-load-more="canLoadMore"
:loading="isLoadingMore"
@load-more="loadMore"
/>
</template>
</Stack> </Stack>
</Stack> </template>
</div>
<template #filters>
<CatalogFilterSelect :filters="filters" v-model="selectedFilter" />
</template>
<template #card="{ item }">
<HubCard
:hub="item"
selectable
:is-selected="isSelected('hub', item.uuid)"
/>
</template>
<template #pagination>
<PaginationLoadMore
:shown="items.length"
:total="total"
:can-load-more="canLoadMore"
:loading="isLoadingMore"
@load-more="loadMore"
/>
</template>
<template #empty>
<EmptyState :title="t('catalogMap.noHubs')" />
</template>
</CatalogPage>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
@@ -113,6 +105,10 @@ const {
init init
} = useCatalogHubs() } = useCatalogHubs()
// Selected/hovered hub for map
const selectedHubId = ref<string>()
const hoveredHubId = ref<string>()
await init() await init()
// Load team addresses // Load team addresses
@@ -151,7 +147,7 @@ const goToRequestIfReady = () => {
} }
const selectHub = async (hub: any) => { const selectHub = async (hub: any) => {
console.log('[selectHub] called', { hub, isSearchMode: isSearchMode.value }) selectedHubId.value = hub.uuid
if (isSearchMode.value) { if (isSearchMode.value) {
searchStore.setLocation(hub.name) searchStore.setLocation(hub.name)
@@ -162,13 +158,9 @@ const selectHub = async (hub: any) => {
} }
try { try {
console.log('[selectHub] calling locationStore.select')
const success = await locationStore.select('hub', hub.uuid, hub.name, hub.latitude, hub.longitude) const success = await locationStore.select('hub', hub.uuid, hub.name, hub.latitude, hub.longitude)
console.log('[selectHub] result:', success)
if (success) { if (success) {
router.back() router.back()
} else {
console.error('[selectHub] Selection failed - success=false')
} }
} catch (e) { } catch (e) {
console.error('[selectHub] Error:', e) console.error('[selectHub] Error:', e)
@@ -176,8 +168,6 @@ const selectHub = async (hub: any) => {
} }
const selectAddress = async (addr: any) => { const selectAddress = async (addr: any) => {
console.log('[selectAddress] called', { addr, isSearchMode: isSearchMode.value })
if (isSearchMode.value) { if (isSearchMode.value) {
searchStore.setLocation(addr.address || addr.name) searchStore.setLocation(addr.address || addr.name)
searchStore.setLocationUuid(addr.uuid) searchStore.setLocationUuid(addr.uuid)
@@ -187,13 +177,9 @@ const selectAddress = async (addr: any) => {
} }
try { try {
console.log('[selectAddress] calling locationStore.select')
const success = await locationStore.select('address', addr.uuid, addr.name, addr.latitude, addr.longitude) const success = await locationStore.select('address', addr.uuid, addr.name, addr.latitude, addr.longitude)
console.log('[selectAddress] result:', success)
if (success) { if (success) {
router.back() router.back()
} else {
console.error('[selectAddress] Selection failed - success=false')
} }
} catch (e) { } catch (e) {
console.error('[selectAddress] Error:', e) console.error('[selectAddress] Error:', e)