doxa-maps-cdn/modules/region-routes.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
2.3 KiB
TypeScript
Raw Permalink 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.

// Build-time module that enumerates the region and country pages for
// prerendering.
//
// Crawling is disabled (nitro.prerender.crawlLinks = false), and the region and
// country sets are data-driven (derived from the prayer API), so the routes
// can't be a static list like the other marketing pages. At build we fetch the
// people-groups list once, derive the region and country slugs, and queue
// /regions, /regions/<region> and /regions/<country> for every enabled locale.
//
// If the prayer API is unreachable at build time, no region pages are
// prerendered (the build still succeeds); they then resolve live on request.
import { defineNuxtModule } from '@nuxt/kit'
import { PEOPLE_GROUP_LIST_FIELDS, summarizeRegions } from '../config/countries-meta'
import { ENABLED_LANGUAGE_CODES } from '../config/languages'
export default defineNuxtModule({
meta: { name: 'region-routes' },
async setup(_options, nuxt) {
// Only relevant for the production build's prerender pass.
if (nuxt.options.dev) return
const base = process.env.NUXT_PRAY_BASE_URL || 'https://pray.doxa.life'
let slugs: string[]
try {
const res = await fetch(`${base}/api/people-groups/list?fields=${PEOPLE_GROUP_LIST_FIELDS}&lang=en`)
if (!res.ok) throw new Error(`HTTP ${res.status}`)
const data = await res.json() as { posts?: unknown[] }
slugs = summarizeRegions((data.posts ?? []) as never[])
.flatMap(region => [region.slug, ...region.countries.map(c => c.slug)])
} catch (err) {
console.warn('[region-routes] could not fetch people-groups list; region pages will not be prerendered:', (err as Error).message)
return
}
// '' = default locale (no prefix); others are /es, /fr, …
const prefixes = ['', ...ENABLED_LANGUAGE_CODES.filter(code => code !== 'en').map(code => `/${code}`)]
const routes: string[] = []
for (const prefix of prefixes) {
routes.push(`${prefix}/regions`)
for (const slug of slugs) routes.push(`${prefix}/regions/${slug}`)
}
nuxt.options.nitro.prerender ||= {}
nuxt.options.nitro.prerender.routes ||= []
nuxt.options.nitro.prerender.routes.push(...routes)
console.log(`[region-routes] queued ${routes.length} routes for prerender (${slugs.length} regions + countries × ${prefixes.length} locales)`)
}
})