changed locales from .ts to .json,

configured i18n-ally,
upgrade APIlite and regenerated BackendAPI.ts,
fixed successMessage value
This commit is contained in:
2026-02-14 06:47:14 +01:00
parent 210ab43a0b
commit 92086055dc
20 changed files with 336 additions and 269 deletions

9
frontend/.vscode/extensions.json vendored Normal file
View File

@ -0,0 +1,9 @@
{
"recommendations": [
"Vue.volar",
"dbaeumer.vscode-eslint",
"EditorConfig.EditorConfig",
"oxc.oxc-vscode",
"esbenp.prettier-vscode"
]
}

View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<link rel="icon" href="/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vite App</title>
<title>Nutrio</title>
</head>
<body>
<div id="app"></div>

View File

@ -1,12 +1,12 @@
{
"name": "nutrio",
"version": "0.0.0",
"version": "0.1.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "nutrio",
"version": "0.0.0",
"version": "0.1.0",
"dependencies": {
"@fortawesome/fontawesome-svg-core": "^7.2.0",
"@fortawesome/free-solid-svg-icons": "^7.2.0",
@ -2292,13 +2292,10 @@
}
},
"node_modules/@vue/devtools-api": {
"version": "8.0.6",
"resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-8.0.6.tgz",
"integrity": "sha512-+lGBI+WTvJmnU2FZqHhEB8J1DXcvNlDeEalz77iYgOdY1jTj1ipSBaKj3sRhYcy+kqA8v/BSuvOz1XJucfQmUA==",
"license": "MIT",
"dependencies": {
"@vue/devtools-kit": "^8.0.6"
}
"version": "6.6.4",
"resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.4.tgz",
"integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==",
"license": "MIT"
},
"node_modules/@vue/devtools-core": {
"version": "8.0.6",
@ -5128,16 +5125,16 @@
}
},
"node_modules/vue-eslint-parser": {
"version": "10.2.0",
"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-10.2.0.tgz",
"integrity": "sha512-CydUvFOQKD928UzZhTp4pr2vWz1L+H99t7Pkln2QSPdvmURT0MoC4wUccfCnuEaihNsu9aYYyk+bep8rlfkUXw==",
"version": "10.4.0",
"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-10.4.0.tgz",
"integrity": "sha512-Vxi9pJdbN3ZnVGLODVtZ7y4Y2kzAAE2Cm0CZ3ZDRvydVYxZ6VrnBhLikBsRS+dpwj4Jv4UCv21PTEwF5rQ9WXg==",
"dev": true,
"license": "MIT",
"dependencies": {
"debug": "^4.4.0",
"eslint-scope": "^8.2.0",
"eslint-visitor-keys": "^4.2.0",
"espree": "^10.3.0",
"eslint-scope": "^8.2.0 || ^9.0.0",
"eslint-visitor-keys": "^4.2.0 || ^5.0.0",
"espree": "^10.3.0 || ^11.0.0",
"esquery": "^1.6.0",
"semver": "^7.6.3"
},
@ -5148,17 +5145,17 @@
"url": "https://github.com/sponsors/mysticatea"
},
"peerDependencies": {
"eslint": "^8.57.0 || ^9.0.0"
"eslint": "^8.57.0 || ^9.0.0 || ^10.0.0"
}
},
"node_modules/vue-eslint-parser/node_modules/eslint-visitor-keys": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
"integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.0.tgz",
"integrity": "sha512-A0XeIi7CXU7nPlfHS9loMYEKxUaONu/hTEzHTGba9Huu94Cq1hPivf+DE5erJozZOky0LfvXAyrV/tcswpLI0Q==",
"dev": true,
"license": "Apache-2.0",
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
"node": "^20.19.0 || ^22.13.0 || >=24"
},
"funding": {
"url": "https://opencollective.com/eslint"
@ -5184,12 +5181,6 @@
"vue": "^3.0.0"
}
},
"node_modules/vue-i18n/node_modules/@vue/devtools-api": {
"version": "6.6.4",
"resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.4.tgz",
"integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==",
"license": "MIT"
},
"node_modules/vue-router": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-5.0.2.tgz",
@ -5235,6 +5226,15 @@
}
}
},
"node_modules/vue-router/node_modules/@vue/devtools-api": {
"version": "8.0.6",
"resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-8.0.6.tgz",
"integrity": "sha512-+lGBI+WTvJmnU2FZqHhEB8J1DXcvNlDeEalz77iYgOdY1jTj1ipSBaKj3sRhYcy+kqA8v/BSuvOz1XJucfQmUA==",
"license": "MIT",
"dependencies": {
"@vue/devtools-kit": "^8.0.6"
}
},
"node_modules/vue-router/node_modules/picomatch": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",

