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 (CRM Module)

Module-specific widgets on top of the shared component library (00-shared/03_Component_Library.md). Shared atoms (AppButton, AppCard, AppTextField, AppChips, AppBadge, AppAvatar, AppTimeline, AppDialog, AppBottomSheet, AppSkeleton, AppEmptyState, AppFAB, AppDatePicker, AppSegmentedButton) are reused as-is; only CRM-specific compositions are specified here. All colors from 00-shared/02_Design_Tokens.md (proposed until designer sign-off).


1. LeadStatusChip (status badge)

PropValues
statusnew|contacted|qualified|converted|closed (lead.schema.ts:7-13)
StatusColor (semantic)IconLabel key
newcolor.secondaryContainerinboxcrm.status.new
contactedcolor.primaryContainercallcrm.status.contacted
qualifiedcolor.tertiaryContainerverifiedcrm.status.qualified
convertedsuccess containercheck_circlecrm.status.converted
closedsurface-variantblockcrm.status.closed
  • Icon + text, never color-only (00-shared/09).
  • Disabled variant renders grayed + reduced opacity for non-actionable chips.

2. LeadSourceIcon

sourceiconlabel key
websitelanguagecrm.source.website
referralgroupcrm.source.referral
walk_instorefrontcrm.source.walk_in
phonephonecrm.source.phone
campaigncampaigncrm.source.campaign
othermore_horizcrm.source.other

Sizes: 16 dp inline (list rows), 20 dp in detail header.

3. LeadListTile (S1 row)

Composition: AppAvatar(40, initials) · column(name, subtitle) · trailing (LeadStatusChip + LeadSourceIcon). Subtitle auto-composed: email · next follow-up {date} / overdue variant {date} overdue in color.error. Subtitle logic in a pure function followUpSummary(lead) — unit-tested.

4. FollowUpCard (S2 timeline item)

note (body), meta row: scheduledAt (formatted, DateTime.toDisplayDate), "completed" check when completedAt set, "by {createdBy}". Data: lead.schema.ts:24-39. Variants: upcoming (default), due today (primary border), overdue (error border), completed (muted + check).

5. ConvertDialog (S4)

AppDialog wrapper with pre-condition list + destructive-primary confirm. Props: lead, canConvert (client rule check per crm.service.ts:118-149), onConvert. Fixed copy from 06 §S4.

6. StatusBadge (admission, S5/S6)

statuscolorlabel key
draft / submittedsecondaryContainercrm.adm.status.draft|submitted
documents_pendingtertiaryContainercrm.adm.status.documents_pending
interview_scheduledprimaryContainercrm.adm.status.interview_scheduled
under_reviewsecondaryContainercrm.adm.status.under_review
approvedsuccess containercrm.adm.status.approved
rejectederror containercrm.adm.status.rejected
waitlistedsurface-variantcrm.adm.status.waitlisted
convertedsuccess container + checkcrm.adm.status.converted

Statuses: admission.schema.ts:7-17.

7. AdmissionListTile (S5 row)

AppAvatar(40) · name · email · submitted {date} · trailing StatusBadge. Optional document hint line: "docs: 2/3" (count from documents array; required-set knowledge (planned)).

8. WorkflowTimeline (S6)

Read-only vertical AppTimeline over workflow[] (admission.schema.ts:52-67): each node "statusA → statusB", approver name, comment (italic), at timestamp. Rendered newest-first. Never editable.

9. DocumentCard (S6)

Icon by type (tc → description, marksheet → table_chart, certificate → workspaces, photo → photo, other → attach_file — admission.schema.ts:27-33), filename, meta "by {uploadedBy} · {uploadedAt}". Tap → open file (fileId via storage layer; no download endpoint in this module — (planned)).

10. InterviewCard (S6)

scheduledAt (prominent), mode chip (online/offline), panel chips (names), feedback body. Empty variant: "No interview scheduled" + Schedule action. Data: admission.schema.ts:69-81.

11. FunnelStatCard (S5 header)

Title (label key), big number, sub-label. Variants: total, per-status count, and conversionRate ("N%") from GET /crm/admissions/stats (admission.service.ts:227-237). Loading → AppSkeleton box; error → "—" with retry icon.

12. CampaignCard (S10 row)

name (title), type icon + label, StatusBadge (campaign enum — campaign.schema.ts:7-12), date range, metrics line leadsGenerated · converted (campaign.schema.ts:45-52); metrics absent → "—". Tap → read-only info sheet (no detail endpoint).

13. FilterChipRow (S1/S5)

Horizontal SingleChildScrollView of AppChips (filter chips): first = "All", selected chip emphasized. Wraps the shared status-filter interaction used by both lists; emits onChanged(value|null).

14. FollowUpComposer (S2 sheet)

AppTextField multiline (note*), AppDatePicker datetime (scheduledAt*), optional completedAt toggle (create-follow-up.dto.ts:4-17). Submit Add follow-up.


Composition rules

  • Module widgets never fetch data; they render models passed by cubits (00-shared/06 §2).
  • All labels via i18n keys (crm.* namespace) — server text only for business 4xx fallback (00-shared/11 §9).
  • Goldens required for: LeadStatusChip (6 statuses × light/dark), StatusBadge (9), WorkflowTimeline, LeadListTile, FunnelStatCard.