Regions: a Country Posters toggle under each region

Each region on /regions gets a small Country Posters dropdown. On first opening it embeds DX Maps' poster section for that region (<dxm-poster-section type="country" scope="<region>">) from this site's /dx-maps/ copy, in the site's language; the posters' script loads once, only when a toggle is opened.
This commit is contained in:
Doxa Life 2026-10-02 08:28:00 +00:00
parent 59e9130926
commit f750d2451c

View file

@ -41,6 +41,64 @@ useSeoMeta({
})
useTextHighlight()
// COUNTRY POSTERS, per region: a small toggle under each region that, when first opened, embeds DX Maps' poster
// section for that region (<dxm-poster-section>, from this site's own /dx-maps/ copy). Nothing poster-specific lives
// here: the element draws the posters, and the page loads its script once and hands it the region and the language.
// The label is DX Maps' own name for its Country Posters, in each language the site has (English for any other).
const POSTERS_LABEL: Record<string, string> = {
en: 'Country Posters',
ar: 'ملصقات الدول',
de: 'Länderposter',
es: 'Carteles por país',
fr: 'Affiches par pays',
hi: 'देश पोस्टर',
it: 'Poster per paese',
pt: 'Cartazes por país',
ro: 'Afișe pe țări',
ru: 'Плакаты по странам',
zh: '国家海报'
}
const postersLabel = computed(() => POSTERS_LABEL[locale.value] || POSTERS_LABEL.en)
const POSTERS_TAG = 'dxm-poster-section'
const POSTERS_SCRIPT = '/dx-maps/country-posters/country-posters.js'
const runtimeConfig = useRuntimeConfig()
let postersLoad: Promise<void> | null = null
function loadPosters(): Promise<void> {
if (customElements.get(POSTERS_TAG)) return Promise.resolve()
postersLoad ??= new Promise<void>((resolve, reject) => {
// the prayer API the posters read is set before the script runs
if (runtimeConfig.public.prayBaseUrl) window.MAP_APP_API_URL = runtimeConfig.public.prayBaseUrl as string
const script = document.createElement('script')
script.src = POSTERS_SCRIPT
script.onload = () => customElements.get(POSTERS_TAG) ? resolve() : reject(new Error('the posters bundle did not register'))
script.onerror = () => reject(new Error('the posters bundle failed to load'))
document.head.appendChild(script)
}).catch((err) => {
postersLoad = null // a later opening tries again
throw err
})
return postersLoad
}
async function onPostersToggle(event: Event, slug: string) {
const details = event.currentTarget as HTMLDetailsElement
const body = details.querySelector('.region-posters__body')
if (!details.open || !body || body.firstElementChild) return
try {
await loadPosters()
} catch (err) {
console.error('[regions posters]', err)
return
}
const section = document.createElement(POSTERS_TAG)
section.setAttribute('type', 'country')
section.setAttribute('scope', slug)
section.setAttribute('locale', locale.value)
section.setAttribute('collapsible', 'false')
section.setAttribute('assets-base', '/dx-maps/assets')
if (runtimeConfig.public.prayBaseUrl) section.setAttribute('api-base-url', runtimeConfig.public.prayBaseUrl as string)
body.appendChild(section)
}
</script>
<template>
@ -93,6 +151,15 @@ useTextHighlight()
</NuxtLink>
</li>
</ul>
<details
class="region-posters"
@toggle="onPostersToggle($event, region.slug)"
>
<summary class="region-posters__toggle">
{{ postersLabel }}
</summary>
<div class="region-posters__body" />
</details>
<p class="region-card__footer">
<NuxtLink
:to="localePath(`/regions/${region.slug}`)"
@ -171,6 +238,21 @@ useTextHighlight()
text-decoration: underline;
}
/* The Country Posters toggle under each region's countries: a small native dropdown; its section loads on opening. */
.region-posters {
margin-top: var(--spacing-lg);
}
.region-posters__toggle {
cursor: pointer;
font-weight: 600;
color: var(--color-brand-primary);
}
.region-posters__body {
margin-top: var(--spacing-md);
}
.region-card__footer {
display: flex;
justify-content: flex-end;