diff --git a/EnvelopeGenerator.Application/Resources/Resource.de-DE.resx b/EnvelopeGenerator.Application/Resources/Resource.de-DE.resx index 223b8e72..f7ff6001 100644 --- a/EnvelopeGenerator.Application/Resources/Resource.de-DE.resx +++ b/EnvelopeGenerator.Application/Resources/Resource.de-DE.resx @@ -651,4 +651,123 @@ Status - \ No newline at end of file + Geändert am + Schließen + Sprachmenü schließen + Unterschrift bestätigen + Erstellt + Löschen + Dokument + Dokument konnte nicht geladen werden + Dokument wird geladen... + E-Mail-Adresse + Umschlag + Fehler + Fehler beim Laden des Dokuments: {0} + Entwicklungsmodus + Dies kann dazu führen, dass vertrauliche Informationen aus Ausnahmen Endbenutzern angezeigt werden. Für lokales Debugging setzen Sie ASPNETCORE_ENVIRONMENT auf Development und starten die App neu. + Im Entwicklungsmodus werden detailliertere Fehlerinformationen angezeigt. + Der Entwicklungsmodus sollte in bereitgestellten Anwendungen nicht aktiviert sein. + Bei der Verarbeitung Ihrer Anfrage ist ein Fehler aufgetreten. + Anfrage-ID + Fehler: {0} + Von + Vor- und Nachname + Historie + Digitale Unterschrift + PDF-Export + Sicherer Zugang + Willkommen im eSign-Portal + Zur Umschlag-Übersicht + Sprachen + Lädt... + Anmelden + Anmelden ... + Nicht authentifiziert. Bitte melden Sie sich erneut an. + Nur + Dokument öffnen + optional + Ausstehend + Vorschau + Datenschutz + Empfänger + Zugangscode eingeben + Bitte geben Sie den Zugangscode ein, den Sie per E-Mail erhalten haben, um das Dokument sicher zu öffnen. + Bei Problemen wenden Sie sich bitte an den Absender des Dokuments. + Der eingegebene Code ist falsch. Bitte versuchen Sie es erneut. + Ungültiger Zugangscode. + Der angegebene Zugangscode konnte keinem Dokument zugeordnet werden. Bitte prüfen Sie den Link in Ihrer E-Mail. + Dokument nicht gefunden. + Sicherer Zugang mit Zugangscode + Diese Aktion kann nicht rückgängig gemacht werden. Mit der Bestätigung erklären Sie, das oben angezeigte Dokument elektronisch unterzeichnet zu haben. Das unterzeichnete Dokument wird anschließend an alle beteiligten Parteien übermittelt. + Möchten Sie das Dokument verbindlich unterschreiben? + Envelope-Schlüssel fehlt. + Aktualisieren + Pflichtfeld + ausgewählte + Senden + Aktive Umschläge + Abgeschlossene Umschläge + Neuer Umschlag + Neuen Umschlag erstellen + Umschlag löschen + Begründung eingeben... + Bitte geben Sie einen Grund an, warum der Umschlag gelöscht/zurückgezogen werden soll. + Bitte geben Sie einen Löschgrund an. + Ausgewählten Umschlag löschen + Bearbeiten + Ausgewählten Umschlag bearbeiten + Aktuelle Ansicht exportieren + Exportformat auswählen + Export der aktuellen Tabellenansicht + Fehler beim Laden der Umschläge + Umschläge werden geladen... + Keine Historie vorhanden + Keine Empfänger + Ausgewählten Umschlag als PDF anzeigen + Das Dokument für Umschlag #{0} wurde nicht gefunden oder Sie haben keinen Zugriff darauf. + Signatur hinzufügen + Klicken Sie auf die Stelle im Dokument für + Bereits verwendete E-Mail-Adressen werden bei der Eingabe vorgeschlagen. + E-Mail-Vorschläge werden geladen... + Fehler beim Erstellen des Umschlags + Fehler beim Laden des Umschlags #{0}: {1} + Fehler beim Laden der Datei: {0} + Bitte unterzeichnen Sie das beigefügte Dokument. + Kein Dokument geladen + Noch keine Empfänger hinzugefügt. + Signaturfeld platzieren + Alle Signaturfelder entfernen + Bitte wählen Sie eine PDF-Datei aus. + Der bestehende Entwurf wurde versendet. + Umschlag gesendet + Umschlag wurde erfolgreich gesendet. + Signaturfeld + z.B. Arbeitsvertrag 2025 + Zur Übersicht + Laden Sie eine PDF-Datei hoch, um Signaturfelder zu platzieren. + Diese E-Mail-Adresse wurde bereits hinzugefügt. + Bitte geben Sie eine gültige E-Mail-Adresse ein. + Bitte geben Sie eine E-Mail-Adresse ein. + Bitte geben Sie einen Vor- und Nachnamen ein. + Bitte fügen Sie mindestens einen Empfänger hinzu. + Bitte platzieren Sie mindestens ein Signaturfeld. + Bitte geben Sie einen Titel ein. + Bitte laden Sie zuerst ein PDF-Dokument hoch. + Bitte melden Sie sich mit Ihren Zugangsdaten an, um auf das Sender-Dashboard zuzugreifen. + Bei Problemen wenden Sie sich bitte an den Administrator. + Benutzername oder Passwort ist falsch. Bitte versuchen Sie es erneut. + Ungültige Anmeldedaten. + Passwort eingeben + Sicherer Zugang zum Sender-Dashboard + Sender Anmeldung + Benutzername eingeben + Serverfehler. + Unterschrieben + Signiertes Dokument + System + Ein unerwarteter Fehler ist aufgetreten. Bitte versuchen Sie es später erneut. + PDF hochladen + Benutzername + Überprüfen ... + diff --git a/EnvelopeGenerator.Application/Resources/Resource.en-US.resx b/EnvelopeGenerator.Application/Resources/Resource.en-US.resx index 0db372f4..01de8aec 100644 --- a/EnvelopeGenerator.Application/Resources/Resource.en-US.resx +++ b/EnvelopeGenerator.Application/Resources/Resource.en-US.resx @@ -651,4 +651,123 @@ Status - \ No newline at end of file + Changed at + Close + Close language menu + Confirm signature + Created + Delete + Document + Document could not be loaded + Document is loading... + Email address + Envelope + Error + Error loading document: {0} + Development Mode + This can result in sensitive exception information being shown to end users. For local debugging, set ASPNETCORE_ENVIRONMENT to Development and restart the app. + Switching to Development will display more detailed error information. + The Development environment should not be enabled in deployed applications. + An error occurred while processing your request. + Request ID + Error: {0} + From + First and last name + History + Digital signature + PDF export + Secure access + Welcome to the eSign portal + Go to envelope overview + Languages + Loading... + Sign in + Signing in ... + Not authenticated. Please sign in again. + Only + Open document + optional + Pending + Preview + Privacy policy + Receiver + Enter access code + Please enter the access code you received by email to securely open the document. + If you have issues, please contact the document sender. + The entered code is incorrect. Please try again. + Invalid access code. + The provided access code could not be matched to a document. Please verify the link in your email. + Document not found. + Secure access with access code + This action cannot be undone. By confirming, you declare that you have electronically signed the document shown above. The signed document will then be delivered to all involved parties. + Do you want to sign this document as binding? + Envelope key is missing. + Refresh + Required field + selected + Send + Active envelopes + Completed envelopes + New envelope + Create new envelope + Delete envelope + Enter reason... + Please provide a reason why the envelope should be deleted/withdrawn. + Please provide a deletion reason. + Delete selected envelope + Edit + Edit selected envelope + Export current view + Select export format + Export current table view + Error loading envelopes + Loading envelopes... + No history available + No receivers + Show selected envelope as PDF + The document for envelope #{0} was not found or you do not have access. + Add signature + Click on the location in the document for + Previously used email addresses are suggested while typing. + Loading email suggestions... + Error creating envelope + Error loading envelope #{0}: {1} + Error loading file: {0} + Please sign the attached document. + No document loaded + No receivers added yet. + Place signature field + Remove all signature fields + Please select a PDF file. + The existing draft has been sent. + Envelope sent + Envelope was sent successfully. + Signature field + e.g. Employment contract 2025 + To overview + Upload a PDF file to place signature fields. + This email address has already been added. + Please enter a valid email address. + Please enter an email address. + Please enter first and last name. + Please add at least one receiver. + Please place at least one signature field. + Please enter a title. + Please upload a PDF document first. + Please sign in with your credentials to access the sender dashboard. + If you have issues, please contact the administrator. + Username or password is incorrect. Please try again. + Invalid credentials. + Enter password + Secure access to sender dashboard + Sender login + Enter username + Server error. + Signed + Signed document + System + An unexpected error occurred. Please try again later. + Upload PDF + Username + Verifying ... + diff --git a/EnvelopeGenerator.Application/Resources/Resource.fr-FR.resx b/EnvelopeGenerator.Application/Resources/Resource.fr-FR.resx index 75834e1b..50fcfe87 100644 --- a/EnvelopeGenerator.Application/Resources/Resource.fr-FR.resx +++ b/EnvelopeGenerator.Application/Resources/Resource.fr-FR.resx @@ -651,4 +651,123 @@ Statut - \ No newline at end of file + Modifié le + Fermer + Fermer le menu des langues + Confirmer la signature + Créé + Supprimer + Document + Le document n'a pas pu être chargé + Chargement du document... + Adresse e-mail + Enveloppe + Erreur + Erreur lors du chargement du document : {0} + Mode développement + Cela peut afficher des informations sensibles d'exception aux utilisateurs finaux. Pour le débogage local, définissez ASPNETCORE_ENVIRONMENT sur Development et redémarrez l'application. + Le mode développement affiche des informations d'erreur plus détaillées. + Le mode développement ne doit pas être activé dans les applications déployées. + Une erreur s'est produite lors du traitement de votre demande. + ID de requête + Erreur : {0} + De + Nom et prénom + Historique + Signature numérique + Export PDF + Accès sécurisé + Bienvenue sur le portail eSign + Aller à l'aperçu des enveloppes + Langues + Chargement... + Connexion + Connexion ... + Non authentifié. Veuillez vous reconnecter. + Uniquement + Ouvrir le document + optionnel + En attente + Aperçu + Politique de confidentialité + Destinataire + Saisir le code d'accès + Veuillez saisir le code d'accès reçu par e-mail pour ouvrir le document en toute sécurité. + En cas de problème, veuillez contacter l'expéditeur du document. + Le code saisi est incorrect. Veuillez réessayer. + Code d'accès invalide. + Le code d'accès indiqué ne correspond à aucun document. Veuillez vérifier le lien dans votre e-mail. + Document introuvable. + Accès sécurisé avec code d'accès + Cette action est irréversible. En confirmant, vous déclarez avoir signé électroniquement le document affiché ci-dessus. Le document signé sera ensuite transmis à toutes les parties concernées. + Voulez-vous signer ce document de manière contraignante ? + La clé d'enveloppe est manquante. + Actualiser + Champ obligatoire + sélectionnées + Envoyer + Enveloppes actives + Enveloppes terminées + Nouvelle enveloppe + Créer une nouvelle enveloppe + Supprimer l'enveloppe + Saisir la raison... + Veuillez indiquer la raison pour laquelle l'enveloppe doit être supprimée/retirée. + Veuillez indiquer un motif de suppression. + Supprimer l'enveloppe sélectionnée + Modifier + Modifier l'enveloppe sélectionnée + Exporter la vue actuelle + Sélectionner le format d'export + Exporter la vue actuelle du tableau + Erreur lors du chargement des enveloppes + Chargement des enveloppes... + Aucun historique disponible + Aucun destinataire + Afficher l'enveloppe sélectionnée en PDF + Le document de l'enveloppe #{0} est introuvable ou vous n'avez pas l'autorisation d'y accéder. + Ajouter une signature + Cliquez sur l'emplacement dans le document pour + Les adresses e-mail déjà utilisées sont proposées pendant la saisie. + Chargement des suggestions d'e-mail... + Erreur lors de la création de l'enveloppe + Erreur lors du chargement de l'enveloppe #{0} : {1} + Erreur lors du chargement du fichier : {0} + Veuillez signer le document ci-joint. + Aucun document chargé + Aucun destinataire ajouté pour le moment. + Placer un champ de signature + Supprimer tous les champs de signature + Veuillez sélectionner un fichier PDF. + Le brouillon existant a été envoyé. + Enveloppe envoyée + L'enveloppe a été envoyée avec succès. + Champ de signature + p. ex. Contrat de travail 2025 + Vers l'aperçu + Téléversez un fichier PDF pour placer des champs de signature. + Cette adresse e-mail a déjà été ajoutée. + Veuillez saisir une adresse e-mail valide. + Veuillez saisir une adresse e-mail. + Veuillez saisir le nom et le prénom. + Veuillez ajouter au moins un destinataire. + Veuillez placer au moins un champ de signature. + Veuillez saisir un titre. + Veuillez d'abord téléverser un document PDF. + Veuillez vous connecter avec vos identifiants pour accéder au tableau de bord expéditeur. + En cas de problème, veuillez contacter l'administrateur. + Le nom d'utilisateur ou le mot de passe est incorrect. Veuillez réessayer. + Identifiants invalides. + Saisir le mot de passe + Accès sécurisé au tableau de bord expéditeur + Connexion expéditeur + Saisir le nom d'utilisateur + Erreur serveur. + Signé + Document signé + Système + Une erreur inattendue s'est produite. Veuillez réessayer plus tard. + Téléverser un PDF + Nom d'utilisateur + Vérification ... + diff --git a/EnvelopeGenerator.Server/EnvelopeGenerator.Server.Client/Layout/LanguageControls.razor b/EnvelopeGenerator.Server/EnvelopeGenerator.Server.Client/Layout/LanguageControls.razor index fbab5db4..3603dbff 100644 --- a/EnvelopeGenerator.Server/EnvelopeGenerator.Server.Client/Layout/LanguageControls.razor +++ b/EnvelopeGenerator.Server/EnvelopeGenerator.Server.Client/Layout/LanguageControls.razor @@ -1,14 +1,17 @@ @using EnvelopeGenerator.Server.Client.Services +@using EnvelopeGenerator.Application.Resources +@using Microsoft.Extensions.Localization @rendermode InteractiveWebAssembly @inject LocalizationService LocalizationService @inject NavigationManager Navigation +@inject IStringLocalizer UiLocalizer
@@ -17,11 +20,11 @@ { -
+
@foreach (var option in _options) {
- Digitale Unterschrift + @L("Index_DigitalSignature", "Digitale Unterschrift")
- PDF-Export + @L("Index_PdfExport", "PDF-Export")
@@ -80,10 +83,9 @@
@code { - private const string HomePageDescription = - "Das digitale Unterschriftenportal ist eine Plattform, die entwickelt wurde, um Ihre Dokumente sicher zu unterschreiben und zu verwalten. " + - "Mit seiner benutzerfreundlichen Oberfläche können Sie Ihre Dokumente schnell hochladen, die Unterschriftsprozesse verfolgen und Ihre digitalen Unterschriftenanwendungen einfach durchführen. " + - "Dieses Portal beschleunigt Ihren Arbeitsablauf mit rechtlich gültigen Unterschriften und erhöht gleichzeitig die Sicherheit Ihrer Dokumente."; + private string HomePageDescription => L( + "HomePageDescription", + "Das digitale Unterschriftenportal ist eine Plattform, die entwickelt wurde, um Ihre Dokumente sicher zu unterschreiben und zu verwalten. Mit seiner benutzerfreundlichen Oberfläche können Sie Ihre Dokumente schnell hochladen, die Unterschriftsprozesse verfolgen und Ihre digitalen Unterschriftenanwendungen einfach durchführen. Dieses Portal beschleunigt Ihren Arbeitsablauf mit rechtlich gültigen Unterschriften und erhöht gleichzeitig die Sicherheit Ihrer Dokumente."); private EnvelopeGenerator.Server.Client.Services.CustomImageDto? _appLogo; @@ -99,4 +101,10 @@ if (!firstRender) return; await JS.InvokeVoidAsync("receiverSignature.startTyped", "home-description", HomePageDescription, 15); } + + string L(string key, string fallback) + { + var value = UiLocalizer[key]; + return value.ResourceNotFound ? fallback : value.Value; + } } diff --git a/EnvelopeGenerator.Server/EnvelopeGenerator.Server.Client/Pages/LoginReceiverPage.razor b/EnvelopeGenerator.Server/EnvelopeGenerator.Server.Client/Pages/LoginReceiverPage.razor index b3f39ddd..962858a4 100644 --- a/EnvelopeGenerator.Server/EnvelopeGenerator.Server.Client/Pages/LoginReceiverPage.razor +++ b/EnvelopeGenerator.Server/EnvelopeGenerator.Server.Client/Pages/LoginReceiverPage.razor @@ -1,8 +1,11 @@ @page "/envelope/login/{EnvelopeKey}" @rendermode InteractiveWebAssembly @using EnvelopeGenerator.Server.Client.Services +@using EnvelopeGenerator.Application.Resources +@using Microsoft.Extensions.Localization @inject AuthService AuthService @inject NavigationManager Navigation +@inject IStringLocalizer UiLocalizer

- Bitte geben Sie den Zugangscode ein, den Sie per E-Mail erhalten haben, um das Dokument sicher zu öffnen. + @L("ReceiverLogin_Description", "Bitte geben Sie den Zugangscode ein, den Sie per E-Mail erhalten haben, um das Dokument sicher zu öffnen.")

@if (LoginResult == EnvelopeLoginResult.NotFound) @@ -30,8 +33,8 @@
- Dokument nicht gefunden.
- Der angegebene Zugangscode konnte keinem Dokument zugeordnet werden. Bitte prüfen Sie den Link in Ihrer E-Mail. + @L("ReceiverLogin_NotFound_Title", "Dokument nicht gefunden.")
+ @L("ReceiverLogin_NotFound_Body", "Der angegebene Zugangscode konnte keinem Dokument zugeordnet werden. Bitte prüfen Sie den Link in Ihrer E-Mail.")
} @@ -42,8 +45,8 @@
- Ungültiger Zugangscode.
- Der eingegebene Code ist falsch. Bitte versuchen Sie es erneut. + @L("ReceiverLogin_InvalidCode_Title", "Ungültiger Zugangscode.")
+ @L("ReceiverLogin_InvalidCode_Body", "Der eingegebene Code ist falsch. Bitte versuchen Sie es erneut.")
} @@ -55,15 +58,15 @@
- Serverfehler.
- Ein unerwarteter Fehler ist aufgetreten. Bitte versuchen Sie es später erneut. + @L("ServerError", "Serverfehler.")
+ @L("UnexpectedErrorTryAgainLater", "Ein unerwarteter Fehler ist aufgetreten. Bitte versuchen Sie es später erneut.")
}
@@ -75,7 +78,7 @@ - Überprüfen … + @L("VerifyInProgress", "Überprüfen …") } else { - Dokument öffnen + @L("OpenDocument", "Dokument öffnen") }
@@ -167,5 +170,11 @@ IsLoading = false; await InvokeAsync(StateHasChanged); } + + string L(string key, string fallback) + { + var value = UiLocalizer[key]; + return value.ResourceNotFound ? fallback : value.Value; + } } diff --git a/EnvelopeGenerator.Server/EnvelopeGenerator.Server.Client/Pages/LoginSenderPage.razor b/EnvelopeGenerator.Server/EnvelopeGenerator.Server.Client/Pages/LoginSenderPage.razor index 150fbc65..d6affc7f 100644 --- a/EnvelopeGenerator.Server/EnvelopeGenerator.Server.Client/Pages/LoginSenderPage.razor +++ b/EnvelopeGenerator.Server/EnvelopeGenerator.Server.Client/Pages/LoginSenderPage.razor @@ -1,8 +1,11 @@ @page "/sender/login" @rendermode InteractiveWebAssembly @using EnvelopeGenerator.Server.Client.Services +@using EnvelopeGenerator.Application.Resources +@using Microsoft.Extensions.Localization @inject AuthService AuthService @inject NavigationManager Navigation +@inject IStringLocalizer UiLocalizer

