Overview
Maintenance today only exists as a tab inside a single asset's detail page. Teams need the global view: everything scheduled/in-progress/overdue across all assets — the core screen of CMMS tools like UpKeep and Fiix.
What to Build
A /maintenance page under frontend/app/(dashboard)/:
- Board view: columns for SCHEDULED / IN_PROGRESS / COMPLETED / CANCELLED (dnd-kit is already installed for drag-to-change-status)
- Calendar view toggle: month grid plotting records by
scheduledDate
- Each card: asset name + link, maintenance type badge, scheduled date, cost
- Filters: type (PREVENTIVE/CORRECTIVE/SCHEDULED), department, date range
- "New maintenance" modal (asset picker + the fields from the existing per-asset form)
- Needs a small backend addition: list maintenance across assets (
GET /api/maintenance?status=&from=&to=) — coordinate with [BE-11] or file the endpoint as part of this issue's PR
Conventions to Follow
- API calls: add a typed client in
frontend/lib/api/ (see frontend/lib/api/assets.ts for the pattern) — never call axios directly from components
- Data fetching: TanStack Query hooks in
frontend/lib/query/hooks/ with keys registered in frontend/lib/query/keys.ts
- UI: reuse
frontend/components/ui/ (button, input, confirm-dialog, toast) and the badge/modal patterns in frontend/components/assets/
- Route goes under
frontend/app/(dashboard)/ and gets a sidebar entry in frontend/components/layout/sidebar.tsx
- Forms: React Hook Form + Zod resolver, matching the existing create-asset modal
References
- Blocked by [BE-11]
- Per-asset maintenance UI already exists in
frontend/app/(dashboard)/assets/[id]/page.tsx — reuse its types and form
Acceptance Criteria
Overview
Maintenance today only exists as a tab inside a single asset's detail page. Teams need the global view: everything scheduled/in-progress/overdue across all assets — the core screen of CMMS tools like UpKeep and Fiix.
What to Build
A
/maintenancepage underfrontend/app/(dashboard)/:scheduledDateGET /api/maintenance?status=&from=&to=) — coordinate with [BE-11] or file the endpoint as part of this issue's PRConventions to Follow
frontend/lib/api/(seefrontend/lib/api/assets.tsfor the pattern) — never call axios directly from componentsfrontend/lib/query/hooks/with keys registered infrontend/lib/query/keys.tsfrontend/components/ui/(button, input, confirm-dialog, toast) and the badge/modal patterns infrontend/components/assets/frontend/app/(dashboard)/and gets a sidebar entry infrontend/components/layout/sidebar.tsxReferences
frontend/app/(dashboard)/assets/[id]/page.tsx— reuse its types and formAcceptance Criteria