Initial commit from monorepo
This commit is contained in:
138
app/components/CompanyCard.vue
Normal file
138
app/components/CompanyCard.vue
Normal file
@@ -0,0 +1,138 @@
|
||||
<template>
|
||||
<div
|
||||
class="card bg-base-100 border border-base-300 shadow-sm transition-all duration-200 hover:scale-105"
|
||||
:class="sizeClasses"
|
||||
>
|
||||
<div class="flex items-center space-x-3">
|
||||
<!-- Company logo -->
|
||||
<div class="flex-shrink-0">
|
||||
<div
|
||||
class="rounded-full bg-gradient-to-br from-primary to-accent flex items-center justify-center text-primary-content font-bold"
|
||||
:class="logoSizeClasses"
|
||||
>
|
||||
{{ getCompanyInitials(company.name) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Company info -->
|
||||
<div class="flex-1 min-w-0">
|
||||
<h4 class="font-semibold text-base-content truncate" :class="nameSizeClasses">
|
||||
{{ company.name }}
|
||||
</h4>
|
||||
<p class="text-base-content/70 text-xs">
|
||||
{{ company.country }} • {{ company.taxId }}
|
||||
</p>
|
||||
|
||||
<!-- Extra info -->
|
||||
<div v-if="tripCount" class="mt-2">
|
||||
<p class="text-xs text-primary font-medium">
|
||||
{{ tripCount }} trips
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Trust rating -->
|
||||
<div class="flex-shrink-0 text-center">
|
||||
<div class="flex items-center space-x-1">
|
||||
<span class="font-semibold text-sm text-base-content">{{ getTrustRating(company) }}</span>
|
||||
</div>
|
||||
<p class="text-xs text-base-content/60">rating</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Stats (only for large size) -->
|
||||
<div v-if="size === 'large'" class="mt-4 pt-4 border-t border-base-300">
|
||||
<div class="grid grid-cols-3 gap-4 text-center">
|
||||
<div>
|
||||
<p class="text-lg font-semibold text-base-content">{{ getCompanyStats().totalTrips }}</p>
|
||||
<p class="text-xs text-base-content/60">trips</p>
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-lg font-semibold text-base-content">{{ getCompanyStats().totalWeight }}t</p>
|
||||
<p class="text-xs text-base-content/60">carried</p>
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-lg font-semibold text-base-content">{{ getCompanyStats().onTimePercentage }}%</p>
|
||||
<p class="text-xs text-base-content/60">on time</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const props = defineProps({
|
||||
company: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
tripCount: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
size: {
|
||||
type: String,
|
||||
default: 'medium', // small, medium, large
|
||||
validator: value => ['small', 'medium', 'large'].includes(value)
|
||||
}
|
||||
})
|
||||
|
||||
const sizeClasses = computed(() => {
|
||||
switch (props.size) {
|
||||
case 'small': return 'p-3'
|
||||
case 'large': return 'p-6'
|
||||
default: return 'p-4'
|
||||
}
|
||||
})
|
||||
|
||||
const logoSizeClasses = computed(() => {
|
||||
switch (props.size) {
|
||||
case 'small': return 'w-8 h-8 text-xs'
|
||||
case 'large': return 'w-16 h-16 text-xl'
|
||||
default: return 'w-12 h-12 text-sm'
|
||||
}
|
||||
})
|
||||
|
||||
const nameSizeClasses = computed(() => {
|
||||
switch (props.size) {
|
||||
case 'small': return 'text-sm'
|
||||
case 'large': return 'text-lg'
|
||||
default: return 'text-base'
|
||||
}
|
||||
})
|
||||
|
||||
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) => {
|
||||
// Generate pseudo-rating based on company name
|
||||
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
|
||||
}
|
||||
|
||||
const getCompanyStats = () => {
|
||||
// Demo stats stub
|
||||
return {
|
||||
totalTrips: props.tripCount || Math.floor(Math.random() * 50) + 10,
|
||||
totalWeight: (props.tripCount || 25) * 25, // 25t per trip
|
||||
onTimePercentage: Math.floor(Math.random() * 20) + 80 // 80-100%
|
||||
}
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user