Update OfferResultCard: add location, mini map, fix price format
All checks were successful
Build Docker Image / build (push) Successful in 4m30s
All checks were successful
Build Docker Image / build (push) Successful in 4m30s
- 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
This commit is contained in:
@@ -1,21 +1,32 @@
|
||||
<template>
|
||||
<Card padding="md" interactive @click="$emit('select')">
|
||||
<!-- Header: Source + Price -->
|
||||
<div class="flex items-start justify-between mb-2">
|
||||
<!-- Header: Source name + Location + Price -->
|
||||
<div class="flex items-start justify-between mb-3">
|
||||
<div>
|
||||
<Text weight="semibold">{{ sourceName }}</Text>
|
||||
<Text v-if="productName" tone="muted" size="sm">{{ productName }}</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 tone="muted" size="sm">{{ formatDistance(totalDistance) }} км</Text>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Route stepper -->
|
||||
<RouteStepper v-if="stages.length > 0" :stages="stages" />
|
||||
<!-- 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"
|
||||
/>
|
||||
</Card>
|
||||
</template>
|
||||
|
||||
@@ -24,11 +35,13 @@ 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
|
||||
totalDistance: number
|
||||
latitude?: number | null
|
||||
longitude?: number | null
|
||||
stages?: RouteStage[]
|
||||
}>(), {
|
||||
stages: () => []
|
||||
@@ -40,13 +53,33 @@ defineEmits<{
|
||||
|
||||
const priceDisplay = computed(() => {
|
||||
if (!props.pricePerUnit) return null
|
||||
const curr = props.currency || 'USD'
|
||||
const u = props.unit || 'т'
|
||||
return `${props.pricePerUnit} ${curr}/${u}`
|
||||
const currSymbol = getCurrencySymbol(props.currency)
|
||||
const unitName = getUnitName(props.unit)
|
||||
const formattedPrice = props.pricePerUnit.toLocaleString()
|
||||
return `${currSymbol}${formattedPrice}/${unitName}`
|
||||
})
|
||||
|
||||
const formatDistance = (km?: number | null) => {
|
||||
if (!km) return '0'
|
||||
return Math.round(km).toLocaleString()
|
||||
const getCurrencySymbol = (currency?: string | null) => {
|
||||
switch (currency?.toUpperCase()) {
|
||||
case 'USD': return '$'
|
||||
case 'EUR': return '€'
|
||||
case 'RUB': return '₽'
|
||||
case 'CNY': return '¥'
|
||||
default: return '$'
|
||||
}
|
||||
}
|
||||
|
||||
const getUnitName = (unit?: string | null) => {
|
||||
switch (unit?.toLowerCase()) {
|
||||
case 'т':
|
||||
case 'ton':
|
||||
case 'tonne':
|
||||
return 'тонна'
|
||||
case 'кг':
|
||||
case 'kg':
|
||||
return 'кг'
|
||||
default:
|
||||
return 'тонна'
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user