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 (| Figure | Scope | Value | Source | Published | Confidence | Tier | Status |
|---|---|---|---|---|---|---|---|
|
|
|
|
|
{c.publishedAt ? fmtDate(c.publishedAt) : "—"} |
|
|
{CLAIM_STATUS_LABEL[c.status]} |