mirror of
https://github.com/sysadminsmedia/homebox.git
synced 2026-01-03 19:44:55 +01:00
feat: adding initial i18n support
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="py-4">
|
||||
<p class="text-sm">Password Strength: {{ message }}</p>
|
||||
<p class="text-sm">{{ $t("password_strength") }}: {{ message }}</p>
|
||||
<progress
|
||||
class="progress w-full progress-bar"
|
||||
:value="score"
|
||||
|
||||
17
frontend/locales/en.json5
Normal file
17
frontend/locales/en.json5
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"tagline": "Track, Organize, and Manage your Things.",
|
||||
"version": "Version",
|
||||
"build": "Build",
|
||||
"disabled_registration": "Registration Disabled",
|
||||
"login": "Login",
|
||||
"register": "Register",
|
||||
"remember_me": "Remember Me",
|
||||
"password": "Password",
|
||||
"email": "Email",
|
||||
"set_email": "What's your email?",
|
||||
"set_password": "Set your password",
|
||||
"set_name": "What's your name?",
|
||||
"password_strength": "Password Strength",
|
||||
"joining_group": "You're Joining an Existing Group!",
|
||||
"dont_join_group": "Don't want to join a group?",
|
||||
}
|
||||
@@ -1,8 +1,21 @@
|
||||
import { resolve, dirname } from "node:path";
|
||||
import { fileURLToPath } from "url";
|
||||
import { defineNuxtConfig } from "nuxt/config";
|
||||
import VueI18nVitePlugin from "@intlify/unplugin-vue-i18n/vite";
|
||||
|
||||
// https://v3.nuxtjs.org/api/configuration/nuxt.config
|
||||
export default defineNuxtConfig({
|
||||
ssr: false,
|
||||
build: {
|
||||
transpile: ["vue-i18n"],
|
||||
},
|
||||
vite: {
|
||||
plugins: [
|
||||
VueI18nVitePlugin({
|
||||
include: [resolve(dirname(fileURLToPath(import.meta.url)), "./locales/**")],
|
||||
}),
|
||||
],
|
||||
},
|
||||
modules: [
|
||||
"@nuxtjs/tailwindcss",
|
||||
"@pinia/nuxt",
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
"devDependencies": {
|
||||
"@faker-js/faker": "^8.0.0",
|
||||
"@iconify-json/mdi": "^1.1.64",
|
||||
"@intlify/unplugin-vue-i18n": "^4.0.0",
|
||||
"@nuxtjs/eslint-config-typescript": "^12.0.0",
|
||||
"@types/dompurify": "^3.0.0",
|
||||
"@types/markdown-it": "^13.0.0",
|
||||
@@ -27,13 +28,15 @@
|
||||
"eslint-plugin-prettier": "^5.1.3",
|
||||
"eslint-plugin-vue": "^9.4.0",
|
||||
"h3": "^1.7.1",
|
||||
"intl-messageformat": "^10.5.14",
|
||||
"isomorphic-fetch": "^3.0.0",
|
||||
"nuxt": "3.6.5",
|
||||
"prettier": "^3.2.5",
|
||||
"typescript": "^5.0.0",
|
||||
"unplugin-icons": "^0.18.5",
|
||||
"vite-plugin-eslint": "^1.8.1",
|
||||
"vitest": "^1.0.0"
|
||||
"vitest": "^1.0.0",
|
||||
"vue-i18n": "^9.13.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@headlessui/vue": "^1.7.9",
|
||||
|
||||
@@ -149,13 +149,13 @@
|
||||
<AppLogo class="w-12 -mb-4" />
|
||||
x
|
||||
</h2>
|
||||
<p class="ml-1 text-lg text-base-content/50">Track, Organize, and Manage your Things.</p>
|
||||
<p class="ml-1 text-lg text-base-content/50">{{ $t("tagline") }}</p>
|
||||
</div>
|
||||
<div class="flex mt-6 sm:mt-0 gap-4 ml-auto text-neutral-content">
|
||||
<a class="tooltip" data-tip="Project Github" href="https://github.com/sysadminsmedia/homebox" target="_blank">
|
||||
<MdiGithub class="h-8 w-8" />
|
||||
</a>
|
||||
<a href="https://twitter.com/haybytes" class="tooltip" data-tip="Follow The Developer" target="_blank">
|
||||
<a href="https://noc.social/@sysadminsmedia" class="tooltip" data-tip="Follow The Developer" target="_blank">
|
||||
<MdiTwitter class="h-8 w-8" />
|
||||
</a>
|
||||
<a href="https://discord.gg/aY4DCkpNA9" class="tooltip" data-tip="Join The Discord" target="_blank">
|
||||
@@ -174,17 +174,17 @@
|
||||
<div class="card-body">
|
||||
<h2 class="card-title text-2xl align-center">
|
||||
<MdiAccount class="mr-1 w-7 h-7" />
|
||||
Register
|
||||
{{ $t("register") }}
|
||||
</h2>
|
||||
<FormTextField v-model="email" label="Set your email?" />
|
||||
<FormTextField v-model="username" label="What's your name?" />
|
||||
<FormTextField v-model="email" :label="$t('set_email')" />
|
||||
<FormTextField v-model="username" :label="$t('set_name')" />
|
||||
<div v-if="!(groupToken == '')" class="pt-4 pb-1 text-center">
|
||||
<p>You're Joining an Existing Group!</p>
|
||||
<p>{{ $t("joining_group") }}</p>
|
||||
<button type="button" class="text-xs underline" @click="groupToken = ''">
|
||||
Don't Want To Join a Group?
|
||||
{{ $t("dont_join_group") }}
|
||||
</button>
|
||||
</div>
|
||||
<FormPassword v-model="password" label="Set your password" />
|
||||
<FormPassword v-model="password" :label="$t('set_password')" />
|
||||
<PasswordScore v-model:valid="canRegister" :password="password" />
|
||||
<div class="card-actions justify-end">
|
||||
<button
|
||||
@@ -193,7 +193,7 @@
|
||||
:class="loading ? 'loading' : ''"
|
||||
:disabled="loading || !canRegister"
|
||||
>
|
||||
Register
|
||||
{{ $t("register") }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -204,17 +204,17 @@
|
||||
<div class="card-body">
|
||||
<h2 class="card-title text-2xl align-center">
|
||||
<MdiAccount class="mr-1 w-7 h-7" />
|
||||
Login
|
||||
{{ $t("login") }}
|
||||
</h2>
|
||||
<template v-if="status && status.demo">
|
||||
<p class="text-xs italic text-center">This is a demo instance</p>
|
||||
<p class="text-xs text-center"><b>Email</b> demo@example.com</p>
|
||||
<p class="text-xs text-center"><b>Password</b> demo</p>
|
||||
<p class="text-xs text-center"><b>{{ $t("email") }}</b> demo@example.com</p>
|
||||
<p class="text-xs text-center"><b>{{ $t("password") }}</b> demo</p>
|
||||
</template>
|
||||
<FormTextField v-model="email" label="Email" />
|
||||
<FormPassword v-model="loginPassword" label="Password" />
|
||||
<FormTextField v-model="email" :label="$t('email')" />
|
||||
<FormPassword v-model="loginPassword" :label="$t('password')" />
|
||||
<div class="max-w-[140px]">
|
||||
<FormCheckbox v-model="remember" label="Remember Me" />
|
||||
<FormCheckbox v-model="remember" :label="$t('remember_me')" />
|
||||
</div>
|
||||
<div class="card-actions justify-end">
|
||||
<button
|
||||
@@ -241,18 +241,20 @@
|
||||
<MdiLogin v-else class="w-5 h-5 swap-off" />
|
||||
<MdiArrowRight class="w-5 h-5 swap-on" />
|
||||
</template>
|
||||
{{ registerForm ? "Login" : "Register" }}
|
||||
{{ registerForm ? $t("login") : $t("register") }}
|
||||
</BaseButton>
|
||||
<p v-else class="text-base-content italic text-sm inline-flex items-center gap-2">
|
||||
<MdiLock class="w-4 h-4 inline-block" />
|
||||
Registration Disabled
|
||||
{{ $t("disabled_registration") }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<footer v-if="status" class="mt-auto text-center w-full bottom-0 pb-4">
|
||||
<p class="text-center text-sm">Version: {{ status.build.version }} ~ Build: {{ status.build.commit }}</p>
|
||||
<p class="text-center text-sm">
|
||||
{{ $t("version") }}: {{ status.build.version }} ~ {{ $t("build") }}: {{ status.build.commit }}
|
||||
</p>
|
||||
</footer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
36
frontend/plugins/i18n.ts
Normal file
36
frontend/plugins/i18n.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import type { CompileError, MessageCompiler, MessageContext } from "vue-i18n";
|
||||
import { createI18n } from "vue-i18n";
|
||||
import IntlMessageFormat from "intl-messageformat";
|
||||
import messages from '@intlify/unplugin-vue-i18n/messages'
|
||||
|
||||
export default defineNuxtPlugin(({ vueApp }) => {
|
||||
const i18n = createI18n({
|
||||
legacy: false,
|
||||
globalInjection: true,
|
||||
locale: "en",
|
||||
messageCompiler,
|
||||
messages,
|
||||
});
|
||||
|
||||
vueApp.use(i18n);
|
||||
});
|
||||
|
||||
export const messageCompiler: MessageCompiler = (message, { locale, key, onError }) => {
|
||||
if (typeof message === "string") {
|
||||
/**
|
||||
* You can tune your message compiler performance more with your cache strategy or also memoization at here
|
||||
*/
|
||||
const formatter = new IntlMessageFormat(message, locale);
|
||||
return (ctx: MessageContext) => {
|
||||
return formatter.format(ctx.values);
|
||||
};
|
||||
} else {
|
||||
/**
|
||||
* for AST.
|
||||
* If you would like to support it,
|
||||
* You need to transform locale messages such as `json`, `yaml`, etc. with the bundle plugin.
|
||||
*/
|
||||
onError && onError(new Error("not support for AST") as CompileError);
|
||||
return () => key;
|
||||
}
|
||||
};
|
||||
12656
frontend/pnpm-lock.yaml
generated
12656
frontend/pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user