Add dismiss and mark-read interactions to ReminderNotificationCard
epic-assignment-follow-up-reminders-ui-task-002 — Implement the dismiss and mark-as-read gesture and button interactions on ReminderNotificationCard. Wire up swipe-to-dismiss and explicit action buttons to the BLoC/Riverpod notification state layer. Ensure optimistic UI updates with rollback on failure, and emit the correct state events consumed by the in-app notification repository.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 1 - 540 tasks
Can start after Tier 0 completes
Implementation Notes
Use Flutter's `Dismissible` widget for swipe-to-dismiss — set `dismissThresholds` to 0.4 to prevent accidental dismissals. For optimistic updates with rollback, dispatch an optimistic state change immediately in the BLoC/notifier, then call the repository; on error, dispatch a revert event. Keep the rollback logic inside the BLoC/notifier, not in the widget — the widget only dispatches events and renders state. Ensure the `Dismissible` key is the notification ID (not an index) to prevent incorrect widget reuse during list updates.
The mark-as-read button should be accessible via `Semantics(label: 'Mark reminder as read', button: true)`. Test the rollback path explicitly — it is the most likely source of subtle bugs in optimistic UI patterns.
Testing Requirements
Widget tests using flutter_test with a mocked notification repository (mocktail): (1) simulate swipe-to-dismiss and verify the BLoC/notifier receives a DismissNotification event with the correct ID; (2) tap the mark-read button and verify a MarkNotificationRead event is dispatched; (3) stub the repository to throw an exception and verify the card reappears in the list and an error snackbar is displayed; (4) verify the dismiss animation completes without errors. Use `WidgetTester.drag` for swipe simulation. All tests must pass without a live Supabase connection.
The deep-link from the notification card to the assignment detail screen depends on the assignment detail route being stable and accepting an assignment ID parameter. If the routing contract is undocumented or changes during parallel development, the CTA will silently navigate to a fallback screen.
Mitigation & Contingency
Mitigation: Confirm the assignment detail route path and parameter contract with the team building or maintaining that screen before implementing the CTA. Add an integration test that asserts navigating from a mock notification card with a known assignment ID lands on the correct route.
Contingency: If the route is unstable, implement the deep-link as a late-bound string resolved from a central route registry, allowing the target route to be updated without changing the notification card.
Visually distinguishing escalation cards from standard reminder cards using colour alone fails WCAG 1.4.1 (use of colour). Blindeforbundet users relying on screen readers must receive equivalent contextual information through semantics, not just visual styling.
Mitigation & Contingency
Mitigation: Use both colour and an icon/label difference to distinguish card types. Add explicit Semantics widgets with descriptive labels ('Escalation alert: peer mentor has not responded') so screen readers announce the type without visual context.
Contingency: If accessibility review flags the distinction, add a text badge ('Escalation') alongside the visual treatment as a code-change-only fix with no schema or service impact.