From 46772d542f629b58e86cf0ea215aca47e5805cf2 Mon Sep 17 00:00:00 2001 From: Pandipipas <62224708+Pandipipas@users.noreply.github.com> Date: Thu, 19 Feb 2026 23:43:02 +0100 Subject: [PATCH] Ampliar i18n (EN/ES) en labels del dashboard y mensajes de update (#112) * Expand EN/ES translations for panels and update status texts * Translate remaining dashboard labels and localize country names * Translate Players top action buttons and search placeholder --- .../scoreko-dev/components/BracketPanel.vue | 9 +- .../components/CommentaryPanel.vue | 11 +- .../components/ScoreboardPanel.vue | 49 ++-- src/dashboard/scoreko-dev/i18n.ts | 241 ++++++++++++++++++ src/dashboard/scoreko-dev/main.vue | 17 +- src/dashboard/scoreko-dev/views/About.vue | 35 ++- src/dashboard/scoreko-dev/views/Graphics.vue | 17 +- src/dashboard/scoreko-dev/views/Players.vue | 78 +++--- src/dashboard/scoreko-dev/views/Settings.vue | 44 +++- src/shared/countries.ts | 42 ++- 10 files changed, 430 insertions(+), 113 deletions(-) create mode 100644 src/dashboard/scoreko-dev/i18n.ts diff --git a/src/dashboard/scoreko-dev/components/BracketPanel.vue b/src/dashboard/scoreko-dev/components/BracketPanel.vue index 2d96f71..a6e6a5a 100644 --- a/src/dashboard/scoreko-dev/components/BracketPanel.vue +++ b/src/dashboard/scoreko-dev/components/BracketPanel.vue @@ -1,5 +1,6 @@ diff --git a/src/dashboard/scoreko-dev/views/About.vue b/src/dashboard/scoreko-dev/views/About.vue index 7a04e5c..d77716e 100644 --- a/src/dashboard/scoreko-dev/views/About.vue +++ b/src/dashboard/scoreko-dev/views/About.vue @@ -1,10 +1,11 @@ diff --git a/src/shared/countries.ts b/src/shared/countries.ts index 96cefdc..d8f9159 100644 --- a/src/shared/countries.ts +++ b/src/shared/countries.ts @@ -7,18 +7,38 @@ export interface CountryOption { const baseCountries = getData(); -export const countryOptions: CountryOption[] = baseCountries - .map((country: CountryRecord) => ({ - value: country.code, - label: country.name, - })) - .sort((a: CountryOption, b: CountryOption) => a.label.localeCompare(b.label)); +const optionsCache = new Map(); + +const getDisplayNames = (locale: string) => { + try { + return new Intl.DisplayNames([locale], { type: 'region' }); + } catch { + return null; + } +}; + +export const getCountryOptions = (locale = 'en'): CountryOption[] => { + if (optionsCache.has(locale)) { + return optionsCache.get(locale)!; + } + + const displayNames = getDisplayNames(locale); + const options = baseCountries + .map((country: CountryRecord) => ({ + value: country.code, + label: displayNames?.of(country.code) ?? country.name, + })) + .sort((a: CountryOption, b: CountryOption) => a.label.localeCompare(b.label)); + + optionsCache.set(locale, options); + return options; +}; const countryByCode = new Map( - countryOptions.map((country) => [country.value.toUpperCase(), country.label]), + baseCountries.map((country) => [country.code.toUpperCase(), country.name]), ); const countryByName = new Map( - countryOptions.map((country) => [country.label.toLowerCase(), country.value]), + baseCountries.map((country) => [country.name.toLowerCase(), country.code]), ); export const resolveCountryCode = (value?: string) => { @@ -37,7 +57,7 @@ export const resolveCountryCode = (value?: string) => { return byName ?? ''; }; -export const getCountryLabel = (value?: string) => { +export const getCountryLabel = (value?: string, locale = 'en') => { if (!value) { return ''; } @@ -45,5 +65,7 @@ export const getCountryLabel = (value?: string) => { if (!resolved) { return value; } - return countryByCode.get(resolved) ?? value; + + const match = getCountryOptions(locale).find((country) => country.value === resolved); + return match?.label ?? countryByCode.get(resolved) ?? value; };