From fcf54ea0cc84822a2977c7ee11b1b443c14e22aa Mon Sep 17 00:00:00 2001 From: Sven Carstensen Date: Thu, 19 Feb 2026 20:51:33 +0100 Subject: [PATCH] Erweiterungen --- src/main/frontend/utils/language-cookie.ts | 56 ++++++ .../config/LocaleVaadinInitListener.java | 141 +++++++++++-- .../votianlt/config/TranslationProvider.java | 44 +++- .../de/assecutor/votianlt/model/Language.java | 8 +- .../votianlt/pages/view/EditProfileView.java | 37 ++++ .../votianlt/pages/view/RegisterView.java | 51 +++-- .../votianlt/pages/view/StartView.java | 125 +++++++++--- src/main/resources/messages.properties | 3 + src/main/resources/messages_ee.properties | 188 ++++++++++++++++++ src/main/resources/messages_en.properties | 3 + src/main/resources/messages_es.properties | 3 + src/main/resources/messages_fr.properties | 3 + src/main/resources/messages_lt.properties | 188 ++++++++++++++++++ src/main/resources/messages_lv.properties | 188 ++++++++++++++++++ src/main/resources/messages_pl.properties | 188 ++++++++++++++++++ src/main/resources/messages_ru.properties | 188 ++++++++++++++++++ src/main/resources/messages_tr.properties | 188 ++++++++++++++++++ 17 files changed, 1532 insertions(+), 70 deletions(-) create mode 100644 src/main/frontend/utils/language-cookie.ts create mode 100644 src/main/resources/messages_ee.properties create mode 100644 src/main/resources/messages_lt.properties create mode 100644 src/main/resources/messages_lv.properties create mode 100644 src/main/resources/messages_pl.properties create mode 100644 src/main/resources/messages_ru.properties create mode 100644 src/main/resources/messages_tr.properties diff --git a/src/main/frontend/utils/language-cookie.ts b/src/main/frontend/utils/language-cookie.ts new file mode 100644 index 0000000..be1da26 --- /dev/null +++ b/src/main/frontend/utils/language-cookie.ts @@ -0,0 +1,56 @@ +/** + * Cookie names for language preference + */ +const LANGUAGE_COOKIE_NAME = 'votianlt.language'; +const COOKIE_MAX_AGE_DAYS = 365; // Cookie gültig für 1 Jahr + +/** + * Sets the language cookie with the selected language code + * @param languageCode - The language code (e.g., 'de', 'en', 'fr', 'es') + */ +export function setLanguageCookie(languageCode: string): void { + const maxAge = COOKIE_MAX_AGE_DAYS * 24 * 60 * 60; // Convert days to seconds + document.cookie = `${LANGUAGE_COOKIE_NAME}=${languageCode};path=/;max-age=${maxAge};SameSite=Lax`; +} + +/** + * Gets the language code from the cookie + * @returns The language code or null if not found + */ +export function getLanguageCookie(): string | null { + const cookies = document.cookie.split(';'); + for (const cookie of cookies) { + const [name, value] = cookie.trim().split('='); + if (name === LANGUAGE_COOKIE_NAME) { + return decodeURIComponent(value); + } + } + return null; +} + +/** + * Clears the language cookie + */ +export function clearLanguageCookie(): void { + document.cookie = `${LANGUAGE_COOKIE_NAME}=;path=/;max-age=0;SameSite=Lax`; +} + +/** + * Maps Language enum values to locale strings + */ +export const languageToLocale: Record = { + 'DE': 'de', + 'EN': 'en', + 'FR': 'fr', + 'ES': 'es' +}; + +/** + * Maps locale strings to Language enum values + */ +export const localeToLanguage: Record = { + 'de': 'DE', + 'en': 'EN', + 'fr': 'FR', + 'es': 'ES' +}; \ No newline at end of file diff --git a/src/main/java/de/assecutor/votianlt/config/LocaleVaadinInitListener.java b/src/main/java/de/assecutor/votianlt/config/LocaleVaadinInitListener.java index 852a7cc..f6016b3 100644 --- a/src/main/java/de/assecutor/votianlt/config/LocaleVaadinInitListener.java +++ b/src/main/java/de/assecutor/votianlt/config/LocaleVaadinInitListener.java @@ -5,6 +5,7 @@ import com.vaadin.flow.server.ServiceInitEvent; import com.vaadin.flow.server.VaadinServiceInitListener; import de.assecutor.votianlt.model.Language; import de.assecutor.votianlt.security.CustomUserPrincipal; +import jakarta.servlet.http.Cookie; import lombok.extern.slf4j.Slf4j; import org.springframework.security.authentication.AnonymousAuthenticationToken; import org.springframework.security.core.Authentication; @@ -17,48 +18,154 @@ import java.util.Locale; * Sets the user's preferred locale on the UI BEFORE any layout or view is * constructed. Registered via {@code UIInitListener} → {@code BeforeEnterListener}, * which fires prior to the router creating the layout component tree. + * + * For authenticated users: Uses the language preference from the user profile. + * For anonymous users: Uses the language from the 'votianlt.language' cookie + * or falls back to the browser's preferred locale. */ @Component @Slf4j public class LocaleVaadinInitListener implements VaadinServiceInitListener { + private static final String LANGUAGE_COOKIE_NAME = "votianlt.language"; + @Override public void serviceInit(ServiceInitEvent event) { event.getSource().addUIInitListener(uiInitEvent -> { UI ui = uiInitEvent.getUI(); - ui.addBeforeEnterListener(beforeEnterEvent -> applyLocaleFromCurrentUser(ui)); + ui.addBeforeEnterListener(beforeEnterEvent -> applyLocale(ui)); }); } - private void applyLocaleFromCurrentUser(UI ui) { + private void applyLocale(UI ui) { try { Authentication auth = SecurityContextHolder.getContext().getAuthentication(); - if (auth == null || !auth.isAuthenticated() || auth instanceof AnonymousAuthenticationToken) { - return; - } - if (!(auth.getPrincipal() instanceof CustomUserPrincipal cup)) { - return; - } - Language language = cup.getUser().getLanguage(); - if (language == null) { - return; - } - Locale targetLocale = getLocaleFromLanguage(language); - if (!targetLocale.equals(ui.getLocale())) { - ui.setLocale(targetLocale); - log.debug("Locale set to {} for user {}", targetLocale, cup.getUsername()); + + if (auth != null && auth.isAuthenticated() && !(auth instanceof AnonymousAuthenticationToken)) { + // Authenticated user: use profile language + applyLocaleFromAuthenticatedUser(ui, auth); + } else { + // Anonymous user: use cookie or browser locale + applyLocaleFromCookieOrBrowser(ui); } } catch (Exception e) { - log.debug("Could not apply locale from user preferences: {}", e.getMessage()); + log.debug("Could not apply locale: {}", e.getMessage()); } } + private void applyLocaleFromAuthenticatedUser(UI ui, Authentication auth) { + if (!(auth.getPrincipal() instanceof CustomUserPrincipal cup)) { + return; + } + Language language = cup.getUser().getLanguage(); + if (language == null) { + return; + } + Locale targetLocale = getLocaleFromLanguage(language); + if (!targetLocale.equals(ui.getLocale())) { + ui.setLocale(targetLocale); + log.debug("Locale set to {} for authenticated user {}", targetLocale, cup.getUsername()); + } + } + + private void applyLocaleFromCookieOrBrowser(UI ui) { + Locale targetLocale = null; + + // Try to get locale from cookie first + String cookieLanguage = getLanguageFromCookie(ui); + if (cookieLanguage != null) { + targetLocale = getLocaleFromLanguageCode(cookieLanguage); + log.debug("Using locale {} from cookie for anonymous user", targetLocale); + } + + // If no cookie, use browser's preferred locale if supported + if (targetLocale == null) { + targetLocale = getSupportedLocaleFromBrowser(ui); + if (targetLocale != null) { + log.debug("Using browser locale {} for anonymous user", targetLocale); + } + } + + // Apply the locale if different from current + if (targetLocale != null && !targetLocale.equals(ui.getLocale())) { + ui.setLocale(targetLocale); + log.debug("Locale set to {} for anonymous user", targetLocale); + } + } + + private String getLanguageFromCookie(UI ui) { + try { + var request = com.vaadin.flow.server.VaadinRequest.getCurrent(); + if (request == null) { + return null; + } + + Cookie[] cookies = request.getCookies(); + if (cookies == null) { + return null; + } + + for (Cookie cookie : cookies) { + if (LANGUAGE_COOKIE_NAME.equals(cookie.getName())) { + return cookie.getValue(); + } + } + } catch (Exception e) { + log.debug("Could not read language cookie: {}", e.getMessage()); + } + return null; + } + + private Locale getSupportedLocaleFromBrowser(UI ui) { + // Get the browser's preferred locales + var locale = ui.getSession().getBrowser().getLocale(); + if (locale == null) { + return null; + } + + // Check if the browser locale is supported + String language = locale.getLanguage().toLowerCase(); + return switch (language) { + case "de" -> Locale.GERMAN; + case "en" -> Locale.ENGLISH; + case "fr" -> Locale.FRENCH; + case "es" -> Locale.of("es", "ES"); + default -> null; // Return null to use Vaadin's default + }; + } + private Locale getLocaleFromLanguage(Language language) { return switch (language) { case DE -> Locale.GERMAN; case EN -> Locale.ENGLISH; case FR -> Locale.FRENCH; case ES -> Locale.of("es", "ES"); + case TR -> Locale.of("tr", "TR"); + case PL -> Locale.of("pl", "PL"); + case RU -> Locale.of("ru", "RU"); + case EE -> Locale.of("et", "EE"); + case LV -> Locale.of("lv", "LV"); + case LT -> Locale.of("lt", "LT"); + }; + } + + private Locale getLocaleFromLanguageCode(String languageCode) { + if (languageCode == null) { + return null; + } + + return switch (languageCode.toUpperCase()) { + case "DE" -> Locale.GERMAN; + case "EN" -> Locale.ENGLISH; + case "FR" -> Locale.FRENCH; + case "ES" -> Locale.of("es", "ES"); + case "TR" -> Locale.of("tr", "TR"); + case "PL" -> Locale.of("pl", "PL"); + case "RU" -> Locale.of("ru", "RU"); + case "EE" -> Locale.of("et", "EE"); + case "LV" -> Locale.of("lv", "LV"); + case "LT" -> Locale.of("lt", "LT"); + default -> null; }; } } diff --git a/src/main/java/de/assecutor/votianlt/config/TranslationProvider.java b/src/main/java/de/assecutor/votianlt/config/TranslationProvider.java index f42862e..7f1e68c 100644 --- a/src/main/java/de/assecutor/votianlt/config/TranslationProvider.java +++ b/src/main/java/de/assecutor/votianlt/config/TranslationProvider.java @@ -9,11 +9,39 @@ import java.util.Collections; import java.util.List; import java.util.Locale; import java.util.ResourceBundle; +import java.util.ResourceBundle.Control; @Component public class TranslationProvider implements I18NProvider { public static final String BUNDLE_PREFIX = "messages"; + + // Custom Control to map language codes to file names + private static final Control BUNDLE_CONTROL = new Control() { + @Override + public List getCandidateLocales(String baseName, Locale locale) { + // Map Estonian "et" to "ee" file, Latvian "lv" to "lv", Lithuanian "lt" to "lt" + String language = locale.getLanguage(); + String country = locale.getCountry(); + + // Create a locale that matches our file naming convention + Locale mappedLocale = switch (language) { + case "et" -> new Locale("ee"); // Estonian -> messages_ee.properties + case "lv" -> new Locale("lv"); // Latvian -> messages_lv.properties + case "lt" -> new Locale("lt"); // Lithuanian -> messages_lt.properties + case "ru" -> new Locale("ru"); // Russian -> messages_ru.properties + case "pl" -> new Locale("pl"); // Polish -> messages_pl.properties + case "tr" -> new Locale("tr"); // Turkish -> messages_tr.properties + case "es" -> new Locale("es"); // Spanish -> messages_es.properties + case "fr" -> new Locale("fr"); // French -> messages_fr.properties + case "en" -> new Locale("en"); // English -> messages_en.properties + case "de" -> new Locale("de"); // German -> messages.properties (default) + default -> locale; + }; + + return super.getCandidateLocales(baseName, mappedLocale); + } + }; @Override public List getProvidedLocales() { @@ -21,7 +49,13 @@ public class TranslationProvider implements I18NProvider { Locale.GERMAN, Locale.ENGLISH, Locale.FRENCH, - Locale.of("es", "ES") + Locale.of("es", "ES"), + Locale.of("tr", "TR"), + Locale.of("pl", "PL"), + Locale.of("ru", "RU"), + Locale.of("et", "EE"), + Locale.of("lv", "LV"), + Locale.of("lt", "LT") )); } @@ -32,7 +66,7 @@ public class TranslationProvider implements I18NProvider { } try { - ResourceBundle bundle = ResourceBundle.getBundle(BUNDLE_PREFIX, locale); + ResourceBundle bundle = ResourceBundle.getBundle(BUNDLE_PREFIX, locale, BUNDLE_CONTROL); String value = bundle.getString(key); if (params.length > 0) { @@ -51,6 +85,12 @@ public class TranslationProvider implements I18NProvider { case EN -> Locale.ENGLISH; case FR -> Locale.FRENCH; case ES -> Locale.of("es", "ES"); + case TR -> Locale.of("tr", "TR"); + case PL -> Locale.of("pl", "PL"); + case RU -> Locale.of("ru", "RU"); + case EE -> Locale.of("et", "EE"); + case LV -> Locale.of("lv", "LV"); + case LT -> Locale.of("lt", "LT"); }; return getTranslation(key, locale); } diff --git a/src/main/java/de/assecutor/votianlt/model/Language.java b/src/main/java/de/assecutor/votianlt/model/Language.java index d5c8ccb..7754d77 100644 --- a/src/main/java/de/assecutor/votianlt/model/Language.java +++ b/src/main/java/de/assecutor/votianlt/model/Language.java @@ -4,7 +4,13 @@ public enum Language { DE("Deutsch"), EN("English"), FR("Français"), - ES("Español"); + ES("Español"), + TR("Türkçe"), + PL("Polski"), + RU("Русский"), + EE("Eesti"), + LV("Latviešu"), + LT("Lietuvių"); private final String displayName; diff --git a/src/main/java/de/assecutor/votianlt/pages/view/EditProfileView.java b/src/main/java/de/assecutor/votianlt/pages/view/EditProfileView.java index 3956d49..c91aa17 100644 --- a/src/main/java/de/assecutor/votianlt/pages/view/EditProfileView.java +++ b/src/main/java/de/assecutor/votianlt/pages/view/EditProfileView.java @@ -498,6 +498,12 @@ public class EditProfileView extends HorizontalLayout implements HasDynamicTitle case EN -> "🇬🇧 "; case FR -> "🇫🇷 "; case ES -> "🇪🇸 "; + case TR -> "🇹🇷 "; + case PL -> "🇵🇱 "; + case RU -> "🇷🇺 "; + case EE -> "🇪🇪 "; + case LV -> "🇱🇻 "; + case LT -> "🇱🇹 "; }; return flag + language.getDisplayName(); }); @@ -507,6 +513,9 @@ public class EditProfileView extends HorizontalLayout implements HasDynamicTitle languageCombo.addValueChangeListener(e -> { // Language will be saved when the user clicks save button currentUser.setLanguage(e.getValue()); + + // Also set the language cookie so it's available before login + setLanguageCookie(e.getValue()); }); languageLayout.add(languageLabel, languageCombo); @@ -1845,6 +1854,34 @@ public class EditProfileView extends HorizontalLayout implements HasDynamicTitle } } + /** + * Sets the language cookie via JavaScript so the selected language + * is available even before the user logs in (e.g., on the login page). + * + * @param language the selected language + */ + private void setLanguageCookie(Language language) { + String languageCode = switch (language) { + case DE -> "DE"; + case EN -> "EN"; + case FR -> "FR"; + case ES -> "ES"; + case TR -> "TR"; + case PL -> "PL"; + case RU -> "RU"; + case EE -> "EE"; + case LV -> "LV"; + case LT -> "LT"; + }; + + // Execute JavaScript to set the cookie + UI.getCurrent().getPage().executeJs( + "const maxAge = 365 * 24 * 60 * 60;" + + "document.cookie = 'votianlt.language=' + $0 + ';path=/;max-age=' + maxAge + ';SameSite=Lax';", + languageCode + ); + } + @Override public String getPageTitle() { return getTranslation("page.title.profile.edit"); diff --git a/src/main/java/de/assecutor/votianlt/pages/view/RegisterView.java b/src/main/java/de/assecutor/votianlt/pages/view/RegisterView.java index 903bbb9..c9280f8 100644 --- a/src/main/java/de/assecutor/votianlt/pages/view/RegisterView.java +++ b/src/main/java/de/assecutor/votianlt/pages/view/RegisterView.java @@ -223,32 +223,32 @@ public class RegisterView extends VerticalLayout implements HasDynamicTitle { // Validierung if (email.isEmpty()) { - Notification.show("Bitte geben Sie eine E-Mail-Adresse ein.", 3000, Notification.Position.MIDDLE); + Notification.show(getTranslation("register.notification.email.required"), 3000, Notification.Position.MIDDLE); emailField.focus(); return; } if (!email.contains("@") || !email.contains(".")) { - Notification.show("Bitte geben Sie eine gültige E-Mail-Adresse ein.", 3000, Notification.Position.MIDDLE); + Notification.show(getTranslation("register.notification.email.invalid"), 3000, Notification.Position.MIDDLE); emailField.focus(); return; } if (userService.existsByEmail(email)) { - Notification.show("Ein Benutzer mit dieser E-Mail-Adresse existiert bereits.", 4000, + Notification.show(getTranslation("register.notification.email.duplicate"), 4000, Notification.Position.MIDDLE); return; } if (password.isEmpty()) { - Notification.show("Bitte geben Sie ein Passwort ein.", 3000, Notification.Position.MIDDLE); + Notification.show(getTranslation("register.notification.password.required"), 3000, Notification.Position.MIDDLE); passwordField.focus(); return; } if (password.length() < 6) { - Notification.show("Das Passwort muss mindestens 6 Zeichen lang sein.", 3000, Notification.Position.MIDDLE); + Notification.show(getTranslation("register.notification.password.min"), 3000, Notification.Position.MIDDLE); passwordField.focus(); return; } if (!password.equals(confirmPassword)) { - Notification.show("Die Passwörter stimmen nicht überein.", 3000, Notification.Position.MIDDLE); + Notification.show(getTranslation("register.notification.password.mismatch"), 3000, Notification.Position.MIDDLE); confirmPasswordField.focus(); return; } @@ -256,49 +256,49 @@ public class RegisterView extends VerticalLayout implements HasDynamicTitle { // Weitere Pflichtfelder prüfen (aus Edit-Profile) var firstName = firstNameField.getValue() != null ? firstNameField.getValue().trim() : ""; if (firstName.isEmpty()) { - Notification.show("Bitte geben Sie Ihren Vornamen ein.", 3000, Notification.Position.MIDDLE); + Notification.show(getTranslation("register.notification.firstname.required"), 3000, Notification.Position.MIDDLE); firstNameField.focus(); return; } var lastName = lastNameField.getValue() != null ? lastNameField.getValue().trim() : ""; if (lastName.isEmpty()) { - Notification.show("Bitte geben Sie Ihren Nachnamen ein.", 3000, Notification.Position.MIDDLE); + Notification.show(getTranslation("register.notification.lastname.required"), 3000, Notification.Position.MIDDLE); lastNameField.focus(); return; } var phone = phoneField.getValue() != null ? phoneField.getValue().trim() : ""; if (phone.isEmpty()) { - Notification.show("Bitte geben Sie Ihre Telefonnummer ein.", 3000, Notification.Position.MIDDLE); + Notification.show(getTranslation("register.notification.phone.required"), 3000, Notification.Position.MIDDLE); phoneField.focus(); return; } var company = companyField.getValue() != null ? companyField.getValue().trim() : ""; if (company.isEmpty()) { - Notification.show("Bitte geben Sie den Firmennamen ein.", 3000, Notification.Position.MIDDLE); + Notification.show(getTranslation("register.notification.company.required"), 3000, Notification.Position.MIDDLE); companyField.focus(); return; } var street = streetField.getValue() != null ? streetField.getValue().trim() : ""; if (street.isEmpty()) { - Notification.show("Bitte geben Sie die Straße ein.", 3000, Notification.Position.MIDDLE); + Notification.show(getTranslation("register.notification.street.required"), 3000, Notification.Position.MIDDLE); streetField.focus(); return; } var houseNo = houseNumberField.getValue() != null ? houseNumberField.getValue().trim() : ""; if (houseNo.isEmpty()) { - Notification.show("Bitte geben Sie die Hausnummer ein.", 3000, Notification.Position.MIDDLE); + Notification.show(getTranslation("register.notification.housenr.required"), 3000, Notification.Position.MIDDLE); houseNumberField.focus(); return; } var zip = zipField.getValue() != null ? zipField.getValue().trim() : ""; if (zip.isEmpty()) { - Notification.show("Bitte geben Sie die Postleitzahl ein.", 3000, Notification.Position.MIDDLE); + Notification.show(getTranslation("register.notification.zip.required"), 3000, Notification.Position.MIDDLE); zipField.focus(); return; } var city = cityField.getValue() != null ? cityField.getValue().trim() : ""; if (city.isEmpty()) { - Notification.show("Bitte geben Sie die Stadt ein.", 3000, Notification.Position.MIDDLE); + Notification.show(getTranslation("register.notification.city.required"), 3000, Notification.Position.MIDDLE); cityField.focus(); return; } @@ -311,7 +311,7 @@ public class RegisterView extends VerticalLayout implements HasDynamicTitle { // Rate-Limit: 60 Sekunden zwischen Sendungen if (lastSentAt != null && Duration.between(lastSentAt, LocalDateTime.now()).getSeconds() < 60) { long wait = 60 - Duration.between(lastSentAt, LocalDateTime.now()).getSeconds(); - Notification.show("Bitte warten Sie " + wait + " Sekunden, bevor Sie den Code erneut senden.", 4000, + Notification.show(getTranslation("passwordreset.notification.wait", wait), 4000, Notification.Position.MIDDLE); return; } @@ -320,9 +320,8 @@ public class RegisterView extends VerticalLayout implements HasDynamicTitle { codeExpiresAt = LocalDateTime.now().plusMinutes(10); lastSentAt = LocalDateTime.now(); - String subject = "Ihr VotianLT Bestätigungscode"; - String body = "Ihr Bestätigungscode lautet: " + code + "\n\n" + "Dieser Code ist 10 Minuten gültig.\n" - + "Wenn Sie diese Registrierung nicht angefragt haben, ignorieren Sie diese E-Mail."; + String subject = getTranslation("email.2fa.subject"); + String body = getTranslation("email.2fa.body", code); try { emailService.sendSimpleEmail(email, subject, body); awaitingVerification = true; @@ -348,31 +347,31 @@ public class RegisterView extends VerticalLayout implements HasDynamicTitle { submitButton.setEnabled(false); - Notification.show("Ein Bestätigungscode wurde an " + email + " gesendet.", 4000, + Notification.show(getTranslation("register.notification.code.sent", email), 4000, Notification.Position.MIDDLE); } catch (Exception e) { awaitingVerification = false; - Notification.show("Fehler beim Senden der E-Mail: " + e.getMessage(), 5000, Notification.Position.MIDDLE); + Notification.show(getTranslation("register.notification.code.emailerror", e.getMessage()), 5000, Notification.Position.MIDDLE); } } private void onVerifyCode() { if (!awaitingVerification) { - Notification.show("Bitte starten Sie zuerst die Registrierung.", 3000, Notification.Position.MIDDLE); + Notification.show(getTranslation("register.notification.code.startfirst"), 3000, Notification.Position.MIDDLE); return; } String entered = codeField.getValue() != null ? codeField.getValue().trim() : ""; if (!entered.matches("\\d{6}")) { - Notification.show("Bitte geben Sie den 6-stelligen Code ein.", 3000, Notification.Position.MIDDLE); + Notification.show(getTranslation("register.notification.code.required"), 3000, Notification.Position.MIDDLE); return; } if (codeExpiresAt == null || LocalDateTime.now().isAfter(codeExpiresAt)) { - Notification.show("Der Code ist abgelaufen. Bitte senden Sie einen neuen Code.", 4000, + Notification.show(getTranslation("register.notification.code.expired"), 4000, Notification.Position.MIDDLE); return; } if (!entered.equals(pendingCode)) { - Notification.show("Der eingegebene Code ist ungültig.", 3000, Notification.Position.MIDDLE); + Notification.show(getTranslation("register.notification.code.invalid"), 3000, Notification.Position.MIDDLE); return; } @@ -399,10 +398,10 @@ public class RegisterView extends VerticalLayout implements HasDynamicTitle { user.setCity(city); userService.save(user); VaadinSession.getCurrent().setAttribute("flashMessage", - "Registrierung erfolgreich. Bitte melden Sie sich an."); + getTranslation("register.notification.success")); getUI().ifPresent(ui -> ui.navigate("login")); } catch (RuntimeException e) { - Notification.show("Registrierung fehlgeschlagen: " + e.getMessage(), 5000, Notification.Position.MIDDLE); + Notification.show(getTranslation("register.notification.failed", e.getMessage()), 5000, Notification.Position.MIDDLE); } } diff --git a/src/main/java/de/assecutor/votianlt/pages/view/StartView.java b/src/main/java/de/assecutor/votianlt/pages/view/StartView.java index 64f62e0..e38dca9 100644 --- a/src/main/java/de/assecutor/votianlt/pages/view/StartView.java +++ b/src/main/java/de/assecutor/votianlt/pages/view/StartView.java @@ -5,6 +5,7 @@ import com.vaadin.flow.component.UI; import com.vaadin.flow.component.button.Button; import com.vaadin.flow.component.button.ButtonVariant; import com.vaadin.flow.component.combobox.ComboBox; +import com.vaadin.flow.component.contextmenu.ContextMenu; import com.vaadin.flow.component.html.*; import com.vaadin.flow.component.icon.Icon; import com.vaadin.flow.component.icon.VaadinIcon; @@ -16,9 +17,12 @@ import com.vaadin.flow.router.Route; import com.vaadin.flow.router.BeforeEnterEvent; import com.vaadin.flow.router.BeforeEnterObserver; import com.vaadin.flow.server.auth.AnonymousAllowed; +import de.assecutor.votianlt.model.Language; import de.assecutor.votianlt.security.SecurityService; import org.springframework.beans.factory.annotation.Value; +import java.util.Locale; + @Route("") @AnonymousAllowed public class StartView extends VerticalLayout implements BeforeEnterObserver, HasDynamicTitle { @@ -94,10 +98,90 @@ public class StartView extends VerticalLayout implements BeforeEnterObserver, Ha Button registerBtn = new Button(getTranslation("start.button.register"), event -> register()); registerBtn.addThemeVariants(ButtonVariant.LUMO_PRIMARY); - navButtons.add(loginBtn, registerBtn); + // Sprachauswahl Button + + Button languageBtn = createLanguageSelector(); + + navButtons.add(loginBtn, registerBtn, languageBtn); return navButtons; } + private Button createLanguageSelector() { + // Aktuelle Sprache aus der UI-Locale ermitteln (wird vom LocaleVaadinInitListener gesetzt) + String currentLang = getCurrentLanguageFromLocale(); + String flag = getFlagForLanguage(currentLang); + + Button languageBtn = new Button(flag + " " + currentLang); + languageBtn.addThemeVariants(ButtonVariant.LUMO_TERTIARY); + + ContextMenu languageMenu = new ContextMenu(); + languageMenu.setOpenOnClick(true); + languageMenu.setTarget(languageBtn); + + // Alle Sprachen hinzufügen + for (Language lang : Language.values()) { + String langFlag = getFlagForLanguage(lang.name()); + String langText = langFlag + " " + lang.getDisplayName(); + + languageMenu.addItem(langText, event -> { + setLanguageCookie(lang.name()); + // Seite neu laden um die neue Sprache anzuwenden + UI.getCurrent().getPage().reload(); + }); + } + + return languageBtn; + } + + private String getCurrentLanguageFromLocale() { + // Aktuelle UI-Locale verwenden (wird vom LocaleVaadinInitListener aus Cookie/Browser gesetzt) + Locale locale = UI.getCurrent().getLocale(); + if (locale == null) { + return "DE"; + } + + String language = locale.getLanguage(); + return switch (language) { + case "en" -> "EN"; + case "fr" -> "FR"; + case "es" -> "ES"; + case "tr" -> "TR"; + case "pl" -> "PL"; + case "ru" -> "RU"; + case "et" -> "EE"; // Estnisch + case "lv" -> "LV"; // Lettisch + case "lt" -> "LT"; // Litauisch + default -> "DE"; // German as default + }; + } + + private String getFlagForLanguage(String languageCode) { + if (languageCode == null) { + return "🇩🇪"; + } + return switch (languageCode.toUpperCase()) { + case "DE" -> "🇩🇪"; + case "EN" -> "🇬🇧"; + case "FR" -> "🇫🇷"; + case "ES" -> "🇪🇸"; + case "TR" -> "🇹🇷"; + case "PL" -> "🇵🇱"; + case "RU" -> "🇷🇺"; + case "EE" -> "🇪🇪"; + case "LV" -> "🇱🇻"; + case "LT" -> "🇱🇹"; + default -> "🇩🇪"; + }; + } + + private void setLanguageCookie(String languageCode) { + UI.getCurrent().getPage().executeJs( + "const maxAge = 365 * 24 * 60 * 60;" + + "document.cookie = 'votianlt.language=' + $0 + ';path=/;max-age=' + maxAge + ';SameSite=Lax';", + languageCode + ); + } + private Component createAuthenticatedNavigation() { HorizontalLayout navLayout = new HorizontalLayout(); navLayout.setSpacing(true); @@ -185,9 +269,7 @@ public class StartView extends VerticalLayout implements BeforeEnterObserver, Ha heroTitle.getStyle().set("color", "var(--lumo-primary-text-color)"); heroTitle.getStyle().set("margin-bottom", "var(--lumo-space-l)"); - Paragraph heroDescription = new Paragraph("Für Solo-Selbstständige und Kleinunternehmer im Transportgewerbe - " - + "volldigital und aus einem Guss. Konzentrieren Sie sich auf Ihr Geschäft, " - + "wir kümmern uns um die Büroarbeit."); + Paragraph heroDescription = new Paragraph(getTranslation("start.hero.description")); heroDescription.getStyle().set("text-align", "center"); heroDescription.getStyle().set("max-width", "600px"); heroDescription.getStyle().set("font-size", "var(--lumo-font-size-l)"); @@ -208,13 +290,11 @@ public class StartView extends VerticalLayout implements BeforeEnterObserver, Ha systemSection.getStyle().set("background-color", "var(--lumo-base-color)"); // Section Header - H2 systemTitle = new H2("Das System"); + H2 systemTitle = new H2(getTranslation("start.system.title")); systemTitle.getStyle().set("color", "var(--lumo-primary-color)"); systemTitle.getStyle().set("text-align", "center"); - Paragraph systemIntro = new Paragraph( - "Für Solo-Selbstständige und Kleinunternehmer im Transportgewerbe ist von entscheidender Bedeutung, " - + "dass sie sich in erster Linie auf ihr eigentliches Geschäft konzentrieren können: Kunden gewinnen und Waren von A nach B liefern."); + Paragraph systemIntro = new Paragraph(getTranslation("start.system.intro")); systemIntro.getStyle().set("text-align", "center"); systemIntro.getStyle().set("max-width", "800px"); systemIntro.getStyle().set("margin-bottom", "var(--lumo-space-xl)"); @@ -227,12 +307,12 @@ public class StartView extends VerticalLayout implements BeforeEnterObserver, Ha featuresGrid.setDefaultVerticalComponentAlignment(FlexComponent.Alignment.STRETCH); // Feature Cards - featuresGrid.add(createFeatureCard(VaadinIcon.COG, "Einrichtungsassistent", - "Mithilfe des Einrichtungsassistenten haben Sie die Möglichkeit, Ihr Nutzerprofil zu vervollständigen."), - createFeatureCard(VaadinIcon.USERS, "Kunden- und Auftragsverwaltung", - "Mit der Kunden- und Auftragsverwaltung haben Sie alle Kontaktdaten und Auftragsdetails stets im Blick."), - createFeatureCard(VaadinIcon.CLIPBOARD_TEXT, "Auftragserstellung", - "Stellen Sie mit wenigen Mausklicks Aufträge ins System ein und legen Sie fest, welcher Mitarbeiter welchen Transportauftrag abarbeiten soll.")); + featuresGrid.add(createFeatureCard(VaadinIcon.COG, getTranslation("start.feature.setup.title"), + getTranslation("start.feature.setup.desc")), + createFeatureCard(VaadinIcon.USERS, getTranslation("start.feature.customers.title"), + getTranslation("start.feature.customers.desc")), + createFeatureCard(VaadinIcon.CLIPBOARD_TEXT, getTranslation("start.feature.jobs.title"), + getTranslation("start.feature.jobs.desc"))); systemSection.add(systemTitle, systemIntro, featuresGrid); return systemSection; @@ -274,13 +354,11 @@ public class StartView extends VerticalLayout implements BeforeEnterObserver, Ha appSection.setDefaultHorizontalComponentAlignment(FlexComponent.Alignment.CENTER); appSection.getStyle().set("background-color", "var(--lumo-contrast-5pct)"); - H2 appTitle = new H2("Die App"); + H2 appTitle = new H2(getTranslation("start.app.title")); appTitle.getStyle().set("color", "var(--lumo-primary-color)"); appTitle.getStyle().set("text-align", "center"); - Paragraph appDescription = new Paragraph( - "Jeder Auftrag kann optional über die votianLT-App abgearbeitet werden – ganz ohne \"Zettelwirtschaft\". " - + "So gelangen alle relevanten Auftragsinformationen direkt auf das Smartphone des Fahrers."); + Paragraph appDescription = new Paragraph(getTranslation("start.app.description")); appDescription.getStyle().set("text-align", "center"); appDescription.getStyle().set("max-width", "800px"); @@ -302,7 +380,7 @@ public class StartView extends VerticalLayout implements BeforeEnterObserver, Ha footer.getStyle().set("border-top", "1px solid var(--lumo-contrast-20pct)"); // Company Info - H3 companyTitle = new H3("Impressum"); + H3 companyTitle = new H3(getTranslation("start.imprint.title")); companyTitle.getStyle().set("color", "var(--lumo-primary-color)"); companyTitle.getStyle().set("text-align", "center"); @@ -311,18 +389,17 @@ public class StartView extends VerticalLayout implements BeforeEnterObserver, Ha companyInfo.setPadding(false); companyInfo.setDefaultHorizontalComponentAlignment(FlexComponent.Alignment.CENTER); - companyInfo.add(new Paragraph("Assecutor Data Service GmbH"), new Paragraph("Ottensener Str. 8, 22525 Hamburg"), - new Paragraph("Telefon: +49 40 18 123 771 0"), new Paragraph("E-Mail: ahoi@assecutor.de")); + companyInfo.add(new Paragraph(getTranslation("start.imprint.company")), new Paragraph(getTranslation("start.imprint.address")), + new Paragraph(getTranslation("start.imprint.phone")), new Paragraph(getTranslation("start.imprint.email"))); // Call to Action - Paragraph ctaText = new Paragraph("Registrieren Sie sich noch heute und nutzen den kostenfreien Probemonat, " - + "um das System auf Herz und Nieren zu testen."); + Paragraph ctaText = new Paragraph(getTranslation("start.cta.text")); ctaText.getStyle().set("text-align", "center"); ctaText.getStyle().set("font-weight", "bold"); ctaText.getStyle().set("color", "var(--lumo-primary-color)"); ctaText.getStyle().set("margin-top", "var(--lumo-space-l)"); - Paragraph slogan = new Paragraph("Betreiben Sie Ihr Geschäft smart … mit votianLT!"); + Paragraph slogan = new Paragraph(getTranslation("start.slogan")); slogan.getStyle().set("text-align", "center"); slogan.getStyle().set("font-style", "italic"); slogan.getStyle().set("color", "var(--lumo-primary-color)"); diff --git a/src/main/resources/messages.properties b/src/main/resources/messages.properties index 5c2c7d8..7615ff3 100644 --- a/src/main/resources/messages.properties +++ b/src/main/resources/messages.properties @@ -763,7 +763,9 @@ start.button.register=Registrieren start.button.createorder=Auftragserstellung start.button.notifications=Benachrichtigungen start.button.nonotifications=Keine neuen Benachrichtigungen +start.hero.description=Für Solo-Selbstständige und Kleinunternehmer im Transportgewerbe - volldigital und aus einem Guss. Konzentrieren Sie sich auf Ihr Geschäft, wir kümmern uns um die Büroarbeit. start.system.title=Das System +start.system.intro=Für Solo-Selbstständige und Kleinunternehmer im Transportgewerbe ist von entscheidender Bedeutung, dass sie sich in erster Linie auf ihr eigentliches Geschäft konzentrieren können: Kunden gewinnen und Waren von A nach B liefern. start.feature.setup.title=Einrichtungsassistent start.feature.setup.desc=Mithilfe des Einrichtungsassistenten haben Sie die Möglichkeit, Ihr Nutzerprofil zu vervollständigen. start.feature.customers.title=Kunden- und Auftragsverwaltung @@ -777,6 +779,7 @@ start.imprint.company=Assecutor Data Service GmbH start.imprint.address=Ottensener Str. 8, 22525 Hamburg start.imprint.phone=Telefon: +49 40 18 123 771 0 start.imprint.email=E-Mail: ahoi@assecutor.de +start.cta.text=Registrieren Sie sich noch heute und nutzen den kostenfreien Probemonat, um das System auf Herz und Nieren zu testen. start.slogan=Betreiben Sie Ihr Geschäft smart … mit votianLT! start.version=Version diff --git a/src/main/resources/messages_ee.properties b/src/main/resources/messages_ee.properties new file mode 100644 index 0000000..b917d95 --- /dev/null +++ b/src/main/resources/messages_ee.properties @@ -0,0 +1,188 @@ +# Navigation and Main Layout +nav.jobs=Ülesanded +nav.job.create=Loo ülesanne +nav.customers=Kliendid +nav.appusers=Rakenduse kasutajad +nav.statistics=Statistika +nav.invoices=Arved +nav.messages=Sõnumid +nav.profile=Minu profiil +nav.myinvoices=Minu arved +nav.imprint=Impressum +nav.management=Juhtimine +nav.users=Kasutajad +nav.showprofile=Kuva profiil +nav.settings=Seaded +nav.logout=Logi välja + +# Profile View +profile.title=Muuda profiili +profile.language=Keel +profile.company=Ettevõte +profile.companyadd=Ettevõtte lisa +profile.firstname=Eesnimi +profile.lastname=Perekonnanimi +profile.phone=Telefoninumber +profile.fax=Faks +profile.mobile=Mobiiltelefon +profile.email=E-posti aadress (Sisselogimine)* +profile.street=Tänav +profile.housenr=Maja number +profile.addressadd=Aadressi lisa +profile.postcode=Postiindeks +profile.city=Linn +profile.diffinvoice=Erinev arveaadress +profile.basicdata=Põhiandmed +profile.map=Kaart +profile.invoicecreation=Arve loomine +profile.settings=Seaded +profile.account=Konto +profile.security=Turvalisus +profile.services=Teenuste kataloog +profile.saved=Profiil salvestatud +profile.save.error=Viga salvestamisel: {0} +profile.validation.required.fill=Palun täitke kõik kohustuslikud väljad õigesti + +# Profile Settings +settings.digitalprocessing=Digitaalne töötlemine rakenduse kaudu +settings.digitalprocessinginfo=Lubab digitaalse ülesannete töötlemise mobiilirakenduse kaudu +settings.locationtracking=Rakenduse kasutajate asukoha jälgimine +settings.locationtrackinginfo=Võimaldab jälgida rakenduse kasutajate asukohta ülesande täitmise ajal +settings.twofactor=Kahefaktoriline autentimine +settings.twofactorinfo=Aktiveerimisel saadetakse igal sisselogimisel e-posti teel kood + +# Profile Billing +profile.billing.enabled=Arveldamine votianLT kaudu + +# Profile Validation +profile.validation.company=Ettevõte on kohustuslik väli +profile.validation.firstname=Eesnimi on kohustuslik väli +profile.validation.lastname=Perekonnanimi on kohustuslik väli +profile.validation.phone=Telefoninumber on kohustuslik väli +profile.validation.street=Tänav on kohustuslik väli +profile.validation.housenr=Maja number on kohustuslik väli +profile.validation.postcode=Postiindeks on kohustuslik väli +profile.validation.city=Linn on kohustuslik väli +profile.validation.email.required=E-posti aadress on kohustuslik väli +profile.validation.email.invalid=Palun sisestage kehtiv e-posti aadress +profile.validation.company.required=Ettevõte on nõutav +profile.validation.street.required=Tänav on nõutav +profile.validation.housenr.required=Maja number on nõutav +profile.validation.postcode.required=Postiindeks on nõutav +profile.validation.city.required=Linn on nõutav +profile.validation.firstname.required=Eesnimi on nõutav +profile.validation.lastname.required=Perekonnanimi on nõutav +profile.validation.phone.required=Telefoninumber on nõutav + +# Buttons +button.save=Salvesta profiili muudatused +button.savechanges=Salvesta +button.clear=Tühjenda +button.preview=Eelvaade +button.savetemplate=Salvesta mall +button.changepassword=Muuda parooli +button.deleteaccount=Kustuta konto +button.add=Uus +button.edit=Muuda +button.delete=Kustuta +button.cancel=Tühista +button.close=Sulge +button.download=Lae alla +button.back=Tagasi + +# Common +common.name=Nimi +common.yes=Jah +common.no=Ei +common.total=Kokku +common.price=Hind +common.service=Teenus +common.customer=Klient +common.actions=Tegevused +common.loading=Laadimine... +common.error=Viga +common.success=Edu +common.required=Kohustuslik väli + +# Validation +validation.required=Väli on kohustuslik +validation.email=Kehtetu e-posti aadress +validation.error=Valideerimise viga + +# Notifications +notification.saved=Profiil salvestatud +notification.error=Viga salvestamisel +notification.languagechanged=Keel muudetud + +# Login +login.title=Logi sisse +login.username=Kasutajanimi +login.password=Parool +login.login=Logi sisse +login.forgotpassword=Unustasid parooli? +login.rememberme=Jäta meelde +login.register=Registreeru +login.2fa.helper=6-kohaline kood +login.2fa.sent=Kood saadetud e-postiga +login.2fa.no.credentials=Sisselogimisandmeid pole +login.2fa.invalid.code=Kehtetu kood +login.2fa.wrong.code=Vale kood + +# Error Messages +error.loading=Laadimise viga +error.saving=Salvestamise viga +error.validation=Valideerimise viga + +# Page Titles +page.title.welcome=VotianLT - Tere tulemast +page.title.login=VotianLT - Sisselogimine + +# Start Page +start.title=VotianLT - Teie digitaalne transpordipartner +start.button.login=Logi sisse +start.button.register=Registreeru +start.button.createorder=Loo ülesanne +start.button.notifications=Teated +start.button.nonotifications=Uusi teateid pole +start.hero.description=Transporditööstuses tegutsevatele üksikettevõtjatele ja väikeettevõtetele – täiesti digitaalne ja kõik-ühes. Keskenduge oma ärile, meie hoolitseme paberitöö eest. +start.system.title=Süsteem +start.system.intro=Transporditööstuses tegutsevatele üksikettevõtjatele ja väikeettevõtetele on äärmiselt oluline keskenduda eelkõige oma põhitegevusele: klientide võitmisele ja kaupade kohaletoimetamisele punktist A punkti B. +start.feature.setup.title=Seadistusassistent +start.feature.setup.desc=Kasutage seadistusassistenti, et täita oma kasutajaprofiil. +start.feature.customers.title=Klientide ja ülesannete haldamine +start.feature.customers.desc=Klientide ja ülesannete haldamisega on teil alati kõik kontaktandmed ja ülesannete üksikasjad silme ees. +start.feature.jobs.title=Ülesannete loomine +start.feature.jobs.desc=Looge süsteemis ülesandeid vaid mõne klõpsuga ja määrake, milline töötaja peab millist transpordiülesannet täitma. +start.app.title=Rakendus +start.app.description=Iga ülesanne saab vabatahtlikult täidetud votianLT rakenduse kaudu – täiesti ilma "paberimajandusteta". Kogu oluline ülesande info läheb otse juhi nutitelefoni. +start.imprint.title=Impressum +start.imprint.company=Assecutor Data Service GmbH +start.imprint.address=Ottensener Str. 8, 22525 Hamburg +start.imprint.phone=Telefon: +49 40 18 123 771 0 +start.imprint.email=E-post: ahoi@assecutor.de +start.cta.text=Registreeruge juba täna ja kasutage süsteemi põhjalikuks testimiseks tasuta proovikuud! +start.slogan=Juhtige oma äri nutikalt … koos votianLT-ga! +start.version=Versioon + +# Register +register.title=Registreerimine +register.subtitle=Loo oma VotianLT konto +register.email=E-posti aadress +register.password=Parool +register.password.placeholder=Vähemalt 6 tähemärki +register.password.confirm=Kinnita parool +register.password.confirm.placeholder=Sisesta parool uuesti +register.firstname=Eesnimi +register.lastname=Perekonnanimi +register.phone=Telefoninumber +register.company=Ettevõte +register.street=Tänav +register.housenr=Maja number +register.postcode=Postiindeks +register.city=Linn +register.button.submit=Registreeru +register.notification.success=Registreerimine õnnestus. Palun logi sisse. +register.notification.failed=Registreerimine ebaõnnestus: {0} + +# CTA Button +cta.freetest=Proovi tasuta \ No newline at end of file diff --git a/src/main/resources/messages_en.properties b/src/main/resources/messages_en.properties index a2349b6..cea1b6b 100644 --- a/src/main/resources/messages_en.properties +++ b/src/main/resources/messages_en.properties @@ -763,7 +763,9 @@ start.button.register=Register start.button.createorder=Create Order start.button.notifications=Notifications start.button.nonotifications=No new notifications +start.hero.description=For solo self-employed and small business owners in the transport industry - fully digital and all-in-one. Focus on your business, we take care of the paperwork. start.system.title=The System +start.system.intro=For solo self-employed and small business owners in the transport industry, it is crucial to focus primarily on their core business: winning customers and delivering goods from A to B. start.feature.setup.title=Setup Assistant start.feature.setup.desc=Use the setup assistant to complete your user profile. start.feature.customers.title=Customer and Job Management @@ -777,6 +779,7 @@ start.imprint.company=Assecutor Data Service GmbH start.imprint.address=Ottensener Str. 8, 22525 Hamburg start.imprint.phone=Phone: +49 40 18 123 771 0 start.imprint.email=Email: ahoi@assecutor.de +start.cta.text=Register today and use the free trial month to test the system thoroughly. start.slogan=Run your business smart … with votianLT! start.version=Version diff --git a/src/main/resources/messages_es.properties b/src/main/resources/messages_es.properties index 3b904b4..b9752f4 100644 --- a/src/main/resources/messages_es.properties +++ b/src/main/resources/messages_es.properties @@ -763,7 +763,9 @@ start.button.register=Registrarse start.button.createorder=Crear Pedido start.button.notifications=Notificaciones start.button.nonotifications=No hay notificaciones nuevas +start.hero.description=Para autónomos y pequeñas empresas del sector del transporte - totalmente digital y todo en uno. Concéntrese en su negocio, nosotros nos ocupamos del papeleo. start.system.title=El Sistema +start.system.intro=Para autónomos y pequeñas empresas del sector del transporte, es crucial concentrarse principalmente en su negocio principal: ganar clientes y entregar mercancías de A a B. start.feature.setup.title=Asistente de Configuración start.feature.setup.desc=Use el asistente de configuración para completar su perfil de usuario. start.feature.customers.title=Gestión de Clientes y Trabajos @@ -777,6 +779,7 @@ start.imprint.company=Assecutor Data Service GmbH start.imprint.address=Ottensener Str. 8, 22525 Hamburg start.imprint.phone=Teléfono: +49 40 18 123 771 0 start.imprint.email=Correo: ahoi@assecutor.de +start.cta.text=¡Regístrese hoy y use el mes de prueba gratuito para probar el sistema a fondo! start.slogan=¡Opere su negocio de forma inteligente … con votianLT! start.version=Versión diff --git a/src/main/resources/messages_fr.properties b/src/main/resources/messages_fr.properties index a1ce1da..a7e0fd9 100644 --- a/src/main/resources/messages_fr.properties +++ b/src/main/resources/messages_fr.properties @@ -772,6 +772,9 @@ start.feature.jobs.title=Création d'Emplois start.feature.jobs.desc=Créez des emplois dans le système en quelques clics et déterminez quel employé doit traiter quel emploi de transport. start.app.title=L'App start.app.description=Chaque emploi peut être traité optionnellement via l'app votianLT - complètement sans "paperasse". Toutes les informations pertinentes de l'emploi vont directement sur le smartphone du conducteur. +start.hero.description=Pour indépendants et petites entreprises du secteur du transport - entièrement numérique et tout-en-un. Concentrez-vous sur votre entreprise, nous nous occupons de la paperasse. +start.system.intro=Pour indépendants et petites entreprises du secteur du transport, il est crucial de se concentrer principalement sur leur cœur de métier : gagner des clients et livrer des marchandises de A à B. +start.cta.text=Inscrivez-vous dès aujourd'hui et profitez du mois d'essai gratuit pour tester le système à fond ! start.imprint.title=Mentions Légales start.imprint.company=Assecutor Data Service GmbH start.imprint.address=Ottensener Str. 8, 22525 Hambourg diff --git a/src/main/resources/messages_lt.properties b/src/main/resources/messages_lt.properties new file mode 100644 index 0000000..6a690ae --- /dev/null +++ b/src/main/resources/messages_lt.properties @@ -0,0 +1,188 @@ +# Navigation and Main Layout +nav.jobs=Užduotys +nav.job.create=Sukurti užduotį +nav.customers=Klientai +nav.appusers=Programėlės naudotojai +nav.statistics=Statistika +nav.invoices=Sąskaitos +nav.messages=Žinutės +nav.profile=Mano profilis +nav.myinvoices=Mano sąskaitos +nav.imprint=Impressum +nav.management=Valdymas +nav.users=Naudotojai +nav.showprofile=Rodyti profilį +nav.settings=Nustatymai +nav.logout=Atsijungti + +# Profile View +profile.title=Redaguoti profilį +profile.language=Kalba +profile.company=Įmonė +profile.companyadd=Įmonės papildymas +profile.firstname=Vardas +profile.lastname=Pavardė +profile.phone=Telefono numeris +profile.fax=Faksas +profile.mobile=Mobilusis telefonas +profile.email=El. pašto adresas (Prisijungimas)* +profile.street=Gatvė +profile.housenr=Namo numeris +profile.addressadd=Adreso papildymas +profile.postcode=Pašto kodas +profile.city=Miestas +profile.diffinvoice=Kitas atsiskaitymo adresas +profile.basicdata=Pagrindiniai duomenys +profile.map=Žemėlapis +profile.invoicecreation=Sąskaitos kūrimas +profile.settings=Nustatymai +profile.account=Paskyra +profile.security=Saugumas +profile.services=Paslaugų katalogas +profile.saved=Profilis išsaugotas +profile.save.error=Klaida išsaugant: {0} +profile.validation.required.fill=Prašome teisingai užpildyti visus privalomus laukus + +# Profile Settings +settings.digitalprocessing=Skaitmeninis apdorojimas per programėlę +settings.digitalprocessinginfo=Įgalina skaitmeninį užduočių apdorojimą per mobiliojo programėlę +settings.locationtracking=Programėlės naudotojų vietos sekimas +settings.locationtrackinginfo=Leidžia sekti programėlės naudotojų vietą užduoties vykdymo metu +settings.twofactor=Dvivėjinė autentifikacija +settings.twofactorinfo=Aktyvavus, kiekvieno prisijungimo metu el. paštu siunčiamas kodas + +# Profile Billing +profile.billing.enabled=Atsiskaitymas per votianLT + +# Profile Validation +profile.validation.company=Įmonė yra privalomas laukas +profile.validation.firstname=Vardas yra privalomas laukas +profile.validation.lastname=Pavardė yra privalomas laukas +profile.validation.phone=Telefono numeris yra privalomas laukas +profile.validation.street=Gatvė yra privalomas laukas +profile.validation.housenr=Namo numeris yra privalomas laukas +profile.validation.postcode=Pašto kodas yra privalomas laukas +profile.validation.city=Miestas yra privalomas laukas +profile.validation.email.required=El. pašto adresas yra privalomas laukas +profile.validation.email.invalid=Prašome įvesti galiojantį el. pašto adresą +profile.validation.company.required=Reikalinga įmonė +profile.validation.street.required=Reikalinga gatvė +profile.validation.housenr.required=Reikalingas namo numeris +profile.validation.postcode.required=Reikalingas pašto kodas +profile.validation.city.required=Reikalingas miestas +profile.validation.firstname.required=Reikalingas vardas +profile.validation.lastname.required=Reikalinga pavardė +profile.validation.phone.required=Reikalingas telefono numeris + +# Buttons +button.save=Išsaugoti profilio pakeitimus +button.savechanges=Išsaugoti +button.clear=Išvalyti +button.preview=Peržiūra +button.savetemplate=Išsaugoti šabloną +button.changepassword=Keisti slaptažodį +button.deleteaccount=Ištrinti paskyrą +button.add=Naujas +button.edit=Redaguoti +button.delete=Ištrinti +button.cancel=Atšaukti +button.close=Uždaryti +button.download=Atsisiųsti +button.back=Atgal + +# Common +common.name=Pavadinimas +common.yes=Taip +common.no=Ne +common.total=Iš viso +common.price=Kaina +common.service=Paslauga +common.customer=Klientas +common.actions=Veiksmai +common.loading=Įkeliama... +common.error=Klaida +common.success=Sėkmė +common.required=Privalomas laukas + +# Validation +validation.required=Laukas yra privalomas +validation.email=Netinkamas el. pašto adresas +validation.error=Validavimo klaida + +# Notifications +notification.saved=Profilis išsaugotas +notification.error=Klaida išsaugant +notification.languagechanged=Kalba pakeista + +# Login +login.title=Prisijungti +login.username=Naudotojo vardas +login.password=Slaptažodis +login.login=Prisijungti +login.forgotpassword=Pamiršote slaptažodį? +login.rememberme=Prisiminti mane +login.register=Registruotis +login.2fa.helper=6 skaitmenų kodas +login.2fa.sent=Kodas išsiųstas el. paštu +login.2fa.no.credentials=Nėra prisijungimo duomenų +login.2fa.invalid.code=Netinkamas kodas +login.2fa.wrong.code=Neteisingas kodas + +# Error Messages +error.loading=Įkėlimo klaida +error.saving=Išsaugojimo klaida +error.validation=Validavimo klaida + +# Page Titles +page.title.welcome=VotianLT - Sveiki atvykę +page.title.login=VotianLT - Prisijungimas + +# Start Page +start.title=VotianLT - Jūsų skaitmeninis transporto partneris +start.button.login=Prisijungti +start.button.register=Registruotis +start.button.createorder=Sukurti užduotį +start.button.notifications=Pranešimai +start.button.nonotifications=Nėra naujų pranešimų +start.hero.description=Individualiems specialistams ir mažoms transporto įmonėms – visiškai skaitmeninis ir viskas viename. Susikoncentruokite į savo verslą, o mes pasirūpinsime dokumentais. +start.system.title=Sistema +start.system.intro=Individualiems specialistams ir mažoms transporto įmonėms labai svarbu susikoncentruoti į pagrindinę veiklą: klientų pritraukimą ir krovinių gabenimą iš taško A į tašką B. +start.feature.setup.title=Nustatymo asistentas +start.feature.setup.desc=Naudokitės nustatymo asistentu, kad užpildytumėte savo naudotojo profilį. +start.feature.customers.title=Klientų ir užduočių valdymas +start.feature.customers.desc=Su klientų ir užduočių valdymu visada turite visus kontaktinius duomenis ir užduočių detales prieš akis. +start.feature.jobs.title=Užduočių kūrimas +start.feature.jobs.desc=Sukurkite užduotis sistemoje vos keliais paspaudimais ir nustatykite, kuris darbuotojas turi atlikti kurią transporto užduotį. +start.app.title=Programėlė +start.app.description=Kiekviena užduotis gali būti atliekama pasirinktinai per votianLT programėlę – visiškai be "popierizmo". Visa svarbi užduoties informacija tiesiai patenka į vairuotojo išmanųjį telefoną. +start.imprint.title=Impressum +start.imprint.company=Assecutor Data Service GmbH +start.imprint.address=Ottensener Str. 8, 22525 Hamburg +start.imprint.phone=Telefonas: +49 40 18 123 771 0 +start.imprint.email=El. paštas: ahoi@assecutor.de +start.cta.text=Registruokitės jau šiandien ir pasinaudokite nemokamu bandomuoju mėnesiu, kad kruopščiai išbandytumėte sistemą! +start.slogan=Veskite savo verslą protingai … su votianLT! +start.version=Versija + +# Register +register.title=Registracija +register.subtitle=Sukurkite savo VotianLT paskyrą +register.email=El. pašto adresas +register.password=Slaptažodis +register.password.placeholder=Mažiausiai 6 simboliai +register.password.confirm=Patvirtinkite slaptažodį +register.password.confirm.placeholder=Įveskite slaptažodį dar kartą +register.firstname=Vardas +register.lastname=Pavardė +register.phone=Telefono numeris +register.company=Įmonė +register.street=Gatvė +register.housenr=Namo numeris +register.postcode=Pašto kodas +register.city=Miestas +register.button.submit=Registruotis +register.notification.success=Registracija sėkminga. Prašome prisijungti. +register.notification.failed=Registracijos klaida: {0} + +# CTA Button +cta.freetest=Išbandykite nemokamai \ No newline at end of file diff --git a/src/main/resources/messages_lv.properties b/src/main/resources/messages_lv.properties new file mode 100644 index 0000000..7cd7a58 --- /dev/null +++ b/src/main/resources/messages_lv.properties @@ -0,0 +1,188 @@ +# Navigation and Main Layout +nav.jobs=Uzdevumi +nav.job.create=Izveidot uzdevumu +nav.customers=Klienti +nav.appusers=Lietotnes lietotāji +nav.statistics=Statistika +nav.invoices=Rēķini +nav.messages=Ziņojumi +nav.profile=Mans profils +nav.myinvoices=Mani rēķini +nav.imprint=Impressum +nav.management=Pārvaldība +nav.users=Lietotāji +nav.showprofile=Rādīt profilu +nav.settings=Iestatījumi +nav.logout=Izrakstīties + +# Profile View +profile.title=Rediģēt profilu +profile.language=Valoda +profile.company=Uzņēmums +profile.companyadd=Uzņēmuma papildinājums +profile.firstname=Vārds +profile.lastname=Uzvārds +profile.phone=Tālruņa numurs +profile.fax=Fakss +profile.mobile=Mobilais tālrunis +profile.email=E-pasta adrese (Pieteikšanās)* +profile.street=Iela +profile.housenr=Mājas numurs +profile.addressadd=Adreses papildinājums +profile.postcode=Pasta indekss +profile.city=Pilsēta +profile.diffinvoice=Cita norēķinu adrese +profile.basicdata=Pamatdati +profile.map=Karte +profile.invoicecreation=Rēķina izveide +profile.settings=Iestatījumi +profile.account=Konts +profile.security=Drošība +profile.services=Pakalpojumu katalogs +profile.saved=Profils saglabāts +profile.save.error=Kļūda saglabājot: {0} +profile.validation.required.fill=Lūdzu, pareizi aizpildiet visus obligātos laukus + +# Profile Settings +settings.digitalprocessing=Digitālā apstrāde caur lietotni +settings.digitalprocessinginfo=Iespējo digitālo uzdevumu apstrādi caur mobilās lietotnes +settings.locationtracking=Lietotnes lietotāju atrašanās vietas izsekošana +settings.locationtrackinginfo=Ļauj izsekot lietotnes lietotāju atrašanās vietu uzdevuma izpildes laikā +settings.twofactor=Divfaktoru autentifikācija +settings.twofactorinfo=Aktivējot, katras pieteikšanās laikā pa e-pastu tiek nosūtīts kods + +# Profile Billing +profile.billing.enabled=Norēķini caur votianLT + +# Profile Validation +profile.validation.company=Uzņēmums ir obligāts lauks +profile.validation.firstname=Vārds ir obligāts lauks +profile.validation.lastname=Uzvārds ir obligāts lauks +profile.validation.phone=Tālruņa numurs ir obligāts lauks +profile.validation.street=Iela ir obligāts lauks +profile.validation.housenr=Mājas numurs ir obligāts lauks +profile.validation.postcode=Pasta indekss ir obligāts lauks +profile.validation.city=Pilsēta ir obligāts lauks +profile.validation.email.required=E-pasta adrese ir obligāts lauks +profile.validation.email.invalid=Lūdzu, ievadiet derīgu e-pasta adresi +profile.validation.company.required=Nepieciešams uzņēmums +profile.validation.street.required=Nepieciešama iela +profile.validation.housenr.required=Nepieciešams mājas numurs +profile.validation.postcode.required=Nepieciešams pasta indekss +profile.validation.city.required=Nepieciešama pilsēta +profile.validation.firstname.required=Nepieciešams vārds +profile.validation.lastname.required=Nepieciešams uzvārds +profile.validation.phone.required=Nepieciešams tālruņa numurs + +# Buttons +button.save=Saglabāt profila izmaiņas +button.savechanges=Saglabāt +button.clear=Notīrīt +button.preview=Priekšskatījums +button.savetemplate=Saglabāt veidni +button.changepassword=Mainīt paroli +button.deleteaccount=Dzēst kontu +button.add=Jauns +button.edit=Rediģēt +button.delete=Dzēst +button.cancel=Atcelt +button.close=Aizvērt +button.download=Lejupielādēt +button.back=Atpakaļ + +# Common +common.name=Nosaukums +common.yes=Jā +common.no=Nē +common.total=Kopā +common.price=Cena +common.service=Pakalpojums +common.customer=Klients +common.actions=Darbības +common.loading=Ielādējas... +common.error=Kļūda +common.success=Veiksmīgi +common.required=Obligāts lauks + +# Validation +validation.required=Lauks ir obligāts +validation.email=Nederīga e-pasta adrese +validation.error=Validācijas kļūda + +# Notifications +notification.saved=Profils saglabāts +notification.error=Kļūda saglabājot +notification.languagechanged=Valoda nomainīta + +# Login +login.title=Pieteikties +login.username=Lietotājvārds +login.password=Parole +login.login=Pieteikties +login.forgotpassword=Aizmirsi paroli? +login.rememberme=Atcerēties mani +login.register=Reģistrēties +login.2fa.helper=6 ciparu kods +login.2fa.sent=Kods nosūtīts pa e-pastu +login.2fa.no.credentials=Nav pieteikšanās datu +login.2fa.invalid.code=Nederīgs kods +login.2fa.wrong.code=Nepareizs kods + +# Error Messages +error.loading=Ielādes kļūda +error.saving=Saglabāšanas kļūda +error.validation=Validācijas kļūda + +# Page Titles +page.title.welcome=VotianLT - Laipni lūdzam +page.title.login=VotianLT - Pieteikšanās + +# Start Page +start.title=VotianLT - Jūsu digitālais transporta partneris +start.button.login=Pieteikties +start.button.register=Reģistrēties +start.button.createorder=Izveidot uzdevumu +start.button.notifications=Paziņojumi +start.button.nonotifications=Nav jaunu paziņojumu +start.hero.description=Pašnodarbinātajiem un mazajiem transporta uzņēmumiem – pilnībā digitāls un viss vienā. Koncentrējieties uz savu biznesu, mēs parūpēsimies par birokrātiju. +start.system.title=Sistēma +start.system.intro=Pašnodarbinātajiem un mazajiem transporta uzņēmumiem ir ārkārtīgi svarīgi koncentrēties galvenokārt uz savu pamatdarbību: klientu piesaisti un preču piegādi no punkta A uz punktu B. +start.feature.setup.title=Iestatīšanas asistents +start.feature.setup.desc=Izmantojiet iestatīšanas asistentu, lai aizpildītu savu lietotāja profilu. +start.feature.customers.title=Klientu un uzdevumu pārvaldība +start.feature.customers.desc=Ar klientu un uzdevumu pārvaldību jums vienmēr ir visas kontaktinformācijas un uzdevumu detaļas acu priekšā. +start.feature.jobs.title=Uzdevumu izveide +start.feature.jobs.desc=Izveidojiet uzdevumus sistēmā tikai ar dažiem klikšķiem un noteikiet, kurš darbinieks veic kādu transporta uzdevumu. +start.app.title=Lietotne +start.app.description=Katru uzdevumu var pildīt pēc izvēles caur votianLT lietotni – pilnīgi bez "birokrātijas". Visa svarīgā uzdevuma informācija nonāk tieši vadītāja viedtālrunī. +start.imprint.title=Impressum +start.imprint.company=Assecutor Data Service GmbH +start.imprint.address=Ottensener Str. 8, 22525 Hamburg +start.imprint.phone=Tālrunis: +49 40 18 123 771 0 +start.imprint.email=E-pasts: ahoi@assecutor.de +start.cta.text=Reģistrējieties jau šodien un izmantojiet bezmaksas izmēģinājuma mēnesi, lai rūpīgi pārbaudītu sistēmu! +start.slogan=Vadīt savu biznesu gudri … ar votianLT! +start.version=Versija + +# Register +register.title=Reģistrācija +register.subtitle=Izveidojiet savu VotianLT kontu +register.email=E-pasta adrese +register.password=Parole +register.password.placeholder=Vismaz 6 rakstzīmes +register.password.confirm=Apstipriniet paroli +register.password.confirm.placeholder=Ievadiet paroli vēlreiz +register.firstname=Vārds +register.lastname=Uzvārds +register.phone=Tālruņa numurs +register.company=Uzņēmums +register.street=Iela +register.housenr=Mājas numurs +register.postcode=Pasta indekss +register.city=Pilsēta +register.button.submit=Reģistrēties +register.notification.success=Reģistrācija veiksmīga. Lūdzu, pieteikties. +register.notification.failed=Reģistrācijas kļūda: {0} + +# CTA Button +cta.freetest=Izmēģiniet bez maksas \ No newline at end of file diff --git a/src/main/resources/messages_pl.properties b/src/main/resources/messages_pl.properties new file mode 100644 index 0000000..0b1f940 --- /dev/null +++ b/src/main/resources/messages_pl.properties @@ -0,0 +1,188 @@ +# Navigation and Main Layout +nav.jobs=Zadania +nav.job.create=Utwórz zadanie +nav.customers=Klienci +nav.appusers=Użytkownicy aplikacji +nav.statistics=Statystyki +nav.invoices=Faktury +nav.messages=Wiadomości +nav.profile=Mój profil +nav.myinvoices=Moje faktury +nav.imprint=Impressum +nav.management=Zarządzanie +nav.users=Użytkownicy +nav.showprofile=Pokaż profil +nav.settings=Ustawienia +nav.logout=Wyloguj się + +# Profile View +profile.title=Edytuj profil +profile.language=Język +profile.company=Firma +profile.companyadd=Dodatek do firmy +profile.firstname=Imię +profile.lastname=Nazwisko +profile.phone=Numer telefonu +profile.fax=Faks +profile.mobile=Telefon komórkowy +profile.email=Adres e-mail (Logowanie)* +profile.street=Ulica +profile.housenr=Nr domu +profile.addressadd=Dodatek do adresu +profile.postcode=Kod pocztowy +profile.city=Miasto +profile.diffinvoice=Inny adres rozliczeniowy +profile.basicdata=Dane podstawowe +profile.map=Mapa +profile.invoicecreation=Tworzenie faktury +profile.settings=Ustawienia +profile.account=Konto +profile.security=Bezpieczeństwo +profile.services=Katalog usług +profile.saved=Profil zapisany +profile.save.error=Błąd podczas zapisywania: {0} +profile.validation.required.fill=Wypełnij wszystkie wymagane pola poprawnie + +# Profile Settings +settings.digitalprocessing=Cyfrowe przetwarzanie przez aplikację +settings.digitalprocessinginfo=Umożliwia cyfrowe przetwarzanie zadań za pośrednictwem aplikacji mobilnej +settings.locationtracking=Lokalizowanie użytkowników aplikacji +settings.locationtrackinginfo=Umożliwia lokalizowanie użytkowników aplikacji podczas wykonywania zadań +settings.twofactor=Uwierzytelnianie dwuskładnikowe +settings.twofactorinfo=Po włączeniu przy każdym logowaniu wysyłany jest kod e-mailem + +# Profile Billing +profile.billing.enabled=Fakturowanie przez votianLT + +# Profile Validation +profile.validation.company=Firma jest polem wymaganym +profile.validation.firstname=Imię jest polem wymaganym +profile.validation.lastname=Nazwisko jest polem wymaganym +profile.validation.phone=Numer telefonu jest polem wymaganym +profile.validation.street=Ulica jest polem wymaganym +profile.validation.housenr=Numer domu jest polem wymaganym +profile.validation.postcode=Kod pocztowy jest polem wymaganym +profile.validation.city=Miasto jest polem wymaganym +profile.validation.email.required=Adres e-mail jest polem wymaganym +profile.validation.email.invalid=Podaj prawidłowy adres e-mail +profile.validation.company.required=Firma jest wymagana +profile.validation.street.required=Ulica jest wymagana +profile.validation.housenr.required=Numer domu jest wymagany +profile.validation.postcode.required=Kod pocztowy jest wymagany +profile.validation.city.required=Miasto jest wymagane +profile.validation.firstname.required=Imię jest wymagane +profile.validation.lastname.required=Nazwisko jest wymagane +profile.validation.phone.required=Numer telefonu jest wymagany + +# Buttons +button.save=Zapisz zmiany w profilu +button.savechanges=Zapisz +button.clear=Wyczyść +button.preview=Podgląd +button.savetemplate=Zapisz szablon +button.changepassword=Zmień hasło +button.deleteaccount=Usuń konto +button.add=Nowy +button.edit=Edytuj +button.delete=Usuń +button.cancel=Anuluj +button.close=Zamknij +button.download=Pobierz +button.back=Wstecz + +# Common +common.name=Nazwa +common.yes=Tak +common.no=Nie +common.total=Suma +common.price=Cena +common.service=Usługa +common.customer=Klient +common.actions=Działania +common.loading=Ładowanie... +common.error=Błąd +common.success=Sukces +common.required=Pole wymagane + +# Validation +validation.required=Pole jest wymagane +validation.email=Nieprawidłowy adres e-mail +validation.error=Błąd walidacji + +# Notifications +notification.saved=Profil zapisany +notification.error=Błąd podczas zapisywania +notification.languagechanged=Język zmieniony + +# Login +login.title=Zaloguj się +login.username=Nazwa użytkownika +login.password=Hasło +login.login=Zaloguj się +login.forgotpassword=Nie pamiętasz hasła? +login.rememberme=Zapamiętaj mnie +login.register=Zarejestruj się +login.2fa.helper=6-cyfrowy kod +login.2fa.sent=Kod został wysłany e-mailem +login.2fa.no.credentials=Brak danych logowania +login.2fa.invalid.code=Nieprawidłowy kod +login.2fa.wrong.code=Zły kod + +# Error Messages +error.loading=Błąd ładowania +error.saving=Błąd zapisywania +error.validation=Błąd walidacji + +# Page Titles +page.title.welcome=VotianLT - Witamy +page.title.login=VotianLT - Logowanie + +# Start Page +start.title=VotianLT - Twój cyfrowy partner transportowy +start.button.login=Zaloguj się +start.button.register=Zarejestruj się +start.button.createorder=Utwórz zadanie +start.button.notifications=Powiadomienia +start.button.nonotifications=Brak nowych powiadomień +start.hero.description=Dla samozatrudnionych i małych przedsiębiorstw w branży transportowej - w pełni cyfrowe i kompleksowe. Skoncentruj się na swoim biznesie, my zajmiemy się dokumentacją. +start.system.title=System +start.system.intro=Dla samozatrudnionych i małych przedsiębiorstw w branży transportowej kluczowe jest skupienie się przede wszystkim na ich podstawowej działalności: pozyskiwaniu klientów i dostarczaniu towarów z punktu A do B. +start.feature.setup.title=Asystent konfiguracji +start.feature.setup.desc=Za pomocą asystenta konfiguracji masz możliwość uzupełnienia swojego profilu użytkownika. +start.feature.customers.title=Zarządzanie klientami i zadaniami +start.feature.customers.desc=Dzięki zarządzaniu klientami i zadaniami masz wszystkie dane kontaktowe i szczegóły zadań zawsze pod kontrolą. +start.feature.jobs.title=Tworzenie zadań +start.feature.jobs.desc=Twórz zadania w systemie za pomocą kilku kliknięć i określ, który pracownik powinien wykonać które zadanie transportowe. +start.app.title=Aplikacja +start.app.description=Każde zadanie może być opcjonalnie realizowane za pośrednictwem aplikacji votianLT - całkowicie bez "papierkowej roboty". Wszystkie istotne informacje o zadaniu trafiają bezpośrednio na smartfon kierowcy. +start.imprint.title=Stopka +start.imprint.company=Assecutor Data Service GmbH +start.imprint.address=Ottensener Str. 8, 22525 Hamburg +start.imprint.phone=Telefon: +49 40 18 123 771 0 +start.imprint.email=E-Mail: ahoi@assecutor.de +start.cta.text=Zarejestruj się już dziś i skorzystaj z bezpłatnego miesiąca próbnego, aby dokładnie przetestować system! +start.slogan=Prowadź swój biznes inteligentnie … z votianLT! +start.version=Wersja + +# Register +register.title=Rejestracja +register.subtitle=Utwórz swoje konto VotianLT +register.email=Adres e-mail +register.password=Hasło +register.password.placeholder=Co najmniej 6 znaków +register.password.confirm=Potwierdź hasło +register.password.confirm.placeholder=Wprowadź hasło ponownie +register.firstname=Imię +register.lastname=Nazwisko +register.phone=Numer telefonu +register.company=Firma +register.street=Ulica +register.housenr=Nr domu +register.postcode=Kod pocztowy +register.city=Miasto +register.button.submit=Zarejestruj się +register.notification.success=Rejestracja zakończona sukcesem. Zaloguj się. +register.notification.failed=Rejestracja nie powiodła się: {0} + +# CTA Button +cta.freetest=Wypróbuj teraz za darmo \ No newline at end of file diff --git a/src/main/resources/messages_ru.properties b/src/main/resources/messages_ru.properties new file mode 100644 index 0000000..c33cf9d --- /dev/null +++ b/src/main/resources/messages_ru.properties @@ -0,0 +1,188 @@ +# Navigation and Main Layout +nav.jobs=Задачи +nav.job.create=Создать задачу +nav.customers=Клиенты +nav.appusers=Пользователи приложения +nav.statistics=Статистика +nav.invoices=Счета +nav.messages=Сообщения +nav.profile=Мой профиль +nav.myinvoices=Мои счета +nav.imprint=Выходные данные +nav.management=Управление +nav.users=Пользователи +nav.showprofile=Показать профиль +nav.settings=Настройки +nav.logout=Выйти + +# Profile View +profile.title=Редактировать профиль +profile.language=Язык +profile.company=Компания +profile.companyadd=Дополнение к компании +profile.firstname=Имя +profile.lastname=Фамилия +profile.phone=Номер телефона +profile.fax=Факс +profile.mobile=Мобильный телефон +profile.email=Адрес электронной почты (Вход)* +profile.street=Улица +profile.housenr=Номер дома +profile.addressadd=Дополнение к адресу +profile.postcode=Почтовый индекс +profile.city=Город +profile.diffinvoice=Другой адрес для выставления счетов +profile.basicdata=Основные данные +profile.map=Карта +profile.invoicecreation=Создание счета +profile.settings=Настройки +profile.account=Аккаунт +profile.security=Безопасность +profile.services=Каталог услуг +profile.saved=Профиль сохранен +profile.save.error=Ошибка сохранения: {0} +profile.validation.required.fill=Пожалуйста, правильно заполните все обязательные поля + +# Profile Settings +settings.digitalprocessing=Цифровая обработка через приложение +settings.digitalprocessinginfo=Включает цифровую обработку задач через мобильное приложение +settings.locationtracking=Отслеживание местоположения пользователей приложения +settings.locationtrackinginfo=Позволяет отслеживать местоположение пользователей приложения во время выполнения задач +settings.twofactor=Двухфакторная аутентификация +settings.twofactorinfo=При активации при каждом входе отправляется код по электронной почте + +# Profile Billing +profile.billing.enabled=Выставление счетов через votianLT + +# Profile Validation +profile.validation.company=Компания - обязательное поле +profile.validation.firstname=Имя - обязательное поле +profile.validation.lastname=Фамилия - обязательное поле +profile.validation.phone=Номер телефона - обязательное поле +profile.validation.street=Улица - обязательное поле +profile.validation.housenr=Номер дома - обязательное поле +profile.validation.postcode=Почтовый индекс - обязательное поле +profile.validation.city=Город - обязательное поле +profile.validation.email.required=Адрес электронной почты - обязательное поле +profile.validation.email.invalid=Пожалуйста, введите действительный адрес электронной почты +profile.validation.company.required=Требуется компания +profile.validation.street.required=Требуется улица +profile.validation.housenr.required=Требуется номер дома +profile.validation.postcode.required=Требуется почтовый индекс +profile.validation.city.required=Требуется город +profile.validation.firstname.required=Требуется имя +profile.validation.lastname.required=Требуется фамилия +profile.validation.phone.required=Требуется номер телефона + +# Buttons +button.save=Сохранить изменения профиля +button.savechanges=Сохранить +button.clear=Очистить +button.preview=Предпросмотр +button.savetemplate=Сохранить шаблон +button.changepassword=Изменить пароль +button.deleteaccount=Удалить аккаунт +button.add=Новый +button.edit=Редактировать +button.delete=Удалить +button.cancel=Отмена +button.close=Закрыть +button.download=Скачать +button.back=Назад + +# Common +common.name=Название +common.yes=Да +common.no=Нет +common.total=Итого +common.price=Цена +common.service=Услуга +common.customer=Клиент +common.actions=Действия +common.loading=Загрузка... +common.error=Ошибка +common.success=Успех +common.required=Обязательное поле + +# Validation +validation.required=Поле обязательно для заполнения +validation.email=Недействительный адрес электронной почты +validation.error=Ошибка валидации + +# Notifications +notification.saved=Профиль сохранен +notification.error=Ошибка сохранения +notification.languagechanged=Язык изменен + +# Login +login.title=Войти +login.username=Имя пользователя +login.password=Пароль +login.login=Войти +login.forgotpassword=Забыли пароль? +login.rememberme=Запомнить меня +login.register=Зарегистрироваться +login.2fa.helper=6-значный код +login.2fa.sent=Код отправлен по электронной почте +login.2fa.no.credentials=Нет учетных данных +login.2fa.invalid.code=Недействительный код +login.2fa.wrong.code=Неправильный код + +# Error Messages +error.loading=Ошибка загрузки +error.saving=Ошибка сохранения +error.validation=Ошибка валидации + +# Page Titles +page.title.welcome=VotianLT - Добро пожаловать +page.title.login=VotianLT - Вход + +# Start Page +start.title=VotianLT - Ваш цифровой транспортный партнер +start.button.login=Войти +start.button.register=Зарегистрироваться +start.button.createorder=Создать задачу +start.button.notifications=Уведомления +start.button.nonotifications=Нет новых уведомлений +start.hero.description=Для самозанятых и малых предприятий в транспортной отрасли — полностью цифровое и комплексное решение. Сосредоточьтесь на своем бизнесе, а о документах мы позаботимся. +start.system.title=Система +start.system.intro=Для самозанятых и малых предприятий в транспортной отрасли крайне важно сосредоточиться прежде всего на своей основной деятельности: привлечении клиентов и доставке товаров из пункта А в пункт Б. +start.feature.setup.title=Помощник настройки +start.feature.setup.desc=Используйте помощник настройки для заполнения профиля пользователя. +start.feature.customers.title=Управление клиентами и задачами +start.feature.customers.desc=С управлением клиентами и задачами вы всегда имеете под рукой все контактные данные и детали задач. +start.feature.jobs.title=Создание задач +start.feature.jobs.desc=Создавайте задачи в системе всего за несколько кликов и определяйте, какой сотрудник должен выполнить какую транспортную задачу. +start.app.title=Приложение +start.app.description=Каждая задача может быть выполнена через приложение votianLT — полностью без "бумажной работы". Вся важная информация о задаче поступает прямо на смартфон водителя. +start.imprint.title=Выходные данные +start.imprint.company=Assecutor Data Service GmbH +start.imprint.address=Ottensener Str. 8, 22525 Hamburg +start.imprint.phone=Телефон: +49 40 18 123 771 0 +start.imprint.email=Эл. почта: ahoi@assecutor.de +start.cta.text=Зарегистрируйтесь уже сегодня и воспользуйтесь бесплатным пробным месяцем, чтобы тщательно протестировать систему! +start.slogan=Умно управляйте своим бизнесом … с votianLT! +start.version=Версия + +# Register +register.title=Регистрация +register.subtitle=Создайте свою учетную запись VotianLT +register.email=Адрес электронной почты +register.password=Пароль +register.password.placeholder=Минимум 6 символов +register.password.confirm=Подтвердите пароль +register.password.confirm.placeholder=Введите пароль еще раз +register.firstname=Имя +register.lastname=Фамилия +register.phone=Номер телефона +register.company=Компания +register.street=Улица +register.housenr=Номер дома +register.postcode=Почтовый индекс +register.city=Город +register.button.submit=Зарегистрироваться +register.notification.success=Регистрация прошла успешно. Пожалуйста, войдите. +register.notification.failed=Ошибка регистрации: {0} + +# CTA Button +cta.freetest=Попробуйте бесплатно \ No newline at end of file diff --git a/src/main/resources/messages_tr.properties b/src/main/resources/messages_tr.properties new file mode 100644 index 0000000..d84df0a --- /dev/null +++ b/src/main/resources/messages_tr.properties @@ -0,0 +1,188 @@ +# Navigation and Main Layout +nav.jobs=Görevler +nav.job.create=Görev Oluştur +nav.customers=Müşteriler +nav.appusers=App Kullanıcıları +nav.statistics=İstatistikler +nav.invoices=Faturalar +nav.messages=Mesajlar +nav.profile=Profilim +nav.myinvoices=Faturalarım +nav.imprint=Künye +nav.management=Yönetim +nav.users=Kullanıcılar +nav.showprofile=Profili Göster +nav.settings=Ayarlar +nav.logout=Çıkış Yap + +# Profile View +profile.title=Profili Düzenle +profile.language=Dil +profile.company=Şirket +profile.companyadd=Şirket Eki +profile.firstname=Ad +profile.lastname=Soyad +profile.phone=Telefon Numarası +profile.fax=Faks +profile.mobile=Cep Telefonu +profile.email=E-Posta Adresi (Giriş)* +profile.street=Sokak +profile.housenr=Ev No +profile.addressadd=Adres Eki +profile.postcode=Posta Kodu +profile.city=Şehir +profile.diffinvoice=Farklı Fatura Adresi +profile.basicdata=Temel Veriler +profile.map=Harita +profile.invoicecreation=Fatura Oluşturma +profile.settings=Ayarlar +profile.account=Hesap +profile.security=Güvenlik +profile.services=Hizmet Kataloğu +profile.saved=Profil kaydedildi +profile.save.error=Kaydetme hatası: {0} +profile.validation.required.fill=Lütfen tüm zorunlu alanları doğru şekilde doldurun + +# Profile Settings +settings.digitalprocessing=App ile Dijital İşlem +settings.digitalprocessinginfo=Mobil uygulama üzerinden dijital görev işlemeyi etkinleştirir +settings.locationtracking=App kullanıcılarını konumlandırma +settings.locationtrackinginfo=Görev yürütme sırasında App kullanıcılarının konumlandırılmasını sağlar +settings.twofactor=İki Faktörlü Kimlik Doğrulama +settings.twofactorinfo=Etkinleştirildiğinde, her girişte e-posta ile bir kod gönderilir + +# Profile Billing +profile.billing.enabled=votianLT üzerinden faturalandırma + +# Profile Validation +profile.validation.company=Şirket zorunlu bir alandır +profile.validation.firstname=Ad zorunlu bir alandır +profile.validation.lastname=Soyad zorunlu bir alandır +profile.validation.phone=Telefon numarası zorunlu bir alandır +profile.validation.street=Sokak zorunlu bir alandır +profile.validation.housenr=Ev numarası zorunlu bir alandır +profile.validation.postcode=Posta kodu zorunlu bir alandır +profile.validation.city=Şehir zorunlu bir alandır +profile.validation.email.required=E-posta adresi zorunlu bir alandır +profile.validation.email.invalid=Lütfen geçerli bir e-posta adresi girin +profile.validation.company.required=Şirket gereklidir +profile.validation.street.required=Sokak gereklidir +profile.validation.housenr.required=Ev numarası gereklidir +profile.validation.postcode.required=Posta kodu gereklidir +profile.validation.city.required=Şehir gereklidir +profile.validation.firstname.required=Ad gereklidir +profile.validation.lastname.required=Soyad gereklidir +profile.validation.phone.required=Telefon numarası gereklidir + +# Buttons +button.save=Profil değişikliklerini kaydet +button.savechanges=Kaydet +button.clear=Temizle +button.preview=Önizleme +button.savetemplate=Şablonu kaydet +button.changepassword=Şifreyi değiştir +button.deleteaccount=Hesabı sil +button.add=Yeni +button.edit=Düzenle +button.delete=Sil +button.cancel=İptal +button.close=Kapat +button.download=İndir +button.back=Geri + +# Common +common.name=Ad +common.yes=Evet +common.no=Hayır +common.total=Toplam +common.price=Fiyat +common.service=Hizmet +common.customer=Müşteri +common.actions=İşlemler +common.loading=Yükleniyor... +common.error=Hata +common.success=Başarı +common.required=Zorunlu alan + +# Validation +validation.required=Alan zorunludur +validation.email=Geçersiz e-posta adresi +validation.error=Doğrulama hatası + +# Notifications +notification.saved=Profil kaydedildi +notification.error=Kaydetme hatası +notification.languagechanged=Dil değiştirildi + +# Login +login.title=Giriş Yap +login.username=Kullanıcı adı +login.password=Şifre +login.login=Giriş Yap +login.forgotpassword=Şifrenizi mi unuttunuz? +login.rememberme=Beni hatırla +login.register=Kaydol +login.2fa.helper=6 haneli kod +login.2fa.sent=Kod e-posta ile gönderildi +login.2fa.no.credentials=Kimlik bilgileri yok +login.2fa.invalid.code=Geçersiz kod +login.2fa.wrong.code=Yanlış kod + +# Error Messages +error.loading=Yükleme hatası +error.saving=Kaydetme hatası +error.validation=Doğrulama hatası + +# Page Titles +page.title.welcome=VotianLT - Hoş Geldiniz +page.title.login=VotianLT - Giriş Yap + +# Start Page +start.title=VotianLT - Dijital Taşıma Ortağınız +start.button.login=Giriş Yap +start.button.register=Kaydol +start.button.createorder=Görev Oluştur +start.button.notifications=Bildirimler +start.button.nonotifications=Yeni bildirim yok +start.hero.description=Nakliyecilik sektöründe tek çalışanlar ve küçük işletmeler için - tamamen dijital ve hepsi bir arada. Siz işinize odaklanın, kâğıt işleriyle biz ilgilenelim. +start.system.title=Sistem +start.system.intro=Nakliyecilik sektöründe tek çalışanlar ve küçük işletmeler için, öncelikle temel işlerine odaklanmaları çok önemlidir: müşteri kazanmak ve malları A'dan B'ye teslim etmek. +start.feature.setup.title=Kurulum Asistanı +start.feature.setup.desc=Kurulum asistanını kullanarak kullanıcı profilinizi tamamlayabilirsiniz. +start.feature.customers.title=Müşteri ve Görev Yönetimi +start.feature.customers.desc=Müşteri ve görev yönetimi ile tüm iletişim bilgilerini ve görev detaylarını her zaman gözünüzün önünde bulundurun. +start.feature.jobs.title=Görev Oluşturma +start.feature.jobs.desc=Sadece birkaç tıklama ile sistemde görevler oluşturun ve hangi çalışanın hangi taşıma görevini işlemesi gerektiğini belirleyin. +start.app.title=Uygulama +start.app.description=Her görev, votianLT uygulaması üzerinden isteğe bağlı olarak işlenebilir - tamamen "evrak işi" olmadan. Tüm ilgili görev bilgileri doğrudan sürücünün akıllı telefonuna gider. +start.imprint.title=Künye +start.imprint.company=Assecutor Data Service GmbH +start.imprint.address=Ottensener Str. 8, 22525 Hamburg +start.imprint.phone=Telefon: +49 40 18 123 771 0 +start.imprint.email=E-Posta: ahoi@assecutor.de +start.cta.text=Bugün kaydolun ve sistemi derinlemesine test etmek için ücretsiz deneme ayından yararlanın! +start.slogan=İşletmenizi akıllıca yönetin … votianLT ile! +start.version=Sürüm + +# Register +register.title=Kayıt +register.subtitle=VotianLT hesabınızı oluşturun +register.email=E-Posta Adresi +register.password=Şifre +register.password.placeholder=En az 6 karakter +register.password.confirm=Şifreyi Onayla +register.password.confirm.placeholder=Şifreyi tekrar girin +register.firstname=Ad +register.lastname=Soyad +register.phone=Telefon Numarası +register.company=Şirket +register.street=Sokak +register.housenr=Ev No +register.postcode=Posta Kodu +register.city=Şehir +register.button.submit=Kaydol +register.notification.success=Kayıt başarılı. Lütfen giriş yapın. +register.notification.failed=Kayıt başarısız: {0} + +# CTA Button +cta.freetest=Şimdi ücretsiz dene \ No newline at end of file