From d73f51f61a96fdfe0f4872e325d379f284d9ab89 Mon Sep 17 00:00:00 2001 From: duckietm Date: Tue, 2 Jun 2026 12:04:39 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=86=99=20Update=20Texts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/configuration/UITexts_en.json5.example | 67 +++++++++ public/configuration/UITexts_it.json5.example | 67 +++++++++ public/configuration/UITexts_nl.json5.example | 87 +++++++++-- .../user-settings/UserAccountSettingsView.tsx | 138 +++++++++--------- .../user-settings/UserSettingsView.tsx | 22 +-- 5 files changed, 291 insertions(+), 90 deletions(-) diff --git a/public/configuration/UITexts_en.json5.example b/public/configuration/UITexts_en.json5.example index 473c4df..4b4fcdf 100644 --- a/public/configuration/UITexts_en.json5.example +++ b/public/configuration/UITexts_en.json5.example @@ -705,4 +705,71 @@ 'chatcmd.client.ejectall': 'Eject all furni', 'chatcmd.client.settings': 'Room settings', 'chatcmd.client.info': 'Client info', + + // ------------------------------------------------------------------------ + // Me-menu settings + User account settings window + // ------------------------------------------------------------------------ + 'usersettings.tab.general': "General", + 'usersettings.tab.themes': "Themes", + 'memenu.settings.other.place.multiple.objects': "Place multiple objects", + 'memenu.settings.other.skip.purchase.confirmation': "Skip purchase confirmation", + 'memenu.settings.other.enable.chat.window': "Enable chat window", + 'memenu.settings.other.catalog.classic.style': "Catalog: classic style", + 'usersettings.open.title': "User settings", + 'usersettings.open.subtitle': "Password & account", + 'usersettings.themes.custom': "Custom theme", + 'usersettings.themes.default_option': "Default (no theme)", + 'usersettings.themes.active_pieces': "Active pieces", + 'usersettings.themes.invalid': "Theme invalid or unreachable — using the default.", + 'usersettings.themes.none': "No themes available. Add a folder in custom-themes/ on the server.", + 'usersettings.title': "User Settings", + 'usersettings.account.label': "My account", + 'usersettings.guest': "Guest", + 'usersettings.subtitle': "Manage your account and security", + 'usersettings.menu.section': "Account", + 'usersettings.menu.password.title': "Reset password", + 'usersettings.menu.password.desc': "Change the password used to log in.", + 'usersettings.menu.email.title': "Change email", + 'usersettings.menu.email.desc': "Update the email address on your account.", + 'usersettings.menu.username.title': "Change username", + 'usersettings.menu.username.desc': "Pick a new name. You'll need to log in again.", + 'usersettings.menu.soon.title': "More coming soon", + 'usersettings.menu.soon.desc': "Two-factor authentication and more.", + 'usersettings.password.hint': "Use at least %count% characters. Mix upper & lowercase, numbers and symbols for a stronger password.", + 'usersettings.email.hint': "For security we ask you to confirm your current password before changing the email on your account.", + 'usersettings.username.hint': "Renaming will log you out and you can only rename again after 30 days. Make sure your friends know your new name!", + 'usersettings.field.current_password': "Current password", + 'usersettings.field.new_password': "New password", + 'usersettings.field.retype_password': "Retype new password", + 'usersettings.field.new_email': "New email address", + 'usersettings.field.new_username': "New username", + 'usersettings.username.rules': "%min%-%max% characters. Letters, numbers, dot, underscore and dash only.", + 'usersettings.strength.weak': "Weak", + 'usersettings.strength.fair': "Fair", + 'usersettings.strength.good': "Good", + 'usersettings.strength.strong': "Strong", + 'usersettings.aria.show_password': "Show password", + 'usersettings.aria.hide_password': "Hide password", + 'usersettings.btn.cancel': "Cancel", + 'usersettings.btn.saving': "Saving…", + 'usersettings.btn.save_password': "Save password", + 'usersettings.btn.save_email': "Save email", + 'usersettings.btn.renaming': "Renaming…", + 'usersettings.btn.rename': "Rename me", + 'usersettings.error.fields_required': "All fields are required.", + 'usersettings.error.password_min': "Password must be at least %count% characters.", + 'usersettings.error.password_long': "Password is too long.", + 'usersettings.error.password_mismatch': "New passwords do not match.", + 'usersettings.error.password_same': "New password must be different from the current password.", + 'usersettings.error.not_authenticated': "You are not authenticated. Please log in again.", + 'usersettings.error.network': "Could not reach the server. Please try again.", + 'usersettings.error.request_failed': "Request failed (%status%).", + 'usersettings.error.email_long': "Email address is too long.", + 'usersettings.error.email_invalid': "Please enter a valid email address.", + 'usersettings.error.username_length': "Username must be between %min% and %max% characters.", + 'usersettings.error.username_invalid': "Username may only contain letters, numbers, dot, underscore and dash.", + 'usersettings.error.username_same': "New username must be different from the current one.", + 'usersettings.success.password': "Password updated successfully.", + 'usersettings.success.email': "Email updated successfully.", + 'usersettings.success.username': "Username updated. Please log in again with your new name.", } diff --git a/public/configuration/UITexts_it.json5.example b/public/configuration/UITexts_it.json5.example index 5ab9eed..776900d 100644 --- a/public/configuration/UITexts_it.json5.example +++ b/public/configuration/UITexts_it.json5.example @@ -705,4 +705,71 @@ 'chatcmd.client.ejectall': 'Rimuovi tutti gli arredi', 'chatcmd.client.settings': 'Impostazioni stanza', 'chatcmd.client.info': 'Info client', + + // ------------------------------------------------------------------------ + // Me-menu settings + User account settings window + // ------------------------------------------------------------------------ + 'usersettings.tab.general': "Generale", + 'usersettings.tab.themes': "Temi", + 'memenu.settings.other.place.multiple.objects': "Posiziona più oggetti", + 'memenu.settings.other.skip.purchase.confirmation': "Salta la conferma d'acquisto", + 'memenu.settings.other.enable.chat.window': "Abilita finestra chat", + 'memenu.settings.other.catalog.classic.style': "Catalogo: stile classico", + 'usersettings.open.title': "Impostazioni utente", + 'usersettings.open.subtitle': "Password e account", + 'usersettings.themes.custom': "Tema personalizzato", + 'usersettings.themes.default_option': "Predefinito (nessun tema)", + 'usersettings.themes.active_pieces': "Elementi attivi", + 'usersettings.themes.invalid': "Tema non valido o non raggiungibile — uso il predefinito.", + 'usersettings.themes.none': "Nessun tema disponibile. Aggiungi una cartella in custom-themes/ sul server.", + 'usersettings.title': "Impostazioni utente", + 'usersettings.account.label': "Il mio account", + 'usersettings.guest': "Ospite", + 'usersettings.subtitle': "Gestisci il tuo account e la sicurezza", + 'usersettings.menu.section': "Account", + 'usersettings.menu.password.title': "Reimposta password", + 'usersettings.menu.password.desc': "Cambia la password che usi per accedere.", + 'usersettings.menu.email.title': "Cambia email", + 'usersettings.menu.email.desc': "Aggiorna l'indirizzo email del tuo account.", + 'usersettings.menu.username.title': "Cambia nome utente", + 'usersettings.menu.username.desc': "Scegli un nuovo nome. Dovrai accedere di nuovo.", + 'usersettings.menu.soon.title': "Altro in arrivo", + 'usersettings.menu.soon.desc': "Autenticazione a due fattori e altro.", + 'usersettings.password.hint': "Usa almeno %count% caratteri. Combina maiuscole e minuscole, numeri e simboli per una password più sicura.", + 'usersettings.email.hint': "Per sicurezza ti chiediamo di confermare la password attuale prima di cambiare l'email del tuo account.", + 'usersettings.username.hint': "Cambiando nome verrai disconnesso e potrai rinominarti di nuovo solo dopo 30 giorni. Assicurati che i tuoi amici conoscano il tuo nuovo nome!", + 'usersettings.field.current_password': "Password attuale", + 'usersettings.field.new_password': "Nuova password", + 'usersettings.field.retype_password': "Ripeti la nuova password", + 'usersettings.field.new_email': "Nuovo indirizzo email", + 'usersettings.field.new_username': "Nuovo nome utente", + 'usersettings.username.rules': "%min%-%max% caratteri. Solo lettere, numeri, punto, trattino basso e trattino.", + 'usersettings.strength.weak': "Debole", + 'usersettings.strength.fair': "Discreta", + 'usersettings.strength.good': "Buona", + 'usersettings.strength.strong': "Forte", + 'usersettings.aria.show_password': "Mostra password", + 'usersettings.aria.hide_password': "Nascondi password", + 'usersettings.btn.cancel': "Annulla", + 'usersettings.btn.saving': "Salvataggio…", + 'usersettings.btn.save_password': "Salva password", + 'usersettings.btn.save_email': "Salva email", + 'usersettings.btn.renaming': "Rinomina…", + 'usersettings.btn.rename': "Rinominami", + 'usersettings.error.fields_required': "Tutti i campi sono obbligatori.", + 'usersettings.error.password_min': "La password deve contenere almeno %count% caratteri.", + 'usersettings.error.password_long': "La password è troppo lunga.", + 'usersettings.error.password_mismatch': "Le nuove password non corrispondono.", + 'usersettings.error.password_same': "La nuova password deve essere diversa da quella attuale.", + 'usersettings.error.not_authenticated': "Non sei autenticato. Effettua di nuovo l'accesso.", + 'usersettings.error.network': "Impossibile raggiungere il server. Riprova.", + 'usersettings.error.request_failed': "Richiesta non riuscita (%status%).", + 'usersettings.error.email_long': "L'indirizzo email è troppo lungo.", + 'usersettings.error.email_invalid': "Inserisci un indirizzo email valido.", + 'usersettings.error.username_length': "Il nome utente deve contenere tra %min% e %max% caratteri.", + 'usersettings.error.username_invalid': "Il nome utente può contenere solo lettere, numeri, punto, trattino basso e trattino.", + 'usersettings.error.username_same': "Il nuovo nome utente deve essere diverso da quello attuale.", + 'usersettings.success.password': "Password aggiornata con successo.", + 'usersettings.success.email': "Email aggiornata con successo.", + 'usersettings.success.username': "Nome utente aggiornato. Accedi di nuovo con il tuo nuovo nome.", } diff --git a/public/configuration/UITexts_nl.json5.example b/public/configuration/UITexts_nl.json5.example index 9763667..d3aa55a 100644 --- a/public/configuration/UITexts_nl.json5.example +++ b/public/configuration/UITexts_nl.json5.example @@ -372,14 +372,14 @@ // ------------------------------------------------------------------------ // Login // ------------------------------------------------------------------------ - 'login.username': 'Wat is jou Camwijs naam', + 'login.username': 'Wat is jou habbo naam', 'login.forgot_password': 'Wachtwoord vergeten?', // First-time visitors card 'nitro.login.firsttime.title': 'Voor het eerst hier?', - 'nitro.login.firsttime.text': 'Heb je nog geen Camwijs account?', + 'nitro.login.firsttime.text': 'Heb je nog geen habbo account?', 'nitro.login.firsttime.link': 'Je kunt er hier een aanmaken', - 'nitro.login.card.title': 'Aanmelden bij Camwijs', + 'nitro.login.card.title': 'Aanmelden bij habbo', // Server status checks 'nitro.login.server.offline.short': 'De gameserver draait momenteel niet. Probeer het zo meteen opnieuw.', @@ -388,12 +388,12 @@ 'nitro.login.server.retry': 'Opnieuw proberen', // Registration flow - 'nitro.login.register.title': 'Camwijs-gegevens', + 'nitro.login.register.title': 'habbo-gegevens', 'nitro.login.register.next': 'Volgende', 'nitro.login.register.finish': 'Voltooien', 'nitro.login.register.creating': 'Bezig met aanmaken…', 'nitro.login.register.intro.credentials': 'Laten we je account aanmaken. Voer je e-mailadres in en kies een wachtwoord — we controleren of dit e-mailadres nog niet in gebruik is.', - 'nitro.login.register.intro.avatar': 'Nu is het tijd om je eigen Camwijs-personage te maken! Begin met het kiezen van je Camwijs-naam.', + 'nitro.login.register.intro.avatar': 'Nu is het tijd om je eigen habbo-personage te maken! Begin met het kiezen van je habbo-naam.', 'nitro.login.register.intro.room': 'Laatste stap — kies een startkamer, of sla dit over en maak later je eigen kamer.', 'nitro.login.register.confirm.label': 'Bevestig wachtwoord', 'nitro.login.register.username.placeholder': 'HabboNaam', @@ -412,8 +412,8 @@ 'nitro.login.forgot.success': 'E-mail verzonden! Als er een account bij dit adres hoort, vind je binnenkort een resetlink in je inbox (controleer je spam als je binnen een minuut niets ziet).', // Login errors (validation + transport) - 'nitro.login.error.missing_credentials': 'Voer zowel je Camwijs-naam als wachtwoord in.', - 'nitro.login.error.invalid_credentials': 'Ongeldige Camwijs-naam of wachtwoord.', + 'nitro.login.error.missing_credentials': 'Voer zowel je habbo-naam als wachtwoord in.', + 'nitro.login.error.invalid_credentials': 'Ongeldige habbo-naam of wachtwoord.', 'nitro.login.error.too_many_attempts': 'Te veel pogingen. Probeer het opnieuw over %seconds%s.', 'nitro.login.error.turnstile': 'Voltooi de beveiligingscontrole.', 'nitro.login.error.server_offline': 'De gameserver draait niet. Probeer het later opnieuw.', @@ -427,9 +427,9 @@ 'nitro.login.error.password_too_short': 'Je wachtwoord moet minimaal 8 tekens lang zijn.', 'nitro.login.error.password_mismatch': 'Wachtwoorden komen niet overeen.', 'nitro.login.error.email_taken': 'Dit e-mailadres is al in gebruik.', - 'nitro.login.error.missing_username': 'Kies een Camwijs-naam.', - 'nitro.login.error.username_length': 'De Camwijs-naam moet 3–16 tekens bevatten.', - 'nitro.login.error.username_taken': 'Deze Camwijs-naam is al in gebruik.', + 'nitro.login.error.missing_username': 'Kies een habbo-naam.', + 'nitro.login.error.username_length': 'De habbo-naam moet 3–16 tekens bevatten.', + 'nitro.login.error.username_taken': 'Deze habbo-naam is al in gebruik.', 'nitro.login.error.missing_email': 'Voer je e-mailadres in.', // ------------------------------------------------------------------------ @@ -707,4 +707,71 @@ 'chatcmd.client.ejectall': 'Verwijder alle meubels', 'chatcmd.client.settings': 'Kamerinstellingen', 'chatcmd.client.info': 'Client info', + + // ------------------------------------------------------------------------ + // Me-menu settings + User account settings window + // ------------------------------------------------------------------------ + 'usersettings.tab.general': "Algemeen", + 'usersettings.tab.themes': "Thema's", + 'memenu.settings.other.place.multiple.objects': "Meerdere objecten plaatsen", + 'memenu.settings.other.skip.purchase.confirmation': "Aankoopbevestiging overslaan", + 'memenu.settings.other.enable.chat.window': "Chatvenster inschakelen", + 'memenu.settings.other.catalog.classic.style': "Catalogus: klassieke stijl", + 'usersettings.open.title': "Gebruikersinstellingen", + 'usersettings.open.subtitle': "Wachtwoord & account", + 'usersettings.themes.custom': "Aangepast thema", + 'usersettings.themes.default_option': "Standaard (geen thema)", + 'usersettings.themes.active_pieces': "Actieve onderdelen", + 'usersettings.themes.invalid': "Thema ongeldig of onbereikbaar — standaard wordt gebruikt.", + 'usersettings.themes.none': "Geen thema's beschikbaar. Voeg een map toe in custom-themes/ op de server.", + 'usersettings.title': "Gebruikersinstellingen", + 'usersettings.account.label': "Mijn account", + 'usersettings.guest': "Gast", + 'usersettings.subtitle': "Beheer je account en beveiliging", + 'usersettings.menu.section': "Account", + 'usersettings.menu.password.title': "Wachtwoord wijzigen", + 'usersettings.menu.password.desc': "Wijzig het wachtwoord waarmee je inlogt.", + 'usersettings.menu.email.title': "E-mail wijzigen", + 'usersettings.menu.email.desc': "Werk het e-mailadres van je account bij.", + 'usersettings.menu.username.title': "Gebruikersnaam wijzigen", + 'usersettings.menu.username.desc': "Kies een nieuwe naam. Je moet daarna opnieuw inloggen.", + 'usersettings.menu.soon.title': "Meer komt binnenkort", + 'usersettings.menu.soon.desc': "Tweestapsverificatie en meer.", + 'usersettings.password.hint': "Gebruik minimaal %count% tekens. Combineer hoofd- en kleine letters, cijfers en symbolen voor een sterker wachtwoord.", + 'usersettings.email.hint': "Voor de veiligheid vragen we je je huidige wachtwoord te bevestigen voordat je het e-mailadres van je account wijzigt.", + 'usersettings.username.hint': "Door je naam te wijzigen word je uitgelogd en je kunt pas na 30 dagen opnieuw wijzigen. Zorg dat je vrienden je nieuwe naam kennen!", + 'usersettings.field.current_password': "Huidig wachtwoord", + 'usersettings.field.new_password': "Nieuw wachtwoord", + 'usersettings.field.retype_password': "Herhaal nieuw wachtwoord", + 'usersettings.field.new_email': "Nieuw e-mailadres", + 'usersettings.field.new_username': "Nieuwe gebruikersnaam", + 'usersettings.username.rules': "%min%-%max% tekens. Alleen letters, cijfers, punt, underscore en streepje.", + 'usersettings.strength.weak': "Zwak", + 'usersettings.strength.fair': "Redelijk", + 'usersettings.strength.good': "Goed", + 'usersettings.strength.strong': "Sterk", + 'usersettings.aria.show_password': "Wachtwoord tonen", + 'usersettings.aria.hide_password': "Wachtwoord verbergen", + 'usersettings.btn.cancel': "Annuleren", + 'usersettings.btn.saving': "Opslaan…", + 'usersettings.btn.save_password': "Wachtwoord opslaan", + 'usersettings.btn.save_email': "E-mail opslaan", + 'usersettings.btn.renaming': "Bezig met hernoemen…", + 'usersettings.btn.rename': "Hernoem mij", + 'usersettings.error.fields_required': "Alle velden zijn verplicht.", + 'usersettings.error.password_min': "Het wachtwoord moet minimaal %count% tekens bevatten.", + 'usersettings.error.password_long': "Het wachtwoord is te lang.", + 'usersettings.error.password_mismatch': "De nieuwe wachtwoorden komen niet overeen.", + 'usersettings.error.password_same': "Het nieuwe wachtwoord moet anders zijn dan het huidige wachtwoord.", + 'usersettings.error.not_authenticated': "Je bent niet ingelogd. Log opnieuw in.", + 'usersettings.error.network': "Kan de server niet bereiken. Probeer het opnieuw.", + 'usersettings.error.request_failed': "Verzoek mislukt (%status%).", + 'usersettings.error.email_long': "Het e-mailadres is te lang.", + 'usersettings.error.email_invalid': "Voer een geldig e-mailadres in.", + 'usersettings.error.username_length': "De gebruikersnaam moet tussen %min% en %max% tekens bevatten.", + 'usersettings.error.username_invalid': "De gebruikersnaam mag alleen letters, cijfers, punt, underscore en streepje bevatten.", + 'usersettings.error.username_same': "De nieuwe gebruikersnaam moet anders zijn dan de huidige.", + 'usersettings.success.password': "Wachtwoord succesvol bijgewerkt.", + 'usersettings.success.email': "E-mail succesvol bijgewerkt.", + 'usersettings.success.username': "Gebruikersnaam bijgewerkt. Log opnieuw in met je nieuwe naam.", } diff --git a/src/components/user-settings/UserAccountSettingsView.tsx b/src/components/user-settings/UserAccountSettingsView.tsx index c834ba2..f83fcbc 100644 --- a/src/components/user-settings/UserAccountSettingsView.tsx +++ b/src/components/user-settings/UserAccountSettingsView.tsx @@ -1,7 +1,7 @@ import { AddLinkEventTracker, GetSessionDataManager, ILinkEventTracker, RemoveLinkEventTracker } from '@nitrots/nitro-renderer'; import { FC, KeyboardEvent, useEffect, useMemo, useState } from 'react'; import { FaArrowLeft, FaCheckCircle, FaChevronRight, FaEnvelope, FaExclamationTriangle, FaEye, FaEyeSlash, FaIdBadge, FaInfoCircle, FaKey, FaShieldAlt, FaUserCog } from 'react-icons/fa'; -import { GetConfigurationValue, getAccessToken } from '../../api'; +import { GetConfigurationValue, LocalizeText, getAccessToken } from '../../api'; import { Button, LayoutAvatarImageView, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../common'; const MIN_PASSWORD_LENGTH = 8; @@ -17,9 +17,9 @@ const MAX_USERNAME_LENGTH = 25; type FeedbackKind = 'error' | 'success'; type Section = 'menu' | 'password' | 'email' | 'username'; -const passwordStrength = (value: string): { score: number; label: string; color: string } => +const passwordStrength = (value: string): { score: number; labelKey: string; color: string } => { - if(!value) return { score: 0, label: '', color: 'bg-black/10' }; + if(!value) return { score: 0, labelKey: '', color: 'bg-black/10' }; let score = 0; if(value.length >= MIN_PASSWORD_LENGTH) score++; @@ -28,10 +28,10 @@ const passwordStrength = (value: string): { score: number; label: string; color: if(/\d/.test(value)) score++; if(/[^A-Za-z0-9]/.test(value)) score++; - if(score <= 1) return { score: 1, label: 'Weak', color: 'bg-[#a81a12]' }; - if(score === 2) return { score: 2, label: 'Fair', color: 'bg-[#ffc107]' }; - if(score === 3) return { score: 3, label: 'Good', color: 'bg-[#1e7295]' }; - return { score: 4, label: 'Strong', color: 'bg-[#00800b]' }; + if(score <= 1) return { score: 1, labelKey: 'usersettings.strength.weak', color: 'bg-[#a81a12]' }; + if(score === 2) return { score: 2, labelKey: 'usersettings.strength.fair', color: 'bg-[#ffc107]' }; + if(score === 3) return { score: 3, labelKey: 'usersettings.strength.good', color: 'bg-[#1e7295]' }; + return { score: 4, labelKey: 'usersettings.strength.strong', color: 'bg-[#00800b]' }; }; export const UserAccountSettingsView: FC<{}> = () => @@ -131,38 +131,38 @@ export const UserAccountSettingsView: FC<{}> = () => if(!currentPassword || !newPassword || !confirmPassword) { - setFeedback({ kind: 'error', message: 'All fields are required.' }); + setFeedback({ kind: 'error', message: LocalizeText('usersettings.error.fields_required') }); return; } if(newPassword.length < MIN_PASSWORD_LENGTH) { - setFeedback({ kind: 'error', message: `Password must be at least ${ MIN_PASSWORD_LENGTH } characters.` }); + setFeedback({ kind: 'error', message: LocalizeText('usersettings.error.password_min', [ 'count' ], [ MIN_PASSWORD_LENGTH.toString() ]) }); return; } if(newPassword.length > MAX_PASSWORD_LENGTH) { - setFeedback({ kind: 'error', message: 'Password is too long.' }); + setFeedback({ kind: 'error', message: LocalizeText('usersettings.error.password_long') }); return; } if(newPassword !== confirmPassword) { - setFeedback({ kind: 'error', message: 'New passwords do not match.' }); + setFeedback({ kind: 'error', message: LocalizeText('usersettings.error.password_mismatch') }); return; } if(newPassword === currentPassword) { - setFeedback({ kind: 'error', message: 'New password must be different from the current password.' }); + setFeedback({ kind: 'error', message: LocalizeText('usersettings.error.password_same') }); return; } const token = getAccessToken(); if(!token) { - setFeedback({ kind: 'error', message: 'You are not authenticated. Please log in again.' }); + setFeedback({ kind: 'error', message: LocalizeText('usersettings.error.not_authenticated') }); return; } @@ -191,14 +191,14 @@ export const UserAccountSettingsView: FC<{}> = () => { const message = typeof payload.error === 'string' && payload.error ? payload.error - : `Request failed (${ response.status }).`; + : LocalizeText('usersettings.error.request_failed', [ 'status' ], [ response.status.toString() ]); setFeedback({ kind: 'error', message }); return; } const message = typeof payload.message === 'string' && payload.message ? payload.message - : 'Password updated successfully.'; + : LocalizeText('usersettings.success.password'); setFeedback({ kind: 'success', message }); setCurrentPassword(''); setNewPassword(''); @@ -208,7 +208,7 @@ export const UserAccountSettingsView: FC<{}> = () => } catch { - setFeedback({ kind: 'error', message: 'Could not reach the server. Please try again.' }); + setFeedback({ kind: 'error', message: LocalizeText('usersettings.error.network') }); } finally { @@ -224,26 +224,26 @@ export const UserAccountSettingsView: FC<{}> = () => if(!emailCurrentPassword || !newEmail) { - setFeedback({ kind: 'error', message: 'All fields are required.' }); + setFeedback({ kind: 'error', message: LocalizeText('usersettings.error.fields_required') }); return; } if(newEmail.length > MAX_EMAIL_LENGTH) { - setFeedback({ kind: 'error', message: 'Email address is too long.' }); + setFeedback({ kind: 'error', message: LocalizeText('usersettings.error.email_long') }); return; } if(!EMAIL_RE.test(newEmail)) { - setFeedback({ kind: 'error', message: 'Please enter a valid email address.' }); + setFeedback({ kind: 'error', message: LocalizeText('usersettings.error.email_invalid') }); return; } const token = getAccessToken(); if(!token) { - setFeedback({ kind: 'error', message: 'You are not authenticated. Please log in again.' }); + setFeedback({ kind: 'error', message: LocalizeText('usersettings.error.not_authenticated') }); return; } @@ -272,14 +272,14 @@ export const UserAccountSettingsView: FC<{}> = () => { const message = typeof payload.error === 'string' && payload.error ? payload.error - : `Request failed (${ response.status }).`; + : LocalizeText('usersettings.error.request_failed', [ 'status' ], [ response.status.toString() ]); setFeedback({ kind: 'error', message }); return; } const message = typeof payload.message === 'string' && payload.message ? payload.message - : 'Email updated successfully.'; + : LocalizeText('usersettings.success.email'); setFeedback({ kind: 'success', message }); setEmailCurrentPassword(''); setNewEmail(''); @@ -287,7 +287,7 @@ export const UserAccountSettingsView: FC<{}> = () => } catch { - setFeedback({ kind: 'error', message: 'Could not reach the server. Please try again.' }); + setFeedback({ kind: 'error', message: LocalizeText('usersettings.error.network') }); } finally { @@ -303,32 +303,32 @@ export const UserAccountSettingsView: FC<{}> = () => if(!usernameCurrentPassword || !newUsername) { - setFeedback({ kind: 'error', message: 'All fields are required.' }); + setFeedback({ kind: 'error', message: LocalizeText('usersettings.error.fields_required') }); return; } if(newUsername.length < MIN_USERNAME_LENGTH || newUsername.length > MAX_USERNAME_LENGTH) { - setFeedback({ kind: 'error', message: `Username must be between ${ MIN_USERNAME_LENGTH } and ${ MAX_USERNAME_LENGTH } characters.` }); + setFeedback({ kind: 'error', message: LocalizeText('usersettings.error.username_length', [ 'min', 'max' ], [ MIN_USERNAME_LENGTH.toString(), MAX_USERNAME_LENGTH.toString() ]) }); return; } if(!USERNAME_RE.test(newUsername)) { - setFeedback({ kind: 'error', message: 'Username may only contain letters, numbers, dot, underscore and dash.' }); + setFeedback({ kind: 'error', message: LocalizeText('usersettings.error.username_invalid') }); return; } if(newUsername === session.username) { - setFeedback({ kind: 'error', message: 'New username must be different from the current one.' }); + setFeedback({ kind: 'error', message: LocalizeText('usersettings.error.username_same') }); return; } const token = getAccessToken(); if(!token) { - setFeedback({ kind: 'error', message: 'You are not authenticated. Please log in again.' }); + setFeedback({ kind: 'error', message: LocalizeText('usersettings.error.not_authenticated') }); return; } @@ -357,14 +357,14 @@ export const UserAccountSettingsView: FC<{}> = () => { const message = typeof payload.error === 'string' && payload.error ? payload.error - : `Request failed (${ response.status }).`; + : LocalizeText('usersettings.error.request_failed', [ 'status' ], [ response.status.toString() ]); setFeedback({ kind: 'error', message }); return; } const message = typeof payload.message === 'string' && payload.message ? payload.message - : 'Username updated. Please log in again with your new name.'; + : LocalizeText('usersettings.success.username'); setFeedback({ kind: 'success', message }); setUsernameCurrentPassword(''); setNewUsername(''); @@ -382,7 +382,7 @@ export const UserAccountSettingsView: FC<{}> = () => } catch { - setFeedback({ kind: 'error', message: 'Could not reach the server. Please try again.' }); + setFeedback({ kind: 'error', message: LocalizeText('usersettings.error.network') }); } finally { @@ -394,7 +394,7 @@ export const UserAccountSettingsView: FC<{}> = () => return ( - +
@@ -410,16 +410,16 @@ export const UserAccountSettingsView: FC<{}> = () =>
) }
- My account - { session.username || 'Guest' } - Manage your account and security + { LocalizeText('usersettings.account.label') } + { session.username || LocalizeText('usersettings.guest') } + { LocalizeText('usersettings.subtitle') }
{ section === 'menu' && (
- Account + { LocalizeText('usersettings.menu.section') }
- Reset password - Change the password used to log in. + { LocalizeText('usersettings.menu.password.title') } + { LocalizeText('usersettings.menu.password.desc') }
@@ -442,8 +442,8 @@ export const UserAccountSettingsView: FC<{}> = () =>
- Change email - Update the email address on your account. + { LocalizeText('usersettings.menu.email.title') } + { LocalizeText('usersettings.menu.email.desc') }
@@ -456,8 +456,8 @@ export const UserAccountSettingsView: FC<{}> = () =>
- Change username - Pick a new name. You'll need to log in again. + { LocalizeText('usersettings.menu.username.title') } + { LocalizeText('usersettings.menu.username.desc') }
@@ -467,8 +467,8 @@ export const UserAccountSettingsView: FC<{}> = () =>
- More coming soon - Two-factor authentication and more. + { LocalizeText('usersettings.menu.soon.title') } + { LocalizeText('usersettings.menu.soon.desc') }
@@ -485,16 +485,16 @@ export const UserAccountSettingsView: FC<{}> = () => - Reset password + { LocalizeText('usersettings.menu.password.title') }
- Use at least { MIN_PASSWORD_LENGTH } characters. Mix upper & lowercase, numbers and symbols for a stronger password. + { LocalizeText('usersettings.password.hint', [ 'count' ], [ MIN_PASSWORD_LENGTH.toString() ]) }