From 02bbd8d3d5e1a9988e28b18eeb3f9b69676fcb8e Mon Sep 17 00:00:00 2001 From: tetuaoro <65575727+tetuaoro@users.noreply.github.com> Date: Wed, 18 Sep 2024 14:18:12 +0200 Subject: [PATCH] update: setup page - add: database langugage method - update: api lang & export supported languages --- src/app/components/ui/ChooseLang.vue | 17 +++---------- src/app/pages/setup.vue | 7 ++++-- src/app/stores/general.ts | 11 +++++++++ src/app/utils/api.ts | 7 ++++++ src/i18n.config.ts | 25 ++++++++++++++++++++ src/server/api/lang.post.ts | 7 ++++++ src/server/utils/types.ts | 7 ++++++ src/services/database/lowdb.ts | 8 +++++++ src/services/database/repositories/system.ts | 4 +++- 9 files changed, 76 insertions(+), 17 deletions(-) create mode 100644 src/app/stores/general.ts create mode 100644 src/server/api/lang.post.ts diff --git a/src/app/components/ui/ChooseLang.vue b/src/app/components/ui/ChooseLang.vue index ee107fc9..47722921 100644 --- a/src/app/components/ui/ChooseLang.vue +++ b/src/app/components/ui/ChooseLang.vue @@ -43,6 +43,8 @@ diff --git a/src/app/pages/setup.vue b/src/app/pages/setup.vue index 3d224352..3a8e84f6 100644 --- a/src/app/pages/setup.vue +++ b/src/app/pages/setup.vue @@ -104,6 +104,7 @@ import { FetchError } from 'ofetch'; const { t } = useI18n(); const authStore = useAuthStore(); +const generalStore = useGeneralStore(); type SetupError = { title: string; @@ -136,12 +137,14 @@ function updateLang(value: string) { async function increaseStep() { try { if (step.value === 1) { - /* lang */ + // TODO: handle error + await generalStore.updateLanguage(lang.value); + stepInvalide.value.push(1); } if (step.value === 2) { await newAccount(); - stepInvalide.value.push(1); + stepInvalide.value.push(2); } if (step.value === 3) { diff --git a/src/app/stores/general.ts b/src/app/stores/general.ts new file mode 100644 index 00000000..8ee4e786 --- /dev/null +++ b/src/app/stores/general.ts @@ -0,0 +1,11 @@ +export const useGeneralStore = defineStore('General', () => { + /** + * @throws if unsuccessful + */ + async function updateLanguage(language: string) { + const response = await api.updateLanguage({ lang: language }); + return response.success; + } + + return { updateLanguage }; +}); diff --git a/src/app/utils/api.ts b/src/app/utils/api.ts index a42608dd..5d55cbe0 100644 --- a/src/app/utils/api.ts +++ b/src/app/utils/api.ts @@ -129,6 +129,13 @@ class API { body: { username, password, accept }, }); } + + async updateLanguage({ lang }: { lang: string }) { + return $fetch('/api/lang', { + method: 'post', + body: { lang }, + }); + } } type WGClientReturn = Awaited< diff --git a/src/i18n.config.ts b/src/i18n.config.ts index 6cc464a9..e3b02f43 100644 --- a/src/i18n.config.ts +++ b/src/i18n.config.ts @@ -19,6 +19,31 @@ import it from './locales/it.json'; import th from './locales/th.json'; import hi from './locales/hi.json'; +const LOCALES = [ + { value: 'en', name: 'English' }, + { value: 'ua', name: 'Українська' }, + { value: 'ru', name: 'Русский' }, + { value: 'tr', name: 'Türkçe' }, + { value: 'no', name: 'Norsk' }, + { value: 'pl', name: 'Polski' }, + { value: 'fr', name: 'Français' }, + { value: 'de', name: 'Deutsch' }, + { value: 'ca', name: 'Català' }, + { value: 'es', name: 'Español' }, + { value: 'ko', name: '한국어' }, + { value: 'vi', name: 'Tiếng Việt' }, + { value: 'nl', name: 'Nederlands' }, + { value: 'is', name: 'Íslenska' }, + { value: 'pt', name: 'Português' }, + { value: 'zh-chs', name: '简体中文' }, + { value: 'zh-cht', name: '繁體中文' }, + { value: 'it', name: 'Italiano' }, + { value: 'th', name: 'ไทย' }, + { value: 'hi', name: 'हिन्दी' }, +]; + +export { LOCALES }; + export default defineI18nConfig(() => ({ legacy: false, locale: 'en', diff --git a/src/server/api/lang.post.ts b/src/server/api/lang.post.ts new file mode 100644 index 00000000..6bef31df --- /dev/null +++ b/src/server/api/lang.post.ts @@ -0,0 +1,7 @@ +export default defineEventHandler(async (event) => { + const { lang } = await readValidatedBody(event, validateZod(langType)); + setHeader(event, 'Content-Type', 'application/json'); + await Database.system.updateLanguage(lang); + SERVER_DEBUG(`Update Language: ${lang}`); + return { success: true }; +}); diff --git a/src/server/utils/types.ts b/src/server/utils/types.ts index 17a62027..3b13d37f 100644 --- a/src/server/utils/types.ts +++ b/src/server/utils/types.ts @@ -1,6 +1,7 @@ import type { ZodSchema } from 'zod'; import { z, ZodError } from 'zod'; import type { H3Event, EventHandlerRequest } from 'h3'; +import { LOCALES } from '~~/i18n.config'; // TODO: use i18n for messages @@ -74,6 +75,12 @@ const statistics = z.object( const objectMessage = 'zod.body'; // i18n key +const langs = LOCALES.map((lang) => lang.value); +const lang = z.enum(['', ...langs]); +export const langType = z.object({ + lang: lang, +}); + export const clientIdType = z.object( { clientId: id, diff --git a/src/services/database/lowdb.ts b/src/services/database/lowdb.ts index 762dcff2..d045ddf3 100644 --- a/src/services/database/lowdb.ts +++ b/src/services/database/lowdb.ts @@ -24,6 +24,7 @@ import { SystemRepository, type Feature, type Features, + type Lang, type Statistics, } from './repositories/system'; @@ -69,6 +70,13 @@ export class LowDBSystem extends SystemRepository { } }); } + + async updateLanguage(language: Lang): Promise { + DEBUG('Update Language'); + this.#db.update((v) => { + v.system.general.lang = language; + }); + } } export class LowDBUser extends UserRepository { diff --git a/src/services/database/repositories/system.ts b/src/services/database/repositories/system.ts index 2a82d0eb..2ba99187 100644 --- a/src/services/database/repositories/system.ts +++ b/src/services/database/repositories/system.ts @@ -1,6 +1,7 @@ import type { SessionConfig } from 'h3'; +import type { LOCALES } from '~~/i18n.config'; -export type Lang = 'en' | 'fr'; +export type Lang = (typeof LOCALES)[number]['value']; export type IpTables = { PreUp: string; @@ -106,4 +107,5 @@ export abstract class SystemRepository { abstract updateFeatures(features: Record): Promise; abstract updateStatistics(statistics: Statistics): Promise; + abstract updateLanguage(language: Lang): Promise; }