feat(frontend): referrals footer pending referral pill (GitLab #205) #388

Merged
Brouie merged 1 commit from feat/glab-205-referrals-footer-pending-pill into main 2026-05-14 13:40:50 +00:00
Brouie commented 2026-05-14 08:00:23 +00:00 (Migrated from gitlab.com)

Closes #205.

What this changes

Adds a small footer pill on /referrals that shows the browser-locked pending referral code (yieldomega.ref.v1) so participants can confirm what will apply on the next qualifying buy.

Implementation

Followed the spec's "thin component" sketch — pill lives in its own file and mounts into the existing app-footer__row slot, keeping RootLayout.tsx mostly untouched.

New helper shouldShowPendingPill(pathname, code) in referralStorage.ts — pure predicate so the gate logic is unit-testable without React rendering or window.location mocks. Returns true only when:

  • pathname === "/referrals" exact
  • code is non-null and non-whitespace

New component frontend/src/components/ReferralsFooterPendingPill.tsx:

  • Reads pending code via getPendingReferralCode() so the same cross-store sync logic the rest of the app uses applies here
  • Refreshes on route changes (useLocation dep) — picks up new ?ref=XYZ captures on same-tab navigation
  • Subscribes to storage events scoped to the yieldomega.ref.v1 key for cross-tab updates
  • Renders null when off /referrals or when no pending code — per spec acceptance: omit rather than show empty muted state
  • Styles via existing footer-link-pill class for consistency with the Governance pill next to it
  • data-testid="referrals-footer-pending-pill" + aria-label + title for accessibility and tests

Mount point in RootLayout.tsx: between <IndexerStatusBar /> and the Governance anchor inside app-footer__row. Reuses the existing showFooter exclusion for /timecurve so the pill never leaks to the Simple view.

Manual verification

Tested locally against MegaETH mainnet config:

  • /referrals?ref=testcode → pill renders "Pending ref: testcode" in footer
  • Navigate to / → pill disappears
  • Navigate back to /referrals (no ?ref=) → pill still shows "testcode" (cached in localStorage from earlier capture)
  • /referrals?ref=newcode → pill updates to "newcode" without page reload

Tests

New referralStorageShouldShowPendingPill.test.ts covers the pure gate:

  • True on /referrals with valid codes
  • False on every other path (/, /timecurve, /timecurve/arena, /referrals/, /referrals/something)
  • False on null / empty / whitespace-only codes
  • False when both gates fail

Suite delta: 325/325 → 329/329 across 60 files (+4 tests). Zero regressions.

Out of scope (per spec)

  • Not touching yieldomega.myrefcode.v1.* cache (post-register, different surface)
  • No copy changes to existing referrals disclosures
  • No e2e Playwright additions in this MR — existing referrals-surface.spec.ts can extend with data-testid in a follow-up if needed
Closes #205. ## What this changes Adds a small footer pill on `/referrals` that shows the browser-locked pending referral code (`yieldomega.ref.v1`) so participants can confirm what will apply on the next qualifying buy. ## Implementation Followed the spec's "thin component" sketch — pill lives in its own file and mounts into the existing `app-footer__row` slot, keeping `RootLayout.tsx` mostly untouched. **New helper** `shouldShowPendingPill(pathname, code)` in `referralStorage.ts` — pure predicate so the gate logic is unit-testable without React rendering or `window.location` mocks. Returns `true` only when: - `pathname === "/referrals"` exact - code is non-null and non-whitespace **New component** `frontend/src/components/ReferralsFooterPendingPill.tsx`: - Reads pending code via `getPendingReferralCode()` so the same cross-store sync logic the rest of the app uses applies here - Refreshes on route changes (`useLocation` dep) — picks up new `?ref=XYZ` captures on same-tab navigation - Subscribes to `storage` events scoped to the `yieldomega.ref.v1` key for cross-tab updates - Renders `null` when off `/referrals` or when no pending code — per spec acceptance: omit rather than show empty muted state - Styles via existing `footer-link-pill` class for consistency with the Governance pill next to it - `data-testid="referrals-footer-pending-pill"` + `aria-label` + `title` for accessibility and tests **Mount point** in `RootLayout.tsx`: between `<IndexerStatusBar />` and the Governance anchor inside `app-footer__row`. Reuses the existing `showFooter` exclusion for `/timecurve` so the pill never leaks to the Simple view. ## Manual verification Tested locally against MegaETH mainnet config: - `/referrals?ref=testcode` → pill renders **"Pending ref: testcode"** in footer - Navigate to `/` → pill disappears - Navigate back to `/referrals` (no `?ref=`) → pill still shows "testcode" (cached in localStorage from earlier capture) - `/referrals?ref=newcode` → pill updates to "newcode" without page reload ## Tests New `referralStorageShouldShowPendingPill.test.ts` covers the pure gate: - True on `/referrals` with valid codes - False on every other path (`/`, `/timecurve`, `/timecurve/arena`, `/referrals/`, `/referrals/something`) - False on null / empty / whitespace-only codes - False when both gates fail Suite delta: 325/325 → 329/329 across 60 files (+4 tests). Zero regressions. ## Out of scope (per spec) - Not touching `yieldomega.myrefcode.v1.*` cache (post-register, different surface) - No copy changes to existing referrals disclosures - No e2e Playwright additions in this MR — existing `referrals-surface.spec.ts` can extend with `data-testid` in a follow-up if needed
Brouie commented 2026-05-14 08:04:57 +00:00 (Migrated from gitlab.com)

image.png{width=779 height=600}

/referrals (no ?ref=) — pill shows "testcode" cached

image.png{width=806 height=600}

/referrals?ref=newcode — pill updated to "newcode"

image.png{width=735 height=600}

![image.png](/uploads/d0e0a5f5d370253a705cf568b0ffa4e6/image.png){width=779 height=600} `/referrals` (no ?ref=) — pill shows "testcode" cached ![image.png](/uploads/050e57738d099b4d2c860f07aae687ec/image.png){width=806 height=600} `/referrals?ref=newcode` — pill updated to "newcode" ![image.png](/uploads/1b820b4fa4777fcc5dd873c378eb1f9f/image.png){width=735 height=600}
PlasticDigits commented 2026-05-14 13:40:50 +00:00 (Migrated from gitlab.com)

mentioned in commit 316930c44b

mentioned in commit 316930c44b35abd3239ec6bbdb6782e3d6efa661
PlasticDigits (Migrated from gitlab.com) merged commit 316930c44b into main 2026-05-14 13:40:51 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
code/yieldomega!388
No description provided.