doxa-maps-cdn/server/utils/countries.ts
corsacca eae6143be1
Replace country pages with region dashboards (#23)
* replace country pages with region dashboards

- move /countries to /regions, with 301 redirects from the old URLs in
  every locale
- add a region dashboard: a map of the region's countries with pins
  coloured by prayer coverage, headline figures, and prayer, adoption and
  engagement progress against the DOXA goals, plus a per-country table
- roll up progress stats per country and region in the shared summary
  and serve them from /api/regions
- frame region maps with antimeridian-aware bounds
- add Regions to the hamburger menu and translate the new strings in all
  eight locales

* put each region on the regions index in a card with a header band

The region name links to its dashboard with the site's chevron icon, and
the people-group and country counts sit centred beside it on a brand-green
header; the country list is the padded white card body.
2026-09-07 11:49:24 +01:00

49 lines
1.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Server-side accessor for the per-country and per-region summaries used by
// /api/countries and /api/regions. Fetches the full people-groups list from the
// prayer API and reduces it with config/countries-meta.ts.
//
// The list is cached per language for an hour: every prerendered region and
// country page (~185 pages × 8 locales) calls this during build, and the
// upstream list is ~2,100 rows. Without caching each page would re-fetch it.
import {
PEOPLE_GROUP_LIST_FIELDS,
summarizeCountries,
summarizeRegions,
type CountrySummary,
type PeopleGroupLite,
type RegionSummary
} from '~~/config/countries-meta'
import { LANGUAGE_CODES } from '~~/config/languages'
async function fetchPeopleGroups(lang: string): Promise<PeopleGroupLite[]> {
const base = useRuntimeConfig().prayBaseUrl as string
const data = await $fetch<{ posts?: PeopleGroupLite[] }>(`${base}/api/people-groups/list`, {
query: { fields: PEOPLE_GROUP_LIST_FIELDS, lang }
})
return data?.posts ?? []
}
// In dev, skip caching so data changes show up immediately. In production/build
// the per-language list is cached for an hour.
const getPeopleGroups: (lang: string) => Promise<PeopleGroupLite[]>
= import.meta.dev
? fetchPeopleGroups
: defineCachedFunction(fetchPeopleGroups, {
maxAge: 60 * 60,
name: 'people-groups-list',
getKey: (lang: string) => lang
})
export async function getCountriesSummary(lang: string): Promise<CountrySummary[]> {
return summarizeCountries(await getPeopleGroups(lang))
}
export async function getRegionsSummary(lang: string): Promise<RegionSummary[]> {
return summarizeRegions(await getPeopleGroups(lang))
}
// Validate a query `lang` against the known languages, defaulting to English.
export function resolveLang(input: unknown): string {
return LANGUAGE_CODES.includes(input as string) ? (input as string) : 'en'
}