import type { Metadata } from 'next'; import Link from 'next/link'; import { PageHeader, Section, Note } from '@/components/ui/section'; import { EmptyState } from '@/components/ui/empty-state'; import { Freshness } from '@/components/ui/freshness'; import { Badge } from '@/components/ui/badge'; import { SourceBadge } from '@/components/ui/source-badge'; import { listGeographiesWithObservations, topCancersFor, allSitesObservations, WHO_REGION_LABEL } from '@/lib/queries/geography'; import { listSources } from '@/lib/queries/sources'; import { fmtInt, fmtValue, humanize, toDate, unitLabel } from '@/lib/format'; export const metadata: Metadata = { title: 'Countries', description: 'Geographies with cancer epidemiology observations in CancerIndex: years covered, sources, and the latest-year figures per country.', alternates: { canonical: '/countries' }, }; export const revalidate = 3600; /** * /countries (§47): every geography that carries at least one epidemiology observation, with its year span, * the sources behind it and either the all-sites totals (when the source publishes one) or the top cancer by * deaths / new cases for the latest year. Geographies without data are not listed — nothing is invented. */ export default async function CountriesPage() { const [geos, sources] = await Promise.all([listGeographiesWithObservations(), listSources()]); const epiSources = sources.filter((s) => ['cdc-uscs', 'cdc-wonder', 'seer', 'seer-explorer', 'iarc-globocan'].includes(s.slug)); const details = await Promise.all( geos.map(async (g) => { const [allSites, deaths, cases] = await Promise.all([allSitesObservations(g.id, g.max_year, 'all'), topCancersFor(g, 'mortality_count', g.max_year, 'all', 1), topCancersFor(g, 'incidence_count', g.max_year, 'all', 1)]); return { g, allSites, deaths, cases }; }), ); const freshest = geos.map((g) => toDate(g.last_updated)).filter((d): d is Date => !!d).sort((a, b) => b.getTime() - a.getTime())[0] ?? null; return (
Epidemiology sources:
{epiSources.map((s) => (
| Geography | ISO3 | WHO region | Years | Cancers | Observations | Sources | Latest year | Highest annual deaths | Highest annual new cases |
|---|---|---|---|---|---|---|---|---|---|
| {g.name} {humanize(g.kind)} | {g.iso3 ?? '—'} | {g.who_region ? WHO_REGION_LABEL[g.who_region] ?? g.who_region : '—'} | {g.min_year}–{g.max_year} | {fmtInt(g.n_cancers)} | {fmtInt(g.n_obs)} |
{(g.sources ?? []).map((s) => (
|
{g.max_year} | {td ? ( All sites: {fmtValue(td.value, td.unit)} {unitLabel(td.unit)} ({td.year}) ) : d0 ? ( {d0.canonical_name} {' '} {fmtValue(d0.value, d0.unit)} ({deaths.year}) ) : ( — )} | {tc ? ( All sites: {fmtValue(tc.value, tc.unit)} {unitLabel(tc.unit)} ({tc.year}) ) : c0 ? ( {c0.canonical_name} {' '} {fmtValue(c0.value, c0.unit)} ({cases.year}) ) : ( — )} |
"Highest annual deaths / new cases" is the top single site group for the latest year of that metric, both sexes, all ages — not a national total. Where a source publishes an all-sites aggregate it is shown instead and labelled "All sites".
Source registry and license status → {' '} ·{' '} Methodology: country scopes →