130 lines
3.9 KiB
Vue
130 lines
3.9 KiB
Vue
<template>
|
|
<div class="w-full space-y-4">
|
|
<div
|
|
v-for="(stage, index) in stages"
|
|
:key="stage.uuid"
|
|
class="p-6 border border-base-300 rounded-lg hover:bg-base-200 transition-all duration-200"
|
|
>
|
|
<!-- Top row: number + title + location -->
|
|
<div class="flex items-center space-x-6 mb-6">
|
|
<!-- Stage number -->
|
|
<div class="flex-shrink-0 w-12 h-12 bg-primary text-primary-content rounded-full flex items-center justify-center font-bold text-lg">
|
|
{{ index + 1 }}
|
|
</div>
|
|
|
|
<!-- Title and location -->
|
|
<div class="flex-1 flex items-start justify-between">
|
|
<h3 class="text-xl font-semibold text-base-content">{{ stage.name }}</h3>
|
|
<div class="text-right text-sm text-base-content/60">
|
|
<div v-if="stage.stageType === 'transport'">
|
|
{{ stage.sourceLocationName }} → {{ stage.destinationLocationName }}
|
|
</div>
|
|
<div v-else>
|
|
{{ stage.locationName }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Companies row -->
|
|
<div v-if="getStageCompanies(stage).length" class="mb-4">
|
|
<div class="flex flex-wrap gap-4">
|
|
<div
|
|
v-for="company in getStageCompanies(stage)"
|
|
:key="company.uuid"
|
|
class="flex flex-col items-center bg-base-100 rounded-lg p-4 shadow-sm border border-base-300 min-w-32"
|
|
>
|
|
<!-- Company logo -->
|
|
<div class="w-12 h-12 bg-gradient-to-br from-primary to-accent rounded-full flex items-center justify-center text-primary-content text-sm font-bold mb-2">
|
|
{{ getCompanyInitials(company.name) }}
|
|
</div>
|
|
|
|
<!-- Name and rating -->
|
|
<div class="text-center">
|
|
<p class="text-sm font-medium text-base-content mb-1">{{ company.name }}</p>
|
|
<div class="flex items-center justify-center space-x-1">
|
|
<span class="text-yellow-400 text-xs">★</span>
|
|
<span class="text-xs text-base-content/70">{{ getTrustRating(company) }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Stage stats -->
|
|
<div v-if="stage.trips?.length" class="text-left">
|
|
<div class="inline-flex items-center bg-primary/10 rounded-lg px-4 py-2">
|
|
<span class="text-sm font-medium text-primary">{{ t('timelineStages.labels.trips', { count: stage.trips.length }) }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
const props = defineProps({
|
|
stages: {
|
|
type: Array,
|
|
default: () => []
|
|
}
|
|
})
|
|
|
|
const { t } = useI18n()
|
|
|
|
const getStageIcon = (stage) => {
|
|
if (stage.stageType === 'service') return 'Service'
|
|
|
|
switch (stage.transportType) {
|
|
case 'auto': return 'Auto'
|
|
case 'sea': return 'Sea'
|
|
case 'rail': return 'Rail'
|
|
case 'air': return 'Air'
|
|
default: return 'Auto'
|
|
}
|
|
}
|
|
|
|
|
|
const getStageCompanies = (stage) => {
|
|
const companies = []
|
|
|
|
if (stage.selectedCompany) {
|
|
companies.push(stage.selectedCompany)
|
|
}
|
|
|
|
const uniqueCompanies = new Set()
|
|
stage.trips?.forEach(trip => {
|
|
if (trip.company && !uniqueCompanies.has(trip.company.uuid)) {
|
|
uniqueCompanies.add(trip.company.uuid)
|
|
companies.push(trip.company)
|
|
}
|
|
})
|
|
|
|
return companies
|
|
}
|
|
|
|
const getCompanyInitials = (name) => {
|
|
if (!name) return '??'
|
|
|
|
const words = name.split(' ')
|
|
if (words.length >= 2) {
|
|
return (words[0][0] + words[1][0]).toUpperCase()
|
|
}
|
|
return name.substring(0, 2).toUpperCase()
|
|
}
|
|
|
|
const getTrustRating = (company) => {
|
|
const ratings = {
|
|
'Kenya Coffee Logistics Ltd': 4.8,
|
|
'Kenya Highland Transport': 4.6,
|
|
'Mombasa Express Cargo': 4.4,
|
|
'East Africa Shipping Lines': 4.7,
|
|
'Truck LLC': 4.5,
|
|
'Motor Depot #1': 4.3,
|
|
'RailTrans LLC': 4.6,
|
|
'Kenya Ports Authority': 4.9
|
|
}
|
|
|
|
return ratings[company.name] || 4.2
|
|
}
|
|
</script>
|