Files
webapp/app/components/catalog/LocationMiniMap.vue
Ruslan Bakiev f03554893b
All checks were successful
Build Docker Image / build (push) Successful in 4m30s
Update OfferResultCard: add location, mini map, fix price format
- Remove distance from right side (shown in stepper)
- Change price format to symbol + formatted number (e.g. $1,200/тонна)
- Add locationName prop for displaying offer location
- Add LocationMiniMap component for showing point on map
- Update hub page and CalcResultContent to pass coordinates
2026-01-15 00:07:21 +07:00

104 lines
2.3 KiB
Vue

<template>
<div class="rounded-lg overflow-hidden border border-base-300">
<ClientOnly>
<MapboxMap
:key="mapId"
:map-id="mapId"
:style="`height: ${height}px; width: 100%;`"
:options="mapOptions"
@load="onMapCreated"
/>
<template #fallback>
<div :style="`height: ${height}px`" class="w-full bg-base-200 flex items-center justify-center">
<span class="loading loading-spinner loading-xs"></span>
</div>
</template>
</ClientOnly>
</div>
</template>
<script setup lang="ts">
import type { Map as MapboxMapType } from 'mapbox-gl'
import { getCurrentInstance } from 'vue'
const props = withDefaults(defineProps<{
latitude: number
longitude: number
height?: number
}>(), {
height: 120
})
const mapRef = ref<MapboxMapType | null>(null)
const instanceId = getCurrentInstance()?.uid || Math.floor(Math.random() * 100000)
const mapId = computed(() => `location-mini-map-${instanceId}`)
const mapOptions = computed(() => ({
style: 'mapbox://styles/mapbox/streets-v12',
center: [props.longitude, props.latitude] as [number, number],
zoom: 5,
interactive: false,
attributionControl: false
}))
const onMapCreated = (map: MapboxMapType) => {
mapRef.value = map
const initMap = () => {
map.addSource('location-point', {
type: 'geojson',
data: {
type: 'Feature',
properties: {},
geometry: {
type: 'Point',
coordinates: [props.longitude, props.latitude]
}
}
})
map.addLayer({
id: 'location-point-layer',
type: 'circle',
source: 'location-point',
paint: {
'circle-radius': 8,
'circle-color': '#10b981',
'circle-stroke-width': 2,
'circle-stroke-color': '#ffffff'
}
})
}
if (map.loaded()) {
initMap()
} else {
map.on('load', initMap)
}
}
watch(
() => [props.latitude, props.longitude],
() => {
const map = mapRef.value
if (!map) return
map.setCenter([props.longitude, props.latitude])
const source = map.getSource('location-point') as mapboxgl.GeoJSONSource | undefined
if (source) {
source.setData({
type: 'Feature',
properties: {},
geometry: {
type: 'Point',
coordinates: [props.longitude, props.latitude]
}
})
}
}
)
</script>