Scaffold MultiOrgContextSwitcher and fetch user org memberships
epic-organization-selection-and-onboarding-ui-task-006 — Create the MultiOrgContextSwitcher widget. On open, call MultiOrgMembershipResolver to retrieve all organizations the authenticated user belongs to. Render each org as a selectable list item using OrgCardWidget, clearly marking the currently active org with a visual highlight indicator (checkmark icon and accent color). The switcher must be accessible from the settings/hamburger menu. Show a loading skeleton while memberships are being fetched.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 3 - 413 tasks
Can start after Tier 2 completes
Implementation Notes
Implement a MultiOrgContextSwitcherCubit with states: MultiOrgLoading, MultiOrgLoaded(memberships, activeOrgId), MultiOrgError. Open the switcher via showModalBottomSheet and pass the Cubit via BlocProvider.value so its lifecycle is not tied to the sheet. Trigger the fetch in the Cubit's constructor or via an explicit LoadMemberships event dispatched from the sheet's initState equivalent (use a StatefulWidget wrapper if using showModalBottomSheet). Extend OrgCardWidget to accept isActive (bool) and isSelectable (bool) parameters — the active card should render a checkmark trailing icon and use the design token accent color.
For the loading skeleton, build a fixed-height shimmer widget that mirrors the OrgCardWidget dimensions. Use design tokens for all colors and spacing — no hardcoded hex values.
Testing Requirements
Write widget tests: (1) switcher shows skeleton immediately on open before fetch completes, (2) org list renders correctly from mock membership data, (3) active org card shows checkmark and accent color, (4) inactive org cards are tappable (emit event), (5) active org card tap is a no-op, (6) error state shows retry button. Write Cubit unit tests: (7) emits [loading, loaded] on successful fetch, (8) emits [loading, error] on resolver failure. Use flutter_test, bloc_test, and mock MultiOrgMembershipResolver.
OrgSelectionScreen and OrgContextSwitcher render partner-specific logos, colors, and text from dynamic data. Golden tests (pixel-comparison screenshots) will fail whenever branding assets are updated in the backend, causing CI failures that block unrelated PRs and eroding developer trust in the test suite.
Mitigation & Contingency
Mitigation: Use fixture-based golden tests with static mock Organization models containing embedded test assets rather than network-fetched assets. Separate branding asset acceptance tests into a dedicated CI job that only runs on branding-related PRs and is maintained by the design team.
Contingency: If golden test maintenance overhead becomes excessive, replace pixel-comparison goldens with semantic widget tests that assert widget tree structure and key property values, reserving golden tests for only the most stable, design-critical elements.
Several partner organizations (especially Blindeforbundet) have users who rely entirely on VoiceOver or TalkBack. Complex branded card layouts with overlaid logos, names, and selection states are notoriously difficult to make fully accessible; missing semantics or incorrect focus order could make the selection screen completely unusable for screen reader users before launch.
Mitigation & Contingency
Mitigation: Involve an accessibility specialist in the design review before any widget implementation begins. Use Flutter's Semantics widget with explicit label, hint, and button role on OrgCardWidget. Conduct manual screen reader testing on both iOS (VoiceOver) and Android (TalkBack) for every sprint that touches these screens, not just before release.
Contingency: If full WCAG compliance cannot be achieved within the sprint, implement a simplified text-list fallback mode that activates when the system detects an active screen reader, presenting orgs as plain accessible list tiles instead of the branded card layout.