feat(web): rebuild the home page around one number - #1004
Conversation
… page The home page showed two currency tiles and one table, leaving most of the viewport empty and saying little about the organization. It now shows four tiles — total balance, today's volume, wallets and tokens held — plus a per-token balance breakdown ordered largest first. All of it comes from the wallet aggregate the page already fetched and previously discarded after summing, so this adds no request and no latency. Bars scale against the largest holding rather than the total, so a small position next to a dominant one stays visible instead of rounding to nothing. Token symbols go through the shared label resolver with the symbols the balances carry, so org-issued tokens are named rather than shown as shortened mints. The route skeleton now draws four tiles so the grid does not reflow on load.
The first version drew a share bar under every holding. An organization's own issued tokens have no price feed, so their bars were empty full-width tracks that read as dividers — and ranking 132.5 nwSOL against $149.11 on one scale compared quantities that share no unit. Priced holdings now compose a single segmented allocation bar whose shares sum to 100, with a legend carrying the percentage and the value. Unpriced holdings are listed below a No price feed rule with their amount and no bar, because there is no share to show. Holdings past the fourth fold into one Other segment so the bar stays readable. Segment fills step down the neutral emphasis ramp. The design system ships no categorical chart palette, and an allocation bar encodes magnitude rather than identity, so a single ramp is the right encoding — and it re-steps itself per theme instead of needing a hand-picked dark variant.
Four equal tiles gave the balance, the day's volume, a wallet count and a token count the same visual weight, so the page answered no question first — the reader had to pick one. Total balance is what someone opening a custody dashboard came for, so it now leads at roughly twice the type size, with the other three as context beneath it and the primary actions in the same block rather than floating above the page. The token allocation folds into the same card, so the whole money picture is one object instead of three. An organization with no wallets no longer gets four zeroes each with its own apologetic hint, which reads as a broken dashboard rather than a new one. It gets one instruction and the button beside it.
Extracting the hero took the workspace under the cognitive-complexity threshold, so its biome-ignore no longer suppresses anything, and the tile grid took the day's volume hint with it.
Three changes to the same card. Token marks replace the colour swatches. The repo already ships brand SVGs under public/token-logos and a TokenMark component that falls back to a tinted monogram, so an organization's own issued tokens get a mark too rather than a bare square. The secondary figures were 15px against a 46px balance, which read as fine print rather than as the three numbers someone actually scans. They are now 22px. The bar and the list are one object: hovering either a segment or its row lifts that holding and drops the others to 35 percent. Segments are buttons so the same highlight follows keyboard focus, and each carries its share in an accessible label.
Mouse handlers on a plain element are a keyboard trap and biome flags them. The segment button already owns the interaction and drives the dim-others linkage; the row now mirrors it with a CSS hover instead of its own handlers.
Three follow-ups on the balance card. The unpriced list was uncapped. An organization issuing a dozen of its own tokens turned the card into a ledger, so it now lists the largest few and counts the rest, the same way the priced side already folded into Other. Home no longer paints a 36px page title. The sidebar marks Home active and the page opens on a balance, so the heading said nothing the reader could not see; it is now rendered sr-only, which keeps it for assistive tech. Only the home route changed — a wallet detail or a new API key still needs its title for orientation. The route skeleton still drew the retired four-tile grid, so the layout jumped on load. It now mirrors the hero: balance, three context figures, the allocation bar and its rows.
The activity table squeezed Token and Amount into fixed 8rem and 10rem columns while Address took every remaining pixel, so both truncated with space to spare. Amount also repeated the token beside a column that already named it, which is how a row read "132.5 Ackroo…tPc9" twice over. Amount is now numeric, right aligned and tabular, Token carries its mark, and the freed width goes to Address. The mobile card keeps the symbol on the amount, because it has no separate token column to lean on. Page titles are hidden on the top-level list routes. The sidebar already names the active section, so a 36px heading repeating it spent vertical space saying nothing. Detail and action routes keep theirs — the centred title beside a back action is the only orientation those have. Hiding is now visual only: the top bar renders an sr-only h1 in place of the visible one, so every page still has exactly one heading for assistive tech and for the tests that look one up.
resourcefulmind
left a comment
There was a problem hiding this comment.
Home page looks great and the breakdown module is well tested. Three things.
Token column trades one naming bug for another. resolveTransferTokenLabel always returns something for non-blank input, so ?? row.token on 539 only fires when tokenMint is null. The two symbol sets don't nest: yours names tokens you hold that the catalogue doesn't know, the server's names tokens you issued and hold none of, and those now render as a shortened mint where main showed the symbol. Chaining both catches everything: symbolsByMint[row.tokenMint ?? ""] ?? row.token.
Seven routes lose their visible title and the description says other routes are unchanged, but all eight hideTitle lines are in this PR, not inherited from #1006. Policies, wallets, custody and issuance end up with no page heading at all, and wallets and issuance become indistinguishable since they share the Overview/API Playground tabs with payments, which keeps its title. A11y is fine, the sr-only h1 is the right call, it's the consistency I'd want a second opinion on. Was that a design call? Feels like its own PR either way.
countHeldTokens doesn't filter on amount, so emptied accounts count toward the Tokens tile and get 0% segments in the bar. You already filter this in wallet-asset-breakdown.tsx:19-21 on the same data. One caveat, I couldn't tell from code whether Helius actually returns emptied ATAs for these wallets, which is the difference between cosmetic and a wrong number on the front page, so maybe worth an eyeball on a staging response.
Two nits: "Today's Volume" lost the hint that separated loading from a real zero, so they're now identical. And noWalletsYet plus the three hint keys are unused in both catalogs.
…onger holds hideTitle was only ever argued for home; the seven other routes had no replacement heading, so they went from a 36px h1 to sr-only for no stated reason. Home keeps it, the rest are back. The activity Token column re-resolved from the mint against balances alone, which fell through to a shortened mint — truthy, so it beat the authoritative issued symbol the row already carried. Rows now seed the map, balances still win. Tokens held counted every aggregate row, including spent accounts sitting at zero; the list and the tile now share one definition of held.
Tokens held now uses the same finite-and-positive rule as wallet-asset-breakdown rather than a second definition. The breakdown list keeps the looser one on purpose — a row whose amount will not parse is still worth showing as unpriced, just not worth claiming as a holding.
Help check again to see if the updates satisfy the requested changes chief. |
GuiBibeau
left a comment
There was a problem hiding this comment.
do a review of the pull french with the LLM ensuring we kee english context for some words french does not translate in regular talk. Ex: Token, nobody says jetons
The French home copy translated Token to jeton and Wallet to portefeuille, which nobody says in daily use and which the rest of homeWorkspace already avoids. Also drops four home keys nothing renders.
Product PRs change only the English source catalog now; Eve fills locale keys on the release branch and a missing key falls back to English at runtime.
translate only substitutes {name}, so the plural forms reached the page verbatim. Splits them into singular and count keys the way the rest of the catalog does, and guards the catalogs against ICU syntax in a test.
|
all nine keys had it, not just those two.
|
The home page showed two currency tiles and one table, leaving most of the viewport empty and answering no question first.
It now leads with total balance at full weight, with the day's volume, wallet count and tokens held as context beneath it and the primary actions in the same block. Token allocation folds into the same card, so the money picture is one object rather than three.
Details worth a look:
TokenMark, so bundled logos render and everything else gets a monogram. Hovering a segment or a row lifts that holding and drops the others; segments are buttons, so keyboard focus does the same./dashboardstops painting a 36px "Home" title, which said nothing the sidebar and the page did not already say. The heading is nowsr-only; other routes are unchanged.Rendered and checked in dark and light. Allocation logic is a pure module with unit tests.
Screenshots