diff --git a/messages/de.json b/messages/de.json index 725531c59..3246ea3e3 100644 --- a/messages/de.json +++ b/messages/de.json @@ -11069,6 +11069,9 @@ }, "crisisTextLine": { "name": "Crisis Text Line" + }, + "cvv": { + "name": "CVV, Centro de Valorização da Vida (rund um die Uhr, kostenlos, vertraulich)" } }, "instrumentDescription": { diff --git a/messages/en.json b/messages/en.json index e2c3a9223..023d08326 100644 --- a/messages/en.json +++ b/messages/en.json @@ -11069,6 +11069,9 @@ }, "crisisTextLine": { "name": "Crisis Text Line" + }, + "cvv": { + "name": "CVV, Centro de Valorização da Vida (24/7, free, confidential)" } }, "instrumentDescription": { diff --git a/messages/es.json b/messages/es.json index 6c23f0402..3c613d3bc 100644 --- a/messages/es.json +++ b/messages/es.json @@ -11069,6 +11069,9 @@ }, "crisisTextLine": { "name": "Crisis Text Line" + }, + "cvv": { + "name": "CVV, Centro de Valorização da Vida (24/7, gratuito y confidencial)" } }, "instrumentDescription": { diff --git a/messages/fr.json b/messages/fr.json index 763756fd7..dc744e4ab 100644 --- a/messages/fr.json +++ b/messages/fr.json @@ -11069,6 +11069,9 @@ }, "crisisTextLine": { "name": "Crisis Text Line" + }, + "cvv": { + "name": "CVV, Centro de Valorização da Vida (24h/24, 7j/7, gratuit et confidentiel)" } }, "instrumentDescription": { diff --git a/messages/it.json b/messages/it.json index f0b376277..f97e90b09 100644 --- a/messages/it.json +++ b/messages/it.json @@ -11069,6 +11069,9 @@ }, "crisisTextLine": { "name": "Crisis Text Line" + }, + "cvv": { + "name": "CVV, Centro de Valorização da Vida (24/7, gratuito e riservato)" } }, "instrumentDescription": { diff --git a/messages/ko.json b/messages/ko.json index 57a78bf48..2e1f6d750 100644 --- a/messages/ko.json +++ b/messages/ko.json @@ -11069,6 +11069,9 @@ }, "crisisTextLine": { "name": "Crisis Text Line" + }, + "cvv": { + "name": "CVV, Centro de Valorização da Vida (24시간 연중무휴, 무료, 비밀 보장)" } }, "instrumentDescription": { diff --git a/messages/nl.json b/messages/nl.json index ce6a13521..0be779297 100644 --- a/messages/nl.json +++ b/messages/nl.json @@ -11069,6 +11069,9 @@ }, "crisisTextLine": { "name": "Crisis Text Line" + }, + "cvv": { + "name": "CVV, Centro de Valorização da Vida (dag en nacht, gratis, vertrouwelijk)" } }, "instrumentDescription": { diff --git a/messages/pl.json b/messages/pl.json index fd677359a..8d7435a9b 100644 --- a/messages/pl.json +++ b/messages/pl.json @@ -11069,6 +11069,9 @@ }, "crisisTextLine": { "name": "Crisis Text Line" + }, + "cvv": { + "name": "CVV, Centro de Valorização da Vida (całodobowo, bezpłatnie i poufnie)" } }, "instrumentDescription": { diff --git a/messages/pt-BR.json b/messages/pt-BR.json index 28d99aad1..389ae0ba8 100644 --- a/messages/pt-BR.json +++ b/messages/pt-BR.json @@ -11069,6 +11069,9 @@ }, "crisisTextLine": { "name": "Crisis Text Line" + }, + "cvv": { + "name": "CVV, Centro de Valorização da Vida (24 horas, gratuito, sigiloso)" } }, "instrumentDescription": { diff --git a/src/lib/mental-health/__tests__/crisis-resources.test.ts b/src/lib/mental-health/__tests__/crisis-resources.test.ts new file mode 100644 index 000000000..af7c5df12 --- /dev/null +++ b/src/lib/mental-health/__tests__/crisis-resources.test.ts @@ -0,0 +1,36 @@ +import { describe, expect, it } from "vitest"; + +import { locales } from "@/lib/i18n/config"; +import { getServerTranslator } from "@/lib/i18n/server-translator"; + +import { crisisResourcesForLocale } from "../crisis-resources"; + +describe("crisisResourcesForLocale", () => { + it("gives a Brazilian Portuguese reader CVV and SAMU", () => { + const set = crisisResourcesForLocale("pt-BR"); + expect(set.emergencyNumber).toBe("192"); + expect(set.resources[0]).toEqual({ + id: "cvv", + contacts: ["188", "cvv.org.br/chat"], + }); + }); + + it("keeps the international set for Portuguese outside Brazil", () => { + // 188 does not connect from Portugal. + for (const locale of ["pt", "pt-PT"]) { + const set = crisisResourcesForLocale(locale); + expect(set.emergencyNumber).toBe("112"); + expect(set.resources.map((r) => r.id)).not.toContain("cvv"); + } + }); + + it("names every resource of every locale's set in that locale", () => { + for (const locale of locales) { + const { t } = getServerTranslator(locale); + for (const resource of crisisResourcesForLocale(locale).resources) { + const key = `mentalHealth.crisisResource.${resource.id}.name`; + expect(t(key), `${locale} ${key}`).not.toBe(key); + } + } + }); +}); diff --git a/src/lib/mental-health/crisis-resources.ts b/src/lib/mental-health/crisis-resources.ts index bd3743977..386d2680b 100644 --- a/src/lib/mental-health/crisis-resources.ts +++ b/src/lib/mental-health/crisis-resources.ts @@ -98,6 +98,19 @@ const US: CrisisResourceSet = { ], }; +/** + * Brazil (pt-BR) — CVV by phone and chat, SAMU as the emergency number. + * Both numbers are free and answer around the clock (cvv.org.br; the + * Ministry of Health's SAMU 192 page). + */ +const BR: CrisisResourceSet = { + emergencyNumber: "192", + resources: [ + { id: "cvv", contacts: ["188", "cvv.org.br/chat"] }, + { id: "findahelpline", contacts: ["findahelpline.com"] }, + ], +}; + /** * Resolve a crisis-resource set from the user's locale. Region detection is * coarse (locale prefix) and defaults to the international set — the goal is to @@ -117,5 +130,8 @@ export function crisisResourcesForLocale( if (lc === "de-ch" || lc === "de_ch" || lc === "ch") return CH; if (lc.startsWith("de")) return DE_AT_CH; if (lc === "en-us" || lc.startsWith("en_us") || lc === "us") return US; + // Brazilian Portuguese only: CVV's 188 does not connect from Portugal, so a + // bare "pt" or "pt-PT" keeps the international set. + if (lc === "pt-br" || lc === "pt_br" || lc === "br") return BR; return INTERNATIONAL; }