stats: /stats/countries comparison and /stats/countries/[iso3] profiles (Curaçao via World Bank), more WB indicators, Countries + Curaçao cards, nav/sitemap/start links
All checks were successful
Deploy production / deploy (push) Successful in 1m13s

This commit is contained in:
2026-10-25 21:22:20 +00:00
parent d19313035f
commit 2a4466cb82
12 changed files with 887 additions and 5 deletions

130
src/lib/stats/countries.ts Normal file
View File

@@ -0,0 +1,130 @@
// Country profiles for /stats/countries and /stats/countries/[iso3]: which regions get a page,
// and which normalised series (World Bank, IMF WEO) feed each indicator. IMF first where it
// exists (it has forecasts); the World Bank fills in for places the IMF skips, like Curaçao.
export const COUNTRY_PAGES = [
'NLD',
'CUW',
'USA',
'KOR',
'CHN',
'DEU',
'FRA',
'BEL',
'GBR',
'JPN',
'IND',
'BRA',
'RUS',
'EU27',
'WLD'
] as const;
export type CountryCode = (typeof COUNTRY_PAGES)[number];
export const isCountryPage = (code: string): code is CountryCode =>
(COUNTRY_PAGES as readonly string[]).includes(code);
export const FLAG: Record<string, string> = {
NLD: '🇳🇱',
CUW: '🇨🇼',
USA: '🇺🇸',
KOR: '🇰🇷',
CHN: '🇨🇳',
DEU: '🇩🇪',
FRA: '🇫🇷',
BEL: '🇧🇪',
GBR: '🇬🇧',
JPN: '🇯🇵',
IND: '🇮🇳',
BRA: '🇧🇷',
RUS: '🇷🇺',
EU27: '🇪🇺',
WLD: '🌍'
};
export const COUNTRY_COLOR: Record<string, string> = {
NLD: '#f97316',
CUW: '#06b6d4',
USA: '#3b82f6',
KOR: '#e11d48',
CHN: '#eab308',
DEU: '#64748b',
FRA: '#6366f1',
BEL: '#a16207',
GBR: '#a855f7',
JPN: '#ec4899',
IND: '#10b981',
BRA: '#84cc16',
RUS: '#0d9488',
EU27: '#1d4ed8',
WLD: '#94a3b8'
};
/** Comparison columns: series id candidates in order of preference ({c} = region code). */
export const COMPARE_COLUMNS = [
{ key: 'pop', label: 'Population', ids: ['wb:SP.POP.TOTL:{c}'], fmt: 'compact' },
{ key: 'gdppc', label: 'GDP/cap PPP', ids: ['wb:NY.GDP.PCAP.PP.KD:{c}'], fmt: 'usd' },
{
key: 'growth',
label: 'Growth',
ids: ['imf:NGDP_RPCH:{c}', 'wb:NY.GDP.MKTP.KD.ZG:{c}'],
fmt: 'pct'
},
{
key: 'infl',
label: 'Inflation',
ids: ['imf:PCPIPCH:{c}', 'wb:FP.CPI.TOTL.ZG:{c}'],
fmt: 'pct'
},
{
key: 'unemp',
label: 'Unemployment',
ids: ['imf:LUR:{c}', 'wb:SL.UEM.TOTL.ZS:{c}'],
fmt: 'pct'
},
{
key: 'debt',
label: 'Gov. debt',
ids: ['imf:GGXWDG_NGDP:{c}', 'wb:GC.DOD.TOTL.GD.ZS:{c}'],
fmt: 'pct'
},
{ key: 'life', label: 'Life exp.', ids: ['wb:SP.DYN.LE00.IN:{c}'], fmt: 'years' }
] as const;
export const seriesIds = (c: string, ids: readonly string[]) => ids.map((i) => i.replace('{c}', c));
/** Indicators shown on a country page (World Bank ids unless prefixed). */
export const PROFILE_SERIES = [
'wb:SP.POP.TOTL',
'wb:SM.POP.NETM',
'wb:SP.DYN.LE00.IN',
'wb:SP.DYN.TFRT.IN',
'wb:SP.POP.65UP.TO.ZS',
'wb:NY.GDP.PCAP.KD',
'wb:NY.GDP.PCAP.PP.KD',
'wb:NY.GNP.PCAP.CD',
'wb:NY.GDP.MKTP.CD',
'wb:NY.GDP.MKTP.KD.ZG',
'wb:FP.CPI.TOTL.ZG',
'wb:SL.UEM.TOTL.ZS',
'wb:NE.TRD.GNFS.ZS',
'wb:NE.EXP.GNFS.ZS',
'wb:NE.IMP.GNFS.ZS',
'wb:NV.SRV.TOTL.ZS',
'wb:ST.INT.ARVL',
'wb:ST.INT.RCPT.CD',
'wb:EG.IMP.CONS.ZS',
'wb:EG.ELC.RNEW.ZS',
'wb:TM.TAX.MRCH.WM.AR.ZS',
'wb:GC.REV.XGRT.GD.ZS',
'wb:GC.XPN.TOTL.GD.ZS',
'wb:GC.DOD.TOTL.GD.ZS',
'imf:NGDP_RPCH',
'imf:NGDPDPC',
'imf:PPPPC',
'imf:PCPIPCH',
'imf:LUR',
'imf:GGXWDG_NGDP',
'imf:GGXCNL_NGDP',
'imf:GGR_G01_GDP_PT',
'imf:G_X_G01_GDP_PT'
];

View File

@@ -31,5 +31,8 @@ export const COUNTRY: Record<string, string> = {
BEL: 'Belgium',
GBR: 'United Kingdom',
JPN: 'Japan',
IND: 'India'
IND: 'India',
BRA: 'Brazil',
RUS: 'Russia',
EU27: 'European Union'
};