frontend: add French translation and language i18n keys

Register `fr` in the i18n config (resources + supportedLngs) and add a full
French translation (locales/fr/translation.json) with exact key parity to
English (1661 keys; placeholders and plural suffixes preserved). Also adds the
shared `common.pagination.*` keys, `settings.version.checkNow`, and
`settings.profile.language.*`, and drops the now-unused `patients.pagination.*`.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Khalid Abdi
2026-06-29 21:00:01 +03:00
parent f1c9f8af55
commit 6c074b54f3
3 changed files with 2042 additions and 10 deletions
+7 -2
View File
@@ -5,14 +5,19 @@ import LanguageDetector from "i18next-browser-languagedetector";
import { initReactI18next } from "react-i18next"; import { initReactI18next } from "react-i18next";
import en from "./locales/en/translation.json"; import en from "./locales/en/translation.json";
import fr from "./locales/fr/translation.json";
export const defaultNS = "translation"; export const defaultNS = "translation";
// Add new languages here (and a matching JSON under locales/<lng>/translation.json). // Add new languages here (and a matching JSON under locales/<lng>/translation.json).
export const resources = { export const resources = {
en: { translation: en }, en: { translation: en },
fr: { translation: fr },
} as const; } as const;
// Languages offered in the Settings → Profile switcher (label rendered there).
export const supportedLanguages = ["en", "fr"] as const;
if (!i18n.isInitialized) { if (!i18n.isInitialized) {
i18n i18n
.use(LanguageDetector) .use(LanguageDetector)
@@ -21,8 +26,8 @@ if (!i18n.isInitialized) {
resources, resources,
defaultNS, defaultNS,
fallbackLng: "en", fallbackLng: "en",
// Only `en` exists today; keep this in sync with `resources` as languages grow. // Keep this in sync with `resources` as languages grow.
supportedLngs: ["en"], supportedLngs: ["en", "fr"],
interpolation: { escapeValue: false }, interpolation: { escapeValue: false },
detection: { detection: {
order: ["localStorage", "navigator", "htmlTag"], order: ["localStorage", "navigator", "htmlTag"],
+16 -8
View File
@@ -6,7 +6,14 @@
"signIn": "Sign in", "signIn": "Sign in",
"signUp": "Sign up", "signUp": "Sign up",
"backToSignIn": "Back to sign in", "backToSignIn": "Back to sign in",
"addedByAi": "Added by AI" "addedByAi": "Added by AI",
"pagination": {
"label": "Pages",
"previous": "Previous",
"next": "Next",
"page": "Page {{page}}",
"summary": "Showing {{from}}{{to}} of {{total}}"
}
}, },
"auth": { "auth": {
"login": { "login": {
@@ -222,13 +229,6 @@
"loading": "Loading patients…", "loading": "Loading patients…",
"empty": "No patients found.", "empty": "No patients found.",
"loadError": "Failed to load patients.", "loadError": "Failed to load patients.",
"pagination": {
"label": "Patient pages",
"previous": "Previous",
"next": "Next",
"page": "Page {{page}}",
"summary": "Showing {{from}}{{to}} of {{total}}"
},
"columns": { "columns": {
"name": "Name", "name": "Name",
"mrn": "MRN", "mrn": "MRN",
@@ -1520,6 +1520,7 @@
"current": "Current version", "current": "Current version",
"latest": "Latest release", "latest": "Latest release",
"checking": "Checking for updates…", "checking": "Checking for updates…",
"checkNow": "Check for updates",
"upToDate": "Up to date", "upToDate": "Up to date",
"updateAvailable": "Update available", "updateAvailable": "Update available",
"offline": "Couldn't reach the update server", "offline": "Couldn't reach the update server",
@@ -1683,6 +1684,13 @@
"professionalLinks": "Professional links", "professionalLinks": "Professional links",
"professionalLinksHint": "Registry or institutional profiles used to verify your identity. They are never shown to patients.", "professionalLinksHint": "Registry or institutional profiles used to verify your identity. They are never shown to patients.",
"addLink": "Add link", "addLink": "Add link",
"language": {
"title": "Language",
"description": "The language temetro's interface is shown in on this device.",
"label": "Display language",
"en": "English",
"fr": "Français"
},
"patientNotifications": "Patient notifications", "patientNotifications": "Patient notifications",
"patientNotificationsDescription": "Emails sent to patients about their records, results, and pending approvals", "patientNotificationsDescription": "Emails sent to patients about their records, results, and pending approvals",
"accountNotifications": "Account notifications", "accountNotifications": "Account notifications",
File diff suppressed because it is too large Load Diff