From 9e0f21c53845bdb68da5bbf3edffed5e397b1d82 Mon Sep 17 00:00:00 2001 From: RhenCloud Date: Sun, 2 Aug 2026 08:40:01 +0800 Subject: [PATCH] feat(admin): add zh/en i18n to the config console Introduce a lightweight useI18n composable (zh default, auto-detect via navigator.language, manual toggle persisted to localStorage) with full zh/en dictionaries, and wire translation keys through the console UI. --- admin/components/GroupEditor.vue | 47 +++--- admin/components/SendLogs.vue | 12 +- admin/composables/useI18n.ts | 246 +++++++++++++++++++++++++++++++ 3 files changed, 280 insertions(+), 25 deletions(-) create mode 100644 admin/composables/useI18n.ts diff --git a/admin/components/GroupEditor.vue b/admin/components/GroupEditor.vue index 6dd2962..6928dcb 100644 --- a/admin/components/GroupEditor.vue +++ b/admin/components/GroupEditor.vue @@ -6,39 +6,44 @@ @@ -49,6 +54,8 @@ import { reactive, watch } from "vue"; import type { Group } from "~/types"; +const { t } = useI18n(); + const props = defineProps<{ open: boolean; group: Group | null; saving: boolean }>(); const emit = defineEmits<{ (e: "close"): void; @@ -94,11 +101,11 @@ function save(): void { const id = form.id.trim(); const name = form.name.trim(); if (!/^[a-z0-9][a-z0-9-]*$/.test(id)) { - formError.value = "ID must be a-z / 0-9 / dashes"; + formError.value = t("groupEditor.errIdFormat"); return; } if (!name) { - formError.value = "Name is required"; + formError.value = t("groupEditor.errName"); return; } const owners = splitList(form.owners); diff --git a/admin/components/SendLogs.vue b/admin/components/SendLogs.vue index 73f3629..63c6688 100644 --- a/admin/components/SendLogs.vue +++ b/admin/components/SendLogs.vue @@ -1,12 +1,12 @@