Simplify OfferResultCard and use daisyUI Steps
All checks were successful
Build Docker Image / build (push) Successful in 4m42s
All checks were successful
Build Docker Image / build (push) Successful in 4m42s
- Remove sourceName, latitude, longitude props from OfferResultCard - Remove LocationMiniMap component (not needed, main map is on the side) - Convert RouteStepper to use daisyUI steps-horizontal - Update hub page and CalcResultContent to remove unused props
This commit is contained in:
@@ -1,103 +0,0 @@
|
||||
<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>
|
||||
@@ -1,32 +1,18 @@
|
||||
<template>
|
||||
<Card padding="md" interactive @click="$emit('select')">
|
||||
<!-- Header: Source name + Location + Price -->
|
||||
<!-- Header: Location + Price -->
|
||||
<div class="flex items-start justify-between mb-3">
|
||||
<div>
|
||||
<Text weight="semibold">{{ sourceName }}</Text>
|
||||
<Text v-if="locationName" tone="muted" size="sm">{{ locationName }}</Text>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<Text v-if="priceDisplay" weight="semibold" class="text-primary text-lg">
|
||||
{{ priceDisplay }}
|
||||
</Text>
|
||||
<Text weight="semibold">{{ locationName || 'Локация' }}</Text>
|
||||
<Text v-if="productName" tone="muted" size="sm">{{ productName }}</Text>
|
||||
</div>
|
||||
<Text v-if="priceDisplay" weight="semibold" class="text-primary text-lg">
|
||||
{{ priceDisplay }}
|
||||
</Text>
|
||||
</div>
|
||||
|
||||
<!-- Product name + Route stepper -->
|
||||
<div v-if="productName" class="mb-3">
|
||||
<Text size="sm" class="mb-1">{{ productName }}</Text>
|
||||
<RouteStepper v-if="stages.length > 0" :stages="stages" />
|
||||
</div>
|
||||
<RouteStepper v-else-if="stages.length > 0" :stages="stages" class="mb-3" />
|
||||
|
||||
<!-- Mini map -->
|
||||
<LocationMiniMap
|
||||
v-if="latitude && longitude"
|
||||
:latitude="latitude"
|
||||
:longitude="longitude"
|
||||
:height="100"
|
||||
/>
|
||||
<!-- Route stepper -->
|
||||
<RouteStepper v-if="stages.length > 0" :stages="stages" />
|
||||
</Card>
|
||||
</template>
|
||||
|
||||
@@ -34,14 +20,11 @@
|
||||
import type { RouteStage } from './RouteStepper.vue'
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
sourceName: string
|
||||
locationName?: string
|
||||
productName?: string
|
||||
pricePerUnit?: number | null
|
||||
currency?: string | null
|
||||
unit?: string | null
|
||||
latitude?: number | null
|
||||
longitude?: number | null
|
||||
stages?: RouteStage[]
|
||||
}>(), {
|
||||
stages: () => []
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
<template>
|
||||
<div class="flex items-center gap-1 flex-wrap text-xs">
|
||||
<template v-for="(stage, index) in stages" :key="index">
|
||||
<div v-if="index > 0" class="w-3 h-px bg-base-300" />
|
||||
<div class="flex items-center gap-0.5">
|
||||
<span>{{ getTransportIcon(stage.transportType) }}</span>
|
||||
<span class="text-base-content/70">{{ formatDistance(stage.distanceKm) }}км</span>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
<ul class="steps steps-horizontal text-xs w-full">
|
||||
<li
|
||||
v-for="(stage, index) in stages"
|
||||
:key="index"
|
||||
class="step step-primary"
|
||||
:data-content="getTransportIcon(stage.transportType)"
|
||||
>
|
||||
{{ formatDistance(stage.distanceKm) }} км
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@@ -27,6 +28,7 @@ const getTransportIcon = (type?: string | null) => {
|
||||
case 'sea':
|
||||
return '🚢'
|
||||
case 'road':
|
||||
case 'auto':
|
||||
default:
|
||||
return '🚛'
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user