Implement MentorActivitySummaryPanel stats card
epic-peer-mentor-detail-screen-ui-components-task-011 — Build MentorActivitySummaryPanel as an aggregated stats card widget displaying total activity count, activity type breakdown (rows per type with count), and a time-range label. Implement the empty-state view for mentors with zero logged activities. All data is received via props — the panel does not fetch data itself.
Acceptance Criteria
Technical Requirements
Implementation Notes
Define ActivityTypeSummary as a simple immutable data class (or use a record in Dart 3+): final String activityType; final int count. Create MentorActivitySummaryPanel as a StatelessWidget. In the build method, first check if totalCount == 0 and return the empty-state widget early. For the breakdown, filter breakdown.where((e) => e.count > 0) before mapping to row widgets — this handles the 'zero counts hidden' requirement cleanly.
Use a Column for the breakdown rows rather than ListView since the count is bounded and shrinkWrap/NeverScrollableScrollPhysics complexity is unnecessary here. Style the total count using the design token for headline/display text size (e.g., tokenTypographyHeadline or similar) and the breakdown rows using body/label size. The panel should be self-contained in one file with a private _BreakdownRow widget. The time-range label is display-only — format logic (e.g., 'Last 30 days' vs ISO range) is the caller's responsibility.
Add a section-title string parameter (default: 'Activity Summary') so the caller can localise or org-customise the header label via OrgLabelsProvider if needed in the future.
Testing Requirements
Write widget tests using flutter_test. Test 1: pass totalCount=0 and empty breakdown — assert empty-state widget is present and breakdown rows are absent. Test 2: pass totalCount=5 with breakdown of 2 types — assert exactly 2 breakdown rows are rendered, each displaying the correct label and count. Test 3: pass a breakdown where one type has count=0 — assert that row is NOT rendered.
Test 4: pass 10 activity types — assert the widget builds without overflow (use tester.pump(), check for no RenderFlex overflow exceptions). Test 5: assert the total count Text widget displays the correct integer as a string. Test 6: assert the time-range label Text renders the provided string.
The org labels system may not yet have label keys defined for peer mentor detail screen terminology (role labels, section headings), requiring additions to the label key registry that must be coordinated with the admin configuration team.
Mitigation & Contingency
Mitigation: Audit existing label keys in the terminology system before starting OrgLabelsProvider integration. Submit required new label keys for admin configuration in parallel with component implementation.
Contingency: If label keys are not available at integration time, use hardcoded English fallbacks with a clear TODO for admin configuration, ensuring the widget renders correctly while keys are being provisioned.
The design token semantic colors (warning, error surface) may not meet WCAG 2.2 AA 4.5:1 contrast ratio when rendered on the app's background surface tokens, requiring design system changes that affect the entire app.
Mitigation & Contingency
Mitigation: Run contrast ratio validation on the token palette during Epic 1 design token implementation. Flag any failing pairs to the design system owner before building UI components that depend on them.
Contingency: If tokens fail contrast requirements, define supplementary high-contrast override tokens specific to alert and badge contexts that meet AA without modifying the global palette.