Apps, web, i18n, UI, partners, payouts, backoffice, bariki, prod infra

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
zabudko-ruandClaude Opus 5.5 committed 2026-10-25 22:55:29 +04:00
1 parent 45d7512d2b
commit 3489e0b816
319 files changed
+45483 -121

No files matched your search

+58
View File
@@ -0,0 +1,58 @@
import { createContext, useContext, useEffect, useMemo, useState, type ReactNode } from 'react';
import { createT, formatAmd, formatDateTime, isLocale, type Locale, type TFunction } from '@barev/i18n';
import { reportClientError } from './telegram.ts';
interface I18nValue {
locale: Locale;
t: TFunction;
setLocale: (l: Locale) => void;
amd: (n: number) => string;
dt: (d: Date, opts?: Intl.DateTimeFormatOptions) => string;
}
const Ctx = createContext<I18nValue | null>(null);
export function pickLocale(...candidates: (string | null | undefined)[]): Locale {
for (const c of candidates) {
const base = c?.split('-')[0]?.toLowerCase();
if (isLocale(base)) return base;
}
return 'ru';
}
export function I18nProvider({ initial, children }: { initial: Locale; children: ReactNode }) {
const [locale, setLocale] = useState<Locale>(initial);
useEffect(() => setLocale(initial), [initial]);
useEffect(() => {
document.documentElement.lang = locale;
}, [locale]);
const value = useMemo<I18nValue>(
() => ({
locale,
t: createT(locale),
setLocale,
amd: (n) => formatAmd(locale, n),
dt: (d, opts) => formatDateTime(locale, d, opts),
}),
[locale],
);
return <Ctx.Provider value={value}>{children}</Ctx.Provider>;
}
export function useI18n(): I18nValue {
const v = useContext(Ctx);
if (!v) throw new Error('I18nProvider missing');
return v;
}
/** Текст ошибки API: errors.<код бизнес-ошибки> или общий */
export function errorText(t: TFunction, err: unknown): string {
reportClientError(err, 'errorText');
const e = err as { data?: { domainCode?: string | null; code?: string }; message?: string } | null;
const code = e?.data?.domainCode ?? e?.message;
if (code && /^[A-Z0-9_]+$/.test(code)) {
const s = t(`errors.${code}`);
if (s !== `errors.${code}`) return s;
}
return t('errors.generic');
}