Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

07 — Component Library (Leave Module)

Module-specific widgets. Shared primitives (AppCard, AppChips, AppBadge, AppListTile, AppButton, AppBottomSheet, AppMenu, AppSnackbar, AppEmptyState, AppSkeleton, DatePicker, TimePicker, SegmentedButton) are owned by 00-shared/03; this file only defines leave-specific compositions on top of them. Tokens: 00-shared/02.


1. StatusChip — leave request status

PropValue
Inputstatus: 'pending' | 'approved' | 'rejected' | 'cancelled'
Rendersmall pill: dot + label (see 11_Design_System_Mapping for colors)
Statusespending (tertiary, filled dot), approved (success), rejected (error), cancelled (neutral/outlined — unreachable today, leave-request.schema.ts:11, rendered defensively)
Semanticslabel: "Status: pending"; never color-only
Testsunit: renders each status; snapshot

2. BalanceCard — one leave type balance row

[CL] Casual Leave            8 / 12
    ├─ used 4 · carried 0
    └─ [progress 66%]
PropValue
InputLeaveBalanceEntry (leave.service.ts:66-74)
Variantscarry-forward line shown only when carryForward
Behaviorprogress = daysUsed / daysPerYear clamped 0–1; over-entitlement clamps bar at 1 with error color
a11ycombined Semantics label "Casual Leave, 8 of 12 days remaining"

3. RequestTile — list row for a request

  • Data: LeaveRequest fields used — leaveTypeId (resolved to code via types cache), startDate, endDate, daysRequested, reason, status, decisionNote (leave-request.schema.ts:16-48).
  • Layout: leading AppAvatar-style code badge, title <code> <range> · <days>d, subtitle reason (2-line), trailing StatusChip.
  • Slots: onTap, optional trailingActions (admin approve/reject menu).
  • Variants: ApprovalTile (adds requester line + balance hint (proposed) + Approve/Reject buttons).

4. SubstitutionTile — substitution list row

  • Data: substitution.schema.ts:14-47classId, subjectId, date, startTime, endTime, notes, status.
  • Layout: title <subject> · <class>, subtitle <date> <startTime>–<endTime>, trailing status chip (only assigned reachable, leave.service.ts:261).
  • Resolve class/subject names via their modules' caches (forward-looking).

5. ApprovalActionSheet — decision UI

  • Opens from ApprovalTile menu or row action.
  • Segmented choice approve | reject (leave-decision.dto.ts:4-7); when reject → AppTextField note (optional, :14-17).
  • Confirm → AppButton "Confirm approve/reject" → callback; caller executes PATCH /leave/requests/:id/approve.
  • Shows 409 error inline (already decided / insufficient balance / self-decision, leave.service.ts:175-189).

6. LeaveTypeCard — type row (types admin)

  • Data: leave-type.schema.ts:9-25code, name, daysPerYear, carryForward, maxCarryForward, isDefault (default types badge "Default").
  • Sub-line: "Carries forward up to 60 days" only when carryForward.

7. CalendarDayCell + MonthGrid

  • Cell: date number, up to 3 mini avatars, +N overflow; states: today (outlined), leave-day (tinted), selected (filled).
  • Tap → callback with date; parent shows day detail list.
  • Data source is GET /leave/calendar payload (approved requests, leave.service.ts:282-296).

8. Composition rules

  • Every component is stateless; state lives in Cubits (13_State_Management.md).
  • No business logic in widgets (dates/counts computed in models/services).
  • All components accept theme from AppTheme only; no hardcoded colors (tokens per 00-shared/02).
  • Placeholder resolution (type code ↔ name, teacher id ↔ name) via injected lookup services, never in-widget.

9. Inventory vs shared

Shared (00-shared/03)Leave-specific (this file)
AppCard, AppListTile, AppChips, AppBadge, AppButton, AppMenu, AppBottomSheet, AppSnackbar, AppEmptyState, AppSkeleton, DatePicker, TimePicker, SegmentedButton, RefreshIndicatorStatusChip, BalanceCard, RequestTile/ApprovalTile, SubstitutionTile, ApprovalActionSheet, LeaveTypeCard, CalendarDayCell, MonthGrid