181 lines
5.5 KiB
TypeScript
181 lines
5.5 KiB
TypeScript
import { Translation } from '@/api/resources/Translations.ts'
|
|
import { createApi, Translations } from '../api'
|
|
import dev from './dev.ts'
|
|
import locales from './locales.ts'
|
|
import { Currency } from '@/components/PaymentTable/Price.ts'
|
|
import { symbolByCurrency } from './currency.ts'
|
|
|
|
// const environments = import.meta.env;
|
|
|
|
// export const getClientLocale = () => {
|
|
// return navigator.language
|
|
// }
|
|
export const getClientLocale = async () => {
|
|
const urlParams = new URLSearchParams(document.location.search);
|
|
const languageFromUrl = urlParams.get('lg');
|
|
const languageUrlFromStore = localStorage.getItem("languageFromUrl")
|
|
|
|
if (languageFromUrl?.length) {
|
|
localStorage.setItem("languageFromUrl", languageFromUrl)
|
|
return languageFromUrl;
|
|
}
|
|
|
|
if (languageUrlFromStore?.length) {
|
|
return languageUrlFromStore;
|
|
}
|
|
|
|
const api = createApi();
|
|
try {
|
|
const resp = await api.getLocale(undefined)
|
|
if (resp?.error || !resp?.languages?.length) {
|
|
return navigator.language
|
|
}
|
|
if (resp.country_code === "IN") {
|
|
return "hi"
|
|
}
|
|
return resp.languages.split(',')[0]
|
|
} catch (error) {
|
|
return navigator.language
|
|
}
|
|
}
|
|
|
|
export const getClientTimezone = () => Intl.DateTimeFormat().resolvedOptions().timeZone
|
|
export const fallbackLng = 'en'
|
|
export let language: string = fallbackLng;
|
|
|
|
export const setLanguage = async () => {
|
|
let _language = await getClientLocale();
|
|
|
|
// Normalize English variants to 'en'
|
|
if (_language?.toLowerCase().startsWith('en')) {
|
|
_language = 'en';
|
|
}
|
|
// Handle Spanish variants
|
|
else if (
|
|
(_language?.toLowerCase().match(/es/g) || []).length === 1 &&
|
|
_language?.toLowerCase() !== "es"
|
|
) {
|
|
_language = "es-419";
|
|
}
|
|
|
|
language = _language;
|
|
};
|
|
|
|
const omitKeys = ['href', 'title', 'url_slug', 'type']
|
|
// const isWeb = (group: Elements.ElementGroup) => group.name === 'web'
|
|
const cleanUp = (translation: Partial<Translation[]> = []) => {
|
|
return translation
|
|
.filter((trans) => !omitKeys.includes(trans?.key || ''))
|
|
.reduce((acc, trans) => ({ ...acc, [trans?.key || '']: trans?.value || '' }), {})
|
|
}
|
|
|
|
export const getDefaultLocaleByLanguage = (locale: string) => {
|
|
const language = locale.split('-')[0];
|
|
if (locale in locales) {
|
|
return locale;
|
|
}
|
|
if (language in locales) {
|
|
return language;
|
|
}
|
|
return fallbackLng;
|
|
}
|
|
|
|
export enum ELocalesPlacement {
|
|
V0 = "v0", // Main site version
|
|
V1 = "v1",
|
|
PalmistryV0 = "palmistry-v0",
|
|
PalmistryV01 = "palmistry-v0_1",
|
|
PalmistryV1 = "palmistry-v1",
|
|
PalmistryV11 = "palmistry-v1_1",
|
|
Chats = "chats",
|
|
EmailMarketingCompatibilityV1 = "email-marketing-comp-v1",
|
|
EmailMarketingPalmistryV2 = "email-marketing-palmistry-v2",
|
|
EmailMarketingCompatibilityV2 = "email-marketing-comp-v2",
|
|
EmailMarketingCompatibilityV3 = "email-marketing-comp-v3",
|
|
EmailMarketingCompatibilityV4 = "email-marketing-comp-v4",
|
|
CompatibilityV2 = "compatibility-v2",
|
|
CompatibilityV3 = "compatibility-v3",
|
|
CompatibilityV4 = "compatibility-v4",
|
|
EmailGenerator = "email-generator",
|
|
Profile = "profile",
|
|
RetainingFunnel = "retaining-funnel",
|
|
}
|
|
|
|
interface ITranslationJSON {
|
|
male: { [key: string]: string }
|
|
female: { [key: string]: string }
|
|
fallback: { male: { [key: string]: string }; female: { [key: string]: string } }
|
|
}
|
|
|
|
export type TTranslationPlacements = Partial<
|
|
Record<ELocalesPlacement, ITranslationJSON>
|
|
>
|
|
|
|
export const getTranslationsJSON = async (language: string): Promise<TTranslationPlacements> => {
|
|
const api = createApi();
|
|
// const isDev = false//window.location.hostname === "localhost"
|
|
const isDev = window.location.hostname === "localhost"
|
|
let defaultLanguage = getDefaultLocaleByLanguage(language).toLowerCase();
|
|
if (defaultLanguage === "pt") {
|
|
defaultLanguage = "pt-pt"
|
|
}
|
|
|
|
const placements = Object.values(ELocalesPlacement).filter(placement => placement !== ELocalesPlacement.V0);
|
|
|
|
try {
|
|
const responses = await Promise.allSettled(
|
|
placements.map(async place => {
|
|
try {
|
|
return isDev
|
|
?
|
|
await (await fetch(`/locales/${place}/${defaultLanguage}/male_${defaultLanguage}.json`)).json()
|
|
:
|
|
await api.getLocaleTranslations({
|
|
funnel: place,
|
|
locale: defaultLanguage
|
|
})
|
|
} catch (error) {
|
|
console.error(`Ошибка загрузки переводов для ${place}:`, error);
|
|
return null; // или можно вернуть пустой объект {}
|
|
}
|
|
})
|
|
);
|
|
|
|
// Фильтруем успешные результаты
|
|
const successfulResponses = responses
|
|
.filter(result => result.status === 'fulfilled')
|
|
.map(result => (result as PromiseFulfilledResult<any>).value)
|
|
// .filter(Boolean);
|
|
|
|
const result = successfulResponses.reduce((merged, current, index) => ({
|
|
...merged,
|
|
[placements[index]]: isDev ? { male: current } : current
|
|
// [placements[index]]: current
|
|
}), {});
|
|
|
|
return result;
|
|
} catch (error) {
|
|
console.error('Translation loading error:', error);
|
|
return {};
|
|
}
|
|
}
|
|
|
|
export const buildResources = (resp: Translations.Response, translationJSON: TTranslationPlacements) => {
|
|
const element = resp.translations
|
|
const translation = cleanUp(element)
|
|
return {
|
|
[getDefaultLocaleByLanguage(language)]: {
|
|
translation: {
|
|
...translation, ...dev.translation, translationJSON
|
|
}
|
|
},
|
|
}
|
|
}
|
|
|
|
export const addCurrency = (price: number | string, currency: Currency) => {
|
|
const symbol = symbolByCurrency[currency]
|
|
if ([Currency.EUR].includes(currency)) {
|
|
return `${price} ${symbol}`
|
|
}
|
|
return `${symbol}${price}`
|
|
} |