Compare commits

..

2 Commits

Author SHA1 Message Date
Ruslan Bakiev
0337cebc63 Simplify OfferResultCard and use daisyUI Steps
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
2026-01-15 00:33:17 +07:00
Ruslan Bakiev
f03554893b Update OfferResultCard: add location, mini map, fix price format
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
2026-01-15 00:07:21 +07:00
4 changed files with 46 additions and 30 deletions

View File

@@ -20,12 +20,11 @@
<OfferResultCard <OfferResultCard
v-for="option in productRouteOptions" v-for="option in productRouteOptions"
:key="option.sourceUuid" :key="option.sourceUuid"
:source-name="option.sourceName || 'Склад'" :location-name="getOfferData(option.sourceUuid)?.locationName"
:product-name="productName" :product-name="productName"
:price-per-unit="getOfferData(option.sourceUuid)?.pricePerUnit" :price-per-unit="getOfferData(option.sourceUuid)?.pricePerUnit"
:currency="getOfferData(option.sourceUuid)?.currency" :currency="getOfferData(option.sourceUuid)?.currency"
:unit="getOfferData(option.sourceUuid)?.unit" :unit="getOfferData(option.sourceUuid)?.unit"
:total-distance="option.distanceKm || 0"
:stages="getRouteStages(option)" :stages="getRouteStages(option)"
/> />
</div> </div>

View File

@@ -1,17 +1,14 @@
<template> <template>
<Card padding="md" interactive @click="$emit('select')"> <Card padding="md" interactive @click="$emit('select')">
<!-- Header: Source + Price --> <!-- Header: Location + Price -->
<div class="flex items-start justify-between mb-2"> <div class="flex items-start justify-between mb-3">
<div> <div>
<Text weight="semibold">{{ sourceName }}</Text> <Text weight="semibold">{{ locationName || 'Локация' }}</Text>
<Text v-if="productName" tone="muted" size="sm">{{ productName }}</Text> <Text v-if="productName" tone="muted" size="sm">{{ productName }}</Text>
</div> </div>
<div class="text-right"> <Text v-if="priceDisplay" weight="semibold" class="text-primary text-lg">
<Text v-if="priceDisplay" weight="semibold" class="text-primary text-lg"> {{ priceDisplay }}
{{ priceDisplay }} </Text>
</Text>
<Text tone="muted" size="sm">{{ formatDistance(totalDistance) }} км</Text>
</div>
</div> </div>
<!-- Route stepper --> <!-- Route stepper -->
@@ -23,12 +20,11 @@
import type { RouteStage } from './RouteStepper.vue' import type { RouteStage } from './RouteStepper.vue'
const props = withDefaults(defineProps<{ const props = withDefaults(defineProps<{
sourceName: string locationName?: string
productName?: string productName?: string
pricePerUnit?: number | null pricePerUnit?: number | null
currency?: string | null currency?: string | null
unit?: string | null unit?: string | null
totalDistance: number
stages?: RouteStage[] stages?: RouteStage[]
}>(), { }>(), {
stages: () => [] stages: () => []
@@ -40,13 +36,33 @@ defineEmits<{
const priceDisplay = computed(() => { const priceDisplay = computed(() => {
if (!props.pricePerUnit) return null if (!props.pricePerUnit) return null
const curr = props.currency || 'USD' const currSymbol = getCurrencySymbol(props.currency)
const u = props.unit || 'т' const unitName = getUnitName(props.unit)
return `${props.pricePerUnit} ${curr}/${u}` const formattedPrice = props.pricePerUnit.toLocaleString()
return `${currSymbol}${formattedPrice}/${unitName}`
}) })
const formatDistance = (km?: number | null) => { const getCurrencySymbol = (currency?: string | null) => {
if (!km) return '0' switch (currency?.toUpperCase()) {
return Math.round(km).toLocaleString() 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> </script>

View File

@@ -1,13 +1,14 @@
<template> <template>
<div class="flex items-center gap-1 flex-wrap text-xs"> <ul class="steps steps-horizontal text-xs w-full">
<template v-for="(stage, index) in stages" :key="index"> <li
<div v-if="index > 0" class="w-3 h-px bg-base-300" /> v-for="(stage, index) in stages"
<div class="flex items-center gap-0.5"> :key="index"
<span>{{ getTransportIcon(stage.transportType) }}</span> class="step step-primary"
<span class="text-base-content/70">{{ formatDistance(stage.distanceKm) }}км</span> :data-content="getTransportIcon(stage.transportType)"
</div> >
</template> {{ formatDistance(stage.distanceKm) }} км
</div> </li>
</ul>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
@@ -27,6 +28,7 @@ const getTransportIcon = (type?: string | null) => {
case 'sea': case 'sea':
return '🚢' return '🚢'
case 'road': case 'road':
case 'auto':
default: default:
return '🚛' return '🚛'
} }

View File

@@ -60,12 +60,11 @@
<template #card="{ item }"> <template #card="{ item }">
<OfferResultCard <OfferResultCard
:source-name="item.name" :location-name="getOfferData(item.uuid)?.locationName"
:product-name="selectedProductName" :product-name="selectedProductName"
:price-per-unit="getOfferData(item.uuid)?.pricePerUnit" :price-per-unit="getOfferData(item.uuid)?.pricePerUnit"
:currency="getOfferData(item.uuid)?.currency" :currency="getOfferData(item.uuid)?.currency"
:unit="getOfferData(item.uuid)?.unit" :unit="getOfferData(item.uuid)?.unit"
:total-distance="item.distanceKm"
:stages="item.stages" :stages="item.stages"
/> />
</template> </template>