Initial commit from monorepo
This commit is contained in:
147
app/components/OrderMap.vue
Normal file
147
app/components/OrderMap.vue
Normal file
@@ -0,0 +1,147 @@
|
||||
<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>
|
||||
Reference in New Issue
Block a user