Compose ContactListScreen with mock data and child widgets
epic-contact-list-management-ui-components-task-008 — Build the ContactListScreen as a role-aware Flutter screen that renders ContactCardWidget items in a scrollable ListView. Integrate ContactSearchBar at the top and conditionally render ContactViewSwitcher below it based on the active organization's feature flags. Pass mock data from task-001 fixtures to render a functional UI without live providers. Implement role-specific list filtering logic: coordinators see all contacts, peer mentors see only their assigned contacts, org admins see full roster.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 2 - 518 tasks
Can start after Tier 1 completes
Implementation Notes
Structure ContactListScreen as a ConsumerWidget (Riverpod) that reads three providers: currentUserRoleProvider, orgFeatureFlagsProvider, and orgLabelsProvider — all of which return mock data at this stage. Keep the role-filtering and search-filtering logic in a separate pure function (List
For the ListView, pass the filtered list to ListView.builder's itemCount and itemBuilder — never use a where(...).toList() inside itemBuilder (compute the filtered list once outside the builder). When connecting to real Supabase providers in a later task, the filtering logic should migrate to the repository layer with Supabase RLS as the authoritative enforcement — add a TODO comment marking this handoff point.
Testing Requirements
Write flutter_test widget tests: (1) render with coordinator role mock data and assert all contacts are visible; (2) render with peer mentor role and assert only assigned contacts are visible; (3) enter a search query and assert the list filters to matching contacts only; (4) enter a query with no matches and assert the empty state widget is shown; (5) render with an org that has peerMentorView: false and assert ContactViewSwitcher is absent; (6) render with an org that has peerMentorView: true and assert ContactViewSwitcher is present; (7) switch ContactViewSwitcher to 'Peer Mentors' and assert PeerMentorCardWidget items are rendered instead of ContactCardWidget items; (8) tap a ContactCardWidget and assert the correct navigation event is fired (mock the router or use a navigation observer). Use pumpWidget with a ProviderScope wrapping mock providers for Riverpod-based state.
Design token color values used in role badges, certification status indicators, and availability chips may not meet the WCAG 2.2 AA contrast ratio of 4.5:1 when rendered against card backgrounds, requiring rework after accessibility review and potentially blocking acceptance sign-off.
Mitigation & Contingency
Mitigation: Run the contrast-ratio-validator on every new token combination during widget development. Enforce the CI accessibility lint runner on all PRs touching visualization components, and validate against the contrast-safe-color-palette before finalizing card designs.
Contingency: If contrast failures are found late, adjust token values in the design token theme centrally — since all widgets consume design tokens rather than hardcoded colors, all affected widgets will be corrected by a single token update without per-widget changes.
The ContactViewSwitcher is required for Barnekreftforeningen but must not appear for other organizations. If the organization labels provider does not yet expose a reliable feature flag for this widget, it may render universally or be conditionally hidden in an inconsistent way, breaking the role-specific layout contract.
Mitigation & Contingency
Mitigation: Implement view switcher visibility as a constructor parameter on ContactListScreen injected from a provider, defaulting to hidden. Document the integration point for the org labels provider so the flag can be wired without changing the widget's API.
Contingency: If org labels integration is delayed beyond this epic, use a feature flag constant keyed to the Barnekreftforeningen organization ID as a temporary gate, with a tracked issue to replace it with the runtime labels provider before general release.