View File

@ -1,6 +1,6 @@
{
"name": "nutrio",
"version": "0.0.0",
"version": "0.1.0",
"private": true,
"type": "module",
"scripts": {

View File

@ -2,11 +2,12 @@
* Generated by APIlite
* https://gitea.tpsoft.org/TPsoft.org/APIlite
*
* 2026-02-13 10:00:58 */
* 2026-02-14 06:30:12 */
export interface APIliteActionResponse<T> {
status: 'OK';
data: T;
msg: string;
}
export interface APIliteErrorResponse {
@ -36,6 +37,9 @@ export interface APIliteHelpResponse {
javascript_version: string;
typescript_version: string;
actions: APIliteMethodDoc[];
status: string;
data: string;
msg: string;
}
class BackendAPI {

View File

@ -1,10 +1,10 @@
import { createI18n } from 'vue-i18n'
import cs from '@/locales/cs'
import de from '@/locales/de'
import en from '@/locales/en'
import es from '@/locales/es'
import sk from '@/locales/sk'
import cs from '@/locales/cs.json'
import de from '@/locales/de.json'
import en from '@/locales/en.json'
import es from '@/locales/es.json'
import sk from '@/locales/sk.json'
export const SUPPORTED_LOCALES = ['sk', 'cs', 'en', 'es', 'de'] as const
export type AppLocale = (typeof SUPPORTED_LOCALES)[number]
@ -12,33 +12,33 @@ export type AppLocale = (typeof SUPPORTED_LOCALES)[number]
const fallbackLocale: AppLocale = 'sk'
const isSupportedLocale = (value: string | null): value is AppLocale => {
return value !== null && SUPPORTED_LOCALES.includes(value as AppLocale)
return value !== null && SUPPORTED_LOCALES.includes(value as AppLocale)
}
const browserLocale = navigator.language.slice(0, 2).toLowerCase()
const storedLocale = localStorage.getItem('locale')
const locale: AppLocale = isSupportedLocale(storedLocale)
? storedLocale
: isSupportedLocale(browserLocale)
? browserLocale
: fallbackLocale
? storedLocale
: isSupportedLocale(browserLocale)
? browserLocale
: fallbackLocale
if (!isSupportedLocale(storedLocale) || storedLocale !== locale) {
localStorage.setItem('locale', locale)
localStorage.setItem('locale', locale)
}
const i18n = createI18n({
legacy: false,
locale,
fallbackLocale,
messages: {
sk,
cs,
en,
es,
de,
},
legacy: false,
locale,
fallbackLocale,
messages: {
sk,
cs,
en,
es,
de,
},
})
export default i18n

View File

@ -0,0 +1,41 @@
{
"app": {
"name": "Nutrio",
"slogan": "Plánování jídel, výživa a denní přehled na jednom místě."
},
"auth": {
"title": "Přihlášení",
"subtitle": "Použij e-mail a heslo. Pokud účet neexistuje, vytvoří se automaticky.",
"emailLabel": "E-mail",
"emailPlaceholder": "např. jméno{'@'}domena.cz",
"passwordLabel": "Heslo",
"passwordPlaceholder": "Zadej heslo",
"submit": "Přihlásit se",
"submitting": "Zpracovávám...",
"helper": "Po úspěšném přihlášení bude token uložen do prohlížeče.",
"tokenSaved": "Token byl uložen.",
"successLoggedIn": "Přihlášení bylo úspěšné.",
"successAutoRegistered": "Účet neexistoval, byl vytvořen a uživatel je přihlášen.",
"themeToggle": "Přepnout režim",
"languageLabel": "Jazyk",
"showPassword": "Zobrazit heslo",
"hidePassword": "Skrýt heslo",
"errors": {
"invalidEmail": "Zadej platný email.",
"passwordRequired": "Zadej heslo.",
"invalidCredentials": "Email nebo heslo nejsou správně.",
"loginFailed": "Přihlášení selhalo. Zkus to znovu."
}
},
"theme": {
"light": "Světlý režim",
"dark": "Tmavý režim"
},
"locale": {
"sk": "Slovenština",
"cs": "Čeština",
"en": "Angličtina",
"es": "Španělština",
"de": "Němčina"
}
}

View File

@ -1,43 +0,0 @@
const cs = {
app: {
name: 'Nutrio',
slogan: 'Planovani jidel, vyziva a denni prehled na jednom miste.',
},
auth: {
title: 'Prihlaseni',
subtitle: 'Pouzij email a heslo. Pokud ucet neexistuje, vytvori se automaticky.',
emailLabel: 'E-mail',
emailPlaceholder: "napr. jmeno{'@'}domena.cz",
passwordLabel: 'Heslo',
passwordPlaceholder: 'Zadej heslo',
submit: 'Prihlasit se',
submitting: 'Zpracovavam...',
helper: 'Po uspesnem prihlaseni bude token ulozen do prohlizece.',
tokenSaved: 'Token byl ulozen.',
successLoggedIn: 'Prihlaseni bylo uspesne.',
successAutoRegistered: 'Ucet neexistoval, byl vytvoren a uzivatel je prihlasen.',
themeToggle: 'Prepnout rezim',
languageLabel: 'Jazyk',
showPassword: 'Zobrazit heslo',
hidePassword: 'Skryt heslo',
errors: {
invalidEmail: 'Zadej platny email.',
passwordRequired: 'Zadej heslo.',
invalidCredentials: 'Email nebo heslo nejsou spravne.',
loginFailed: 'Prihlaseni selhalo. Zkus to znovu.',
},
},
theme: {
light: 'Svetly rezim',
dark: 'Tmavy rezim',
},
locale: {
sk: 'Slovenstina',
cs: 'Cestina',
en: 'Anglictina',
es: 'Spanelstina',
de: 'Nemcina',
},
}
export default cs

View File

@ -0,0 +1,41 @@
{
"app": {
"name": "Nutrio",
"slogan": "Mahlzeitenplanung, Ernährung und Tagesübersicht an einem Ort."
},
"auth": {
"title": "Anmelden",
"subtitle": "Nutze E-Mail und Passwort. Wenn das Konto nicht existiert, wird es automatisch erstellt.",
"emailLabel": "E-Mail",
"emailPlaceholder": "z. B. name{'@'}domain.de",
"passwordLabel": "Passwort",
"passwordPlaceholder": "Passwort eingeben",
"submit": "Anmelden",
"submitting": "Wird verarbeitet...",
"helper": "Nach erfolgreicher Anmeldung wird das Token im Browser gespeichert.",
"tokenSaved": "Token wurde gespeichert.",
"successLoggedIn": "Anmeldung war erfolgreich.",
"successAutoRegistered": "Konto war nicht vorhanden, wurde erstellt und der Benutzer ist nun angemeldet.",
"themeToggle": "Modus wechseln",
"languageLabel": "Sprache",
"showPassword": "Passwort anzeigen",
"hidePassword": "Passwort verbergen",
"errors": {
"invalidEmail": "Gib eine gültige E-Mail-Adresse ein.",
"passwordRequired": "Passwort eingeben.",
"invalidCredentials": "E-Mail oder Passwort ist falsch.",
"loginFailed": "Anmeldung fehlgeschlagen. Bitte versuche es erneut."
}
},
"theme": {
"light": "Heller Modus",
"dark": "Dunkler Modus"
},
"locale": {
"sk": "Slowakisch",
"cs": "Tschechisch",
"en": "Englisch",
"es": "Spanisch",
"de": "Deutsch"
}
}

View File

@ -1,43 +0,0 @@
const de = {
app: {
name: 'Nutrio',
slogan: 'Mahlzeitenplanung, Ernahrung und Tagesubersicht an einem Ort.',
},
auth: {
title: 'Anmelden',
subtitle: 'Nutze E-Mail und Passwort. Wenn das Konto nicht existiert, wird es automatisch erstellt.',
emailLabel: 'E-Mail',
emailPlaceholder: "z. B. name{'@'}domain.de",
passwordLabel: 'Passwort',
passwordPlaceholder: 'Passwort eingeben',
submit: 'Anmelden',
submitting: 'Wird verarbeitet...',
helper: 'Nach erfolgreicher Anmeldung wird das Token im Browser gespeichert.',
tokenSaved: 'Token wurde gespeichert.',
successLoggedIn: 'Anmeldung war erfolgreich.',
successAutoRegistered: 'Konto war nicht vorhanden, wurde erstellt und der Benutzer ist nun angemeldet.',
themeToggle: 'Modus wechseln',
languageLabel: 'Sprache',
showPassword: 'Passwort anzeigen',
hidePassword: 'Passwort verbergen',
errors: {
invalidEmail: 'Gib eine gueltige E-Mail-Adresse ein.',
passwordRequired: 'Passwort eingeben.',
invalidCredentials: 'E-Mail oder Passwort ist falsch.',
loginFailed: 'Anmeldung fehlgeschlagen. Bitte versuche es erneut.',
},
},
theme: {
light: 'Heller Modus',
dark: 'Dunkler Modus',
},
locale: {
sk: 'Slowakisch',
cs: 'Tschechisch',
en: 'Englisch',
es: 'Spanisch',
de: 'Deutsch',
},
}
export default de

View File

@ -0,0 +1,41 @@
{
"app": {
"name": "Nutrio",
"slogan": "Meal planning, nutrition, and daily totals in one place."
},
"auth": {
"title": "Sign in",
"subtitle": "Use your email and password. If the account does not exist, it will be created automatically.",
"emailLabel": "Email",
"emailPlaceholder": "e.g. name{'@'}domain.com",
"passwordLabel": "Password",
"passwordPlaceholder": "Enter password",
"submit": "Sign in",
"submitting": "Processing...",
"helper": "After successful sign-in, the token will be stored in your browser.",
"tokenSaved": "Token was saved.",
"successLoggedIn": "Sign-in was successful.",
"successAutoRegistered": "Account did not exist, it was created and the user is now signed in.",
"themeToggle": "Toggle mode",
"languageLabel": "Language",
"showPassword": "Show password",
"hidePassword": "Hide password",
"errors": {
"invalidEmail": "Enter a valid email address.",
"passwordRequired": "Enter password.",
"invalidCredentials": "Email or password is incorrect.",
"loginFailed": "Sign-in failed. Please try again."
}
},
"theme": {
"light": "Light mode",
"dark": "Dark mode"
},
"locale": {
"sk": "Slovak",
"cs": "Czech",
"en": "English",
"es": "Spanish",
"de": "German"
}
}

View File

@ -1,43 +0,0 @@
const en = {
app: {
name: 'Nutrio',
slogan: 'Meal planning, nutrition, and daily totals in one place.',
},
auth: {
title: 'Sign in',
subtitle: 'Use your email and password. If the account does not exist, it will be created automatically.',
emailLabel: 'Email',
emailPlaceholder: "e.g. name{'@'}domain.com",
passwordLabel: 'Password',
passwordPlaceholder: 'Enter password',
submit: 'Sign in',
submitting: 'Processing...',
helper: 'After successful sign-in, the token will be stored in your browser.',
tokenSaved: 'Token was saved.',
successLoggedIn: 'Sign-in was successful.',
successAutoRegistered: 'Account did not exist, it was created and the user is now signed in.',
themeToggle: 'Toggle mode',
languageLabel: 'Language',
showPassword: 'Show password',
hidePassword: 'Hide password',
errors: {
invalidEmail: 'Enter a valid email address.',
passwordRequired: 'Enter password.',
invalidCredentials: 'Email or password is incorrect.',
loginFailed: 'Sign-in failed. Please try again.',
},
},
theme: {
light: 'Light mode',
dark: 'Dark mode',
},
locale: {
sk: 'Slovak',
cs: 'Czech',
en: 'English',
es: 'Spanish',
de: 'German',
},
}
export default en

View File

@ -0,0 +1,41 @@
{
"app": {
"name": "Nutrio",
"slogan": "Planificación de comidas, nutrición y resumen diario en un solo lugar."
},
"auth": {
"title": "Iniciar sesión",
"subtitle": "Usa correo y contraseña. Si la cuenta no existe, se creará automáticamente.",
"emailLabel": "Correo",
"emailPlaceholder": "p. ej. nombre{'@'}dominio.es",
"passwordLabel": "Contraseña",
"passwordPlaceholder": "Introduce la contraseña",
"submit": "Iniciar sesión",
"submitting": "Procesando...",
"helper": "Tras iniciar sesión correctamente, el token se guardará en el navegador.",
"tokenSaved": "El token se ha guardado.",
"successLoggedIn": "Inicio de sesión correcto.",
"successAutoRegistered": "La cuenta no existía, se creó y el usuario ha iniciado sesión.",
"themeToggle": "Cambiar modo",
"languageLabel": "Idioma",
"showPassword": "Mostrar contraseña",
"hidePassword": "Ocultar contraseña",
"errors": {
"invalidEmail": "Introduce un correo válido.",
"passwordRequired": "Introduce la contraseña.",
"invalidCredentials": "El correo o la contraseña son incorrectos.",
"loginFailed": "El inicio de sesión falló. Inténtalo de nuevo."
}
},
"theme": {
"light": "Modo claro",
"dark": "Modo oscuro"
},
"locale": {
"sk": "Eslovaco",
"cs": "Checo",
"en": "Inglés",
"es": "Español",
"de": "Alemán"
}
}

View File

@ -1,43 +0,0 @@
const es = {
app: {
name: 'Nutrio',
slogan: 'Planificacion de comidas, nutricion y resumen diario en un solo lugar.',
},
auth: {
title: 'Iniciar sesion',
subtitle: 'Usa correo y contrasena. Si la cuenta no existe, se creara automaticamente.',
emailLabel: 'Correo',
emailPlaceholder: "p. ej. nombre{'@'}dominio.es",
passwordLabel: 'Contrasena',
passwordPlaceholder: 'Introduce la contrasena',
submit: 'Iniciar sesion',
submitting: 'Procesando...',
helper: 'Tras iniciar sesion correctamente, el token se guardara en el navegador.',
tokenSaved: 'El token se ha guardado.',
successLoggedIn: 'Inicio de sesion correcto.',
successAutoRegistered: 'La cuenta no existia, se creo y el usuario ha iniciado sesion.',
themeToggle: 'Cambiar modo',
languageLabel: 'Idioma',
showPassword: 'Mostrar contrasena',
hidePassword: 'Ocultar contrasena',
errors: {
invalidEmail: 'Introduce un correo valido.',
passwordRequired: 'Introduce la contrasena.',
invalidCredentials: 'El correo o la contrasena son incorrectos.',
loginFailed: 'El inicio de sesion fallo. Intentalo de nuevo.',
},
},
theme: {
light: 'Modo claro',
dark: 'Modo oscuro',
},
locale: {
sk: 'Eslovaco',
cs: 'Checo',
en: 'Ingles',
es: 'Espanol',
de: 'Aleman',
},
}
export default es

View File

@ -0,0 +1,41 @@
{
"app": {
"name": "Nutrio",
"slogan": "Plánovanie jedál, výživa a denný prehľad na jednom mieste."
},
"auth": {
"title": "Prihlásenie",
"subtitle": "Použi email a heslo. Ak účet neexistuje, vytvorí sa automaticky.",
"emailLabel": "Email",
"emailPlaceholder": "napr. meno{'@'}domena.sk",
"passwordLabel": "Heslo",
"passwordPlaceholder": "Zadaj heslo",
"submit": "Prihlásiť sa",
"submitting": "Spracúvam...",
"helper": "Po úspešnom prihlásení bude token uložený do prehliadača.",
"tokenSaved": "Token bol uložený.",
"successLoggedIn": "Prihlásenie bolo úspešné.",
"successAutoRegistered": "Účet neexistoval, bol vytvorený a používateľ je prihlásený.",
"themeToggle": "Prepnúť režim",
"languageLabel": "Jazyk",
"showPassword": "Zobraziť heslo",
"hidePassword": "Skryť heslo",
"errors": {
"invalidEmail": "Zadaj platný email.",
"passwordRequired": "Zadaj heslo.",
"invalidCredentials": "Email alebo heslo nie sú správne.",
"loginFailed": "Prihlásenie zlyhalo. Skús to znova."
}
},
"theme": {
"light": "Svetlý režim",
"dark": "Tmavý režim"
},
"locale": {
"sk": "Slovenčina",
"cs": "Čeština",
"en": "Angličtina",
"es": "Španielčina",
"de": "Nemčina"
}
}

View File

@ -1,43 +0,0 @@
const sk = {
app: {
name: 'Nutrio',
slogan: 'Plánovanie jedál, výživa a denný prehľad na jednom mieste.',
},
auth: {
title: 'Prihlásenie',
subtitle: 'Použi email a heslo. Ak účet neexistuje, vytvorí sa automaticky.',
emailLabel: 'Email',
emailPlaceholder: "napr. meno{'@'}domena.sk",
passwordLabel: 'Heslo',
passwordPlaceholder: 'Zadaj heslo',
submit: 'Prihlásiť sa',
submitting: 'Spracúvam...',
helper: 'Po úspešnom prihlásení bude token uložený do prehliadača.',
tokenSaved: 'Token bol uložený.',
successLoggedIn: 'Prihlásenie bolo úspešné.',
successAutoRegistered: 'Účet neexistoval, bol vytvorený a používateľ je prihlásený.',
themeToggle: 'Prepnúť režim',
languageLabel: 'Jazyk',
showPassword: 'Zobraziť heslo',
hidePassword: 'Skryť heslo',
errors: {
invalidEmail: 'Zadaj platný email.',
passwordRequired: 'Zadaj heslo.',
invalidCredentials: 'Email alebo heslo nie sú správne.',
loginFailed: 'Prihlásenie zlyhalo. Skús to znova.',
},
},
theme: {
light: 'Svetlý režim',
dark: 'Tmavý režim',
},
locale: {
sk: 'Slovenčina',
cs: 'Čeština',
en: 'Angličtina',
es: 'Španielčina',
de: 'Nemčina',
},
}
export default sk

View File

@ -140,7 +140,7 @@ const submitForm = async () => {
}
localStorage.setItem('user_email', userEmail)
successMessage.value = response.auto_registered
successMessage.value = response.data?.auto_registered
? t('auth.successAutoRegistered')
: t('auth.successLoggedIn')