- Bitte melden Sie sich mit Ihren Zugangsdaten an, um auf das Sender-Dashboard zuzugreifen. + @L("SenderLogin_Description", "Bitte melden Sie sich mit Ihren Zugangsdaten an, um auf das Sender-Dashboard zuzugreifen.")

@if (LoginResult == SenderLoginResult.InvalidCredentials) { @@ -30,8 +33,8 @@
- Ungültige Anmeldedaten.
- Benutzername oder Passwort ist falsch. Bitte versuchen Sie es erneut. + @L("SenderLogin_InvalidCredentials_Title", "Ungültige Anmeldedaten.")
+ @L("SenderLogin_InvalidCredentials_Body", "Benutzername oder Passwort ist falsch. Bitte versuchen Sie es erneut.")
} else if (LoginResult == SenderLoginResult.Error) { @@ -41,15 +44,15 @@
- Serverfehler.
- Ein unerwarteter Fehler ist aufgetreten. Bitte versuchen Sie es später erneut. + @L("ServerError", "Serverfehler.")
+ @L("UnexpectedErrorTryAgainLater", "Ein unerwarteter Fehler ist aufgetreten. Bitte versuchen Sie es später erneut.")
}
@@ -61,7 +64,7 @@
@@ -84,7 +87,7 @@ @if (IsLoading) { - Anmelden … + @L("LoginInProgress", "Anmelden …") } else { - Anmelden + @L("Login", "Anmelden") }
@@ -167,4 +170,10 @@ IsLoading = false; await InvokeAsync(StateHasChanged); } + + string L(string key, string fallback) + { + var value = UiLocalizer[key]; + return value.ResourceNotFound ? fallback : value.Value; + } } diff --git a/EnvelopeGenerator.Server/EnvelopeGenerator.Server.Client/Program.cs b/EnvelopeGenerator.Server/EnvelopeGenerator.Server.Client/Program.cs index 88c85d23..015ccfbb 100644 --- a/EnvelopeGenerator.Server/EnvelopeGenerator.Server.Client/Program.cs +++ b/EnvelopeGenerator.Server/EnvelopeGenerator.Server.Client/Program.cs @@ -5,9 +5,17 @@ using DevExpress.Blazor.Reporting; using DevExpress.XtraReports.Web.Extensions; using DevExpress.DataAccess.Web; using DevExpress.XtraReports.Services; +using System.Globalization; var builder = WebAssemblyHostBuilder.CreateDefault(args); +var initialCulture = await ResolveInitialCultureAsync(builder.HostEnvironment.BaseAddress); +var cultureInfo = new CultureInfo(initialCulture); +CultureInfo.DefaultThreadCurrentCulture = cultureInfo; +CultureInfo.DefaultThreadCurrentUICulture = cultureInfo; + +builder.Services.AddLocalization(); + // Named HttpClient for API calls (both for services and DevExpress components) builder.Services.AddHttpClient("EnvelopeGenerator.Server", client => { @@ -67,3 +75,23 @@ ReportStorageWebExtension.RegisterExtensionGlobal(new InMemoryReportStorageWebEx var host = builder.Build(); await FontLoader.LoadFonts(host.Services.GetRequiredService(), new List { "opensans.ttf" }); await host.RunAsync(); + +static async Task ResolveInitialCultureAsync(string baseAddress) +{ + try + { + using var http = new HttpClient { BaseAddress = new Uri(baseAddress) }; + var response = await http.GetAsync("/api/Localization/lang"); + + if (!response.IsSuccessStatusCode) + return "de-DE"; + + var value = await response.Content.ReadAsStringAsync(); + var culture = value.Trim().Trim('"'); + return string.IsNullOrWhiteSpace(culture) ? "de-DE" : culture; + } + catch + { + return "de-DE"; + } +} diff --git a/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Components/Pages/EnvelopeSenderEditorPage.razor b/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Components/Pages/EnvelopeSenderEditorPage.razor index 347a307b..85a68a23 100644 --- a/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Components/Pages/EnvelopeSenderEditorPage.razor +++ b/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Components/Pages/EnvelopeSenderEditorPage.razor @@ -5,11 +5,13 @@ @using DevExpress.Blazor @using EnvelopeGenerator.Application.Common.Dto @using EnvelopeGenerator.Application.Envelopes.Commands +@using EnvelopeGenerator.Application.Resources @using EnvelopeGenerator.Server.Client.Services @using EnvelopeGenerator.Server.Services @using Microsoft.AspNetCore.WebUtilities @using Microsoft.AspNetCore.Components.Forms @using Microsoft.Extensions.Caching.Memory +@using Microsoft.Extensions.Localization @inject IJSRuntime JSRuntime @inject NavigationManager NavigationManager @inject AppVersionService AppVersion @@ -18,6 +20,7 @@ @inject EnvelopeService EnvelopeService @inject IEnvelopeAuthService EnvelopeAuthService @inject IMemoryCache MemoryCache +@inject IStringLocalizer UiLocalizer @@ -41,12 +44,12 @@
@if (_titleTouched && string.IsNullOrWhiteSpace(_envelopeTitle)) { - Pflichtfeld + @L("RequiredField", "Pflichtfeld") }
@@ -63,12 +66,12 @@
- @_signatureFields.Count Signaturfeld@(_signatureFields.Count != 1 ? "er" : "") + @_signatureFields.Count @L("SenderEditor_SignatureField", "Signaturfeld")@(_signatureFields.Count != 1 ? "er" : "") }
@@ -96,24 +99,24 @@
- Empfänger + @L("Receiver", "Empfänger") @_receivers.Count
@if (_receivers.Count == 0) {
- Noch keine Empfänger hinzugefügt. + @L("SenderEditor_NoReceiversAdded", "Noch keine Empfänger hinzugefügt.")
} else @@ -136,11 +139,11 @@ @(_pendingReceiverForPlacement?.Id == receiver.Id ? "pdf-toolbar__btn--signature-change-active" : "")" @onclick="() => ActivatePlacementForReceiver(receiver)" style="@(_pendingReceiverForPlacement?.Id == receiver.Id ? $"background:{receiver.Color};color:#fff;border-color:{receiver.Color};" : $"color:{receiver.Color};border-color:{receiver.Color};")" - title="Signaturfeld platzieren"> + title='@L("SenderEditor_PlaceSignatureField", "Signaturfeld platzieren")'> - Signatur hinzufügen + @L("SenderEditor_AddSignature", "Signatur hinzufügen")
} @@ -154,19 +157,19 @@ @* PDF Upload *@
@@ -229,10 +232,10 @@ {
- 📌 Klicken Sie auf die Stelle im Dokument für @_pendingReceiverForPlacement.FullName. + 📌 @L("SenderEditor_ClickDocumentFor", "Klicken Sie auf die Stelle im Dokument für") @_pendingReceiverForPlacement.FullName.  
} @@ -252,16 +255,16 @@ -
Kein Dokument geladen
+
@L("SenderEditor_NoDocumentLoaded", "Kein Dokument geladen")

