fix: show maintenance records on vehicle summary screen (refs #239)
All checks were successful
Deploy to Staging / Build Images (pull_request) Successful in 1m14s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 42s
Deploy to Staging / Verify Staging (pull_request) Successful in 3s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 4s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
All checks were successful
Deploy to Staging / Build Images (pull_request) Successful in 1m14s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 42s
Deploy to Staging / Verify Staging (pull_request) Successful in 3s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 4s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
The Vehicle Records section on /garage/vehicles/:id never called useMaintenanceRecords, so maintenance rows always rendered empty even when records existed for the vehicle. Wire the existing hook into both the desktop VehicleDetailPage and mobile VehicleDetailMobile, merge records into the unified list with category + subtypes + shop name, and include the maintenance loading state in the section's loading and empty-state guards. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -12,6 +12,9 @@ import { FuelLogResponse, UpdateFuelLogRequest } from '../../fuel-logs/types/fue
|
||||
import { FuelLogEditDialog } from '../../fuel-logs/components/FuelLogEditDialog';
|
||||
import { fuelLogsApi } from '../../fuel-logs/api/fuel-logs.api';
|
||||
import { MaintenanceRecordForm } from '../../maintenance/components/MaintenanceRecordForm';
|
||||
import { useMaintenanceRecords } from '../../maintenance/hooks/useMaintenanceRecords';
|
||||
import { getCategoryDisplayName } from '../../maintenance/types/maintenance.types';
|
||||
import type { MaintenanceRecordResponse } from '../../maintenance/types/maintenance.types';
|
||||
import { VehicleImage } from '../components/VehicleImage';
|
||||
import { OwnershipCostsList } from '../../ownership-costs';
|
||||
import { getVehicleLabel } from '@/core/utils/vehicleDisplay';
|
||||
@@ -46,6 +49,7 @@ export const VehicleDetailMobile: React.FC<VehicleDetailMobileProps> = ({
|
||||
|
||||
const [recordFilter, setRecordFilter] = useState<'All' | 'Fuel Logs' | 'Maintenance' | 'Documents'>('All');
|
||||
const { fuelLogs, isLoading: isFuelLoading } = useFuelLogs(vehicle.id);
|
||||
const { records: maintenanceRecords, isRecordsLoading: isMaintenanceLoading } = useMaintenanceRecords(vehicle.id);
|
||||
const queryClient = useQueryClient();
|
||||
const [editingLog, setEditingLog] = useState<FuelLogResponse | null>(null);
|
||||
const [showMaintenanceDialog, setShowMaintenanceDialog] = useState(false);
|
||||
@@ -124,8 +128,34 @@ export const VehicleDetailMobile: React.FC<VehicleDetailMobileProps> = ({
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (maintenanceRecords && Array.isArray(maintenanceRecords)) {
|
||||
for (const rec of maintenanceRecords as MaintenanceRecordResponse[]) {
|
||||
const catLabel = getCategoryDisplayName(rec.category);
|
||||
const subtypes = Array.isArray(rec.subtypes) ? rec.subtypes : [];
|
||||
const subtypeText = subtypes.length
|
||||
? `${subtypes.slice(0, 3).join(', ')}${subtypes.length > 3 ? ` +${subtypes.length - 3}` : ''}`
|
||||
: '';
|
||||
const summary = subtypeText ? `${catLabel} — ${subtypeText}` : catLabel;
|
||||
const secondaryParts: string[] = [];
|
||||
if (rec.shopName) secondaryParts.push(rec.shopName);
|
||||
secondaryParts.push(new Date(rec.date).toLocaleDateString());
|
||||
secondaryParts.push('Maintenance');
|
||||
const secondary = secondaryParts.join(' • ');
|
||||
const amount = typeof rec.cost === 'number' ? `$${rec.cost.toFixed(2)}` : undefined;
|
||||
list.push({
|
||||
id: rec.id,
|
||||
type: 'Maintenance',
|
||||
date: rec.date,
|
||||
summary,
|
||||
amount,
|
||||
secondary
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return list.sort((a, b) => b.date.localeCompare(a.date));
|
||||
}, [fuelLogs]);
|
||||
}, [fuelLogs, maintenanceRecords]);
|
||||
|
||||
const filteredRecords = useMemo(() => {
|
||||
if (recordFilter === 'All') return records;
|
||||
@@ -243,7 +273,7 @@ export const VehicleDetailMobile: React.FC<VehicleDetailMobileProps> = ({
|
||||
<Section title="Vehicle Records">
|
||||
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 1 }}>
|
||||
<Typography variant="body2" color="text.secondary">
|
||||
{isFuelLoading ? 'Loading…' : `${filteredRecords.length} record${filteredRecords.length === 1 ? '' : 's'}`}
|
||||
{(isFuelLoading || isMaintenanceLoading) ? 'Loading…' : `${filteredRecords.length} record${filteredRecords.length === 1 ? '' : 's'}`}
|
||||
</Typography>
|
||||
<FormControl size="small" sx={{ minWidth: 180 }}>
|
||||
<InputLabel id="vehicle-records-filter">Filter</InputLabel>
|
||||
@@ -262,7 +292,7 @@ export const VehicleDetailMobile: React.FC<VehicleDetailMobileProps> = ({
|
||||
</Box>
|
||||
<Card>
|
||||
<CardContent sx={{ p: 0 }}>
|
||||
{isFuelLoading ? (
|
||||
{(isFuelLoading || isMaintenanceLoading) ? (
|
||||
<Box sx={{ p: 2 }}>
|
||||
<Typography color="text.secondary" variant="body2">Loading records…</Typography>
|
||||
</Box>
|
||||
|
||||
Reference in New Issue
Block a user