high priority low complexity frontend pending frontend specialist Tier 2

Acceptance Criteria

The full referral URL is displayed as readable text below the QR code widget
Tapping the copy button copies the full referral URL to the system clipboard via `Clipboard.setData`
A SnackBar confirmation message appears immediately after successful copy (message in Norwegian, e.g., 'Lenke kopiert')
The SnackBar disappears automatically after 2–3 seconds and does not stack if the button is tapped repeatedly
The link text is wrapped in a `SelectableText` widget so users can manually select and copy parts of the URL
The copy button has a minimum 48x48dp touch target
The copy button has a Semantics label (e.g., 'Copy referral link') for screen reader accessibility
The displayed URL is the same value used for the QR code — both sourced from ReferralCodeService provider
The link text truncates gracefully on narrow screens using ellipsis and does not overflow the layout
If the referral URL is unavailable (provider error), the copy button is disabled and hidden

Technical Requirements

frameworks
Flutter
Riverpod
apis
Flutter Clipboard API (services library)
ReferralCodeService (internal Riverpod provider)
data models
assignment
performance requirements
Clipboard write operation is synchronous-feel — complete within one tap gesture
security requirements
Referral URL is non-sensitive — clipboard write is safe without additional encryption
Do not expose raw database IDs in the shareable URL — use opaque referral code tokens only
ui components
SelectableText (link display)
IconButton or OutlinedButton (copy action with copy_all icon)
SnackBar with ScaffoldMessenger

Execution Context

Execution Tier
Tier 2

Tier 2 - 518 tasks

Can start after Tier 1 completes

Implementation Notes

Use `ScaffoldMessenger.of(context).showSnackBar(...)` for the confirmation — do not use deprecated `Scaffold.of(context).showSnackBar`. Call `ScaffoldMessenger.of(context).clearSnackBars()` before showing a new one to prevent stacking. The referral URL should be derived from the same provider as the QR code — consider a computed provider that exposes both `qrData` and `shareableUrl` as a record or data class to avoid double subscription. Wrap the URL row in a `Row` with `Expanded(child: SelectableText(...))` and the icon button to handle narrow screens cleanly.

Testing Requirements

Write widget tests using flutter_test. Test (1) URL text is displayed when provider has data, (2) copy button tap triggers Clipboard.setData with correct URL, (3) SnackBar appears after copy, (4) copy button is absent/disabled when provider is in error state. Mock `Clipboard.setData` using `TestDefaultBinaryMessengerBinding` or a fake implementation. Verify Semantics node for copy button label.

Run on both iOS and Android simulators to verify SnackBar appearance.

Component
Referral Code Screen
ui medium
Epic Risks (3)
medium impact medium prob technical

QR codes rendered at the minimum 200×200 size may fail to scan under typical indoor lighting conditions on older or lower-resolution phone cameras, causing recruitment moments to fail when a peer mentor shows the screen to a prospective member.

Mitigation & Contingency

Mitigation: Set the default QR render size to 260×260 logical pixels (not the 200px minimum) and apply a high-contrast white module background. Test scan reliability on at minimum three physical devices (budget Android, mid-range Android, iPhone SE) before marking the screen as done.

Contingency: If scan reliability remains an issue, add a 'Enlarge QR' full-screen mode triggered by tapping the code, and ensure the text referral URL with copy-to-clipboard is always visible as a fallback sharing method.

high impact medium prob integration

The onboarding screen submits attribution and then hands off to an external membership registration URL (HLF's Dynamics portal or similar). If the external URL is unavailable, changes its format, or requires authentication the new member does not have, the conversion funnel is broken at its final step.

Mitigation & Contingency

Mitigation: Confirm the external registration URL and its expected query parameters with HLF's portal team before implementing the handoff. Record the pending_signup attribution event before launching the URL so data is not lost if the external site fails. Display a fallback message with contact information if the URL launch fails.

Contingency: If the external membership URL is not available at feature launch, implement a temporary form that collects name and email and stores a pending_member record in Supabase, allowing coordinators to manually complete registration while the integration is finalised.

low impact medium prob integration

Embedding the RecruitmentStatsWidget on the peer mentor home screen may conflict with existing layout components (activity summary, badge shelf), causing overflow or requiring a redesign of the home screen that is outside this epic's scope.

Mitigation & Contingency

Mitigation: Design the widget as a horizontally constrained card with a maximum height of 96dp so it can be inserted into any vertical list without overflow. Coordinate with the home screen's existing layout owners before starting the embedding task.

Contingency: If home screen embedding creates unacceptable layout conflicts, defer embedding to a separate home-screen redesign task and make the widget accessible only via the dedicated ReferralCodeScreen for the initial release.