Skip to content

Commit e664e79

Browse files
sktbrdclaude
andauthored
feat(treasury): Token Holdings beside yield, NFT grid full width (#273)
* wip(treasury): Token Holdings to the right column, NFT grid full width Sponsorship left ~280px of dead space; Token Holdings (three rows) fills it, and its old half-width row goes to the NFT grid — the one section where width is the feature. Preview grows 7 -> 15 + the +N tile: two complete 8-column rows at sm+, four complete 4-column rows on mobile, no holes at either breakpoint. WIP: compiles clean (tsc/eslint/prettier), structure confirmed rendering (Token Holdings in the right column, NFT section full width), but a clean LOADED capture was not obtained - dev-server recompiles kept catching the page mid-stream. Do not merge without the capture. * fix(treasury): two-line token rows so values fit the narrow column The three-column table clipped its Value column once Token Holdings moved into the right-hand column. Stacked value-over-amount rows fit any width; the now-unused table header keys are dropped from both locales. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
1 parent ee4edd3 commit e664e79

5 files changed

Lines changed: 53 additions & 68 deletions

File tree

messages/en/treasury.json

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,6 @@
1515
"tokens": {
1616
"title": "Token Holdings",
1717
"description": "ERC-20 tokens held in the treasury",
18-
"table": {
19-
"token": "Token",
20-
"amount": "Amount",
21-
"valueUsd": "Value (USD)"
22-
},
2318
"empty": "No tokens found",
2419
"emptyDescription": "The treasury currently holds no ERC-20 tokens",
2520
"errorLoading": "Error loading token holdings: {error}"

messages/pt-br/treasury.json

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,6 @@
1515
"tokens": {
1616
"title": "Holdings de Tokens",
1717
"description": "Tokens ERC-20 mantidos no tesouro",
18-
"table": {
19-
"token": "Token",
20-
"amount": "Quantia",
21-
"valueUsd": "Valor (USD)"
22-
},
2318
"empty": "Nenhum token encontrado",
2419
"emptyDescription": "O tesouro não tem tokens ERC-20 no momento",
2520
"errorLoading": "Erro ao carregar holdings de tokens: {error}"

src/app/[locale]/treasury/page.tsx

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,16 @@ export default async function TreasuryPage({ params }: { params: Promise<{ local
138138
<Suspense fallback={<TableSkeleton />}>
139139
<TreasuryInflows locale={locale} />
140140
</Suspense>
141-
<SponsorshipYield />
141+
{/* Sponsorship alone left ~280px of dead space under it while the
142+
inflows column ran long. Token Holdings is three rows — it fills
143+
that void, and surrendering its old half-width row gives the NFT
144+
grid the full width it actually benefits from. */}
145+
<div className="space-y-6">
146+
<SponsorshipYield />
147+
<Suspense fallback={<TableSkeleton />}>
148+
<TokenHoldings treasuryAddress={DAO_ADDRESSES.treasury} />
149+
</Suspense>
150+
</div>
142151
</div>
143152

144153
{/* Charts */}
@@ -151,13 +160,9 @@ export default async function TreasuryPage({ params }: { params: Promise<{ local
151160
</div>
152161
</div>
153162

154-
{/* Holdings, paired: fungible on the left, the Gnars themselves on the
155-
right. Both answer "what is in there", so they belong on one row. */}
156-
<div className="grid grid-cols-1 gap-6 lg:grid-cols-[minmax(0,1.15fr)_minmax(0,1fr)]">
157-
<Suspense fallback={<TableSkeleton />}>
158-
<TokenHoldings treasuryAddress={DAO_ADDRESSES.treasury} />
159-
</Suspense>
160-
163+
{/* The Gnars themselves, full width — the one section where width is
164+
the feature (Token Holdings moved up beside the sponsorship card). */}
165+
<div>
161166
<div className="space-y-4">
162167
<div className="space-y-2">
163168
<h2 className="text-xl font-semibold">{t("page.nftSection.title")}</h2>

src/components/treasury/NftHoldings.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@ import { subgraphQuery } from "@/lib/subgraph";
2525
* scroll for screens on end and left a tall column of page background next to a
2626
* short neighbour.
2727
*/
28-
const PREVIEW_COUNT = 7;
28+
// 15 + the "+N" tile: full width gives the grid 8 columns from `sm`, so the
29+
// preview is two complete rows there — and exactly four complete rows of the
30+
// 4-column mobile grid. Both breakpoints close without holes.
31+
const PREVIEW_COUNT = 15;
2932

3033
interface NftHoldingsProps {
3134
treasuryAddress: string;
@@ -242,7 +245,7 @@ export function NftHoldings({ treasuryAddress }: NftHoldingsProps) {
242245
{/* Preview: plain image tiles, not GnarCards. The card sits in a narrow
243246
column, and the full card's date/bid/winner rows would be unreadable at
244247
this width — the detail belongs in the dialog, where there is room. */}
245-
<div className="grid grid-cols-4 gap-2.5">
248+
<div className="grid grid-cols-4 gap-2.5 sm:grid-cols-8">
246249
{tokens.slice(0, PREVIEW_COUNT).map((token) => (
247250
<div
248251
key={`preview-${token.id}`}

src/components/treasury/TokenHoldingsClient.tsx

Lines changed: 35 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,6 @@
33
import { useLocale, useTranslations } from "next-intl";
44
import Image from "next/image";
55
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
6-
import {
7-
Table,
8-
TableBody,
9-
TableCell,
10-
TableHead,
11-
TableHeader,
12-
TableRow,
13-
} from "@/components/ui/table";
146
import { toIntlLocale } from "@/lib/i18n/format";
157

168
export interface EnrichedToken {
@@ -82,47 +74,42 @@ export function TokenHoldingsClient({ tokens, error }: TokenHoldingsClientProps)
8274
<CardDescription>{t("tokens.description")}</CardDescription>
8375
</CardHeader>
8476
<CardContent>
85-
<Table>
86-
<TableHeader>
87-
<TableRow>
88-
<TableHead>{t("tokens.table.token")}</TableHead>
89-
<TableHead className="text-right">{t("tokens.table.amount")}</TableHead>
90-
<TableHead className="text-right">{t("tokens.table.valueUsd")}</TableHead>
91-
</TableRow>
92-
</TableHeader>
93-
<TableBody>
94-
{tokens.map((token) => (
95-
<TableRow key={token.contractAddress}>
96-
<TableCell>
97-
<div className="flex items-center space-x-3">
98-
{token.logo && (
99-
<Image
100-
src={token.logo}
101-
alt={token.symbol}
102-
width={24}
103-
height={24}
104-
className="rounded-full"
105-
onError={(event) => {
106-
event.currentTarget.style.display = "none";
107-
}}
108-
/>
109-
)}
110-
<div>
111-
<div className="font-medium">{token.name}</div>
112-
<div className="text-sm text-muted-foreground">{token.symbol}</div>
113-
</div>
114-
</div>
115-
</TableCell>
116-
<TableCell className="text-right tabular-nums">
77+
{/* Two-line rows instead of a three-column table: this card lives in
78+
the narrow right column, where the table's Value column clipped
79+
against the card edge. */}
80+
<ul className="divide-y">
81+
{tokens.map((token) => (
82+
<li
83+
key={token.contractAddress}
84+
className="flex items-center justify-between gap-3 py-3 first:pt-0 last:pb-0"
85+
>
86+
<div className="flex min-w-0 items-center gap-3">
87+
{token.logo && (
88+
<Image
89+
src={token.logo}
90+
alt={token.symbol}
91+
width={24}
92+
height={24}
93+
className="rounded-full"
94+
onError={(event) => {
95+
event.currentTarget.style.display = "none";
96+
}}
97+
/>
98+
)}
99+
<div className="min-w-0">
100+
<div className="truncate font-medium">{token.name}</div>
101+
<div className="text-sm text-muted-foreground">{token.symbol}</div>
102+
</div>
103+
</div>
104+
<div className="shrink-0 text-right">
105+
<div className="font-medium tabular-nums">{formatUsdValue(token.usdValue)}</div>
106+
<div className="text-sm text-muted-foreground tabular-nums">
117107
{formatBalance(token.balance, token.decimals)} {token.symbol}
118-
</TableCell>
119-
<TableCell className="text-right tabular-nums">
120-
{formatUsdValue(token.usdValue)}
121-
</TableCell>
122-
</TableRow>
123-
))}
124-
</TableBody>
125-
</Table>
108+
</div>
109+
</div>
110+
</li>
111+
))}
112+
</ul>
126113
</CardContent>
127114
</Card>
128115
);

0 commit comments

Comments
 (0)