Implement save action, navigation, and confirmation toast
epic-contact-detail-and-edit-supporting-ui-task-017 — Wire the save button in EditContactScreen to call contact-edit-service with the current validated form payload. On success, navigate back to the contact detail screen (pop route) and display a confirmation toast/snackbar with a success message. On failure, display a non-dismissable inline error banner with a retry action. Ensure the save button shows a loading indicator while the request is in flight.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 5 - 253 tasks
Can start after Tier 4 completes
Implementation Notes
Use BlocConsumer or BlocListener to separate UI reaction from build logic — place navigation and SnackBar display in the listener callback, never in the build method. For the loading state, add an `isSaving` flag to the form cubit/BLoC state and drive the AppButton's `isLoading` prop from it. For route pop, use `context.pop()` (go_router) or `Navigator.of(context).pop(updatedContact)` passing the updated model so ContactDetailScreen can refresh without a full reload. Cancellation on navigate-away: override `dispose()` in the cubit to cancel any pending Futures.
The inline error banner should be a named widget (e.g. `_SaveErrorBanner`) for testability — avoid anonymous closures in the build tree. Use `ScaffoldMessenger.of(context).showSnackBar()` to ensure the SnackBar appears after the pop on the underlying screen.
Testing Requirements
Write widget tests using flutter_test covering: (1) save button is in loading state after tap and service call is pending, (2) successful save triggers Navigator.pop and SnackBar appears on the previous route, (3) service failure renders inline error banner with correct message and retry CTA, (4) retry action re-dispatches the same event, (5) save button is disabled while loading and re-enabled after failure. Mock contact-edit-service using a Fake/Mock class. Aim for 100% branch coverage on the save action handler. Add a golden test for the error banner appearance.
The encrypted-field-display confirmation dialog adds interaction steps that may frustrate coordinators who access sensitive fields frequently, leading to requests to bypass the flow or skip read-receipt logging, which would violate Blindeforbundet's compliance requirements.
Mitigation & Contingency
Mitigation: Design the confirmation dialog to be as minimal as possible (one clear sentence, single confirm action) and ensure it does not reappear for the same field within a single screen session. Validate the UX with Blindeforbundet coordinators during the TestFlight pilot before finalising.
Contingency: If coordinators raise strong objections, escalate to Blindeforbundet's data protection officer to determine whether a lighter confirmation pattern (e.g., biometric confirmation instead of dialog) satisfies their compliance obligation.
The activity-history-list infinite scroll requires paginated Supabase queries. Contacts with hundreds of activities (e.g., an HLF peer mentor with 380 annual registrations) could cause slow page loads or memory pressure on older devices if pagination boundaries are set too large.
Mitigation & Contingency
Mitigation: Use a page size of 20 records with cursor-based pagination. Implement list item recycling using Flutter's ListView.builder. Benchmark memory usage with 400+ item simulation on a low-end test device before TestFlight release.
Contingency: If performance degrades on older devices, reduce page size to 10 and add a time-window filter (last 30 days, last 6 months, all) so the default view loads a manageable record count for most coordinators.
The cognitive load rule engine (from the Cognitive Accessibility feature) mandates no more than 7 fields per screen section. If a contact model has more than 7 editable fields, the edit-contact-screen layout must be split into sections, adding complexity not accounted for in the initial scope.
Mitigation & Contingency
Mitigation: Audit the full contact field list from all four organisations before implementation. Group fields into logical sections (personal info, contact details, affiliation) so no single section exceeds 7 fields. Use the cognitive-load-rule-engine component if it is already delivered by the Cognitive Accessibility feature.
Contingency: If the rule-engine component is not yet available, implement a simple manual section layout with accordion-style expansion for less-frequently edited fields to stay within the 7-field guideline without blocking delivery.