high priority medium complexity frontend pending frontend specialist Tier 0

Acceptance Criteria

Widget accepts a List<ChapterAffiliation> parameter and renders one chip per entry
When the list has more than 5 entries, only the first 5 chips are shown plus a '+N more' overflow indicator chip
Chips are rendered in a horizontally scrollable SingleChildScrollView with scrollDirection: Axis.horizontal
Each chip displays the chapter name truncated to a configurable maxChars (default 20) with ellipsis
Long-pressing any chip shows a Tooltip with the full untruncated chapter name
Each chip has a Semantics label of 'Chapter: [full chapter name]' for screen reader support
The '+N more' overflow chip, when tapped, triggers an optional onOverflowTapped callback (e.g., to open a bottom sheet with all chapters)
All typography and spacing uses design token values — no hardcoded font sizes or padding values
Widget renders correctly with 0 affiliations (renders nothing), 1 affiliation, and 5+ affiliations
Widget does not overflow its parent container vertically — chip row height is fixed by design tokens

Technical Requirements

frameworks
Flutter
design token system (AppTypography, AppSpacing, AppColors)
data models
ChapterAffiliation (id, name, shortName?)
performance requirements
Widget must not cause layout thrash — avoid unbounded width children in scroll view
Renders within a single frame for lists up to 20 items
ui components
SingleChildScrollView
Row
Chip / custom chip widget
Tooltip
Semantics
GestureDetector (for overflow tap)

Execution Context

Execution Tier
Tier 0

Tier 0 - 440 tasks

Implementation Notes

Build as a StatelessWidget called ChapterAffiliationChips. The chip itself should be a private _ChapterChip StatelessWidget that wraps Flutter's Chip with custom padding and design token styling — avoid using FilterChip or ChoiceChip which carry unnecessary interaction semantics for a read-only display. For the horizontal scroll, use SingleChildScrollView with a Row child. Place the chips list computation (split + overflow count) in the build method as a local variable — no need for a separate method.

For Tooltip: Flutter's built-in Tooltip widget supports triggerMode: TooltipTriggerMode.longPress which is the correct UX here. For accessibility, override the Chip's label widget with a Semantics widget providing the full chapter name. Use AppSpacing tokens for chip padding, AppTypography for chip text style, and AppColors for chip background and border.

Testing Requirements

Widget tests covering: empty list renders nothing, single chip renders correctly, exactly 5 chips renders all without overflow indicator, 6 chips renders 5 + '+1 more' chip, 10 chips renders 5 + '+5 more' chip. Test that long-press on a chip with a name longer than maxChars shows a Tooltip with the full name. Test that Semantics label contains full chapter name (not truncated). Test onOverflowTapped callback is invoked when overflow chip is tapped.

Golden tests for 1-chip, 5-chip, and overflow states. Accessibility test verifying all chips are announced.

Component
Contact Detail Screen
ui medium
Epic Risks (2)
low impact medium prob dependency

The Peer Mentor Profile tab on the contact detail screen depends on the peer-mentor-detail-screen-widget being delivered by the separate Peer Mentor Detail feature. If that feature is delayed, the navigation affordance will be present but lead to a stub screen, which may confuse coordinators in the TestFlight pilot.

Mitigation & Contingency

Mitigation: Implement the peer mentor tab with a feature flag guard. When the Peer Mentor Detail feature is incomplete, the flag disables the tab. Coordinate delivery timelines with the team responsible for Peer Mentor Detail to align TestFlight releases.

Contingency: If the Peer Mentor Detail feature is significantly delayed, ship the contact detail screen without the peer mentor tab in the first TestFlight build and add it as an incremental update once the dependent screen is ready.

medium impact medium prob technical

The contact detail screen must adapt its layout significantly based on organisation context: NHF shows affiliation chips, Blindeforbundet shows encrypted fields and assignment status, standard contacts show neither. Managing this conditional rendering without introducing bugs in each variant is complex and increases the risk of organisation-specific regressions.

Mitigation & Contingency

Mitigation: Define a ContactDetailViewModel that resolves all org-specific flags (showEncryptedFields, showAssignmentStatus, showMultiChapterChips) from the organisation config before the widget tree renders. Widget tests must cover all three organisation variants as separate test cases to catch regressions.

Contingency: If conditional rendering logic grows unwieldy, refactor into separate composable section widgets (ProfileHeaderSection, AffiliationSection, EncryptedFieldsSection) that are conditionally included by the parent screen, isolating org-specific logic to individual components.