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;
}