Files
motovaultpro/frontend/src/features/vehicles/components/VehicleCard.tsx
2026-02-13 19:41:23 -06:00

108 lines
2.9 KiB
TypeScript

/**
* @ai-summary Vehicle card component with Material Design 3
*/
import React from 'react';
import { Card, CardContent, CardActionArea, Box, Typography, IconButton } from '@mui/material';
import EditIcon from '@mui/icons-material/Edit';
import DeleteIcon from '@mui/icons-material/Delete';
import { Vehicle } from '../types/vehicles.types';
import { useUnits } from '../../../core/units/UnitsContext';
import { VehicleImage } from './VehicleImage';
import { getVehicleLabel, getVehicleSubtitle } from '@/core/utils/vehicleDisplay';
interface VehicleCardProps {
vehicle: Vehicle;
onEdit: (vehicle: Vehicle) => void;
onDelete: (id: string) => void;
onSelect: (id: string) => void;
}
export const VehicleCard: React.FC<VehicleCardProps> = ({
vehicle,
onEdit,
onDelete,
onSelect,
}) => {
const { formatDistance } = useUnits();
const displayName = getVehicleLabel(vehicle);
const subtitle = getVehicleSubtitle(vehicle);
return (
<Card
sx={{
height: '100%',
display: 'flex',
flexDirection: 'column',
'&:hover': {
boxShadow: 3,
},
transition: 'box-shadow 0.2s ease-in-out'
}}
>
<CardActionArea
onClick={() => onSelect(vehicle.id)}
sx={{ flexGrow: 1 }}
>
<CardContent>
<VehicleImage vehicle={vehicle} height={96} />
<Typography variant="h6" sx={{ fontWeight: 700, mb: 0.5 }}>
{displayName}
</Typography>
{subtitle && (
<Typography variant="body2" color="text.secondary" sx={{ mb: 0.5 }}>
{subtitle}
</Typography>
)}
{vehicle.vin && (
<Typography variant="body2" color="text.secondary" sx={{ mb: 0.5 }}>
VIN: {vehicle.vin}
</Typography>
)}
{vehicle.licensePlate && (
<Typography variant="body2" color="text.secondary" sx={{ mb: 0.5 }}>
License: {vehicle.licensePlate}
</Typography>
)}
<Typography variant="body2" color="text.primary" sx={{ mt: 1, fontWeight: 500 }}>
Odometer: {formatDistance(vehicle.odometerReading)}
</Typography>
</CardContent>
</CardActionArea>
<Box sx={{
display: 'flex',
justifyContent: 'flex-end',
gap: 1,
p: 2,
pt: 0
}}>
<IconButton
size="small"
onClick={(e) => {
e.stopPropagation();
onEdit(vehicle);
}}
sx={{ color: 'text.secondary' }}
>
<EditIcon fontSize="small" />
</IconButton>
<IconButton
size="small"
onClick={(e) => {
e.stopPropagation();
onDelete(vehicle.id);
}}
sx={{ color: 'error.main' }}
>
<DeleteIcon fontSize="small" />
</IconButton>
</Box>
</Card>
);
};