MVP with new UX
This commit is contained in:
@@ -1,11 +1,12 @@
|
||||
/**
|
||||
* @ai-summary Vehicle card component
|
||||
* @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 { Card } from '../../../shared-minimal/components/Card';
|
||||
import { Button } from '../../../shared-minimal/components/Button';
|
||||
|
||||
interface VehicleCardProps {
|
||||
vehicle: Vehicle;
|
||||
@@ -14,51 +15,96 @@ interface VehicleCardProps {
|
||||
onSelect: (id: string) => void;
|
||||
}
|
||||
|
||||
const CarThumb: React.FC<{ color?: string }> = ({ color = "#F2EAEA" }) => (
|
||||
<Box
|
||||
sx={{
|
||||
height: 96,
|
||||
bgcolor: color,
|
||||
borderRadius: 2,
|
||||
mb: 2,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
export const VehicleCard: React.FC<VehicleCardProps> = ({
|
||||
vehicle,
|
||||
onEdit,
|
||||
onDelete,
|
||||
onSelect,
|
||||
}) => {
|
||||
const displayName = vehicle.nickname ||
|
||||
`${vehicle.year} ${vehicle.make} ${vehicle.model}`;
|
||||
|
||||
return (
|
||||
<Card className="hover:shadow-md transition-shadow cursor-pointer" onClick={() => onSelect(vehicle.id)}>
|
||||
<div className="flex justify-between items-start">
|
||||
<div className="flex-1">
|
||||
<h3 className="text-lg font-semibold text-gray-900">
|
||||
{vehicle.nickname || `${vehicle.year} ${vehicle.make} ${vehicle.model}`}
|
||||
</h3>
|
||||
<p className="text-sm text-gray-500 mt-1">VIN: {vehicle.vin}</p>
|
||||
<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>
|
||||
<CarThumb color={vehicle.color || "#F2EAEA"} />
|
||||
|
||||
<Typography variant="h6" sx={{ fontWeight: 700, mb: 1 }}>
|
||||
{displayName}
|
||||
</Typography>
|
||||
|
||||
<Typography variant="body2" color="text.secondary" sx={{ mb: 0.5 }}>
|
||||
VIN: {vehicle.vin}
|
||||
</Typography>
|
||||
|
||||
{vehicle.licensePlate && (
|
||||
<p className="text-sm text-gray-500">License: {vehicle.licensePlate}</p>
|
||||
<Typography variant="body2" color="text.secondary" sx={{ mb: 0.5 }}>
|
||||
License: {vehicle.licensePlate}
|
||||
</Typography>
|
||||
)}
|
||||
<p className="text-sm text-gray-600 mt-2">
|
||||
|
||||
<Typography variant="body2" color="text.primary" sx={{ mt: 1, fontWeight: 500 }}>
|
||||
Odometer: {vehicle.odometerReading.toLocaleString()} miles
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="flex gap-2">
|
||||
<Button
|
||||
size="sm"
|
||||
variant="secondary"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
onEdit(vehicle);
|
||||
}}
|
||||
>
|
||||
Edit
|
||||
</Button>
|
||||
<Button
|
||||
size="sm"
|
||||
variant="danger"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
onDelete(vehicle.id);
|
||||
}}
|
||||
>
|
||||
Delete
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</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>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user