feat: add runtime locale overrides

This commit is contained in:
3252a8
2026-05-25 17:47:45 +03:00
parent 23784d00fe
commit 59fa301344
51 changed files with 4026 additions and 214 deletions
+42
View File
@@ -8,6 +8,7 @@
Download,
FileText,
Globe2,
Languages,
LayoutDashboard,
LifeBuoy,
Megaphone,
@@ -38,6 +39,7 @@
import SupportSection from "./sections/SupportSection.svelte";
import TariffEditorModal from "./sections/TariffEditorModal.svelte";
import TariffsSection from "./sections/TariffsSection.svelte";
import TranslationsSection from "./sections/TranslationsSection.svelte";
import AppearanceSection from "./sections/AppearanceSection.svelte";
import UserDetailModal from "./sections/UserDetailModal.svelte";
import UsersSection from "./sections/UsersSection.svelte";
@@ -51,6 +53,7 @@
import { createAdminSupportStore } from "../lib/admin/stores/supportStore.js";
import { createTariffsStore } from "../lib/admin/stores/tariffsStore.js";
import { createThemesStore } from "../lib/admin/stores/themesStore.js";
import { createTranslationsStore } from "../lib/admin/stores/translationsStore.js";
import { createUsersStore } from "../lib/admin/stores/usersStore.js";
import {
fmtDate,
@@ -83,6 +86,7 @@
export let onSettingsSaved = () => {};
export let onTariffsSaved = () => {};
export let onThemesSaved = () => {};
export let onTranslationsSaved = () => {};
export let brand = {};
export let brandTitle = "/minishop";
export let appFaviconUrl = "";
@@ -128,6 +132,7 @@
items: [
{ id: "tariffs", label: at("nav_tariffs", {}, "Тарифы"), icon: Coins },
{ id: "appearance", label: at("nav_appearance", {}, "Внешний вид"), icon: Paintbrush },
{ id: "translations", label: at("nav_translations", {}, "Переводы"), icon: Languages },
{ id: "settings", label: at("nav_settings", {}, "Настройки"), icon: Sliders },
],
},
@@ -178,6 +183,14 @@
title: at("section_appearance_title", {}, "Внешний вид"),
subtitle: at("section_appearance_subtitle", {}, "Логотип, темы и акцентные цвета Mini App"),
},
translations: {
title: at("section_translations_title", {}, "Переводы"),
subtitle: at(
"section_translations_subtitle",
{},
"Оверрайды строк локализации из базы данных и data/locales-overrides.json"
),
},
settings: {
title: at("section_settings_title", {}, "Настройки приложения"),
subtitle: at("section_settings_subtitle", {}, "Оверрайды над .env, применяются мгновенно"),
@@ -223,6 +236,7 @@
const supportStore = createAdminSupportStore({ api, onToast: flash, at });
const tariffsStore = createTariffsStore({ api, onToast: flash, onTariffsSaved, flash, at });
const themesStore = createThemesStore({ api, onThemesSaved, flash, at });
const translationsStore = createTranslationsStore({ api, onToast: flash, at });
const usersStore = createUsersStore({ api, onToast: flash, at });
setContext("promosStore", promosStore);
@@ -236,13 +250,16 @@
setContext("usersStore", usersStore);
setContext("tariffsStore", tariffsStore);
setContext("themesStore", themesStore);
setContext("translationsStore", translationsStore);
$: usersStore.setActive(active);
$: paymentsStore.setActive(active);
$: supportStore.setActive(active);
$: dirtyCount = Object.keys($settingsStore.settingsDirty || {}).length;
$: translationsDirtyCount = Object.keys($translationsStore.translationsDirty || {}).length;
$: syncBusy = $statsStore.syncBusy;
$: settingsSaving = $settingsStore.settingsSaving;
$: translationsSaving = $translationsStore.translationsSaving;
$: meta = SECTION_META[active] || { title: active, subtitle: "" };
$: currentLanguageOption =
languageOptions.find((option) => option.value === currentLang) || languageOptions[0];
@@ -676,6 +693,27 @@
: at("btn_save", {}, "Сохранить")}
</AdminButton>
{/if}
{#if active === "translations"}
{#if translationsDirtyCount}
<AdminBadge variant="warning"
>{at(
"settings_dirty_count",
{ count: translationsDirtyCount },
"Изменений: " + translationsDirtyCount
)}</AdminBadge
>
{/if}
<AdminButton
variant="primary"
onclick={() => translationsStore.saveTranslations(onTranslationsSaved)}
disabled={!translationsDirtyCount || translationsSaving}
>
<Save size={14} />
{translationsSaving
? at("btn_saving", {}, "Сохранение...")
: at("btn_save", {}, "Сохранить")}
</AdminButton>
{/if}
</div>
</header>
@@ -751,6 +789,10 @@
{#if active === "settings"}
<SettingsSection {at} {onSettingsSaved} {currentLang} />
{/if}
{#if active === "translations"}
<TranslationsSection {at} {onTranslationsSaved} />
{/if}
</div>
{/key}
</main>