import type { ClaimDTO } from "@dci/core"; import { ExternalLink } from "lucide-react"; import { ConfidenceBadge, EstimateMark, ScopeBadge, SemanticsLabel, TierMark } from "@/components/ui/badge"; import { SourceBadge } from "@/components/ui/source-badge"; import { TBody, THead, Table, Td, Th, Tr } from "@/components/ui/table"; import { fmtDate, fmtValue } from "@/lib/format"; import { CLAIM_STATUS_LABEL, isSiteScopeLabel } from "@/lib/labels"; import { Evidence } from "./evidence-context"; /** * Every capacity / investment claim on a record: predicate · scope · value · source · published · confidence · tier. * Site-scoped claims come first; non-site claims (portfolio, company, metro…) are grouped under * "Figures not assigned to this site" so they are never read as the record's own MW. */ export function ClaimsTable({ claims, kind = "capacity", emptyNote }: { claims: ClaimDTO[]; kind?: "capacity" | "investment" | "all"; emptyNote?: string }) { const rows = claims.filter((c) => (kind === "all" ? true : kind === "capacity" ? /_mw$/.test(c.predicate) : /_usd$/.test(c.predicate))); if (!rows.length) return

{emptyNote ?? `No ${kind === "all" ? "" : `${kind} `}claim has been extracted for this record yet — the figures above come from structured source fields (see Source evidence).`}

; const site = rows.filter((c) => isSiteScopeLabel(c.scope)); const other = rows.filter((c) => !isSiteScopeLabel(c.scope)); return (
{site.length > 0 && } {other.length > 0 && (

Figures not assigned to this site

portfolio, company, metro, country or unknown scope — shown as evidence, never summed into this record
)}
); } function Rows({ rows }: { rows: ClaimDTO[] }) { const sorted = [...rows].sort((a, b) => Number(b.isWinner) - Number(a.isWinner) || a.predicate.localeCompare(b.predicate) || ((a.publishedAt ?? a.retrievedAt) < (b.publishedAt ?? b.retrievedAt) ? 1 : -1)); return ( {sorted.map((c) => ( ))}
Figure Scope Value Source Published Confidence Tier Status
{c.isWinner && shown} {c.isEstimate && } {c.value !== null ? fmtValue(c.value, c.unit === "USD" ? "usd" : "mw") : (c.valueText ?? "—")} {c.sourceName} {c.publishedAt ? fmtDate(c.publishedAt) : "—"} {CLAIM_STATUS_LABEL[c.status]}
); }