high priority medium complexity frontend pending frontend specialist Tier 0

Acceptance Criteria

RecordRenewalScreen renders a cert type selector dropdown populated with all valid certification types from CertificationBLoC state
New issue date picker is visible, tappable, and opens a modal/bottom sheet date selection UI
New expiry date picker is visible, tappable, and opens a modal/bottom sheet date selection UI
All three form fields expose Semantics widgets with descriptive labels for VoiceOver/TalkBack screen reader compatibility
Cert type dropdown, issue date, and expiry date fields are keyboard-navigable in logical top-to-bottom focus order
All form fields use design token spacing, typography, and color values — no hardcoded style values
BLoC Consumer wraps the form and rebuilds correctly when CertificationBLoC state changes
RecordRenewalScreen is reachable via named route and accepts a mentor/certification identifier as route argument
Screen displays a submit button (disabled by default until state is valid per task-006)
Layout is responsive and does not overflow on screens narrower than 320px logical pixels
All date picker widgets meet WCAG 2.2 AA minimum touch target size (48x48dp)

Technical Requirements

frameworks
Flutter
BLoC
data models
Certification
CertificationType
performance requirements
Screen must render initial state within one frame after route push (no visible jank)
Date picker open/close animation must complete within 300ms
security requirements
Route argument (mentor/cert ID) must be validated before being passed to BLoC — reject null/empty values with safe fallback
ui components
DropdownButtonFormField or custom AppDropdown for cert type
showDatePicker (Material) or custom accessible date picker bottom sheet
AppTextField-style wrapper for date display fields
AppButton (submit, disabled state)
Semantics widget wrappers on all interactive elements

Execution Context

Execution Tier
Tier 0

Tier 0 - 440 tasks

Implementation Notes

Use BlocConsumer or BlocBuilder wrapping the entire form body. Initialise form field values from BLoC state on first build, not from local StatefulWidget state, to keep a single source of truth. For date pickers, wrap showDatePicker in a helper method that also dispatches the appropriate BLoC event on date selection — avoid setting local variables. Apply design tokens via Theme.of(context) extension or a token accessor class.

For screen reader accessibility, wrap each date display field in a Semantics widget with label, hint, and onTap; do not rely solely on the Material date picker's built-in semantics. Ensure the cert type list is loaded lazily from BLoC state so the dropdown does not show stale data on re-entry.

Testing Requirements

Write widget tests using flutter_test. Test: (1) screen renders all three form fields; (2) cert type dropdown shows correct options from mocked BLoC state; (3) tapping issue/expiry date fields triggers date picker; (4) Semantics tree contains labels for all three fields (use SemanticsController or tester.getSemantics); (5) BLoC Consumer rebuilds when a mock state is emitted. Use bloc_test MockBloc. Aim for 100% widget render coverage on this screen.

Component
Record Renewal Screen
ui low
Epic Risks (3)
high impact medium prob technical

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.

medium impact high prob scope

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.

medium impact medium prob scope

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.