- Laden Sie eine PDF-Datei hoch, um Signaturfelder zu platzieren. + @L("SenderEditor_UploadPdfToPlaceFields", "Laden Sie eine PDF-Datei hoch, um Signaturfelder zu platzieren.")

@@ -271,7 +274,7 @@ {
- Fehler: @_errorMessage + @L("Error", "Fehler"): @_errorMessage
} @@ -290,7 +293,7 @@
-
Vor- und Nachname
+
@L("FullName", "Vor- und Nachname")
-
Telefonnummer (optional)
+
@L("PhoneNumber", "Telefonnummer") (@L("Optional", "optional"))
-
E-Mail-Adresse
+
@L("EmailAddress", "E-Mail-Adresse")
- Bereits verwendete E-Mail-Adressen werden bei der Eingabe vorgeschlagen. + @L("SenderEditor_EmailSuggestionsHint", "Bereits verwendete E-Mail-Adressen werden bei der Eingabe vorgeschlagen.")
@if (_isReceiverEmailSearchRunning) { -
E-Mail-Vorschläge werden geladen…
+
@L("SenderEditor_EmailSuggestionsLoading", "E-Mail-Vorschläge werden geladen…")
} @if (!string.IsNullOrWhiteSpace(_receiverPopupValidationMessage)) @@ -363,10 +366,10 @@ @@ -375,7 +378,7 @@ @* ── Save result popup (success + error) ── *@

