critical priority low complexity frontend pending frontend specialist Tier 2

Acceptance Criteria

Widget is named `CertificationAlertBanner` and located at `lib/widgets/certification_alert_banner.dart`
Returns `SizedBox.shrink()` (renders nothing) when the current org type is not HLF — determined by reading OrgLabelsProvider or an org-type provider
For HLF orgs, banner displays a human-readable countdown: 'Your certification expires in {N} days' (or equivalent English string)
An 'Enroll' button is present and triggers navigation to the HLF course enrollment screen via the app's router (GoRouter or equivalent deep-link route)
Banner is only shown when the certification is in expiring_soon or expired state — it is suppressed when the cert is fully active (> 30 days remaining) per HLF UX requirements
Banner uses design token colors for background, text, and button — no hardcoded hex values
Widget correctly reads expiry date from the peer mentor data passed as a prop, not from global state
All user-facing strings are drawn from OrgLabelsProvider where configurable, with LabelDefaults as fallback
Widget is covered by at least one widget test asserting it returns SizedBox.shrink for a non-HLF org

Technical Requirements

frameworks
Flutter
Riverpod
data models
PeerMentor (hlf_cert_expiry_date field)
OrgType (enum or string constant)
OrgLabels (label keys for banner text)
performance requirements
OrgLabelsProvider consumption must not cause the parent screen to rebuild — use `ConsumerWidget` with a narrowly scoped `ref.watch` targeting only the org-type field
security requirements
Deep-link route to enrollment screen must be an internal app route — no external URL construction from user data
ui components
Container (banner background with design token color)
Text (countdown message)
AppButton or ElevatedButton (Enroll CTA using design token styles)
Row or Column (layout)

Execution Context

Execution Tier
Tier 2

Tier 2 - 518 tasks

Can start after Tier 1 completes

Implementation Notes

The HLF org detection should rely on a well-defined constant or enum (e.g., `OrgType.hlf`) rather than a string comparison against a magic string. If the project uses a `currentOrgProvider`, read `ref.watch(currentOrgProvider).type == OrgType.hlf`. The 'Enroll' deep-link route path should be defined as a named route constant in the app's router configuration — do not hardcode a path string in the widget. Per the HLF workshop notes, certification expiry is directly tied to the peer mentor's visibility on the local chapter website; this banner is therefore business-critical and must be robustly tested.

Coordinate with the router owner to confirm the enrollment screen route name before implementation.

Testing Requirements

Widget tests: (1) non-HLF org → `find.byType(CertificationAlertBanner)` subtree is empty / SizedBox.shrink, (2) HLF org + cert expiring in 10 days → banner is visible with '10 days' text, (3) HLF org + cert fully active (35 days) → banner is suppressed, (4) HLF org + cert expired → banner is visible with expired messaging, (5) 'Enroll' button tap triggers the expected router navigation call (mock the router). Provide a Riverpod ProviderScope override in each test to inject a fake OrgLabelsProvider with the desired org type.

Component
Certification Alert Banner
ui low
Epic Risks (2)
medium impact medium prob dependency

The org labels system may not yet have label keys defined for peer mentor detail screen terminology (role labels, section headings), requiring additions to the label key registry that must be coordinated with the admin configuration team.

Mitigation & Contingency

Mitigation: Audit existing label keys in the terminology system before starting OrgLabelsProvider integration. Submit required new label keys for admin configuration in parallel with component implementation.

Contingency: If label keys are not available at integration time, use hardcoded English fallbacks with a clear TODO for admin configuration, ensuring the widget renders correctly while keys are being provisioned.

high impact low prob technical

The design token semantic colors (warning, error surface) may not meet WCAG 2.2 AA 4.5:1 contrast ratio when rendered on the app's background surface tokens, requiring design system changes that affect the entire app.

Mitigation & Contingency

Mitigation: Run contrast ratio validation on the token palette during Epic 1 design token implementation. Flag any failing pairs to the design system owner before building UI components that depend on them.

Contingency: If tokens fail contrast requirements, define supplementary high-contrast override tokens specific to alert and badge contexts that meet AA without modifying the global palette.