The Schedules tab on the Maintenance page is always empty despite schedules existing in the database (e.g., 30 schedules created from manual OCR extraction). The UI components are fully implemented but the data query never executes.
Root Cause
MaintenancePage.tsx (line 20) calls useMaintenanceRecords()without a vehicleId parameter:
// BUG: No vehicleId passed
const{records,schedules,isRecordsLoading,isSchedulesLoading,...}=useMaintenanceRecords();
The schedules query in useMaintenanceRecords.ts has enabled: !!vehicleId -- when vehicleId is undefined, the query never runs. The list stays empty.
Additionally, the creation hook (useCreateSchedulesFromExtraction) invalidates ['maintenanceSchedules', vehicleId] with the actual vehicleId, but the page-level query uses ['maintenanceSchedules', undefined] -- the keys don't match, so invalidation has no effect.
Requirements
Wire vehicleId from vehicle selection/context into useMaintenanceRecords(vehicleId)
Ensure query invalidation keys match between creation and list fetching
Both Records and Schedules tabs need vehicle context to display data
Schedules tab displays all schedules for the selected vehicle
Records tab displays all records for the selected vehicle
Due soon and overdue indicators display correctly
After OCR creates schedules, navigating to Schedules tab shows them
Edit and delete actions work on displayed schedules
Works on mobile (320px, 768px) and desktop (1920px) viewports
Relates to #129
## Summary
The Schedules tab on the Maintenance page is always empty despite schedules existing in the database (e.g., 30 schedules created from manual OCR extraction). The UI components are fully implemented but the data query never executes.
## Root Cause
`MaintenancePage.tsx` (line 20) calls `useMaintenanceRecords()` **without a vehicleId parameter**:
```typescript
// BUG: No vehicleId passed
const { records, schedules, isRecordsLoading, isSchedulesLoading, ... } = useMaintenanceRecords();
```
The schedules query in `useMaintenanceRecords.ts` has `enabled: !!vehicleId` -- when vehicleId is undefined, the query never runs. The list stays empty.
Additionally, the creation hook (`useCreateSchedulesFromExtraction`) invalidates `['maintenanceSchedules', vehicleId]` with the actual vehicleId, but the page-level query uses `['maintenanceSchedules', undefined]` -- the keys don't match, so invalidation has no effect.
## Requirements
- Wire vehicleId from vehicle selection/context into `useMaintenanceRecords(vehicleId)`
- Ensure query invalidation keys match between creation and list fetching
- Both Records and Schedules tabs need vehicle context to display data
- Follow existing patterns (e.g., FuelLogsPage uses `useFuelLogs(vehicleId)`)
- Mobile + desktop must work
## Acceptance Criteria
- [ ] Schedules tab displays all schedules for the selected vehicle
- [ ] Records tab displays all records for the selected vehicle
- [ ] Due soon and overdue indicators display correctly
- [ ] After OCR creates schedules, navigating to Schedules tab shows them
- [ ] Edit and delete actions work on displayed schedules
- [ ] Works on mobile (320px, 768px) and desktop (1920px) viewports
egullickson
changed title from feat: Scheduled maintenance list UI with CRUD and due status (#129) to fix: Scheduled maintenance list not displaying schedules (#129)2026-02-13 01:52:18 +00:00
MaintenancePage.tsx and MaintenanceMobileScreen.tsx both call useMaintenanceRecords() without a vehicleId. The hook's schedules query has enabled: !!vehicleId, so it never executes. Records work because the hook falls back to getRecords() (all records), but schedules require vehicleId because the backend only has GET /maintenance/schedules/vehicle/:vehicleId (no "get all schedules" endpoint).
Fix Strategy
Add a vehicle selector to the Maintenance page (matching the FuelLogs pattern) and pass the selected vehicleId to the hook. This is a frontend-only fix -- no backend changes needed.
Milestone 1: Wire vehicleId into MaintenancePage and MaintenanceMobileScreen
Verify the hook already accepts vehicleId?: string and passes it correctly
No changes expected -- the hook is already correctly designed, just not being called with a vehicleId
Expected Behavior After Fix
User navigates to Maintenance page
Vehicle selector shows at top, auto-selects first vehicle
Records tab shows records for selected vehicle (was already partially working for "all")
Schedules tab shows all schedules for selected vehicle (currently broken)
Due soon / overdue indicators display correctly
Changing vehicle selector updates both tabs
After OCR creates schedules, returning to Maintenance page with that vehicle selected shows the new schedules
Out of Scope
No backend changes (API already supports this)
No changes to schedule CRUD components (already working)
No changes to OCR extraction flow
No new VehicleSelector shared component (use inline Select matching existing form pattern)
Risk Assessment
Low risk: Small, targeted change to 2 page files
No API changes: Backend already supports vehicleId-scoped queries
Pattern proven: FuelLogs uses the same approach successfully
Verdict: AWAITING_REVIEW | Next: User approval, then execution
## Plan: Fix scheduled maintenance list not displaying schedules
**Phase**: Planning | **Agent**: Planner | **Status**: AWAITING_REVIEW
### Root Cause Analysis
`MaintenancePage.tsx` and `MaintenanceMobileScreen.tsx` both call `useMaintenanceRecords()` without a `vehicleId`. The hook's schedules query has `enabled: !!vehicleId`, so it never executes. Records work because the hook falls back to `getRecords()` (all records), but schedules require `vehicleId` because the backend only has `GET /maintenance/schedules/vehicle/:vehicleId` (no "get all schedules" endpoint).
### Fix Strategy
Add a vehicle selector to the Maintenance page (matching the FuelLogs pattern) and pass the selected vehicleId to the hook. This is a frontend-only fix -- no backend changes needed.
### Milestone 1: Wire vehicleId into MaintenancePage and MaintenanceMobileScreen
**Files to modify (3):**
1. **`frontend/src/features/maintenance/pages/MaintenancePage.tsx`**
- Add `selectedVehicleId` state (useState)
- Add a vehicle selector at the top of the page (use `useVehicles()` hook + MUI Select, matching the inline pattern already used in MaintenanceRecordForm)
- Pass `selectedVehicleId` to `useMaintenanceRecords(selectedVehicleId)`
- Auto-select first vehicle if user has vehicles and none selected
- Pass `selectedVehicleId` to forms as default vehicle (optional UX improvement)
2. **`frontend/src/features/maintenance/mobile/MaintenanceMobileScreen.tsx`**
- Same changes as MaintenancePage: add vehicle selector state, add selector UI, pass to hook
- Ensure vehicle selector is mobile-friendly (44px touch targets, full-width)
3. **`frontend/src/features/maintenance/hooks/useMaintenanceRecords.ts`** (verification only)
- Verify the hook already accepts `vehicleId?: string` and passes it correctly
- No changes expected -- the hook is already correctly designed, just not being called with a vehicleId
### Expected Behavior After Fix
1. User navigates to Maintenance page
2. Vehicle selector shows at top, auto-selects first vehicle
3. Records tab shows records for selected vehicle (was already partially working for "all")
4. Schedules tab shows all schedules for selected vehicle (currently broken)
5. Due soon / overdue indicators display correctly
6. Changing vehicle selector updates both tabs
7. After OCR creates schedules, returning to Maintenance page with that vehicle selected shows the new schedules
### Out of Scope
- No backend changes (API already supports this)
- No changes to schedule CRUD components (already working)
- No changes to OCR extraction flow
- No new VehicleSelector shared component (use inline Select matching existing form pattern)
### Risk Assessment
- **Low risk**: Small, targeted change to 2 page files
- **No API changes**: Backend already supports vehicleId-scoped queries
- **Pattern proven**: FuelLogs uses the same approach successfully
*Verdict*: AWAITING_REVIEW | *Next*: User approval, then execution
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Relates to #129
Summary
The Schedules tab on the Maintenance page is always empty despite schedules existing in the database (e.g., 30 schedules created from manual OCR extraction). The UI components are fully implemented but the data query never executes.
Root Cause
MaintenancePage.tsx(line 20) callsuseMaintenanceRecords()without a vehicleId parameter:The schedules query in
useMaintenanceRecords.tshasenabled: !!vehicleId-- when vehicleId is undefined, the query never runs. The list stays empty.Additionally, the creation hook (
useCreateSchedulesFromExtraction) invalidates['maintenanceSchedules', vehicleId]with the actual vehicleId, but the page-level query uses['maintenanceSchedules', undefined]-- the keys don't match, so invalidation has no effect.Requirements
useMaintenanceRecords(vehicleId)useFuelLogs(vehicleId))Acceptance Criteria
feat: Scheduled maintenance list UI with CRUD and due status (#129)to fix: Scheduled maintenance list not displaying schedules (#129)Plan: Fix scheduled maintenance list not displaying schedules
Phase: Planning | Agent: Planner | Status: AWAITING_REVIEW
Root Cause Analysis
MaintenancePage.tsxandMaintenanceMobileScreen.tsxboth calluseMaintenanceRecords()without avehicleId. The hook's schedules query hasenabled: !!vehicleId, so it never executes. Records work because the hook falls back togetRecords()(all records), but schedules requirevehicleIdbecause the backend only hasGET /maintenance/schedules/vehicle/:vehicleId(no "get all schedules" endpoint).Fix Strategy
Add a vehicle selector to the Maintenance page (matching the FuelLogs pattern) and pass the selected vehicleId to the hook. This is a frontend-only fix -- no backend changes needed.
Milestone 1: Wire vehicleId into MaintenancePage and MaintenanceMobileScreen
Files to modify (3):
frontend/src/features/maintenance/pages/MaintenancePage.tsxselectedVehicleIdstate (useState)useVehicles()hook + MUI Select, matching the inline pattern already used in MaintenanceRecordForm)selectedVehicleIdtouseMaintenanceRecords(selectedVehicleId)selectedVehicleIdto forms as default vehicle (optional UX improvement)frontend/src/features/maintenance/mobile/MaintenanceMobileScreen.tsxfrontend/src/features/maintenance/hooks/useMaintenanceRecords.ts(verification only)vehicleId?: stringand passes it correctlyExpected Behavior After Fix
Out of Scope
Risk Assessment
Verdict: AWAITING_REVIEW | Next: User approval, then execution
Milestone 1: Wire vehicleId into MaintenancePage and MaintenanceMobileScreen
Phase: Execution | Agent: Developer | Status: PASS
Changes Made
frontend/src/features/maintenance/pages/MaintenancePage.tsxuseVehicles()hook andselectedVehicleIdstateselectedVehicleIdtouseMaintenanceRecords(selectedVehicleId || undefined)['maintenanceRecords', 'all']refetch key in delete handler to use broad['maintenanceRecords']prefixfrontend/src/features/maintenance/mobile/MaintenanceMobileScreen.tsxfrontend/src/features/maintenance/hooks/useMaintenanceRecords.ts(verified, no changes needed)vehicleId?: stringand gates schedules query onenabled: !!vehicleIdQuery Invalidation Alignment Verified
useMaintenanceRecordsmutations['maintenanceSchedules'](broad)useCreateSchedulesFromExtraction['maintenanceSchedules', vehicleId]['maintenanceRecords'](broad, fixed)Quality Checks
Commit
6bb2c57-fix: Wire vehicleId into maintenance page to display schedules (refs #148)Verdict: PASS | Next: PR creation and final review