high priority medium complexity frontend pending frontend specialist Tier 1

Acceptance Criteria

PeerMentorHomeContent renders a personal activity summary card showing total activities and total hours for the current month
A recent registrations list shows the 3 most recent activity registrations with date, type, and duration
Assigned contacts count card shows the number of contacts currently assigned to this peer mentor
Motivational stats section shows a cumulative lifetime total (total activities, total hours since account creation) to reinforce sense of contribution — aligns with gamification direction from workshop findings
When a multi-role user switches from coordinator to peer mentor via the Role Switch Widget, all data refreshes to reflect the peer mentor's personal scope (not coordinator-aggregate data)
Empty state is handled gracefully: if the peer mentor has no activities yet, a welcoming zero-state message is shown with a prompt to register their first activity
All cards meet WCAG 2.2 AA contrast requirements using design token color values
Screen reader announces all numerical values with appropriate context (e.g., 'Total activities this month: 12')
Content loads within 2 seconds on 4G; skeleton placeholders shown during load

Technical Requirements

frameworks
Flutter
BLoC
Riverpod
apis
Supabase PostgREST — activities table (peer_mentor_id scoped)
Supabase PostgREST — contacts/assignments table
data models
Activity
Contact
PeerMentorStats
UserRole
performance requirements
Data load completes within 2 seconds on 4G
Role-switch data refresh completes within 1 second of role state emission
security requirements
All data queries scoped to the authenticated user's own peer_mentor_id — a peer mentor must never see another peer mentor's data
org_id filter applied on all queries for defense in depth alongside Row Level Security
ui components
PeerMentorHomeContent (this widget)
PersonalStatCard (value + label + icon)
RecentRegistrationsList
RecentRegistrationItem
MotivationalLifetimeCard
ZeroStatePrompt
SkeletonCard

Execution Context

Execution Tier
Tier 1

Tier 1 - 540 tasks

Can start after Tier 0 completes

Implementation Notes

Keep PeerMentorHomeContent data-fetching logic in a dedicated PeerMentorHomeCubit or PeerMentorHomeNotifier — do not reuse the coordinator's data provider, as the query scopes are fundamentally different. The motivational lifetime stats section is a lightweight emotional design element aligned with the 'Spotify Wrapped' direction from workshop findings — keep it simple: two numbers (total activities, total hours) with a warm label. For multi-role switch correctness, the provider/cubit must invalidate and re-fetch when the active role context changes, not just on first mount. Reuse SkeletonCard and ZeroStatePrompt components if already created in task-002 to maintain visual consistency.

Testing Requirements

Widget tests using flutter_test. Cover: (a) loaded state with sample activities and contacts, (b) zero-state (new peer mentor with no activities), (c) loading state showing skeletons, (d) error state with retry. Simulate role switch from coordinator to peerMentor: assert that PeerMentorHomeCubit/Notifier triggers a fresh data fetch with peer_mentor_id scope rather than coordinator scope. Assert that the recent registrations list shows exactly the 3 most recent items when more than 3 are available.

Semantics test: verify all stat values have descriptive semantic labels.

Component
Role-Based Home Screen
ui medium
Epic Risks (3)
high impact medium prob technical

Combining GoRouter's declarative redirect logic in the route guard with StatefulShellRoute's stateful branch management is known to produce subtle bugs where the shell rebuilds unnecessarily on role switches, losing tab state or causing double-navigation events.

Mitigation & Contingency

Mitigation: Implement the route guard as a GoRouter redirect callback that only evaluates role from an already-resolved Riverpod provider (not async). Use a dedicated ShellRoute navigator key per tab branch to anchor state independently of role-driven rebuilds. Write integration tests for the full navigation graph.

Contingency: If StatefulShellRoute state loss is confirmed during QA, fall back to a manual tab state preservation approach using a TabStateManager service that caches the last route per tab and restores it after role switches, decoupling tab state from the shell lifecycle.

medium impact high prob scope

The role-based home screen must render three significantly different layouts (coordinator dashboard, peer mentor activity summary, org admin overview). If these variants are implemented as a single widget with conditionals, the file will become unmaintainable and difficult to test in isolation, especially as each variant grows with downstream feature additions.

Mitigation & Contingency

Mitigation: Design the role-based home screen as a router/dispatcher widget that delegates to three separate variant widgets (CoordinatorHomeView, PeerMentorHomeView, OrgAdminHomeView). Each variant is independently testable and can be developed by separate team members in parallel.

Contingency: If variant coupling has already occurred before this risk is addressed, refactor to the dispatcher pattern in a dedicated cleanup task before feature handoff. The dispatcher pattern is a straightforward extraction that carries low refactoring risk.

medium impact medium prob integration

The no-access screen must link global admin users to the correct admin portal URL, which may differ per organization (NHF, HLF, Blindeforbundet each have their own admin portals). Hardcoding a single URL will result in wrong or broken links for some global admin users.

Mitigation & Contingency

Mitigation: Source the admin portal URL from the organization's configuration record in Supabase rather than hardcoding it. The no-access screen reads the active org context and resolves the portal URL dynamically. Provide a safe fallback to a generic Norse Digital Products support page if the URL is not configured.

Contingency: If dynamic URL resolution is not ready when the no-access screen ships, display a static instruction to contact the organization's administrator along with a support email address as an interim measure, and track the URL configuration task as a follow-up.