cautpartener / client / src / app / i18n.ts
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
/**
 * Tiny typed i18n. Romanian is the default and the source of truth for keys;
 * English and Hungarian must cover exactly the same keys (enforced by
 * `satisfies` in en.ts / hu.ts). The active language persists at
 * nsKey("lang"); first visit follows the browser language (hu* → Hungarian,
 * ro* → Romanian, en* → English, everything else → Romanian).
 */

import { nsKey } from "../config";
import { en } from "./locales/en";
import { hu } from "./locales/hu";
import { ro } from "./locales/ro";

export type Lang = "ro" | "en" | "hu";
export type MsgKey = keyof typeof ro;

const dicts: Record<Lang, Record<MsgKey, string>> = { ro, en, hu };

function detect(): Lang {
  try {
    const stored = localStorage.getItem(nsKey("lang"));
    if (stored === "ro" || stored === "en" || stored === "hu") return stored;
  } catch {} // Safari private mode
  const nav = navigator.language?.toLowerCase() ?? "";
  if (nav.startsWith("hu")) return "hu";
  if (nav.startsWith("ro")) return "ro";
  if (nav.startsWith("en")) return "en";
  return "ro";
}

let current: Lang = detect();

export function getLang(): Lang {
  return current;
}

/** Set + persist the language override. Callers re-render themselves. */
export function setLang(l: Lang): void {
  current = l;
  try {
    localStorage.setItem(nsKey("lang"), l);
  } catch {}
  document.documentElement.lang = l;
}

/**
 * BCP-47 locale list for Intl date/time formatting under the active language.
 * Hungarian maps to "hu-RO" (Hungarian as spoken in Romania) with plain "hu"
 * as the fallback; Intl picks the first locale it has data for.
 */
export function dateLocales(): string[] {
  switch (current) {
    case "hu":
      return ["hu-RO", "hu"];
    case "en":
      return ["en-GB"];
    default:
      return ["ro-RO"];
  }
}

/** Translate `key`, interpolating `{var}` placeholders from `vars`. */
export function t(key: MsgKey, vars?: Record<string, string | number>): string {
  let s = dicts[current][key] ?? dicts.ro[key] ?? key;
  if (vars) for (const [k, v] of Object.entries(vars)) s = s.replaceAll(`{${k}}`, String(v));
  return s;
}

document.documentElement.lang = current;

static mirror of HEAD · about · clone: git clone https://cod-sursa.cautpartener.ro/cautpartener.git