Compose AccountingExportScreen UI layout
epic-accounting-system-export-ui-task-006 — Assemble the full AccountingExportScreen widget that hosts ExportDateRangePicker, a trigger button (visible only to coordinator and org admin roles), ExportConfirmationDialog (shown as modal bottom sheet), and ExportHistoryPanel in a scrollable column. Read exporter type (Xledger vs Dynamics) from BLoC ConfigLoaded state and display an org-specific label. Show a role-guard widget that hides the export action for peer mentor role. Apply design token colours and spacing. Ensure the screen passes WCAG 2.2 AA at all interactive elements.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 3 - 413 tasks
Can start after Tier 2 completes
Implementation Notes
Use BlocConsumer splitting the builder (UI rebuild) and listener (side effects like dialogs and snackbars) cleanly β do not show dialogs inside the builder. Dispatch LoadConfig in the BlocProvider's create callback (not in initState) to keep the widget stateless. Use Scaffold with a SingleChildScrollView wrapping a Column for the main layout β avoid ListView for this screen since content length is bounded. The ExportConfirmationDialog should be shown with showDialog() inside the BlocListener β pass the DuplicateWarning state's data as constructor arguments to the dialog.
After ExportSuccess, call context.read
Testing Requirements
Widget tests: pump AccountingExportScreen with a mock BLoC in each state and verify: (1) Correct widgets rendered per state; (2) Trigger button label matches exporterType; (3) Peer mentor role renders only history panel; (4) BlocListener shows dialog on DuplicateWarning state; (5) Success snackbar appears on ExportSuccess state. Golden tests: render screen in ConfigLoaded state for coordinator and peer mentor roles. Accessibility test: verify no missing Semantics labels using the flutter_test semantics API; verify trigger button has correct role and label. Responsive test: set MediaQuery width to 320px and verify no RenderFlex overflow errors.
Integration test: full flow from LoadConfig β InitiateExport β ExportSuccess using a fake BLoC that progresses through all states. Target 85%+ widget test coverage.
Export operations may take several seconds, and the UI must handle all intermediate states (loading, partial success, failure, duplicate warning) without leaving the coordinator on a blank or unresponsive screen. Missing state handling causes confusion and potentially double-submissions.
Mitigation & Contingency
Mitigation: Design the BLoC state machine with explicit states for each transition before writing any widget code: ExportIdle, ExportDuplicateWarning, ExportInProgress, ExportSuccess, ExportPartialSuccess, ExportFailed. Each state maps to a distinct UI. Widget tests cover all states.
Contingency: If a loading state is missed in production, surface a generic error state with a retry action rather than leaving the UI stuck. Add a timeout on the Edge Function call (default 30 seconds) that transitions to ExportFailed with a user-readable message.
The custom Export Date Range Picker may not be fully navigable with VoiceOver if the underlying Flutter date widgets do not expose the correct semantic tree. This is a critical accessibility failure for Blindeforbundet users who rely on screen readers.
Mitigation & Contingency
Mitigation: Use Flutter's built-in DateRangePicker as the base and wrap with explicit Semantics nodes for start and end labels. Test with VoiceOver on a physical iOS device as part of the definition of done for this component. Reference the existing AccessibilityTestHarness pattern used elsewhere in the app.
Contingency: If the custom picker fails accessibility audit, replace it with two independent DatePicker fields (start and end) using Flutter's standard accessible date input, which has broader VoiceOver support than range variants.