Implement renewal history timeline widget
epic-certification-management-ui-task-003 — Build the renewal history timeline inside CertificationStatusScreen. Render a vertical timeline list of past renewal events with date labels and cert type tags. Handle empty state gracefully. Consume renewal history from CertificationBLoC loaded state.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 2 - 518 tasks
Can start after Tier 1 completes
Implementation Notes
Keep the timeline rendering logic in a separate RenewalHistoryTimeline stateless widget with a constructor parameter List
The cert type tag can reuse the badge/chip widget used in other parts of the app for consistency. Parse the renewal_history JSONB in the BLoC's state mapper (not in the widget) — the widget should receive a typed List
Testing Requirements
Widget tests: (1) render with a list of 3 RenewalEvent objects — assert all 3 dates and cert type tags are visible; (2) render with empty list — assert 'No renewal history yet' text is visible; (3) render with list of 10 items — assert ListView.builder is used (check widget type) and no overflow errors; (4) verify descending date order by checking the first visible date text matches the most recent event. Use flutter_test's find.text and find.byType. Accessibility test: set textScaler to 1.5 and assert no overflow.
Flutter date pickers have historically poor screen reader support (VoiceOver/TalkBack), which is especially critical for this feature given that HLF peer mentors may have hearing impairment and the broader user base includes people with visual impairments. An inaccessible date picker on RecordRenewalScreen could block coordinator workflows entirely.
Mitigation & Contingency
Mitigation: Evaluate and adopt a third-party accessible date picker widget with verified WCAG 2.2 AA support, or build a custom picker using Flutter Semantics wrappers following the pattern established by the accessibility epic. Test all date pickers against VoiceOver on iOS and TalkBack on Android before UI sign-off.
Contingency: If no accessible date picker is available in time, provide a manual text field fallback for date entry (ISO format with clear labelling) alongside the picker, ensuring keyboard and screen reader users are never blocked.
Course enrolment initiation may redirect the user to the external HLF course portal (deep link or browser), which breaks the in-app flow and may confuse users expecting a seamless experience. The course data structure from Dynamics may also not be available in a machine-readable format in time for the initial release.
Mitigation & Contingency
Mitigation: Agree with HLF on whether enrolment is in-app or via deep link before UI design begins. If course data is not available from Dynamics at launch, design the enrolment prompt as a placeholder CTA that links to the HLF course portal homepage with a clear label indicating the user is leaving the app.
Contingency: Ship the course enrolment prompt as a configurable deep link per org. If Dynamics integration is delayed, the feature flag for the enrolment section can be disabled without affecting the rest of the certification status screen.
Coordinators may attempt to record a renewal with an expiry date earlier than the previous certification's expiry (e.g., data entry error), or attempt to back-date a renewal. Without strict validation, the renewal history timeline could become chronologically inconsistent and mislead peer mentors about their coverage.
Mitigation & Contingency
Mitigation: CertificationManagementService validates that new expiry_date > current date and new issue_date >= previous renewal's issue_date before persisting. Surface validation errors as plain-language messages on RecordRenewalScreen using the error_message_registry pattern.
Contingency: If invalid renewal entries are discovered in production (from pre-validation data), provide a coordinator-only correction flow (edit renewal entry) behind an admin feature flag to fix historical records without requiring a full reset.