import type { Metadata } from 'next';
import Link from 'next/link';
import { Suspense } from 'react';
import { t } from '@/i18n';
import { api, safe } from '@/lib/api';
import { apiExplore } from '@/lib/api-explore';
import { formatDate } from '@/lib/format';
import { SITE_URL, routes } from '@/lib/site';
import { toCountryLite } from '@/lib/types-compare';
import type { IndicatorOption } from '@/components/controls/indicator-select';
import { Section } from '@/components/data/section';
import { CodeBlock } from '@/components/explore/copy-button';
import { DownloadPicker } from '@/components/explore/download-picker';
import { PageHeader } from '@/components/explore/page-header';
import { FooterCredits } from '@/components/layout/site-footer';
import { DownloadBuilder } from '@/components/platform/download-builder';
export const revalidate = 3600;
export const metadata: Metadata = {
title: t('download.title'),
description: t('download.description'),
alternates: { canonical: routes.download() },
};
const COLUMNS = ['country_id', 'country_name', 'indicator_id', 'indicator_name', 'period', 'year', 'frequency', 'value', 'unit', 'is_estimate', 'is_forecast', 'status', 'source', 'source_name', 'dataset', 'series_code', 'retrieved_at', 'source_updated_at', 'url', 'licence'];
export default async function DownloadPage() {
const [sources, countriesRes, indicatorsRes] = await Promise.all([safe(apiExplore.sources()), safe(api.countries()), safe(apiExplore.indicators({ with_data: true }))]);
const items = sources?.items ?? [];
const names = items.map((s) => s.name ?? s.id);
const built = sources?.meta.built_at ?? null;
const countries = (countriesRes?.items ?? []).filter((c) => c.kind !== 'aggregate').map(toCountryLite).sort((a, b) => a.name.localeCompare(b.name));
// Plain data for the client builder (the helper in indicator-select.tsx is a client module; map here on the server).
const indicators: IndicatorOption[] = (indicatorsRes?.items ?? []).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 maxYear = Math.max(new Date().getUTCFullYear(), ...indicators.map((i) => i.last_year ?? 0));
const bulk = `# list indicators, then fetch each dataset\ncurl -s "${SITE_URL}/api/v1/indicators" | jq -r '.items[].slug' | while read slug; do\n curl -s -o "$slug.csv" "${SITE_URL}/api/v1/indicators/$slug/download.csv"; sleep 0.6\ndone`;
return (
<>
{t('download.quick.countrySub')} {t('download.quick.indicatorSub')}{t('download.quick.country')}
{t('download.quick.indicator')}
{t('download.bulk.text')}
{t('download.api.text', { base: `${SITE_URL}/api/v1` })}
{t('download.api.link')} →{t('download.licence.compilation')}
{t('download.licence.sources')}
| {t('download.licence.source')} | {t('download.licence.licence')} | {t('download.licence.attribution')} |
|---|---|---|
| {s.name ?? s.id} | {s.licence ?? t('common.na')} | {s.attribution ?? ''} |
{t('download.licence.exampleText', { sources: names.slice(0, 4).join(', ') || 'World Bank, IMF, OECD', date: formatDate(built ?? new Date().toISOString()) })}