|
- import { useState, useEffect, createContext, useMemo } from 'react';
- import { IntlProvider } from 'react-intl';
- import enBase from '../translations/en.json';
- import cnBase from '../translations/zh-CN.json';
- import hkBase from '../translations/zh-HK.json';
-
- import { GET_COMBO, GET_CONTENT } from "utils/ApiPathConst";
- import { get } from "utils/HttpUtils";
-
- const LocaleContext = createContext();
-
- export const I18nProvider = ({ children }) => {
- const [locale, setLocale] = useState('en');
-
- // keep base messages immutable
- const [systemMessages, setSystemMessages] = useState({
- en: { ...enBase },
- zh: { ...hkBase },
- 'zh-HK': { ...hkBase },
- 'zh-CN': { ...cnBase }
- });
-
- const [loaded, setLoaded] = useState(false);
-
- useEffect(() => {
- const saved = localStorage.getItem('locale');
- if (!saved) localStorage.setItem('locale', 'en');
- else setLocale(saved);
- }, []);
-
- useEffect(() => {
- let alive = true;
-
- const loadTermsAndConditions = () => {
- // load both endpoints then merge into state
- const p1 = new Promise((resolve) => {
- get({
- url: GET_CONTENT,
- onSuccess: (resp) => resolve(resp || {}),
- onError: () => resolve({})
- });
- });
-
- const p2 = new Promise((resolve) => {
- get({
- url: GET_COMBO,
- onSuccess: (resp) => resolve(resp || []),
- onError: () => resolve([])
- });
- });
-
- Promise.all([p1, p2]).then(([contentMap, comboList]) => {
- if (!alive) return;
-
- setSystemMessages((prev) => {
- // clone prev first (immutably)
- const next = {
- ...prev,
- en: { ...prev.en },
- 'zh-CN': { ...prev['zh-CN'] },
- 'zh-HK': { ...prev['zh-HK'] },
- zh: { ...prev.zh }
- };
-
- // merge GET_CONTENT (object)
- for (const key in contentMap) {
- const v = contentMap[key] || {};
- next.en[key] = v.en ?? "";
- next['zh-CN'][key] = v.cn ?? "";
- next['zh-HK'][key] = v.zh ?? "";
- next.zh[key] = v.zh ?? "";
- }
-
- // merge GET_COMBO (array)
- for (const item of comboList) {
- if (!item?.key) continue;
- next.en[item.key] = item.en ?? "";
- next['zh-CN'][item.key] = item.cn ?? "";
- next['zh-HK'][item.key] = item.zh ?? "";
- next.zh[item.key] = item.zh ?? "";
- }
-
- return next;
- });
-
- setLoaded(true);
- });
- };
-
- loadTermsAndConditions();
-
- return () => {
- alive = false;
- };
- }, []);
-
- const messages = useMemo(() => {
- return systemMessages[locale] || systemMessages.en;
- }, [systemMessages, locale]);
-
- return (
- <LocaleContext.Provider value={{ locale, setLocale }}>
- <IntlProvider
- key={locale}
- locale={locale}
- messages={messages}
- defaultLocale="en"
- >
- {loaded ? children : <div />}
- </IntlProvider>
- </LocaleContext.Provider>
- );
- };
-
- export default LocaleContext;
|