high priority low complexity frontend pending frontend specialist Tier 1

Acceptance Criteria

Dialog displays all four summary fields: (1) export scope (org name or chapter name as a string), (2) selected period formatted as human-readable date range (e.g., 'Jan 1 – Jun 30, 2025'), (3) estimated record count as an integer with unit label (e.g., '47 activities'), (4) chosen format name and file extension
Dialog has a primary 'Confirm export' button and a secondary 'Cancel' button; both are accessible via keyboard/switch-access
Tapping Confirm fires onConfirmed() callback and closes the dialog
Tapping Cancel or dismissing via back gesture fires onCancelled() callback and closes the dialog without side effects
All typography (heading, body, labels) uses design token text styles exclusively — no inline TextStyle()
All spacing uses design token spacing constants — no hardcoded pixel values
The dialog is announced by screen readers as a dialog/alertdialog semantic role so VoiceOver and TalkBack move focus into it automatically on open
First focus on open lands on the dialog title or first informational element — not on a button
Dialog renders without overflow at font scale 2.0× on a 320 dp wide screen
Widget test confirms all four data fields render with provided values and correct callbacks fire

Technical Requirements

frameworks
Flutter
data models
BufdirExportSummary (scope, period: DateTimeRange, estimatedCount: int, format: BufdirExportFormat)
performance requirements
Dialog is a stateless widget; no async in build path
security requirements
Estimated record count is a UI hint only and must not be used as an authoritative count for compliance reporting — display a disclaimer if count exceeds 0
ui components
BufdirExportConfirmationDialog (stateless AlertDialog wrapper)
ExportSummaryRow (label + value row widget)
Primary AppButton (Confirm)
Secondary AppButton (Cancel)

Execution Context

Execution Tier
Tier 1

Tier 1 - 540 tasks

Can start after Tier 0 completes

Implementation Notes

Implement as a stateless widget wrapping Flutter's AlertDialog with a custom content widget rather than the default contentText. Pass a BufdirExportSummary value object as the single data parameter to keep the API clean. Format the date range using a DateFormat helper that respects locale — define the format string as a constant (e.g., 'MMM d – MMM d, yyyy' or 'd. MMM – d.

MMM yyyy' for Norwegian). Use ExportSummaryRow as a tiny Row(label, spacer, value) widget using design token text styles AppTextStyles.bodyMedium and AppTextStyles.labelSmall. Wrap the entire AlertDialog in a Semantics(container: true, label: 'Export confirmation') node to ensure proper screen-reader role announcement. The estimated record count should come from the ExportTriggerBloc state (wired in task-005/006) — this dialog itself is purely presentational.

Testing Requirements

Write flutter_test widget tests: (1) all four summary fields display the values passed in BufdirExportSummary, (2) tapping Confirm fires onConfirmed and does not fire onCancelled, (3) tapping Cancel fires onCancelled and does not fire onConfirmed, (4) dialog renders without RenderFlex overflow at textScaleFactor 2.0, (5) Semantics tree contains a node with DialogRole or equivalent. Also verify period date formatting produces the expected human-readable string for DST boundary dates (last weekend of March / October).

Component
Export Confirmation Dialog
ui low
Epic Risks (2)
medium impact medium prob technical

For large exports that run for 10–30 seconds, a static loading spinner will feel broken to users on slow mobile connections. If the UI cannot display meaningful progress during the export pipeline, coordinators may abandon the flow or trigger duplicate exports by pressing the button multiple times.

Mitigation & Contingency

Mitigation: Implement streaming progress events from the orchestrator BLoC through named pipeline stages (querying, mapping, generating, uploading). Display each stage label with a progress indicator on the trigger screen. Disable the generate button immediately on first tap to prevent duplicates.

Contingency: If streaming pipeline progress is not feasible in the first release, implement a deterministic stage-based progress animation (10% querying, 50% generating, 90% uploading) that gives users feedback without requiring real server events.

high impact medium prob technical

Custom date range pickers are among the most common accessibility failures in mobile apps. Blindeforbundet users rely on VoiceOver, and NHF users include people with cognitive impairments. A non-accessible period picker could make the entire export workflow unusable for a significant portion of the intended user base.

Mitigation & Contingency

Mitigation: Build the period picker using Flutter's native date picker semantics as the foundation, with preset shortcuts as primary navigation (reducing the need to interact with the custom range picker at all). Test with VoiceOver on iOS and TalkBack on Android before UI epic sign-off. Engage Blindeforbundet's test contact for accessibility validation.

Contingency: If the custom date range picker cannot be made fully accessible before release, ship only the preset period shortcuts (covering the majority of use cases) and add the custom range picker in a follow-up sprint after dedicated accessibility remediation.