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 ( {loaded ? children :
} ); }; export default LocaleContext;