07 - Component Library (Transport Module)
- 1. StatTile
- 2. EntityStatusBadge
- 3. ShiftPicker
- 4. RouteStopEditor
- 5. ResourcePicker (vehicle / driver)
- 6. AssignmentTile
- 7. DependencyGuardDialog
- 8. ConflictFieldError
- 8b. NotFoundState
- Composition map (screen -> components)
Module-specific components. Shared primitives (
AppTextField,AppButton,AppSnackbar,AppCard,AppListTile,AppBottomSheet,AppDialog,AppMenu,AppSkeleton,AppEmptyState,AppOfflineBanner,AppFAB,AppChips,AppBadge,AppAvatar,AppErrorState,AppPagination) come from 00-shared/03 and are NOT reproduced here.
1. StatTile
Overview hub tile: count + label + navigate. Props: label, count, icon,
onTap, loading, error, onRetry. Count source: meta.totalItems from
list calls (transport.service.ts:75, 146, 215). Loading -> AppSkeleton block;
error -> inline retry (per-tile independence, 06 §1).
2. EntityStatusBadge
Badge mapping per entity (source: schema enums):
| Entity | Status | Badge tone |
|---|---|---|
Vehicle (vehicle.schema.ts:13-17) | active | success |
| maintenance | warning | |
| inactive | neutral | |
Driver (driver.schema.ts:7-11) | active | success |
| on_leave | warning | |
| inactive | neutral | |
Route (route.schema.ts:7-10) | active | success |
| inactive | neutral | |
Assignment (route-assignment.schema.ts:7-10) | active | success |
| inactive | neutral |
3. ShiftPicker
Segmented control for morning | evening | both - hard IsEnum values from
assign-route.dto.ts:13-15. Displays selected shift chip on assignment tiles
("AM", "PM", "AM+PM").
4. RouteStopEditor
Ordered stop list editor used in route create/update (06 §10):
- Rows: drag handle + text field (stop name) + up/down buttons + delete.
- Ordering: client maintains
order: 1..N; submitted as array of{name, order}(create-route.dto.ts:11-19,route.schema.ts:23-24). - API:
onChanged(List<RouteStopDraft>); dirty state triggers save-enable. - a11y: explicit up/down buttons; drag is enhancement.
- Cap: 20 stops client-side (no server limit).
5. ResourcePicker (vehicle / driver)
Searchable dropdown over cached list data (vehicle/driver list from
GET /transport/vehicles|drivers, transport.controller.ts:36-40, 96-100):
- Displays
plateNumber/firstName lastName(+ subtitlemodel/licenseNumber). - Emits selected
idor null (clear); on submit, null -> field omitted (create-route.dto.ts:41-49). - Empty cache -> fetches page 1; refresh action.
6. AssignmentTile
AppListTile wrapper for an assignment (used in 06 §12): title = populated
route name, subtitle = ShiftPicker chip + stopName, trailing status badge +
AppMenu (Remove). Data: RouteAssignment with routeId populated
(route-assignment.repository.ts:20-24).
7. DependencyGuardDialog
Delete-confirmation variant for 409 conflicts (transport.service.ts:94-99, 168-171, 241-246): shows the server message, a "View related" action when
mappable (vehicle/driver -> route list; route -> student assignments note),
and Cancel. Never retries blindly (conflict is deterministic).
8. ConflictFieldError
Inline field error for duplicate checks, per source:
| Field | Source guard | Server message |
|---|---|---|
| vehicle.plateNumber | transport.service.ts:38-45 | Vehicle "<plate>" already exists. |
| route.name | transport.service.ts:113-116 | Route "<name>" already exists. |
| driver.licenseNumber | transport.service.ts:177-184 | Driver with license "<n>" already exists. |
| driver.phone | transport.service.ts:185-190 | Driver with phone "<p>" already exists. |
| assign (route+student) | transport.service.ts:252-258 | Student already assigned to this route. |
Props: field, message, action? (e.g. "View existing" for assignment).
8b. NotFoundState
Detail-screen 404 rendering (transport.service.ts:80, 151, 220): icon, "Not
found", back button; distinct from generic AppErrorState copy.
Composition map (screen -> components)
| Screen (05) | Components |
|---|---|
| 1 Overview | StatTile x3, AppCard, AppListTile, AppFAB |
| 2-3 Vehicle list/detail | EntityStatusBadge, DependencyGuardDialog, AppPagination |
| 4 Vehicle form | ConflictFieldError, AppTextField/DateField |
| 5-6 Driver list/detail | EntityStatusBadge, AppAvatar, DependencyGuardDialog |
| 7 Driver form | ConflictFieldError, DateField |
| 8-9 Route list/detail | EntityStatusBadge, ResourcePicker (read) |
| 10 Route editor | RouteStopEditor, ResourcePicker, ConflictFieldError |
| 11 Assign sheet | ShiftPicker, ResourcePicker (route), StudentPicker (students module), ConflictFieldError |
| 12 Student assignments | AssignmentTile, ShiftPicker, AppEmptyState |
| 13-15 planned | map/attendance/fee components (planned) |