Add i18n.js module
This commit is contained in:
parent
f2fb10b753
commit
01a7a4cb59
1 changed files with 194 additions and 0 deletions
194
public/js/i18n.js
Normal file
194
public/js/i18n.js
Normal file
|
|
@ -0,0 +1,194 @@
|
||||||
|
const STRINGS = {
|
||||||
|
de: {
|
||||||
|
hint:'Menü → "Zum Startbildschirm" für App-Icon',
|
||||||
|
emptyLine1:'Noch keine Ziele.',emptyLine2:'Tippe auf + um zu starten.',
|
||||||
|
noEntry:'Noch kein Eintrag',log:'+',
|
||||||
|
noch:'Noch',dAbbr:'T',endet:'endet',todayShort:'heute',total:'total',
|
||||||
|
todayHeading:'Heute',done2:'Gemacht',dailyGoal:'Tagesziel',remaining:'Noch',
|
||||||
|
history:'Verlauf — heute & gestern bearbeitbar',
|
||||||
|
legBuf:'Puffer',legDone:'Erreicht',legPartial:'Teilweise',legMissed:'Verpasst',
|
||||||
|
delGoal:'Ziel löschen',
|
||||||
|
qbLabel:'Quick-Buchen',openLabel:'Offen',doneToday:'Heute erledigt',
|
||||||
|
hello:'Hallo {n}!',
|
||||||
|
confirmDelete:'Ziel wirklich löschen?',errDelete:'Fehler beim Löschen',errSave:'Speicherfehler',
|
||||||
|
loginTitle:'Anmelden',emailLabel:'E-Mail',passwordLabel:'Passwort',loginBtn:'Anmelden',
|
||||||
|
forgotPw:'Passwort vergessen?',
|
||||||
|
loginErrEmpty:'Bitte E-Mail und Passwort eingeben',
|
||||||
|
loginErrWrong:'Falsche E-Mail oder Passwort',loginErrRate:'Zu viele Versuche',loginErrConn:'Verbindungsfehler',
|
||||||
|
forgotTitle:'Passwort vergessen',forgotSub:'Wir schicken dir einen Reset-Link',
|
||||||
|
sendLink:'Link senden',back:'Zurück',
|
||||||
|
emailSentTitle:'E-Mail gesendet',
|
||||||
|
emailSentSub:'Falls die Adresse bekannt ist, erhältst du in Kürze einen Reset-Link.',
|
||||||
|
ok:'OK',
|
||||||
|
resetTitle:'Neues Passwort',newPwLabel:'Neues Passwort',setPw:'Passwort setzen',min8:'mind. 8 Zeichen',
|
||||||
|
pwChangedTitle:'Passwort geändert',pwChangedSub:'Du kannst dich jetzt anmelden.',
|
||||||
|
changeNameTitle:'Name ändern',yourName:'Dein Name',save:'Speichern',cancel:'Abbrechen',
|
||||||
|
errNameEmpty:'Name darf nicht leer sein',errNameSave:'Fehler beim Speichern',nameSaved:'Name gespeichert',
|
||||||
|
changePwTitle:'Passwort ändern',currentPwLabel:'Aktuelles Passwort',
|
||||||
|
newPwConfLabel:'Neues Passwort bestätigen',changePwBtn:'Ändern',
|
||||||
|
errPwMismatch:'Die neuen Passwörter stimmen nicht überein',pwChanged:'Passwort geändert',
|
||||||
|
registerTitle:'Konto erstellen',registerSub:'Du wurdest eingeladen',
|
||||||
|
namePlaceholder:'Wie sollen wir dich nennen?',pwConfLabel:'Passwort bestätigen',
|
||||||
|
pwPlaceholder:'Passwort wiederholen',registerBtn:'Registrieren',
|
||||||
|
errPwMismatch2:'Passwörter stimmen nicht überein',errFillAll:'Bitte alle Felder ausfüllen',
|
||||||
|
newGoalTitle:'Neues Ziel',exerciseLabel:'Übung / Gewohnheit',exercisePlaceholder:'Liegestütz, Plank …',
|
||||||
|
unitLabel:'Einheit',unitDefault:'Stück',daysLabel:'Dauer in Tagen',
|
||||||
|
dailyLabel:'Tagesziel',weeklyLabel:'Wochenziel',startGoal:'Ziel starten',errCreate:'Fehler beim Erstellen',
|
||||||
|
dataMenuTitle:'Daten verwalten',dataMenuSub:'Export, Import und Backup',
|
||||||
|
exportLabel:'Exportieren',exportSub:'Alle Ziele als JSON-Datei speichern',
|
||||||
|
importLabel:'Importieren',importSub:'Backup laden oder zusammenführen',
|
||||||
|
inviteLabel:'Freund einladen',inviteSub:'Einladungslink generieren',
|
||||||
|
inviteListLabel:'Meine Einladungen',inviteListSub:'Status aller gesendeten Einladungen',
|
||||||
|
changeName:'Name ändern',changePw:'Passwort ändern',logout:'Abmelden',close:'Schließen',
|
||||||
|
clearAll:'Alle Daten löschen',clearAllSub:'Kann nicht rückgängig gemacht werden',
|
||||||
|
confirmClear:'Alle Daten löschen?',
|
||||||
|
inviteFormTitle:'Freund einladen',inviteFormSub:'Link gilt 7 Tage und kann nur einmal verwendet werden',
|
||||||
|
inviteNameLabel:'Name (für deine Übersicht)',inviteNamePlaceholder:'z.B. Max',
|
||||||
|
generateLink:'Link generieren',inviteLinkTitle:'Einladungslink',
|
||||||
|
copyLink:'Link kopieren',linkCopied:'Link kopiert!',errGenerate:'Fehler beim Generieren',
|
||||||
|
noInvites:'Noch keine Einladungen verschickt',
|
||||||
|
statusPending:'Ausstehend',statusUsed:'Angenommen',statusExpired:'Abgelaufen',
|
||||||
|
errLoad:'Fehler beim Laden',
|
||||||
|
confirmImport:'{n} Ziel(e) importieren?',importDone:'{n} Ziel(e) importiert.',invalidFormat:'Ungültiges Format',
|
||||||
|
linkLabel:'Link',doneLabel:'gemacht',ofLabel:'von',
|
||||||
|
gestern:'Gestern',heute:'Heute',
|
||||||
|
expiresAt:'läuft ab:',acceptedBy:'→',
|
||||||
|
adminLabel:'Nutzer',adminColName:'Name',adminColEmail:'E-Mail',adminColRegistered:'Registriert',
|
||||||
|
},
|
||||||
|
en: {
|
||||||
|
hint:'Menu → "Add to Home Screen" for app icon',
|
||||||
|
emptyLine1:'No goals yet.',emptyLine2:'Tap + to get started.',
|
||||||
|
noEntry:'No entries yet',log:'+',
|
||||||
|
noch:'Left',dAbbr:'d',endet:'ends',todayShort:'today',total:'total',
|
||||||
|
todayHeading:'Today',done2:'Done',dailyGoal:'Daily goal',remaining:'Left',
|
||||||
|
history:'History — today & yesterday editable',
|
||||||
|
legBuf:'Buffer',legDone:'Reached',legPartial:'Partial',legMissed:'Missed',
|
||||||
|
delGoal:'Delete goal',
|
||||||
|
qbLabel:'Quick-log',openLabel:'Open',doneToday:'Done today',
|
||||||
|
hello:'Hello {n}!',
|
||||||
|
confirmDelete:'Really delete this goal?',errDelete:'Delete failed',errSave:'Save failed',
|
||||||
|
loginTitle:'Sign in',emailLabel:'E-Mail',passwordLabel:'Password',loginBtn:'Sign in',
|
||||||
|
forgotPw:'Forgot password?',
|
||||||
|
loginErrEmpty:'Please enter email and password',
|
||||||
|
loginErrWrong:'Wrong email or password',loginErrRate:'Too many attempts',loginErrConn:'Connection error',
|
||||||
|
forgotTitle:'Forgot password',forgotSub:"We'll send you a reset link",
|
||||||
|
sendLink:'Send link',back:'Back',
|
||||||
|
emailSentTitle:'Email sent',
|
||||||
|
emailSentSub:"If the address is registered, you'll receive a reset link shortly.",
|
||||||
|
ok:'OK',
|
||||||
|
resetTitle:'New password',newPwLabel:'New password',setPw:'Set password',min8:'at least 8 characters',
|
||||||
|
pwChangedTitle:'Password changed',pwChangedSub:'You can now sign in.',
|
||||||
|
changeNameTitle:'Change name',yourName:'Your name',save:'Save',cancel:'Cancel',
|
||||||
|
errNameEmpty:'Name cannot be empty',errNameSave:'Save failed',nameSaved:'Name saved',
|
||||||
|
changePwTitle:'Change password',currentPwLabel:'Current password',
|
||||||
|
newPwConfLabel:'Confirm new password',changePwBtn:'Change',
|
||||||
|
errPwMismatch:"The new passwords don't match",pwChanged:'Password changed',
|
||||||
|
registerTitle:'Create account',registerSub:"You've been invited",
|
||||||
|
namePlaceholder:'What should we call you?',pwConfLabel:'Confirm password',
|
||||||
|
pwPlaceholder:'Repeat password',registerBtn:'Register',
|
||||||
|
errPwMismatch2:"Passwords don't match",errFillAll:'Please fill in all fields',
|
||||||
|
newGoalTitle:'New goal',exerciseLabel:'Exercise / Habit',exercisePlaceholder:'Push-ups, Plank …',
|
||||||
|
unitLabel:'Unit',unitDefault:'reps',daysLabel:'Duration (days)',
|
||||||
|
dailyLabel:'Daily goal',weeklyLabel:'Weekly goal',startGoal:'Start goal',errCreate:'Create failed',
|
||||||
|
dataMenuTitle:'Manage data',dataMenuSub:'Export, Import and Backup',
|
||||||
|
exportLabel:'Export',exportSub:'Save all goals as JSON file',
|
||||||
|
importLabel:'Import',importSub:'Load or merge backup',
|
||||||
|
inviteLabel:'Invite friend',inviteSub:'Generate invite link',
|
||||||
|
inviteListLabel:'My invitations',inviteListSub:'Status of all sent invitations',
|
||||||
|
changeName:'Change name',changePw:'Change password',logout:'Sign out',close:'Close',
|
||||||
|
clearAll:'Delete all data',clearAllSub:'Cannot be undone',
|
||||||
|
confirmClear:'Delete all data?',
|
||||||
|
inviteFormTitle:'Invite friend',inviteFormSub:'Link valid 7 days, single use',
|
||||||
|
inviteNameLabel:'Name (for your reference)',inviteNamePlaceholder:'e.g. Max',
|
||||||
|
generateLink:'Generate link',inviteLinkTitle:'Invite link',
|
||||||
|
copyLink:'Copy link',linkCopied:'Link copied!',errGenerate:'Generate failed',
|
||||||
|
noInvites:'No invitations sent yet',
|
||||||
|
statusPending:'Pending',statusUsed:'Accepted',statusExpired:'Expired',
|
||||||
|
errLoad:'Load failed',
|
||||||
|
confirmImport:'Import {n} goal(s)?',importDone:'{n} goal(s) imported.',invalidFormat:'Invalid format',
|
||||||
|
linkLabel:'Link',doneLabel:'done',ofLabel:'of',
|
||||||
|
gestern:'Yesterday',heute:'Today',
|
||||||
|
expiresAt:'expires:',acceptedBy:'→',
|
||||||
|
adminLabel:'Users',adminColName:'Name',adminColEmail:'Email',adminColRegistered:'Registered',
|
||||||
|
},
|
||||||
|
pl: {
|
||||||
|
hint:'Menu → "Dodaj do ekranu głównego" aby zainstalować',
|
||||||
|
emptyLine1:'Brak celów.',emptyLine2:'Dotknij +, aby zacząć.',
|
||||||
|
noEntry:'Brak wpisów',log:'+',
|
||||||
|
noch:'Jeszcze',dAbbr:'d',endet:'kończy',todayShort:'dziś',total:'łącznie',
|
||||||
|
todayHeading:'Dziś',done2:'Wykonano',dailyGoal:'Cel dzienny',remaining:'Pozostało',
|
||||||
|
history:'Historia — dziś i wczoraj edytowalne',
|
||||||
|
legBuf:'Zapas',legDone:'Osiągnięto',legPartial:'Częściowo',legMissed:'Pominięto',
|
||||||
|
delGoal:'Usuń cel',
|
||||||
|
qbLabel:'Szybki wpis',openLabel:'Otwarte',doneToday:'Dziś ukończone',
|
||||||
|
hello:'Cześć {n}!',
|
||||||
|
confirmDelete:'Na pewno usunąć cel?',errDelete:'Błąd podczas usuwania',errSave:'Błąd zapisu',
|
||||||
|
loginTitle:'Zaloguj się',emailLabel:'E-Mail',passwordLabel:'Hasło',loginBtn:'Zaloguj',
|
||||||
|
forgotPw:'Zapomniałeś hasła?',
|
||||||
|
loginErrEmpty:'Podaj e-mail i hasło',
|
||||||
|
loginErrWrong:'Błędny e-mail lub hasło',loginErrRate:'Zbyt wiele prób',loginErrConn:'Błąd połączenia',
|
||||||
|
forgotTitle:'Zapomniane hasło',forgotSub:'Wyślemy Ci link do resetu',
|
||||||
|
sendLink:'Wyślij link',back:'Wróć',
|
||||||
|
emailSentTitle:'E-mail wysłany',
|
||||||
|
emailSentSub:'Jeśli adres jest zarejestrowany, wkrótce otrzymasz link resetujący.',
|
||||||
|
ok:'OK',
|
||||||
|
resetTitle:'Nowe hasło',newPwLabel:'Nowe hasło',setPw:'Ustaw hasło',min8:'min. 8 znaków',
|
||||||
|
pwChangedTitle:'Hasło zmienione',pwChangedSub:'Możesz się teraz zalogować.',
|
||||||
|
changeNameTitle:'Zmień nazwę',yourName:'Twoje imię',save:'Zapisz',cancel:'Anuluj',
|
||||||
|
errNameEmpty:'Imię nie może być puste',errNameSave:'Błąd zapisu',nameSaved:'Imię zapisano',
|
||||||
|
changePwTitle:'Zmień hasło',currentPwLabel:'Aktualne hasło',
|
||||||
|
newPwConfLabel:'Potwierdź nowe hasło',changePwBtn:'Zmień',
|
||||||
|
errPwMismatch:'Nowe hasła się nie zgadzają',pwChanged:'Hasło zmienione',
|
||||||
|
registerTitle:'Utwórz konto',registerSub:'Zostałeś zaproszony',
|
||||||
|
namePlaceholder:'Jak mamy Cię nazywać?',pwConfLabel:'Potwierdź hasło',
|
||||||
|
pwPlaceholder:'Powtórz hasło',registerBtn:'Zarejestruj',
|
||||||
|
errPwMismatch2:'Hasła się nie zgadzają',errFillAll:'Wypełnij wszystkie pola',
|
||||||
|
newGoalTitle:'Nowy cel',exerciseLabel:'Ćwiczenie / Nawyk',exercisePlaceholder:'Pompki, Plank …',
|
||||||
|
unitLabel:'Jednostka',unitDefault:'szt.',daysLabel:'Czas trwania (dni)',
|
||||||
|
dailyLabel:'Cel dzienny',weeklyLabel:'Cel tygodniowy',startGoal:'Rozpocznij cel',errCreate:'Błąd tworzenia',
|
||||||
|
dataMenuTitle:'Zarządzaj danymi',dataMenuSub:'Eksport, import i kopia zapasowa',
|
||||||
|
exportLabel:'Eksportuj',exportSub:'Zapisz wszystkie cele jako plik JSON',
|
||||||
|
importLabel:'Importuj',importSub:'Załaduj lub połącz kopię zapasową',
|
||||||
|
inviteLabel:'Zaproś znajomego',inviteSub:'Wygeneruj link zaproszenia',
|
||||||
|
inviteListLabel:'Moje zaproszenia',inviteListSub:'Status wszystkich wysłanych zaproszeń',
|
||||||
|
changeName:'Zmień nazwę',changePw:'Zmień hasło',logout:'Wyloguj',close:'Zamknij',
|
||||||
|
clearAll:'Usuń wszystkie dane',clearAllSub:'Nie można cofnąć',
|
||||||
|
confirmClear:'Usunąć wszystkie dane?',
|
||||||
|
inviteFormTitle:'Zaproś znajomego',inviteFormSub:'Link ważny 7 dni, jednorazowy',
|
||||||
|
inviteNameLabel:'Nazwa (dla Twojej ewidencji)',inviteNamePlaceholder:'np. Max',
|
||||||
|
generateLink:'Wygeneruj link',inviteLinkTitle:'Link zaproszenia',
|
||||||
|
copyLink:'Kopiuj link',linkCopied:'Link skopiowany!',errGenerate:'Błąd generowania',
|
||||||
|
noInvites:'Brak wysłanych zaproszeń',
|
||||||
|
statusPending:'Oczekujący',statusUsed:'Zaakceptowany',statusExpired:'Wygasły',
|
||||||
|
errLoad:'Błąd ładowania',
|
||||||
|
confirmImport:'Importować {n} cel(e)?',importDone:'Zaimportowano {n} cel(e).',invalidFormat:'Nieprawidłowy format',
|
||||||
|
linkLabel:'Link',doneLabel:'wykonano',ofLabel:'z',
|
||||||
|
gestern:'Wczoraj',heute:'Dziś',
|
||||||
|
expiresAt:'wygasa:',acceptedBy:'→',
|
||||||
|
adminLabel:'Użytkownicy',adminColName:'Nazwa',adminColEmail:'E-mail',adminColRegistered:'Rejestracja',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export let LOCALE = 'de';
|
||||||
|
|
||||||
|
export function tr(key) {
|
||||||
|
return (STRINGS[LOCALE] || STRINGS.de)[key] || STRINGS.de[key] || key;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ldoc() {
|
||||||
|
return LOCALE === 'de' ? 'de-DE' : LOCALE === 'pl' ? 'pl-PL' : 'en-GB';
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setLocale(lang, save) {
|
||||||
|
LOCALE = lang;
|
||||||
|
if (save) localStorage.setItem('zt_locale', lang);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function applyLocale(userLocale) {
|
||||||
|
const lang = userLocale || localStorage.getItem('zt_locale');
|
||||||
|
if (!lang) {
|
||||||
|
const nav = (navigator.language || '').slice(0, 2).toLowerCase();
|
||||||
|
if (STRINGS[nav]) { LOCALE = nav; return; }
|
||||||
|
}
|
||||||
|
if (lang && STRINGS[lang]) LOCALE = lang;
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue