Web: no function props from server pages into client charts (prerender fix)
3 changed files +6 −5
modified
apps/web/src/app/(site)/(home)/page.tsx
+2 −3
@@ -95,8 +95,8 @@ export default async function HomePage() { | ||
| 95 | 95 | href: r.href || routes.market(r.slug), |
| 96 | 96 | coverage: r.coverage, |
| 97 | 97 | secondary: r.coverage !== undefined && r.coverage !== null ? `${fmtPct(r.coverage)} MW coverage` : undefined, |
| 98 | + display: fmtMw(r.value), | |
| 98 | 99 | }))} |
| 99 | − format={(v) => fmtMw(v)} | |
| 100 | 100 | /> |
| 101 | 101 | ) : ( |
| 102 | 102 | <EmptyState compact title="Rankings not computed yet" /> |
@@ -106,8 +106,7 @@ export default async function HomePage() { | ||
| 106 | 106 | <Section title="Largest operators" description="By facility count and known MW." aside={<MoreLink href={routes.rankings("operators")} />}> |
| 107 | 107 | {d?.topOperators?.length ? ( |
| 108 | 108 | <BarList |
| 109 | − items={d.topOperators.slice(0, 10).map((r) => ({ rank: r.rank, label: r.name, value: r.value, href: r.href || routes.operator(r.slug), secondary: r.secondary !== undefined && r.secondary !== null ? fmtMw(r.secondary) : undefined }))} | |
| 110 | − format={(v) => fmtInt(v)} | |
| 109 | + items={d.topOperators.slice(0, 10).map((r) => ({ rank: r.rank, label: r.name, value: r.value, href: r.href || routes.operator(r.slug), secondary: r.secondary !== undefined && r.secondary !== null ? fmtMw(r.secondary) : undefined, display: fmtInt(r.value) }))} | |
| 111 | 110 | /> |
| 112 | 111 | ) : ( |
| 113 | 112 | <EmptyState compact title="Rankings not computed yet" /> |
modified
apps/web/src/app/(site)/rankings/(index)/page.tsx
+1 −1
@@ -60,7 +60,7 @@ function RankingCard({ r }: { r: Ranking }) { | ||
| 60 | 60 | </div> |
| 61 | 61 | {top.length > 0 && ( |
| 62 | 62 | <div className="min-w-0"> |
| 63 | − <BarList items={top.map((row) => ({ label: row.name, value: row.value, href: rowHref(row, r.scope), rank: row.rank, coverage: row.coverage }))} format={(v) => fmtRankValue(v, r.unit)} showRank /> | |
| 63 | + <BarList items={top.map((row) => ({ label: row.name, value: row.value, href: rowHref(row, r.scope), rank: row.rank, coverage: row.coverage, display: fmtRankValue(row.value, r.unit) }))} showRank /> | |
| 64 | 64 | </div> |
| 65 | 65 | )} |
| 66 | 66 | </div> |
modified
apps/web/src/components/ui/charts.tsx
+3 −1
@@ -69,6 +69,8 @@ export interface BarListItem { | ||
| 69 | 69 | /** 0..1 coverage → hatch hint when low */ |
| 70 | 70 | coverage?: number | null; |
| 71 | 71 | rank?: number; |
| 72 | + /** preformatted value (lets server components avoid passing formatter functions) */ | |
| 73 | + display?: string; | |
| 72 | 74 | } |
| 73 | 75 | |
| 74 | 76 | /** Horizontal ranked bars (rankings module). Value formatted by `format`. */ |
@@ -90,7 +92,7 @@ export function BarList({ items, format = fmtCompact, max, className, showRank = | ||
| 90 | 92 | <div className="h-full" style={{ width: `${pct}%`, background: barColor, opacity: it.coverage !== undefined && it.coverage !== null && it.coverage < 0.5 ? 0.55 : 1 }} /> |
| 91 | 93 | </div> |
| 92 | 94 | </div> |
| 93 | − <span className="figure w-[64px] text-right text-[12.5px] text-ink-2">{format(it.value)}</span> | |
| 95 | + <span className="figure w-[64px] text-right text-[12.5px] text-ink-2">{it.display ?? format(it.value)}</span> | |
| 94 | 96 | </div> |
| 95 | 97 | ); |
| 96 | 98 | return ( |
| 97 | 99 | |