import { Download, Scale } from 'lucide-react'; import Link from 'next/link'; import { t } from '@/i18n'; import { compact, displayValue, formatDate, formatPct, grouped, isNum } from '@/lib/format'; import { routes } from '@/lib/site'; import type { CountryResponse } from '@/lib/types'; import type { CountryQualityResponse } from '@/lib/types-analytics'; import { FreshnessBadge } from '@/components/data/freshness-badge'; import { QualityBadges } from '@/components/data/quality-badge'; import { CopyApiButton } from './copy-api-button'; import { MiniMap } from './mini-map'; import { ShareButton } from './share-button'; /** * Country hero 2.0: flag + display name + official name, chips (region · income · capital), a fact strip * (population, GDP, GDP/capita, area, currency), locator mini map, bordering countries, freshness + coverage * badges, actions Compare / Download / Share / API. Editorial: one rule below, no card. */ export function CountryHeader({ data, quality }: { data: CountryResponse; quality: CountryQualityResponse | null }) { const c = data.country; const name = c.name ?? c.id; const pick = (id: string) => data.headline.find((m) => m.indicator === id && m.has_data) ?? null; const pop = pick('population'); const gdp = pick('gdp'); const gpc = pick('gdp-per-capita'); const facts: Array<{ k: string; v: string; sub?: string }> = []; if (pop && isNum(pop.value)) facts.push({ k: t('country.population'), v: displayValue(pop.value, pop, pop.formatted), sub: pop.year ? String(pop.year) : undefined }); if (gdp && isNum(gdp.value)) facts.push({ k: t('common.gdp'), v: displayValue(gdp.value, gdp, gdp.formatted), sub: gdp.year ? String(gdp.year) : undefined }); if (gpc && isNum(gpc.value)) facts.push({ k: t('common.gdpPerCapita'), v: displayValue(gpc.value, gpc, gpc.formatted), sub: gpc.year ? String(gpc.year) : undefined }); if (isNum(c.area_km2)) facts.push({ k: t('country.area'), v: `${c.area_km2 >= 1e6 ? compact(c.area_km2) : grouped(c.area_km2)} km²` }); if (c.currency_code) facts.push({ k: t('country.currency'), v: c.currency_code, sub: c.currency_name ?? undefined }); const chips = [c.region_name, c.income_name, c.capital ? `${t('country.capital')} ${c.capital}` : null].filter(Boolean) as string[]; const badges = quality ? deriveCountryBadges(quality) : null; return (
{c.flag}

{name}

{c.official_name && c.official_name !== name ?

{c.official_name}

: null}
    {chips.map((ch) => (
  • {ch}
  • ))} {c.landlocked ?
  • {t('country.landlocked')}
  • : null} {c.status === 'territory' ?
  • {t('countries.territory')}
  • : null}
{facts.map((f, i) => (
0 ? 'border-l border-rule pl-4 sm:border-l-0' : ''}`}>
{f.k}
{f.v}
{f.sub ?
{f.sub}
: null}
))}
{data.freshness.retrieved_at ? {t('country.refreshed', { date: formatDate(data.freshness.built_at ?? data.freshness.retrieved_at) })} : null} {quality ? {t('country.coverage', { pct: formatPct(quality.summary.coverage_pct), n: grouped(quality.summary.n_with_data) })} : data.coverage ? {t('country.coverage', { pct: formatPct(data.coverage.coverage_pct), n: grouped(data.coverage.n_indicators ?? 0) })} : null} {quality ? {t('country.freshSplit', { fresh: quality.summary.n_fresh, stale: quality.summary.n_stale })} : null}
{t('country.compare')} {t('country.download')}
{data.neighbours.length ? (
{t('country.borders')}:
    {data.neighbours.map((n) => (
  • {n.flag} {n.name}
  • ))}
) : (

{c.landlocked === false ? t('country.noLandBorders') : ''}

)}
); } /** Coarse badges for the whole country from the quality summary. */ function deriveCountryBadges(q: CountryQualityResponse): Array<'fresh' | 'stale' | 'limited-coverage' | 'sparse' | 'flagged'> { const out: Array<'fresh' | 'stale' | 'limited-coverage' | 'sparse' | 'flagged'> = []; const s = q.summary; if (s.n_with_data && s.n_fresh / s.n_with_data >= 0.6) out.push('fresh'); if (s.n_with_data && s.n_stale / s.n_with_data >= 0.4) out.push('stale'); if ((s.coverage_pct ?? 100) < 50) out.push('limited-coverage'); if (s.n_with_data && s.n_sparse / s.n_with_data >= 0.3) out.push('sparse'); if (s.n_with_data && s.n_flagged / s.n_with_data >= 0.3) out.push('flagged'); return out; }