108 lines
2.9 KiB
TypeScript
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>
|
|
);
|
|
}; |