Files
webapp/app/components/OrderMap.vue
2026-01-07 09:10:35 +07:00

148 lines
5.0 KiB
Vue

<template>
<div class="card bg-base-100 border border-base-300 shadow">
<div class="card-body">
<div class="h-full flex items-center justify-center p-4">
<div class="w-full max-w-2xl">
<h3 class="text-lg font-semibold text-base-content mb-4 text-center">{{ t('orderMap.header.title') }}</h3>
<!-- Route visualization -->
<div class="relative">
<!-- Route line -->
<div class="absolute top-1/2 left-0 right-0 h-1 bg-primary transform -translate-y-1/2 z-0"></div>
<!-- Location points -->
<div class="relative z-10 flex justify-between items-center">
<div
v-for="(point, index) in routePoints"
:key="point.id"
class="flex flex-col items-center"
>
<!-- Point marker -->
<div
class="w-4 h-4 rounded-full border-2 border-base-100 shadow-md mb-2"
:class="getPointColor(point.type)"
></div>
<!-- Point info -->
<div class="text-center card bg-base-200 border border-base-300 p-2 max-w-32">
<p class="text-xs font-medium text-base-content">{{ point.name }}</p>
<p class="text-xs text-base-content/60">{{ point.country }}</p>
<div v-if="point.stage" class="mt-1">
<p class="text-xs text-primary">{{ point.stage.name }}</p>
<p v-if="point.stage.selectedCompany" class="text-xs text-base-content/60">
{{ point.stage.selectedCompany.name }}
</p>
</div>
</div>
</div>
</div>
</div>
<!-- Route summary -->
<div class="mt-6 grid grid-cols-2 gap-4 text-center">
<div class="card bg-base-200 border border-base-300">
<div class="card-body p-3 gap-1">
<div class="text-lg font-semibold text-primary">{{ t('orderMap.stats.distance_value', { km: getTotalDistance() }) }}</div>
<div class="text-xs text-base-content/60">{{ t('orderMap.stats.distance_label') }}</div>
</div>
</div>
<div class="card bg-base-200 border border-base-300">
<div class="card-body p-3 gap-1">
<div class="text-lg font-semibold text-success">{{ getCountries() }}</div>
<div class="text-xs text-base-content/60">{{ t('orderMap.stats.countries_label') }}</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
const props = defineProps({
stages: {
type: Array,
default: () => []
}
})
const { t } = useI18n()
// Coordinates of route points
const locationData = {
'Kenya Coffee Farm': { country: 'Kenya', lat: -1.2921, lng: 36.8219 },
'Port of Mombasa': { country: 'Kenya', lat: -4.0435, lng: 39.6682 },
'Novorossiysk Port': { country: 'Russia', lat: 44.7233, lng: 37.7683 },
'Moscow Distribution Center': { country: 'Russia', lat: 55.7558, lng: 37.6176 }
}
const routePoints = computed(() => {
const points = []
props.stages.forEach((stage) => {
if (stage.stageType === 'transport') {
// Add source point
const sourceData = locationData[stage.sourceLocationName]
if (sourceData && !points.find(p => p.name === stage.sourceLocationName)) {
points.push({
id: `source-${stage.uuid}`,
name: stage.sourceLocationName,
country: sourceData.country,
type: 'source',
stage: stage
})
}
// Add destination point
const destData = locationData[stage.destinationLocationName]
if (destData && !points.find(p => p.name === stage.destinationLocationName)) {
points.push({
id: `dest-${stage.uuid}`,
name: stage.destinationLocationName,
country: destData.country,
type: 'destination',
stage: stage
})
}
} else {
// Service stage
const locationData_service = locationData[stage.locationName]
if (locationData_service && !points.find(p => p.name === stage.locationName)) {
points.push({
id: `service-${stage.uuid}`,
name: stage.locationName,
country: locationData_service.country,
type: 'service',
stage: stage
})
}
}
})
return points
})
const getPointColor = (type) => {
const colors = {
source: 'bg-success',
destination: 'bg-error',
service: 'bg-primary'
}
return colors[type] || 'bg-base-300'
}
const getTotalDistance = () => {
// Approximate distance between points
return '15,000' // Kenya → Russia ~15,000 km
}
const getCountries = () => {
const countries = new Set()
routePoints.value.forEach(point => {
countries.add(point.country)
})
return countries.size
}
</script>