Files
service-finder/frontend/src/components/garage/VehicleCard.vue
2026-03-26 07:09:44 +00:00

130 lines
5.0 KiB
Vue

<script setup>
import { useThemeStore } from '@/stores/themeStore'
defineProps({
vehicle: {
type: Object,
required: true
}
})
const themeStore = useThemeStore()
const themeClasses = themeStore.themeClasses
const statusColors = {
'OK': 'bg-green-100 text-green-800',
'Service Due': 'bg-blue-100 text-blue-900',
'Warning': 'bg-orange-100 text-orange-800'
}
const brandLogoUrl = (make) => {
const cleanMake = make.toLowerCase().replace(/\s+/g, '')
// Use simpleicons CDN
return `https://cdn.simpleicons.org/${cleanMake}`
}
// Country flag mapping
const getCountryFlag = (make) => {
const makeLower = make.toLowerCase()
if (makeLower.includes('bmw') || makeLower.includes('mercedes') || makeLower.includes('audi') || makeLower.includes('volkswagen') || makeLower.includes('porsche')) {
return 'https://flagcdn.com/w40/de.png'
} else if (makeLower.includes('tesla') || makeLower.includes('ford') || makeLower.includes('chevrolet') || makeLower.includes('dodge')) {
return 'https://flagcdn.com/w40/us.png'
} else if (makeLower.includes('toyota') || makeLower.includes('honda') || makeLower.includes('nissan') || makeLower.includes('mazda')) {
return 'https://flagcdn.com/w40/jp.png'
} else if (makeLower.includes('ferrari') || makeLower.includes('lamborghini') || makeLower.includes('fiat') || makeLower.includes('alfa romeo')) {
return 'https://flagcdn.com/w40/it.png'
} else if (makeLower.includes('volvo') || makeLower.includes('saab')) {
return 'https://flagcdn.com/w40/se.png'
} else if (makeLower.includes('renault') || makeLower.includes('peugeot') || makeLower.includes('citroen')) {
return 'https://flagcdn.com/w40/fr.png'
} else if (makeLower.includes('skoda') || makeLower.includes('seat')) {
return 'https://flagcdn.com/w40/cz.png'
} else {
return 'https://flagcdn.com/w40/eu.png'
}
}
</script>
<template>
<div :class="['rounded-2xl shadow-lg overflow-hidden hover:shadow-xl transition-all duration-500 border', themeClasses.card]">
<!-- Vehicle Image -->
<div class="h-48 bg-gray-200 relative overflow-hidden">
<img
:src="vehicle.imageUrl"
:alt="`${vehicle.make} ${vehicle.model}`"
class="w-full h-full object-cover"
/>
<!-- Brand Logo -->
<div class="absolute top-3 left-3 bg-white/80 backdrop-blur-sm rounded-lg p-2 shadow-md">
<img
:src="brandLogoUrl(vehicle.make)"
:alt="vehicle.make"
class="w-8 h-8"
@error="(e) => e.target.style.display = 'none'"
/>
</div>
<div class="absolute top-3 right-3">
<span
:class="['px-3 py-1 rounded-full text-xs font-semibold', statusColors[vehicle.status] || 'bg-gray-100 text-gray-800']"
>
{{ vehicle.status }}
</span>
</div>
</div>
<!-- Vehicle Details -->
<div class="p-6">
<div class="flex justify-between items-start mb-4">
<div>
<h3 class="text-xl font-bold text-gray-900">{{ vehicle.make }} {{ vehicle.model }}</h3>
<p class="text-gray-600">{{ vehicle.year }} {{ vehicle.fuelType }}</p>
</div>
<div class="text-right">
<div class="text-2xl font-bold text-blue-700">{{ vehicle.monthlyExpense }}</div>
<div class="text-sm text-gray-500">/month</div>
</div>
</div>
<!-- License Plate with Country Flag -->
<div class="mb-4">
<div class="inline-flex items-center bg-gray-100 px-4 py-2 rounded-lg space-x-3">
<img
:src="getCountryFlag(vehicle.make)"
:alt="`${vehicle.make} origin flag`"
class="w-6 h-4 rounded-sm shadow-sm"
/>
<span class="text-gray-700 font-mono font-bold text-lg">{{ vehicle.licensePlate }}</span>
</div>
</div>
<!-- Stats -->
<div class="grid grid-cols-2 gap-4 mb-6">
<div class="text-center">
<div class="text-2xl font-bold text-gray-900">{{ (vehicle.mileage / 1000).toFixed(1) }}k</div>
<div class="text-sm text-gray-600">km</div>
</div>
<div class="text-center">
<div class="text-2xl font-bold text-gray-900">{{ vehicle.fuelType.charAt(0) }}</div>
<div class="text-sm text-gray-600">Fuel</div>
</div>
</div>
<!-- Actions -->
<div class="flex space-x-3">
<button class="flex-1 bg-blue-600 hover:bg-blue-700 text-white font-semibold py-3 rounded-lg transition-colors duration-200">
View Details
</button>
<button class="px-4 py-3 border border-gray-300 hover:bg-gray-50 rounded-lg transition-colors duration-200">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 text-gray-600" viewBox="0 0 20 20" fill="currentColor">
<path d="M13.586 3.586a2 2 0 112.828 2.828l-.793.793-2.828-2.828.793-.793zM11.379 5.793L3 14.172V17h2.828l8.38-8.379-2.83-2.828z" />
</svg>
</button>
</div>
</div>
</div>
</template>
<style scoped>
/* Custom scrollbar for future use */
</style>