- Fehler beim Erstellen des Umschlags + @L("SenderEditor_ErrorCreatingEnvelope", "Fehler beim Erstellen des Umschlags")

@_saveErrorMessage @@ -430,7 +433,7 @@ @if (_saveNavigateToDashboard) @@ -439,7 +442,7 @@ @onclick="GoToDashboard" style="background:linear-gradient(135deg,#059669,#047857);border:none;border-radius:6px; padding:0.5rem 1.5rem;font-weight:600;color:#fff;"> - Zur Übersicht + @L("SenderEditor_ToOverview", "Zur Übersicht") } } @@ -448,7 +451,7 @@ }

@@ -653,7 +656,10 @@ catch (Exception ex) { Logger.LogError(ex, "Failed to load envelope {EnvelopeId} for edit mode", envelopeId); - _errorMessage = $"Fehler beim Laden des Umschlags #{envelopeId}: {ex.Message}"; + _errorMessage = string.Format( + L("SenderEditor_LoadEnvelopeError", "Fehler beim Laden des Umschlags #{0}: {1}"), + envelopeId, + ex.Message); } finally { @@ -670,7 +676,7 @@ if (!file.Name.EndsWith(".pdf", StringComparison.OrdinalIgnoreCase)) { - _errorMessage = "Bitte wählen Sie eine PDF-Datei aus."; + _errorMessage = L("SenderEditor_SelectPdf", "Bitte wählen Sie eine PDF-Datei aus."); return; } @@ -695,7 +701,9 @@ } catch (Exception ex) { - _errorMessage = $"Fehler beim Laden der Datei: {ex.Message}"; + _errorMessage = string.Format( + L("SenderEditor_LoadFileError", "Fehler beim Laden der Datei: {0}"), + ex.Message); Logger.LogError(ex, "Failed to load PDF file"); } } @@ -853,25 +861,25 @@ _titleTouched = true; if (!_pdfLoaded || _originalPdfBytes is null) { - _saveErrorMessage = "Bitte laden Sie zuerst ein PDF-Dokument hoch."; + _saveErrorMessage = L("SenderEditor_Validation_UploadPdf", "Bitte laden Sie zuerst ein PDF-Dokument hoch."); _savePopupVisible = true; return; } if (string.IsNullOrWhiteSpace(_envelopeTitle)) { - _saveErrorMessage = "Bitte geben Sie einen Titel ein."; + _saveErrorMessage = L("SenderEditor_Validation_TitleRequired", "Bitte geben Sie einen Titel ein."); _savePopupVisible = true; return; } if (_receivers.Count == 0) { - _saveErrorMessage = "Bitte fügen Sie mindestens einen Empfänger hinzu."; + _saveErrorMessage = L("SenderEditor_Validation_ReceiverRequired", "Bitte fügen Sie mindestens einen Empfänger hinzu."); _savePopupVisible = true; return; } if (_signatureFields.Count == 0) { - _saveErrorMessage = "Bitte platzieren Sie mindestens ein Signaturfeld."; + _saveErrorMessage = L("SenderEditor_Validation_SignatureFieldRequired", "Bitte platzieren Sie mindestens ein Signaturfeld."); _savePopupVisible = true; return; } @@ -916,9 +924,9 @@ // Success — show popup; GoToDashboard clears cache and navigates _saveErrorMessage = null; - _saveSuccessHeader = "Umschlag gesendet"; - _saveSuccessTitle = "Umschlag wurde erfolgreich gesendet."; - _saveSuccessBody = "Der bestehende Entwurf wurde versendet."; + _saveSuccessHeader = L("SenderEditor_Sent_Header", "Umschlag gesendet"); + _saveSuccessTitle = L("SenderEditor_Sent_Title", "Umschlag wurde erfolgreich gesendet."); + _saveSuccessBody = L("SenderEditor_Sent_Body", "Der bestehende Entwurf wurde versendet."); _saveNavigateToDashboard = true; _savePopupVisible = true; } @@ -1222,22 +1230,22 @@ if (string.IsNullOrWhiteSpace(fullName)) { - _receiverPopupValidationMessage = "Bitte geben Sie einen Vor- und Nachnamen ein."; + _receiverPopupValidationMessage = L("SenderEditor_Validation_FullNameRequired", "Bitte geben Sie einen Vor- und Nachnamen ein."); return Task.CompletedTask; } if (string.IsNullOrWhiteSpace(email)) { - _receiverPopupValidationMessage = "Bitte geben Sie eine E-Mail-Adresse ein."; + _receiverPopupValidationMessage = L("SenderEditor_Validation_EmailRequired", "Bitte geben Sie eine E-Mail-Adresse ein."); return Task.CompletedTask; } if (!ReceiverEmailValidator.IsValid(email)) { - _receiverPopupValidationMessage = "Bitte geben Sie eine gültige E-Mail-Adresse ein."; + _receiverPopupValidationMessage = L("SenderEditor_Validation_EmailInvalid", "Bitte geben Sie eine gültige E-Mail-Adresse ein."); return Task.CompletedTask; } if (_receivers.Any(r => string.Equals(r.Email, email, StringComparison.OrdinalIgnoreCase))) { - _receiverPopupValidationMessage = "Diese E-Mail-Adresse wurde bereits hinzugefügt."; + _receiverPopupValidationMessage = L("SenderEditor_Validation_EmailDuplicate", "Diese E-Mail-Adresse wurde bereits hinzugefügt."); return Task.CompletedTask; } @@ -1275,4 +1283,10 @@ "#BE185D", // pink "#65A30D", // lime ]; + + string L(string key, string fallback) + { + var value = UiLocalizer[key]; + return value.ResourceNotFound ? fallback : value.Value; + } } diff --git a/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Components/Pages/EnvelopeSenderPage.razor b/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Components/Pages/EnvelopeSenderPage.razor index 7b4e6cfb..c0adaed6 100644 --- a/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Components/Pages/EnvelopeSenderPage.razor +++ b/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Components/Pages/EnvelopeSenderPage.razor @@ -8,6 +8,7 @@ @using EnvelopeGenerator.Server.Client.Services @using EnvelopeGenerator.Application.Common.Dto @using EnvelopeGenerator.Application.Common.Dto.History +@using EnvelopeGenerator.Application.Resources @using EnvelopeGenerator.Domain.Resources @using EnvelopeGenerator.Server.Services @using Microsoft.Extensions.Localization @@ -23,6 +24,7 @@ @inject IJSRuntime JSRuntime @inject AppVersionService AppVersion @inject IStringLocalizer ModelLocalizer +@inject IStringLocalizer UiLocalizer @@ -70,29 +72,29 @@ @* ── Toolbar (rechts) ─────────────────────────────────────────── *@
- - - - - -
- @@ -121,15 +123,15 @@
-
@@ -196,14 +198,14 @@
@@ -67,9 +70,9 @@
- Lädt... + @L("Loading", "Lädt...")
-

