Handle dynamic people groups number (#4)

* Handle dynamic people groups number

* build tweaks.

* locale number formatting
This commit is contained in:
corsacca 2026-05-21 05:11:41 -05:00 committed by GitHub
parent 56104fa554
commit 594bed8f4c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 126 additions and 35 deletions

View file

@ -1,6 +1,7 @@
// Port of marketing-theme/js/components/src/main.ts (the // Port of marketing-theme/js/components/src/main.ts (the
// `getPeopleGroupsStatistics` function). Fetches totals from // `getPeopleGroupsStatistics` function). Fetches totals from our own
// `pray.doxa.life/api/people-groups/statistics` and exposes them as // server route `/api/people-groups/statistics` (which proxies+caches
// `pray.doxa.life/api/people-groups/statistics`) and exposes them as
// reactive refs plus a `reload()` method. Consumers render their own // reactive refs plus a `reload()` method. Consumers render their own
// counters and progress bars; in the original source the DOM was updated // counters and progress bars; in the original source the DOM was updated
// imperatively via `#prayer-current-status`, `#adopted-current-status` // imperatively via `#prayer-current-status`, `#adopted-current-status`
@ -8,18 +9,22 @@
// to keep the composable side-effect free. // to keep the composable side-effect free.
export interface PrayerStatistics { export interface PrayerStatistics {
total: number
total_with_prayer: number total_with_prayer: number
total_with_full_prayer: number total_with_full_prayer: number
total_adopted: number total_adopted: number
} }
const TOTAL_PEOPLE_GROUPS = 2085 // Fallback denominator used only when the upstream API hasn't responded
// yet (first paint on a cold cache, or upstream failure). Prevents a
// divide-by-zero in the percent computeds.
const FALLBACK_TOTAL = 2085
export function usePrayerStatistics() { export function usePrayerStatistics() {
const config = useRuntimeConfig() const { locale } = useI18n()
const prayBaseUrl = config.public.prayBaseUrl as string
const stats = useState<PrayerStatistics>('prayer-stats', () => ({ const stats = useState<PrayerStatistics>('prayer-stats', () => ({
total: 0,
total_with_prayer: 0, total_with_prayer: 0,
total_with_full_prayer: 0, total_with_full_prayer: 0,
total_adopted: 0 total_adopted: 0
@ -31,9 +36,9 @@ export function usePrayerStatistics() {
loading.value = true loading.value = true
error.value = null error.value = null
try { try {
const response = await fetch(`${prayBaseUrl}/api/people-groups/statistics`) const data = await $fetch<PrayerStatistics>('/api/people-groups/statistics')
const data = await response.json()
stats.value = { stats.value = {
total: Number(data.total || 0),
total_with_prayer: Number(data.total_with_prayer || 0), total_with_prayer: Number(data.total_with_prayer || 0),
total_with_full_prayer: Number(data.total_with_full_prayer || 0), total_with_full_prayer: Number(data.total_with_full_prayer || 0),
total_adopted: Number(data.total_adopted || 0) total_adopted: Number(data.total_adopted || 0)
@ -46,20 +51,49 @@ export function usePrayerStatistics() {
} }
} }
// SSR-friendly loader: populates the shared `stats` state during the
// server render via useAsyncData, so denominators render correctly on
// first paint without a client-side flicker.
async function ensureLoaded() {
if (stats.value.total > 0) return
await useAsyncData('prayer-stats', async () => {
const data = await $fetch<PrayerStatistics>('/api/people-groups/statistics')
stats.value = {
total: Number(data.total || 0),
total_with_prayer: Number(data.total_with_prayer || 0),
total_with_full_prayer: Number(data.total_with_full_prayer || 0),
total_adopted: Number(data.total_adopted || 0)
}
return stats.value
})
}
const totalPeopleGroups = computed(() => stats.value.total || FALLBACK_TOTAL)
// Use the active locale's grouping separator (e.g. "2.085" in de, "2 085"
// in fr/ru) but force Latin digits via the `-u-nu-latn` numbering system so
// the count matches the Western digits used everywhere else on the page —
// the raw numerator counts and the numbers hardcoded in translated strings
// (e.g. "144", "202"). Without this, ar would render Eastern-Arabic digits.
const totalPeopleGroupsFormatted = computed(() =>
totalPeopleGroups.value.toLocaleString(`${locale.value}-u-nu-latn`)
)
const prayerCoveragePercent = computed( const prayerCoveragePercent = computed(
() => Math.min(100, (stats.value.total_with_full_prayer / TOTAL_PEOPLE_GROUPS) * 100) () => Math.min(100, (stats.value.total_with_full_prayer / totalPeopleGroups.value) * 100)
) )
const adoptedPercent = computed( const adoptedPercent = computed(
() => Math.min(100, (stats.value.total_adopted / TOTAL_PEOPLE_GROUPS) * 100) () => Math.min(100, (stats.value.total_adopted / totalPeopleGroups.value) * 100)
) )
return { return {
stats: readonly(stats), stats: readonly(stats),
loading: readonly(loading), loading: readonly(loading),
error: readonly(error), error: readonly(error),
totalPeopleGroups,
totalPeopleGroupsFormatted,
prayerCoveragePercent, prayerCoveragePercent,
adoptedPercent, adoptedPercent,
reload, reload,
TOTAL_PEOPLE_GROUPS ensureLoaded
} }
} }

View file

@ -16,7 +16,14 @@ const adoptBase = computed(() => {
return p.endsWith('/') ? p : `${p}/` return p.endsWith('/') ? p : `${p}/`
}) })
const { stats, adoptedPercent, reload } = usePrayerStatistics() const {
stats,
adoptedPercent,
totalPeopleGroups,
reload,
ensureLoaded
} = usePrayerStatistics()
await ensureLoaded()
onMounted(() => reload()) onMounted(() => reload())
const config = useRuntimeConfig() const config = useRuntimeConfig()
@ -58,7 +65,7 @@ useTextHighlight()
<div> <div>
<h2 class="h3">{{ t('Current Status') }}</h2> <h2 class="h3">{{ t('Current Status') }}</h2>
<span class="font-size-4xl font-weight-bold font-button"> <span class="font-size-4xl font-weight-bold font-button">
<span id="adopted-current-status">{{ stats.total_adopted }}</span> / 2085 <span id="adopted-current-status">{{ stats.total_adopted }}</span> / {{ totalPeopleGroups }}
</span> </span>
<div class="stack stack--3xs"> <div class="stack stack--3xs">
<p class="subtext font-size-md">{{ t('people groups adopted') }}</p> <p class="subtext font-size-md">{{ t('people groups adopted') }}</p>

View file

@ -19,6 +19,9 @@ function openVideo() {
videoModalRef.value?.open() videoModalRef.value?.open()
} }
const { totalPeopleGroupsFormatted, ensureLoaded } = usePrayerStatistics()
await ensureLoaded()
const mapboxToken = config.public.mapboxToken as string const mapboxToken = config.public.mapboxToken as string
// Preload the heading font (Bebas Neue) for the homepage hero h1 (the LCP text) // Preload the heading font (Bebas Neue) for the homepage hero h1 (the LCP text)
@ -118,7 +121,7 @@ useTextHighlight()
<div class="container stack stack--4xl"> <div class="container stack stack--4xl">
<div class="stack stack--2xl"> <div class="stack stack--2xl">
<h2 class="highlight" data-highlight-index="1"> <h2 class="highlight" data-highlight-index="1">
{{ t('{0} unengaged people groups', ['2,085']) }} {{ t('{0} unengaged people groups', [totalPeopleGroupsFormatted]) }}
</h2> </h2>
<p class="subtext"> <p class="subtext">
{{ t('Our hope is to see each of them covered in 24-hour prayer, and your church can be part of it.') }} {{ t('Our hope is to see each of them covered in 24-hour prayer, and your church can be part of it.') }}
@ -203,7 +206,7 @@ useTextHighlight()
<div class="stack stack--lg | info-card__content"> <div class="stack stack--lg | info-card__content">
<h3>{{ t('Unengaged') }}</h3> <h3>{{ t('Unengaged') }}</h3>
<span>{{ t('{0} Million', ['202']) }}</span> <span>{{ t('{0} Million', ['202']) }}</span>
<span>{{ t('{0} People Groups', ['2,085']) }}</span> <span>{{ t('{0} People Groups', [totalPeopleGroupsFormatted]) }}</span>
</div> </div>
</div> </div>
</div> </div>
@ -247,7 +250,7 @@ useTextHighlight()
<div class="stack stack--xl"> <div class="stack stack--xl">
<h3 class="subtext">{{ t('In partnership with the global church, our vision is for...') }}</h3> <h3 class="subtext">{{ t('In partnership with the global church, our vision is for...') }}</h3>
<ul class="stack stack--md" data-list-color="primary"> <ul class="stack stack--md" data-list-color="primary">
<li>{{ t('Daily 24-hour prayer coverage for all 2,085 unengaged peoples') }}</li> <li>{{ t('Daily 24-hour prayer coverage for all {0} unengaged peoples', [totalPeopleGroupsFormatted]) }}</li>
<li>{{ t('No unengaged people groups by 2033') }}</li> <li>{{ t('No unengaged people groups by 2033') }}</li>
<li>{{ t('Mobilization of 20,000+ DOXA partnership missionaries') }}</li> <li>{{ t('Mobilization of 20,000+ DOXA partnership missionaries') }}</li>
<li>{{ t('Fruitful engagement among frontier peoples and the under-engaged') }}</li> <li>{{ t('Fruitful engagement among frontier peoples and the under-engaged') }}</li>

View file

@ -14,8 +14,15 @@ const selectUrl = computed(() =>
const translations = computed(() => buildUupgListTranslations(t)) const translations = computed(() => buildUupgListTranslations(t))
const { stats, prayerCoveragePercent } = usePrayerStatistics() const {
const { reload } = usePrayerStatistics() stats,
prayerCoveragePercent,
totalPeopleGroups,
totalPeopleGroupsFormatted,
reload,
ensureLoaded
} = usePrayerStatistics()
await ensureLoaded()
onMounted(() => reload()) onMounted(() => reload())
const mapboxToken = config.public.mapboxToken as string const mapboxToken = config.public.mapboxToken as string
@ -54,12 +61,12 @@ useTextHighlight()
<div class="stack stack--lg"> <div class="stack stack--lg">
<h2 class="h3">{{ t('Prayer Goal') }}</h2> <h2 class="h3">{{ t('Prayer Goal') }}</h2>
<p class="subtext font-size-md">{{ t('24-Hour Prayer Coverage') }}</p> <p class="subtext font-size-md">{{ t('24-Hour Prayer Coverage') }}</p>
<p class="subtext font-size-md">{{ t('Mobilize 144+ people praying 10 minutes a day for all 2,085 people groups') }}</p> <p class="subtext font-size-md">{{ t('Mobilize 144+ people praying 10 minutes a day for all {0} people groups', [totalPeopleGroupsFormatted]) }}</p>
</div> </div>
<div> <div>
<h2 class="h3">{{ t('Current Status') }}</h2> <h2 class="h3">{{ t('Current Status') }}</h2>
<span class="font-size-4xl font-weight-bold font-button"> <span class="font-size-4xl font-weight-bold font-button">
<span id="prayer-current-status">{{ stats.total_with_full_prayer }}</span> / 2085 <span id="prayer-current-status">{{ stats.total_with_full_prayer }}</span> / {{ totalPeopleGroups }}
</span> </span>
<div class="stack stack--3xs"> <div class="stack stack--3xs">
<p class="subtext font-size-md">{{ t('People groups with committed 24-hour prayer coverage') }}</p> <p class="subtext font-size-md">{{ t('People groups with committed 24-hour prayer coverage') }}</p>

View file

@ -52,7 +52,7 @@
"DOXA Playbook Slides": "عرض شرائح دليل دوكسا", "DOXA Playbook Slides": "عرض شرائح دليل دوكسا",
"DOXA Promo Video": "الفيديو الترويجي لدليل دوكسا", "DOXA Promo Video": "الفيديو الترويجي لدليل دوكسا",
"DOXA is the Greek word for \"GLORY\".": "دوكسا هي الكلمة اليونانية التي تعني \"المجد\".", "DOXA is the Greek word for \"GLORY\".": "دوكسا هي الكلمة اليونانية التي تعني \"المجد\".",
"Daily 24-hour prayer coverage for all 2,085 unengaged peoples": "توفير تغطية صلاة يومية على مدار 24 ساعة لمجموعة الشعوب الغير مخدومة روحيا والبالغ عدوهم 2.085", "Daily 24-hour prayer coverage for all {0} unengaged peoples": "توفير تغطية صلاة يومية على مدار 24 ساعة لمجموعة الشعوب الغير مخدومة روحيا والبالغ عدوهم {0}",
"Definitions": "التعريفات", "Definitions": "التعريفات",
"Disciple & church multiplication": "تضاعف التلاميذ والكنيسة", "Disciple & church multiplication": "تضاعف التلاميذ والكنيسة",
"Discussion Guide": "دليل النقاش", "Discussion Guide": "دليل النقاش",
@ -124,7 +124,7 @@
"Message": "الرسالة", "Message": "الرسالة",
"Mobilization of 20,000+ DOXA partnership missionaries": "حشد أكثر من 20.000 مبشّر بالتعاون مع شركاء دوكسا لتحقيق الرسالة المشتركة", "Mobilization of 20,000+ DOXA partnership missionaries": "حشد أكثر من 20.000 مبشّر بالتعاون مع شركاء دوكسا لتحقيق الرسالة المشتركة",
"Mobilize": "حشد المؤمنين", "Mobilize": "حشد المؤمنين",
"Mobilize 144+ people praying 10 minutes a day for all 2,085 people groups": "حشد أكثر من 144 شخص للصلاة لمدة 10 دقائق يوميا من أجل جميع المجموعات العرقية البالغ عددها 2,085 مجموعة", "Mobilize 144+ people praying 10 minutes a day for all {0} people groups": "حشد أكثر من 144 شخص للصلاة لمدة 10 دقائق يوميا من أجل جميع المجموعات العرقية البالغ عددها {0} مجموعة",
"Mobilize others in your church to join in prayer": "شجّعوا الآخرين في كنيستك على المشاركة في الصلاة", "Mobilize others in your church to join in prayer": "شجّعوا الآخرين في كنيستك على المشاركة في الصلاة",
"Mobilize toward the goal of at least 144 prayer partners to cover the people group in continuous, daily prayer (10 minutes each, 24 hours a day).": "تعبئة المشاركين نحو هدف الحصول على ما يقل عن 144 شريك صلاة لتغطية المجموعة البشرية بصلاة مستمرة يوميا، (10 دقائق كل شخص، على مدار 24 ساعة).", "Mobilize toward the goal of at least 144 prayer partners to cover the people group in continuous, daily prayer (10 minutes each, 24 hours a day).": "تعبئة المشاركين نحو هدف الحصول على ما يقل عن 144 شريك صلاة لتغطية المجموعة البشرية بصلاة مستمرة يوميا، (10 دقائق كل شخص، على مدار 24 ساعة).",
"More": "المزيد", "More": "المزيد",

View file

@ -52,7 +52,7 @@
"DOXA Playbook Slides": "DOXA-Playbook-Folien", "DOXA Playbook Slides": "DOXA-Playbook-Folien",
"DOXA Promo Video": "DOXA-Werbevideo", "DOXA Promo Video": "DOXA-Werbevideo",
"DOXA is the Greek word for \"GLORY\".": "DOXA ist das griechische Wort für „EHRE“.", "DOXA is the Greek word for \"GLORY\".": "DOXA ist das griechische Wort für „EHRE“.",
"Daily 24-hour prayer coverage for all 2,085 unengaged peoples": "Täglich alle 2085 völlig unerreichte Volksgruppen durch kontinuierliches Gebet abzudecken", "Daily 24-hour prayer coverage for all {0} unengaged peoples": "Täglich alle {0} völlig unerreichte Volksgruppen durch kontinuierliches Gebet abzudecken",
"Definitions": "Begriffsbestimmungen", "Definitions": "Begriffsbestimmungen",
"Disciple & church multiplication": "Jüngerschaft & Gemeindemultiplikation", "Disciple & church multiplication": "Jüngerschaft & Gemeindemultiplikation",
"Discussion Guide": "Diskussionsleitfaden", "Discussion Guide": "Diskussionsleitfaden",
@ -124,7 +124,7 @@
"Message": "Nachricht", "Message": "Nachricht",
"Mobilization of 20,000+ DOXA partnership missionaries": "20,000 DOXA-Partnerschafts-Missionare zu mobilisieren", "Mobilization of 20,000+ DOXA partnership missionaries": "20,000 DOXA-Partnerschafts-Missionare zu mobilisieren",
"Mobilize": "Mobilize", "Mobilize": "Mobilize",
"Mobilize 144+ people praying 10 minutes a day for all 2,085 people groups": "Mobilisiere 144+ Fürbitter, welche 10 Minuten am Tag für alle 2085 Volksgruppen beten", "Mobilize 144+ people praying 10 minutes a day for all {0} people groups": "Mobilisiere 144+ Fürbitter, welche 10 Minuten am Tag für alle {0} Volksgruppen beten",
"Mobilize others in your church to join in prayer": "Mobilisieren Sie andere in Ihrer Gemeinde, sich dem Gebet anzuschließen", "Mobilize others in your church to join in prayer": "Mobilisieren Sie andere in Ihrer Gemeinde, sich dem Gebet anzuschließen",
"Mobilize toward the goal of at least 144 prayer partners to cover the people group in continuous, daily prayer (10 minutes each, 24 hours a day).": "Mobilisiere für das Ziel, mindestens 144 Gebetspartner zu gewinnen, die diese Volksgruppe täglich ununterbrochen im Gebet begleiten (jeweils 10 Minuten, innerhalb 24 Stunden eines Tages).", "Mobilize toward the goal of at least 144 prayer partners to cover the people group in continuous, daily prayer (10 minutes each, 24 hours a day).": "Mobilisiere für das Ziel, mindestens 144 Gebetspartner zu gewinnen, die diese Volksgruppe täglich ununterbrochen im Gebet begleiten (jeweils 10 Minuten, innerhalb 24 Stunden eines Tages).",
"More": "Mehr", "More": "Mehr",

View file

@ -52,7 +52,7 @@
"DOXA Playbook Slides": "DOXA Playbook Slides", "DOXA Playbook Slides": "DOXA Playbook Slides",
"DOXA Promo Video": "DOXA Promo Video", "DOXA Promo Video": "DOXA Promo Video",
"DOXA is the Greek word for \"GLORY\".": "DOXA is the Greek word for \"GLORY\".", "DOXA is the Greek word for \"GLORY\".": "DOXA is the Greek word for \"GLORY\".",
"Daily 24-hour prayer coverage for all 2,085 unengaged peoples": "Daily 24-hour prayer coverage for all 2,085 unengaged peoples", "Daily 24-hour prayer coverage for all {0} unengaged peoples": "Daily 24-hour prayer coverage for all {0} unengaged peoples",
"Definitions": "Definitions", "Definitions": "Definitions",
"Disciple & church multiplication": "Disciple & church multiplication", "Disciple & church multiplication": "Disciple & church multiplication",
"Discussion Guide": "Discussion Guide", "Discussion Guide": "Discussion Guide",
@ -124,7 +124,7 @@
"Message": "Message", "Message": "Message",
"Mobilization of 20,000+ DOXA partnership missionaries": "Mobilization of 20,000+ DOXA partnership missionaries", "Mobilization of 20,000+ DOXA partnership missionaries": "Mobilization of 20,000+ DOXA partnership missionaries",
"Mobilize": "Mobilize", "Mobilize": "Mobilize",
"Mobilize 144+ people praying 10 minutes a day for all 2,085 people groups": "Mobilize 144+ people praying 10 minutes a day for all 2,085 people groups", "Mobilize 144+ people praying 10 minutes a day for all {0} people groups": "Mobilize 144+ people praying 10 minutes a day for all {0} people groups",
"Mobilize others in your church to join in prayer": "Mobilize others in your church to join in prayer", "Mobilize others in your church to join in prayer": "Mobilize others in your church to join in prayer",
"Mobilize toward the goal of at least 144 prayer partners to cover the people group in continuous, daily prayer (10 minutes each, 24 hours a day).": "Mobilize toward the goal of at least 144 prayer partners to cover the people group in continuous, daily prayer (10 minutes each, 24 hours a day).", "Mobilize toward the goal of at least 144 prayer partners to cover the people group in continuous, daily prayer (10 minutes each, 24 hours a day).": "Mobilize toward the goal of at least 144 prayer partners to cover the people group in continuous, daily prayer (10 minutes each, 24 hours a day).",
"More": "More", "More": "More",

View file

@ -52,7 +52,7 @@
"DOXA Playbook Slides": "Diapositivas del manual de DOXA", "DOXA Playbook Slides": "Diapositivas del manual de DOXA",
"DOXA Promo Video": "Vídeo promocional de DOXA", "DOXA Promo Video": "Vídeo promocional de DOXA",
"DOXA is the Greek word for \"GLORY\".": "DOXA es la palabra griega para «GLORIA».", "DOXA is the Greek word for \"GLORY\".": "DOXA es la palabra griega para «GLORIA».",
"Daily 24-hour prayer coverage for all 2,085 unengaged peoples": "Cobertura diaria de oración las 24 horas por los 2.085 pueblos no evangelizados", "Daily 24-hour prayer coverage for all {0} unengaged peoples": "Cobertura diaria de oración las 24 horas por los {0} pueblos no evangelizados",
"Definitions": "Definiciones", "Definitions": "Definiciones",
"Disciple & church multiplication": "Discípulo y multiplicación de iglesias", "Disciple & church multiplication": "Discípulo y multiplicación de iglesias",
"Discussion Guide": "Guía para el debate", "Discussion Guide": "Guía para el debate",
@ -124,7 +124,7 @@
"Message": "Mensaje", "Message": "Mensaje",
"Mobilization of 20,000+ DOXA partnership missionaries": "Movilización de más de 20.000 misioneros asociados a DOXA", "Mobilization of 20,000+ DOXA partnership missionaries": "Movilización de más de 20.000 misioneros asociados a DOXA",
"Mobilize": "Movilizar", "Mobilize": "Movilizar",
"Mobilize 144+ people praying 10 minutes a day for all 2,085 people groups": "Movilizar a más de 144 personas para que recen 10 minutos al día por los 2085 grupos étnicos.", "Mobilize 144+ people praying 10 minutes a day for all {0} people groups": "Movilizar a más de 144 personas para que recen 10 minutos al día por los {0} grupos étnicos.",
"Mobilize others in your church to join in prayer": "Anima a otros miembros de tu iglesia a unirse a la oración", "Mobilize others in your church to join in prayer": "Anima a otros miembros de tu iglesia a unirse a la oración",
"Mobilize toward the goal of at least 144 prayer partners to cover the people group in continuous, daily prayer (10 minutes each, 24 hours a day).": "Movilízate con el objetivo de conseguir al menos 144 compañeros de oración para cubrir al grupo étnico con oraciones continuas y diarias (10 minutos cada uno, las 24 horas del día).", "Mobilize toward the goal of at least 144 prayer partners to cover the people group in continuous, daily prayer (10 minutes each, 24 hours a day).": "Movilízate con el objetivo de conseguir al menos 144 compañeros de oración para cubrir al grupo étnico con oraciones continuas y diarias (10 minutos cada uno, las 24 horas del día).",
"More": "Más", "More": "Más",

View file

@ -52,7 +52,7 @@
"DOXA Playbook Slides": "Diapositives du guide pratique DOXA", "DOXA Playbook Slides": "Diapositives du guide pratique DOXA",
"DOXA Promo Video": "Vidéo promotionnelle DOXA", "DOXA Promo Video": "Vidéo promotionnelle DOXA",
"DOXA is the Greek word for \"GLORY\".": "DOXA est le mot grec qui signifie « GLOIRE ».", "DOXA is the Greek word for \"GLORY\".": "DOXA est le mot grec qui signifie « GLOIRE ».",
"Daily 24-hour prayer coverage for all 2,085 unengaged peoples": "Prière quotidienne 24 heures sur 24 pour les 2 085 peuples non ciblés", "Daily 24-hour prayer coverage for all {0} unengaged peoples": "Prière quotidienne 24 heures sur 24 pour les {0} peuples non ciblés",
"Definitions": "Définitions", "Definitions": "Définitions",
"Disciple & church multiplication": "Disciple et multiplication d'églises", "Disciple & church multiplication": "Disciple et multiplication d'églises",
"Discussion Guide": "Guide de discussion", "Discussion Guide": "Guide de discussion",
@ -124,7 +124,7 @@
"Message": "Message", "Message": "Message",
"Mobilization of 20,000+ DOXA partnership missionaries": "Mobilisation de plus de 20 000 missionnaires partenaires de DOXA", "Mobilization of 20,000+ DOXA partnership missionaries": "Mobilisation de plus de 20 000 missionnaires partenaires de DOXA",
"Mobilize": "Mobiliser", "Mobilize": "Mobiliser",
"Mobilize 144+ people praying 10 minutes a day for all 2,085 people groups": "Mobiliser plus de 144 personnes pour prier 10 minutes par jour pour les 2 085 groupes ethniques.", "Mobilize 144+ people praying 10 minutes a day for all {0} people groups": "Mobiliser plus de 144 personnes pour prier 10 minutes par jour pour les {0} groupes ethniques.",
"Mobilize others in your church to join in prayer": "Mobilisez les autres membres de votre paroisse pour qu'ils se joignent à vous dans la prière", "Mobilize others in your church to join in prayer": "Mobilisez les autres membres de votre paroisse pour qu'ils se joignent à vous dans la prière",
"Mobilize toward the goal of at least 144 prayer partners to cover the people group in continuous, daily prayer (10 minutes each, 24 hours a day).": "Mobilisez-vous pour atteindre l'objectif d'au moins 144 partenaires de prière afin de couvrir ce groupe ethnique par une prière quotidienne et continue (10 minutes chacun, 24 heures sur 24).", "Mobilize toward the goal of at least 144 prayer partners to cover the people group in continuous, daily prayer (10 minutes each, 24 hours a day).": "Mobilisez-vous pour atteindre l'objectif d'au moins 144 partenaires de prière afin de couvrir ce groupe ethnique par une prière quotidienne et continue (10 minutes chacun, 24 heures sur 24).",
"More": "Plus", "More": "Plus",

View file

@ -52,7 +52,7 @@
"DOXA Playbook Slides": "डॉक्सा प्लेबुक स्लाइड्स", "DOXA Playbook Slides": "डॉक्सा प्लेबुक स्लाइड्स",
"DOXA Promo Video": "डॉक्सा प्रमो वीडियो", "DOXA Promo Video": "डॉक्सा प्रमो वीडियो",
"DOXA is the Greek word for \"GLORY\".": "DOXA ग्रीक शब्द है जिसका अर्थ \"महिमा\" है।", "DOXA is the Greek word for \"GLORY\".": "DOXA ग्रीक शब्द है जिसका अर्थ \"महिमा\" है।",
"Daily 24-hour prayer coverage for all 2,085 unengaged peoples": "सभी 2,085 असंलग्न लोगों के लिए प्रतिदिन 24 घंटे प्रार्थना कवरेज", "Daily 24-hour prayer coverage for all {0} unengaged peoples": "सभी {0} असंलग्न लोगों के लिए प्रतिदिन 24 घंटे प्रार्थना कवरेज",
"Definitions": "परिभाषाएँ", "Definitions": "परिभाषाएँ",
"Disciple & church multiplication": "शिष्य और चर्च की वृद्धि", "Disciple & church multiplication": "शिष्य और चर्च की वृद्धि",
"Discussion Guide": "चर्चा मार्गदर्शिका", "Discussion Guide": "चर्चा मार्गदर्शिका",
@ -124,7 +124,7 @@
"Message": "संदेश", "Message": "संदेश",
"Mobilization of 20,000+ DOXA partnership missionaries": "20,000+ DOXA साझेदारी मिशनरियों का संगठित होना", "Mobilization of 20,000+ DOXA partnership missionaries": "20,000+ DOXA साझेदारी मिशनरियों का संगठित होना",
"Mobilize": "लगातार सक्रिय रहो", "Mobilize": "लगातार सक्रिय रहो",
"Mobilize 144+ people praying 10 minutes a day for all 2,085 people groups": "सभी 2,085 जनसमूहों के लिए प्रतिदिन 10 मिनट प्रार्थना करने हेतु 144+ लोगों को सक्रिय करें।", "Mobilize 144+ people praying 10 minutes a day for all {0} people groups": "सभी {0} जनसमूहों के लिए प्रतिदिन 10 मिनट प्रार्थना करने हेतु 144+ लोगों को सक्रिय करें।",
"Mobilize others in your church to join in prayer": "अपने चर्च में दूसरों को प्रार्थना में शामिल होने के लिए प्रेरित करें।", "Mobilize others in your church to join in prayer": "अपने चर्च में दूसरों को प्रार्थना में शामिल होने के लिए प्रेरित करें।",
"Mobilize toward the goal of at least 144 prayer partners to cover the people group in continuous, daily prayer (10 minutes each, 24 hours a day).": "लोगों के समूह को निरंतर, दैनिक प्रार्थना (प्रत्येक 10 मिनट, दिन में 24 घंटे) के माध्यम से आच्छादित करने के लिए कम से कम 144 प्रार्थना साझेदारों को जुटाएँ।", "Mobilize toward the goal of at least 144 prayer partners to cover the people group in continuous, daily prayer (10 minutes each, 24 hours a day).": "लोगों के समूह को निरंतर, दैनिक प्रार्थना (प्रत्येक 10 मिनट, दिन में 24 घंटे) के माध्यम से आच्छादित करने के लिए कम से कम 144 प्रार्थना साझेदारों को जुटाएँ।",
"More": "और ज्यादा", "More": "और ज्यादा",

View file

@ -52,7 +52,7 @@
"DOXA Playbook Slides": "Slides do Manual do DOXA", "DOXA Playbook Slides": "Slides do Manual do DOXA",
"DOXA Promo Video": "Vídeo promocional da DOXA", "DOXA Promo Video": "Vídeo promocional da DOXA",
"DOXA is the Greek word for \"GLORY\".": "DOXA é a palavra grega para «GLÓRIA».", "DOXA is the Greek word for \"GLORY\".": "DOXA é a palavra grega para «GLÓRIA».",
"Daily 24-hour prayer coverage for all 2,085 unengaged peoples": "Cobertura diária de oração 24 horas por dia para todos os 2.085 povos não engajados", "Daily 24-hour prayer coverage for all {0} unengaged peoples": "Cobertura diária de oração 24 horas por dia para todos os {0} povos não engajados",
"Definitions": "Definições", "Definitions": "Definições",
"Disciple & church multiplication": "Multiplicação de discípulos e igrejas", "Disciple & church multiplication": "Multiplicação de discípulos e igrejas",
"Discussion Guide": "Guia de discussão", "Discussion Guide": "Guia de discussão",
@ -124,7 +124,7 @@
"Message": "Mensagem", "Message": "Mensagem",
"Mobilization of 20,000+ DOXA partnership missionaries": "Mobilização de mais de 20.000 missionários parceiros da DOXA", "Mobilization of 20,000+ DOXA partnership missionaries": "Mobilização de mais de 20.000 missionários parceiros da DOXA",
"Mobilize": "Mobilize", "Mobilize": "Mobilize",
"Mobilize 144+ people praying 10 minutes a day for all 2,085 people groups": "Mobilizar mais de 144 pessoas para orar 10 minutos por dia por todos os 2.085 grupos étnicos", "Mobilize 144+ people praying 10 minutes a day for all {0} people groups": "Mobilizar mais de 144 pessoas para orar 10 minutos por dia por todos os {0} grupos étnicos",
"Mobilize others in your church to join in prayer": "Mobilize outros membros da sua igreja para se unirem em oração", "Mobilize others in your church to join in prayer": "Mobilize outros membros da sua igreja para se unirem em oração",
"Mobilize toward the goal of at least 144 prayer partners to cover the people group in continuous, daily prayer (10 minutes each, 24 hours a day).": "Mobilize-se com o objetivo de ter pelo menos 144 parceiros de oração para cobrir o grupo étnico em oração contínua e diária (10 minutos cada, 24 horas por dia).", "Mobilize toward the goal of at least 144 prayer partners to cover the people group in continuous, daily prayer (10 minutes each, 24 hours a day).": "Mobilize-se com o objetivo de ter pelo menos 144 parceiros de oração para cobrir o grupo étnico em oração contínua e diária (10 minutos cada, 24 horas por dia).",
"More": "Mais", "More": "Mais",

View file

@ -52,7 +52,7 @@
"DOXA Playbook Slides": "Слайды из руководства DOXA", "DOXA Playbook Slides": "Слайды из руководства DOXA",
"DOXA Promo Video": "Промо-ролик DOXA", "DOXA Promo Video": "Промо-ролик DOXA",
"DOXA is the Greek word for \"GLORY\".": "DOXA — это греческое слово, означающее «СЛАВА».", "DOXA is the Greek word for \"GLORY\".": "DOXA — это греческое слово, означающее «СЛАВА».",
"Daily 24-hour prayer coverage for all 2,085 unengaged peoples": "Ежедневная 24-часовая молитвенная поддержка для всех 2085 незадействованных народов", "Daily 24-hour prayer coverage for all {0} unengaged peoples": "Ежедневная 24-часовая молитвенная поддержка для всех {0} незадействованных народов",
"Definitions": "Определения", "Definitions": "Определения",
"Disciple & church multiplication": "Ученики и умножение церквей", "Disciple & church multiplication": "Ученики и умножение церквей",
"Discussion Guide": "Руководство по обсуждению", "Discussion Guide": "Руководство по обсуждению",
@ -124,7 +124,7 @@
"Message": "Сообщение", "Message": "Сообщение",
"Mobilization of 20,000+ DOXA partnership missionaries": "Мобилизация более 20 000 миссионеров-партнеров DOXA", "Mobilization of 20,000+ DOXA partnership missionaries": "Мобилизация более 20 000 миссионеров-партнеров DOXA",
"Mobilize": "Мобилизовать", "Mobilize": "Мобилизовать",
"Mobilize 144+ people praying 10 minutes a day for all 2,085 people groups": "Мобилизуйте 144+ человек для молитвы по 10 минут в день за все 2 085 народностей", "Mobilize 144+ people praying 10 minutes a day for all {0} people groups": "Мобилизуйте 144+ человек для молитвы по 10 минут в день за все {0} народностей",
"Mobilize others in your church to join in prayer": "Призовите других членов вашей церкви присоединиться к молитве", "Mobilize others in your church to join in prayer": "Призовите других членов вашей церкви присоединиться к молитве",
"Mobilize toward the goal of at least 144 prayer partners to cover the people group in continuous, daily prayer (10 minutes each, 24 hours a day).": "Мобилизуйтесь для достижения цели: собрать как минимум 144 молитвенных партнера, которые будут ежедневно, непрерывно молиться за эту народность (по 10 минут каждый, 24 часа в сутки).", "Mobilize toward the goal of at least 144 prayer partners to cover the people group in continuous, daily prayer (10 minutes each, 24 hours a day).": "Мобилизуйтесь для достижения цели: собрать как минимум 144 молитвенных партнера, которые будут ежедневно, непрерывно молиться за эту народность (по 10 минут каждый, 24 часа в сутки).",
"More": "Больше", "More": "Больше",

View file

@ -0,0 +1,40 @@
// Server-side cached proxy to campaigns-sever's `/api/people-groups/statistics`.
// The composable `usePrayerStatistics` calls this so the upstream is only hit
// once per cache window per server instance — and so `total` (the live count
// of people groups) can drive the denominator that used to be hardcoded as
// 2,085 in templates.
import { defineCachedEventHandler } from 'nitropack/runtime'
export interface PrayerStatisticsResponse {
total: number
total_with_prayer: number
total_with_full_prayer: number
total_adopted: number
people_committed: string
committed_duration: string
}
export default defineCachedEventHandler(
async (): Promise<PrayerStatisticsResponse> => {
const config = useRuntimeConfig()
const prayBaseUrl = String(config.public.prayBaseUrl || '').replace(/\/$/, '')
const data = await $fetch<Partial<PrayerStatisticsResponse>>(
`${prayBaseUrl}/api/people-groups/statistics`,
{ timeout: 10_000 }
)
return {
total: Number(data.total || 0),
total_with_prayer: Number(data.total_with_prayer || 0),
total_with_full_prayer: Number(data.total_with_full_prayer || 0),
total_adopted: Number(data.total_adopted || 0),
people_committed: String(data.people_committed || '0'),
committed_duration: String(data.committed_duration || '0')
}
},
{
maxAge: 60 * 60,
swr: true,
name: 'people-groups-statistics'
}
)