SPB Git forge

spb/countryatlas

Public
20commits 1branches 0releases
268.3 MBsize
maindefault branch
12 days agolast push
TypeScript 57% Python 38.6% JavaScript 3.6% CSS 0.6%
2.6 KB · 57 lines tsx
Raw Blame History
1import type { Metadata } from 'next';2import { t } from '@/i18n';3import { isNotBuilt, safe } from '@/lib/api';4import { apiAnalytics } from '@/lib/api-analytics';5import { apiExplore } from '@/lib/api-explore';6import { routes } from '@/lib/site';7import { NotBuiltState } from '@/components/data/empty-state';8import { DEFAULT_TRAJ, explorerIndicators, firstParam, parseYearParam, slugParam, type SP } from '@/components/explorer/options';9import { ScatterView } from '@/components/explorer/scatter-view';1011export const revalidate = 900;1213function parseState(sp: SP) {14  const log = (firstParam(sp, 'log') ?? '').toLowerCase();15  const country = (firstParam(sp, 'country') ?? '').toLowerCase();16  return {17    x: slugParam(firstParam(sp, 'x'), DEFAULT_TRAJ.x)!,18    y: slugParam(firstParam(sp, 'y'), DEFAULT_TRAJ.y)!,19    size: slugParam(firstParam(sp, 'size'), DEFAULT_TRAJ.size)!,20    year: parseYearParam(firstParam(sp, 'year')),21    group: slugParam(firstParam(sp, 'group'), 'world')!,22    log: /^(x|y|x,y|y,x|none)$/.test(log) ? log : null,23    fit: firstParam(sp, 'fit') === '1',24    country: /^[a-z]{3}$/.test(country) ? country : null,25  };26}2728export async function generateMetadata({ searchParams }: { searchParams: Promise<SP> }): Promise<Metadata> {29  const sp = await searchParams;30  return {31    title: t('scatter.metaTitle'),32    description: t('scatter.description'),33    alternates: { canonical: routes.scatter() },34    robots: Object.keys(sp).length ? { index: false, follow: true } : undefined,35    openGraph: { title: `${t('scatter.metaTitle')} — ${t('site.name')}`, description: t('scatter.description'), url: routes.scatter(), type: 'website' },36  };37}3839export default async function ScatterPage({ searchParams }: { searchParams: Promise<SP> }) {40  const state = parseState(await searchParams);41  let indicatorsRes;42  try {43    indicatorsRes = await apiExplore.indicators({ with_data: true });44  } catch (e) {45    if (isNotBuilt(e)) return <NotBuiltState />;46    throw e;47  }48  const logX = state.log == null ? null : state.log.includes('x');49  const logY = state.log == null ? null : state.log.includes('y');50  const [groupsRes, scatter, related] = await Promise.all([51    safe(apiExplore.regions()),52    safe(apiAnalytics.scatter({ x: state.x, y: state.y, size: state.size, year: state.year, group: state.group !== 'world' ? state.group : null, log_x: logX == null ? null : String(logX), log_y: logY == null ? null : String(logY) })),53    safe(apiAnalytics.indicatorRelated(state.x, { limit: 8 })),54  ]);55  return <ScatterView indicators={explorerIndicators(indicatorsRes.items)} groups={groupsRes?.items ?? []} initial={scatter} initialRelated={related} initialState={state} />;56}57