/** * @ai-summary Vehicle roster card component for dashboard fleet grid * Displays vehicle image, health status, attention items, and odometer */ import React from 'react'; import { clsx } from 'clsx'; import { GlassCard } from '../../../shared-minimal/components/mobile/GlassCard'; import { VehicleImage } from '../../vehicles/components/VehicleImage'; import { getVehicleLabel } from '../../../core/utils/vehicleDisplay'; import { VehicleRosterData, AttentionItem } from '../types'; interface VehicleRosterCardProps { data: VehicleRosterData; onClick: (vehicleId: string) => void; } const getHealthBadgeClass = (health: VehicleRosterData['health']): string => { switch (health) { case 'green': return 'bg-emerald-500'; case 'yellow': return 'bg-amber-500'; case 'red': return 'bg-red-500'; } }; const getAttentionItemClass = (urgency: AttentionItem['urgency']): string => { switch (urgency) { case 'overdue': return 'text-red-600 dark:text-red-400'; case 'due-soon': return 'text-amber-600 dark:text-amber-400'; case 'upcoming': return 'text-slate-500 dark:text-titanio'; } }; const formatAttentionStatus = (item: AttentionItem): string => { if (item.urgency === 'overdue') { return 'OVERDUE'; } return `${item.daysUntilDue} days`; }; export const VehicleRosterCard: React.FC = ({ data, onClick, }) => { const { vehicle, health, attentionItems } = data; const displayedItems = attentionItems.slice(0, 3); return ( onClick(vehicle.id)}> {/* Top row: Image, Label, Health Badge */}
{/* Vehicle image container - clips the built-in mb-2 margin */}
{/* Vehicle label */}
{getVehicleLabel(vehicle)}
{/* Health badge */}
{/* Attention items */}
{displayedItems.length === 0 ? (
All clear
) : ( displayedItems.map((item, index) => (
{item.label} - {formatAttentionStatus(item)}
)) )}
{/* Odometer */}
{vehicle.odometerReading.toLocaleString()} mi
); };