Skip to content

Navbar's 'Online 213 / Users 30,738 / TVL $302M' stat pills are hardcoded string literals with a pulsing live indicator, shown on every page #133

Description

@prodbycorne

Overview

src/components/Navbar/Navbar.tsx renders, for every disconnected visitor on every single page of the app (the navbar is mounted once in AppShell, globally), three "live"-looking stat pills:

{isConnected && publicKey ? (
  <StatPill label="Wallet" value={shortenStellarAddress(publicKey)} />
) : (
  <>
    <StatPill label="Online" value="213" pulse />
    <StatPill label="Users" value="30,738" />
    <StatPill label="TVL" value="$302M" />
  </>
)}

"213", "30,738", and "$302M" are raw string literals baked directly into JSX. There is no useQuery, no fetch, no sorobanService call, no prop, nothing — these three numbers can never change, are not connected to any data source in the codebase, and will read the same on the day the app has zero users as on a day it has a million. The pulse prop on the "Online" pill renders an animated pulsing dot (StatPill, Navbar.tsx:91-101, className="animate-pulse"), a UI convention universally understood to mean "this is live/real-time data" — actively reinforcing the false impression that 213 is a real, moving online-user count. This is materially different from (and more absolute than) the app's other fabricated-stat issues: it isn't a heuristic derived from some real number, it's three constants with no data source at all, and it's the single most-seen fabricated number in the app, since it renders on literally every page for every not-yet-connected visitor — the most common state for a first-time visitor evaluating the product.

Requirements

  • Replace the three hardcoded pill values with real data from an existing live source (usePlatformStats()/sorobanService.getPlatformStats(), already used elsewhere in the app), or remove the pills entirely if no real "online users" concept exists yet.
  • If "Online" (concurrent presence) has no real backing data source at all (unlike TVL/total users, which do have a real, if imperfect, code path via getPlatformStats()), don't display a pulsing "live" indicator over a number that cannot possibly be live — either drop that specific pill or clearly relabel it as something it accurately is.
  • Ensure the values actually update over time (respecting whatever refetchInterval the underlying query already uses) rather than being computed once and frozen.

Acceptance Criteria

  • Navbar's "Users" and "TVL" pills render values sourced from usePlatformStats() (or equivalent live query), not string literals.
  • Changing the underlying pool/user data (in a test, via a mocked usePlatformStats return value) changes what the Navbar displays.
  • The "Online" pill either reflects a real, defined metric with an honest data source, or is removed/relabeled — it does not retain a pulsing "live" indicator over a hardcoded number.
  • A snapshot/unit test asserts the Navbar's disconnected-state stat pills are not static literals (e.g. by mocking two different usePlatformStats results across two renders and asserting the displayed text differs accordingly).

Additional Notes

More precise references

  • src/components/Navbar/Navbar.tsx:131-140 — confirmed the exact JSX and literal values ("213", "30,738", "$302M").
  • src/components/Navbar/Navbar.tsx:91-101 (StatPill) — confirmed the pulse prop renders <span className="h-1.5 w-1.5 shrink-0 animate-pulse rounded-full bg-...accent" />, applied only to the "Online" pill.
  • src/components/Navbar/Navbar.tsx:1-13 — confirmed the file's imports contain no data-fetching hook of any kind (useStellarWallet is imported only for isConnected/publicKey, not stats).
  • src/hooks/useSorobanQuery.ts:468-492 (usePlatformStats) — confirmed this is the existing, already-real (factory-driven) hook used elsewhere (e.g. PlatformStats.tsx, page.tsx) that could supply real totalUsers/tvl values here instead.

Additional edge cases

  • BASE_USERS = 30_738 and BASE_TVL_MILLIONS = 302 in src/lib/stats.ts:77-78 produce the exact same "30,738" and (once formatted) "$302M" figures as this Navbar's hardcoded literals — see the separate "dead fake stats subsystem" issue in this batch. The two files were evidently seeded from the same one-time demo numbers independently; fixing one without checking the other risks leaving a second, differently-shaped copy of the same fabricated data behind.
  • Because these pills only render in the disconnected state (!isConnected), this bug is invisible to anyone testing primarily as a connected wallet user — worth noting in the PR/test plan so reviewers deliberately check the logged-out navbar, not just the logged-in one.

Implementation sketch

const { data: stats } = usePlatformStats();
...
<StatPill label="Users" value={stats ? stats.totalUsers.toLocaleString() : "—"} />
<StatPill label="TVL" value={stats?.totalValueLocked ?? "—"} />
// "Online" pill: either removed, or wired to a real presence metric if/when one exists

Test/reproduction plan

  • Mock usePlatformStats to return { totalUsers: 42, totalValueLocked: "$1,234" }; render Navbar in the disconnected state; assert "42" and "$1,234" (not "30,738"/"$302M") appear.
  • Mock a second, different usePlatformStats result; re-render; assert the displayed text changes accordingly (proves it's live-bound, not just swapped for a different constant).

Cross-references

Metadata

Metadata

Assignees

No one assigned

    Labels

    GrantFox OSSIssue tracked in GrantFox OSSMaybe RewardedIssue may be eligible for a GrantFox rewardOfficial CampaignCampaign: Official CampaignOfficial Campaign | FWC26Campaign: Official Campaign | FWC26Third CampaignCampaign: Third CampaignbugSomething isn't workingvery hardExtremely hard — deep expertise, careful design, and significant time required

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions