import type { Metadata } from 'next'; import Link from 'next/link'; import { t } from '@/i18n'; import { api, isNotBuilt, safe } from '@/lib/api'; import { apiAnalytics } from '@/lib/api-analytics'; import { apiExplore } from '@/lib/api-explore'; import { routes } from '@/lib/site'; import { HEADLINE_INDICATORS } from '@/lib/topics'; import { RankedBars, rankedRowFromCountry } from '@/components/charts/ranked-bars'; import type { IndicatorOption } from '@/components/controls/indicator-select'; import { NotBuiltState } from '@/components/data/empty-state'; import { Section } from '@/components/data/section'; import { SimilarityPlayground } from '@/components/explore/similarity-playground'; import { CompareTeaser } from '@/components/home/compare-teaser'; import { IndicatorList } from '@/components/home/featured-indicators'; import { Hero } from '@/components/home/hero'; import { HeroMap, type HeroCountry } from '@/components/home/hero-map'; import { LatestUpdates } from '@/components/home/latest-updates'; import { Movers } from '@/components/home/movers'; import { SnapshotStrip } from '@/components/home/snapshot-strip'; import { TopicsGrid } from '@/components/home/topics-grid'; import { TrajectoryTeaser } from '@/components/home/trajectory-teaser'; import { Transparency } from '@/components/home/transparency'; import { WorldPulse } from '@/components/home/world-pulse'; import { baseFeatures } from '@/components/indicators/map-geometry'; export const metadata: Metadata = { alternates: { canonical: '/' } }; export const revalidate = 900; const DEFAULT_MAP = 'gdp-per-capita-ppp'; const MAP_CHIPS = ['gdp-per-capita-ppp', 'population', 'gdp', 'gdp-growth', 'inflation', 'life-expectancy', 'fertility-rate', 'internet-users', 'co2-per-capita', 'renewable-electricity-share', 'unemployment-rate', 'population-growth']; /** The three curated lists kept on the home page (the rest lives on /rankings). */ const LIST_KEYS = ['largest_economies', 'highest_life_expectancy', 'energy_transition_leaders'] as const; export default async function HomePage() { let home: Awaited> | null = null; let notBuilt = false; try { home = await api.home(); } catch (e) { if (isNotBuilt(e)) notBuilt = true; else throw e; } if (notBuilt || !home) { return ( <> ); } const [countriesRes, frames, indicators, pulse, movers, scatter, updates, sources] = await Promise.all([ safe(api.countries()), safe(apiAnalytics.indicatorFrames(DEFAULT_MAP)), safe(apiExplore.indicators({ with_data: true })), safe(apiAnalytics.pulse()), safe(apiAnalytics.movers({ window: 1, limit: 12 })), safe(apiAnalytics.scatter({ x: 'gdp-per-capita-ppp', y: 'life-expectancy', size: 'population' })), safe(apiAnalytics.updates()), safe(apiExplore.sources()), ]); const countries = countriesRes?.items ?? []; const { features, sphere } = countries.length ? baseFeatures(countries) : { features: [], sphere: '' }; const heroCountries: HeroCountry[] = countries.map((c) => ({ id: c.id, slug: c.slug, name: c.name ?? c.id, flag: c.flag, region: c.region })); const options: IndicatorOption[] = (indicators?.items ?? []) .filter((i) => (i.n_countries ?? 0) >= 20 && i.frequency === 'A') .map((i) => ({ slug: i.slug, name: i.name ?? i.slug, short_name: i.short_name, topic: i.topic, unit: i.unit, featured: i.featured, first_year: i.first_year, last_year: i.last_year, n_countries: i.n_countries })); const chips = MAP_CHIPS.filter((s) => options.some((o) => o.slug === s)); const s = home.snapshot; return ( <> {/* Global interactive hero map + time machine */}

{t('home.map.title')}

{features.length ? ({ slug: sl, name: sl }))} chips={chips.length ? chips : [DEFAULT_MAP]} countries={heroCountries} /> : null}
{pulse && pulse.items.length ? (
{t('home.changes.all')} →}>
) : null}
{t('common.seeAll')} →}>
{LIST_KEYS.map((key) => { const list = home.lists[key]; if (!list || !list.rows?.length) return null; const latestYear = Math.max(0, ...list.rows.map((r) => r.year ?? 0)); return (

{list.title}

{list.description}
{list.filter_note ?

{list.filter_note}

: null} rankedRowFromCountry(r.country, r.value, r.rank, null, r.year != null && latestYear - r.year >= 2 ? r.year : null))} spec={list.indicator} provenance={list.rows[0]?.provenance ?? null} /> {t('common.seeFullRanking')} →
); })}
{scatter && scatter.points.length ? (
) : null}
{updates ? (
) : (
)}
); }