Dokument wird geladen...

+

@L("DocumentLoading", "Dokument wird geladen...")

} @@ -83,7 +86,7 @@
-
Fehler
+
@L("Error", "Fehler")

@_errorMessage

@@ -99,7 +102,7 @@ @* Submit confirmation popup *@

- Möchten Sie das Dokument verbindlich unterschreiben? + @L("ReceiverSigned_ConfirmQuestion", "Möchten Sie das Dokument verbindlich unterschreiben?")

- Diese Aktion kann nicht rückgängig gemacht werden. Mit der Bestätigung erklären Sie, das oben angezeigte Dokument elektronisch unterzeichnet zu haben. Das unterzeichnete Dokument wird anschließend an alle beteiligten Parteien übermittelt. + @L("ReceiverSigned_ConfirmBody", "Diese Aktion kann nicht rückgängig gemacht werden. Mit der Bestätigung erklären Sie, das oben angezeigte Dokument elektronisch unterzeichnet zu haben. Das unterzeichnete Dokument wird anschließend an alle beteiligten Parteien übermittelt.")

@@ -128,7 +131,7 @@
@@ -178,7 +181,7 @@ { if (string.IsNullOrWhiteSpace(EnvelopeKey)) { - _errorMessage = "Envelope-Schlüssel fehlt."; + _errorMessage = L("ReceiverSigned_EnvelopeKeyMissing", "Envelope-Schlüssel fehlt."); _isLoading = false; return; } @@ -215,7 +218,7 @@ var pdfBytes = await PageDataService.GetDocumentOfReceiverAsync(_receiverUser); if (pdfBytes is not { Length: > 0 }) { - _errorMessage = "Dokument konnte nicht geladen werden."; + _errorMessage = L("DocumentCouldNotBeLoaded", "Dokument konnte nicht geladen werden."); _isLoading = false; return; } @@ -244,7 +247,7 @@ } catch (Exception ex) { - _errorMessage = $"Fehler: {ex.Message}"; + _errorMessage = string.Format(L("ErrorWithReason", "Fehler: {0}"), ex.Message); Logger.LogError(ex, "Error loading signed page for {EnvelopeKey}", EnvelopeKey); } @@ -393,4 +396,10 @@ if (comma < 0) return null; return Convert.FromBase64String(dataUrl[(comma + 1)..]); } + + string L(string key, string fallback) + { + var value = UiLocalizer[key]; + return value.ResourceNotFound ? fallback : value.Value; + } }