import Link from 'next/link'; import { Section, KV, Note } from '@/components/ui/section'; import { EmptyState } from '@/components/ui/empty-state'; import { Badge, ClaimBadge } from '@/components/ui/badge'; import { SourceBadge } from '@/components/ui/source-badge'; import { Freshness } from '@/components/ui/freshness'; import { CompletenessDots } from '@/components/ui/completeness'; import { loadProvenance, toInfo } from '@/lib/queries/provenance'; import { fmtInt, humanize, isoDate } from '@/lib/format'; import { KeyFigures, CompletenessRow } from '../key-figures'; import type { CancerBundle } from '../load'; export async function OverviewTab({ b }: { b: CancerBundle }) { const { cancer: c, counters, parents, children, aliases, anatomy } = b; const prov = await loadProvenance([c.description_provenance_id]); const descProv = toInfo(prov.get(c.description_provenance_id ?? -1), 'raw'); const byType = new Map(); for (const p of parents) byType.set(p.hierarchy_type, [...(byType.get(p.hierarchy_type) ?? []), p]); const childrenByType = new Map(); for (const ch of children) childrenByType.set(ch.hierarchy_type, [...(childrenByType.get(ch.hierarchy_type) ?? []), ch]); const synonyms = aliases.filter((a) => a.alias_type !== 'preferred' && a.alias_type !== 'abbreviation'); const knows = [ { label: `Taxonomy: ${parents.length} parent${parents.length === 1 ? '' : 's'}, ${children.length} ${children.length === 1 ? 'child' : 'children'}`, href: `/cancer/${c.slug}#taxonomy` }, ...(anatomy.length ? [{ label: `Anatomy: ${anatomy.map((a) => a.name).join(', ')}`, href: `/cancer/${c.slug}#anatomy` }] : []), ...(b.codes.length ? [{ label: `${b.codes.length} cross-reference codes`, href: `/cancer/${c.slug}/sources` }] : []), ]; return (
{/* Key figures strip (§43, §309): full width, above the definition. */}
{c.description ? ( <>

{c.description}

{/* div, not p: the SourceBadge popover contains a
, which the HTML parser uses to close an open

→ hydration mismatch (React #418). */}

Definition text as published by {descProv ? : 'the source terminology'}
) : ( The NCIt definition is attached when the NCIt connector ingests this concept{c.primary_ncit_code ? ` (${c.primary_ncit_code})` : ''}. CancerIndex does not write its own definitions. )}
{parents.length === 0 && children.length === 0 ? ( No hierarchy edge for this entity yet. ) : (

Parents

{parents.length ? ( [...byType.entries()].map(([type, ps]) => (
{type}
    {ps.map((p) => (
  • {p.canonical_name} {humanize(p.entity_type)}
  • ))}
)) ) : (

Root node — no parent in any ingested hierarchy.

)}

Children ({fmtInt(children.length)})

{children.length ? ( [...childrenByType.entries()].map(([type, cs]) => (
{type}
    {cs.map((ch) => (
  • {ch.canonical_name} {ch.child_count > 0 ? {ch.child_count} sub : null}
  • ))}
)) ) : (

Leaf node — no children.

)}
)} {counters && counters.descendant_count > children.length ?

{fmtInt(counters.descendant_count)} descendants in total; counters on this page aggregate over all of them.

: null}
{anatomy.length ? (
    {anatomy.map((a) => (
  • {a.name} {a.relation !== 'primary' ? {a.relation} : null} {a.ncit_code ? {a.ncit_code} : null}
  • ))}
) : ( No anatomical site linked yet. )}
); }