From bc343177208fd693db4592ad955cc647e82f2b17 Mon Sep 17 00:00:00 2001 From: TekH Date: Wed, 1 Jul 2026 11:12:16 +0200 Subject: [PATCH 1/6] Adjust signature box layout and add background color Updated the signature box proportions by adjusting `imgRatio` to 52% and `textRatio` to 43%. Added a cream-tone background with extra padding (`bgPad`) and rendered it behind the signature content. Tightened gaps between the image, separator line, and text area. Increased text row height slightly for better spacing. --- .../EnvelopeReceiverReportSignedPage.razor | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Components/Pages/EnvelopeReceiverReportSignedPage.razor b/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Components/Pages/EnvelopeReceiverReportSignedPage.razor index 120de638..b4eaec17 100644 --- a/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Components/Pages/EnvelopeReceiverReportSignedPage.razor +++ b/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Components/Pages/EnvelopeReceiverReportSignedPage.razor @@ -208,13 +208,18 @@ const double sigW = 1.77 * 72; // 127.44 pt const double sigH = 1.96 * 72; // 141.12 pt - const double imgRatio = 0.60; // top 60% = image - const double textRatio = 0.38; // bottom 38% = text (2% padding) + const double imgRatio = 0.52; // top 52% = image (was 0.60) + const double textRatio = 0.43; // bottom 43% = text (was 0.38) var black = PdfSharp.Drawing.XColor.FromArgb(255, 20, 20, 20); var darkGray = PdfSharp.Drawing.XColor.FromArgb(255, 80, 80, 80); var lineColor = PdfSharp.Drawing.XColor.FromArgb(180, 100, 100, 120); + // Background: paper/cream tone, no border + var bgColor = PdfSharp.Drawing.XColor.FromArgb(255, 255, 253, 240); + var bgBrush = new PdfSharp.Drawing.XSolidBrush(bgColor); + const double bgPad = 3.0; // extra padding around the signature box (pt) + var fontBold = new PdfSharp.Drawing.XFont("Arial", 7.5, PdfSharp.Drawing.XFontStyleEx.Bold); var fontNormal = new PdfSharp.Drawing.XFont("Arial", 6.5, PdfSharp.Drawing.XFontStyleEx.Regular); var linePen = new PdfSharp.Drawing.XPen(lineColor, 0.5); @@ -239,6 +244,10 @@ double x = field.X; double y = field.Y; + // --- Background rectangle (drawn first, sits between PDF and signature) --- + var bgRect = new PdfSharp.Drawing.XRect(x - bgPad, y - bgPad, sigW + bgPad * 2, sigH + bgPad * 2); + gfx.DrawRectangle(bgBrush, bgRect); + // --- Image area --- double imgH = sigH * imgRatio; var imgRect = new PdfSharp.Drawing.XRect(x, y, sigW, imgH); @@ -248,13 +257,13 @@ gfx.DrawImage(xImg, imgRect); // --- Separator line --- - double lineY = y + imgH + sigH * 0.01; + double lineY = y + imgH + sigH * 0.005; // was 0.01 — tighter gap after image gfx.DrawLine(linePen, x + 2, lineY, x + sigW - 2, lineY); // --- Text area --- - double textY = lineY + 2; + double textY = lineY + 1; // was +2 — tighter gap below line double textH = sigH * textRatio; - double lineH = textH / 3.5; // max 3 text rows + double lineH = textH / 3.0; // was /3.5 — rows closer together double padding = 3; // Row 1: FullName (bold) From 789e312316e4014cfaa4304017d55608b523d3f5 Mon Sep 17 00:00:00 2001 From: TekH Date: Wed, 1 Jul 2026 11:38:07 +0200 Subject: [PATCH 2/6] Refactor signature box layout and improve readability Refactored the signature box layout to dynamically calculate positions based on content, improving flexibility and precision. Introduced new constants (`lineH`, `bgPad`) to standardize spacing and replaced hardcoded values for better maintainability. Adjusted background rectangle sizing to fit content dynamically and improved text layout logic to handle optional fields more gracefully. Simplified image area logic and reduced redundant calculations. Overall, improved code readability and alignment for a cleaner, more compact layout. --- .../EnvelopeReceiverReportSignedPage.razor | 53 +++++++++++-------- 1 file changed, 30 insertions(+), 23 deletions(-) diff --git a/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Components/Pages/EnvelopeReceiverReportSignedPage.razor b/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Components/Pages/EnvelopeReceiverReportSignedPage.razor index b4eaec17..65e1a3a2 100644 --- a/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Components/Pages/EnvelopeReceiverReportSignedPage.razor +++ b/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Components/Pages/EnvelopeReceiverReportSignedPage.razor @@ -206,19 +206,18 @@ var document = PdfSharp.Pdf.IO.PdfReader.Open( inputMs, PdfSharp.Pdf.IO.PdfDocumentOpenMode.Modify); - const double sigW = 1.77 * 72; // 127.44 pt - const double sigH = 1.96 * 72; // 141.12 pt - const double imgRatio = 0.52; // top 52% = image (was 0.60) - const double textRatio = 0.43; // bottom 43% = text (was 0.38) + const double sigW = 1.77 * 72; // 127.44 pt + const double sigH = 1.96 * 72; // 141.12 pt + const double imgRatio = 0.52; // top 52% = image + const double lineH = 11.5; // fixed row height matching font size (bold 7.5pt + normal 6.5pt) + const double bgPad = 3.0; // background box padding around content (pt) var black = PdfSharp.Drawing.XColor.FromArgb(255, 20, 20, 20); var darkGray = PdfSharp.Drawing.XColor.FromArgb(255, 80, 80, 80); var lineColor = PdfSharp.Drawing.XColor.FromArgb(180, 100, 100, 120); - // Background: paper/cream tone, no border var bgColor = PdfSharp.Drawing.XColor.FromArgb(255, 255, 253, 240); var bgBrush = new PdfSharp.Drawing.XSolidBrush(bgColor); - const double bgPad = 3.0; // extra padding around the signature box (pt) var fontBold = new PdfSharp.Drawing.XFont("Arial", 7.5, PdfSharp.Drawing.XFontStyleEx.Bold); var fontNormal = new PdfSharp.Drawing.XFont("Arial", 6.5, PdfSharp.Drawing.XFontStyleEx.Regular); @@ -244,44 +243,52 @@ double x = field.X; double y = field.Y; - // --- Background rectangle (drawn first, sits between PDF and signature) --- - var bgRect = new PdfSharp.Drawing.XRect(x - bgPad, y - bgPad, sigW + bgPad * 2, sigH + bgPad * 2); + // --- Calculate layout positions first (needed for bg rect) --- + double imgH = sigH * imgRatio; + double lineY = y + imgH + 1.0; // 1pt gap between image and separator + double textY = lineY + 1.5; // 1.5pt gap below separator line + double padding = 3; + + // Row 1: FullName + double row1Y = textY; + // Row 2: Position (optional) + double row2Y = row1Y + lineH; + // Row 3: Place, Date — immediately after row2 regardless of position + double row3Y = !string.IsNullOrWhiteSpace(sig.Position) ? row2Y + lineH : row2Y; + double contentBottom = row3Y + lineH; + + // --- Background rectangle sized to actual content (not full sigH) --- + var bgRect = new PdfSharp.Drawing.XRect( + x - bgPad, + y - bgPad, + sigW + bgPad * 2, + (contentBottom - y) + bgPad * 2); gfx.DrawRectangle(bgBrush, bgRect); // --- Image area --- - double imgH = sigH * imgRatio; - var imgRect = new PdfSharp.Drawing.XRect(x, y, sigW, imgH); - + var imgRect = new PdfSharp.Drawing.XRect(x, y, sigW, imgH); using var imgStream = new System.IO.MemoryStream(imgBytes); var xImg = PdfSharp.Drawing.XImage.FromStream(imgStream); gfx.DrawImage(xImg, imgRect); // --- Separator line --- - double lineY = y + imgH + sigH * 0.005; // was 0.01 — tighter gap after image gfx.DrawLine(linePen, x + 2, lineY, x + sigW - 2, lineY); - // --- Text area --- - double textY = lineY + 1; // was +2 — tighter gap below line - double textH = sigH * textRatio; - double lineH = textH / 3.0; // was /3.5 — rows closer together - double padding = 3; - + // --- Text rows --- // Row 1: FullName (bold) - var nameRect = new PdfSharp.Drawing.XRect(x + padding, textY, sigW - padding * 2, lineH); + var nameRect = new PdfSharp.Drawing.XRect(x + padding, row1Y, sigW - padding * 2, lineH); gfx.DrawString(sig.FullName, fontBold, new PdfSharp.Drawing.XSolidBrush(black), nameRect, fmtLeft); // Row 2: Position (optional) - double row2Y = textY + lineH; if (!string.IsNullOrWhiteSpace(sig.Position)) { var posRect = new PdfSharp.Drawing.XRect(x + padding, row2Y, sigW - padding * 2, lineH); gfx.DrawString(sig.Position, fontNormal, new PdfSharp.Drawing.XSolidBrush(darkGray), posRect, fmtLeft); - row2Y += lineH; } - // Row 3 (or 2 if no position): Place, Date + // Row 3: Place, Date var placeDate = $"{sig.Place}, {date}"; - var dateRect = new PdfSharp.Drawing.XRect(x + padding, row2Y, sigW - padding * 2, lineH); + var dateRect = new PdfSharp.Drawing.XRect(x + padding, row3Y, sigW - padding * 2, lineH); gfx.DrawString(placeDate, fontNormal, new PdfSharp.Drawing.XSolidBrush(darkGray), dateRect, fmtLeft); } From 47bc7675c9007bb123ffe0f42ff7954834193e89 Mon Sep 17 00:00:00 2001 From: TekH Date: Wed, 1 Jul 2026 11:47:09 +0200 Subject: [PATCH 3/6] Handle cache miss and redirect in SignedPage Added a check for `_sig` being `null` to handle cache misses or missing `sid`. Logged a warning with `Sid` and `EnvelopeKey` details when this occurs. Implemented a redirection to the report page (`/envelope/{EnvelopeKey}/report`) using `Navigation.NavigateTo` with `forceLoad: true`. Added an early return to prevent further execution after redirection. --- .../Pages/EnvelopeReceiverReportSignedPage.razor | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Components/Pages/EnvelopeReceiverReportSignedPage.razor b/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Components/Pages/EnvelopeReceiverReportSignedPage.razor index 65e1a3a2..7ab5aca2 100644 --- a/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Components/Pages/EnvelopeReceiverReportSignedPage.razor +++ b/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Components/Pages/EnvelopeReceiverReportSignedPage.razor @@ -120,6 +120,18 @@ _sig = cached; } + // Cache miss or missing sid — redirect back to report page + if (_sig is null) + { + Logger.LogWarning( + "[SignedPage] Cache miss or no sid={Sid} for {EnvelopeKey}, redirecting to report page.", + Sid, EnvelopeKey); + Navigation.NavigateTo( + $"/envelope/{Uri.EscapeDataString(EnvelopeKey)}/report", + forceLoad: true); + return; + } + try { var pdfBytes = await PageDataService.GetDocumentAsync(_receiverUser); From e6722803bb18aac79c21f443581a8e806b74c5c1 Mon Sep 17 00:00:00 2001 From: TekH Date: Wed, 1 Jul 2026 12:36:50 +0200 Subject: [PATCH 4/6] Add submit confirmation popup and logout functionality Added dependency injection for `AuthService`, `ReceiverAuthorizationService`, `PageDataService`, and `Logger` to enable their usage in the component. Introduced a "Submit" button in the UI to confirm the signing process and complete the workflow. Implemented a `DxPopup` component to display a confirmation dialog when the "Submit" button is clicked. The popup includes a message about the successful signing of the document and asks the user to confirm whether to complete the process and log out. Added state variables `_isLoggingOut` and `_submitConfirmVisible` to manage the popup visibility and logout process. Created `OpenSubmitConfirmPopup` to toggle the popup and `SubmitAndLogoutAsync` to handle the submission process, including logging out via `AuthService` and navigating to the login page. Updated the `@code` block with the new state variables and methods for managing the submit and logout functionality. --- .../EnvelopeReceiverReportSignedPage.razor | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Components/Pages/EnvelopeReceiverReportSignedPage.razor b/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Components/Pages/EnvelopeReceiverReportSignedPage.razor index 7ab5aca2..fe426150 100644 --- a/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Components/Pages/EnvelopeReceiverReportSignedPage.razor +++ b/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Components/Pages/EnvelopeReceiverReportSignedPage.razor @@ -9,6 +9,7 @@ @using System.Security.Claims @inject NavigationManager Navigation @inject IJSRuntime JSRuntime +@inject EnvelopeGenerator.Server.Client.Services.AuthService AuthService @inject EnvelopeGenerator.Server.Services.EnvelopeReceiverAuthorizationService ReceiverAuthorizationService @inject EnvelopeGenerator.Server.Services.EnvelopeReceiverPageDataService PageDataService @inject AppVersionService AppVersion @@ -42,6 +43,20 @@
Signiertes Dokument
} + + @* Right: Submit button *@ +
+ +
@@ -82,6 +97,53 @@ +@* Submit confirmation popup *@ + + +
+
+ + + +
+
+

+ Dokument erfolgreich unterschrieben +

+

+ Ihre Unterschrift wurde auf dem Dokument platziert. Möchten Sie den Vorgang abschließen und sich abmelden? +

+
+
+
+ +
+ + +
+
+
+ @code { [Parameter] public string? EnvelopeKey { get; set; } @@ -96,6 +158,24 @@ XtraReport? _report; SignatureCaptureDto? _sig; + // ----- Submit / logout state ----- + bool _isLoggingOut = false; + bool _submitConfirmVisible = false; + + void OpenSubmitConfirmPopup() => _submitConfirmVisible = true; + + async Task SubmitAndLogoutAsync() + { + if (_isLoggingOut) return; + _isLoggingOut = true; + _submitConfirmVisible = false; + await InvokeAsync(StateHasChanged); + await AuthService.LogoutEnvelopeReceiverAsync(EnvelopeKey!); + Navigation.NavigateTo( + $"/envelope/login/{Uri.EscapeDataString(EnvelopeKey!)}", + forceLoad: true); + } + protected override async Task OnInitializedAsync() { if (string.IsNullOrWhiteSpace(EnvelopeKey)) From 278b9964f197cf36e1a84f2987f0a5fe2ff8cd16 Mon Sep 17 00:00:00 2001 From: TekH Date: Wed, 1 Jul 2026 12:56:51 +0200 Subject: [PATCH 5/6] Update signing confirmation text and logout navigation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The user-facing text in `EnvelopeReceiverReportSignedPage.razor` has been updated to provide a more detailed and formal confirmation message for signing a document. - Replaced "Dokument erfolgreich unterschrieben" with "Möchten Sie das Dokument verbindlich unterschreiben?". - Updated the follow-up message to clarify the irreversibility of the action and the electronic signing process. Additionally, the logout navigation behavior has been modified: - Changed the post-logout redirect from `/envelope/login/{EnvelopeKey}` to the root page (`/`), while retaining the `forceLoad` parameter. --- .../Pages/EnvelopeReceiverReportSignedPage.razor | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Components/Pages/EnvelopeReceiverReportSignedPage.razor b/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Components/Pages/EnvelopeReceiverReportSignedPage.razor index fe426150..eed5d77d 100644 --- a/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Components/Pages/EnvelopeReceiverReportSignedPage.razor +++ b/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Components/Pages/EnvelopeReceiverReportSignedPage.razor @@ -115,10 +115,10 @@

- Dokument erfolgreich unterschrieben + Möchten Sie das Dokument verbindlich unterschreiben?

- Ihre Unterschrift wurde auf dem Dokument platziert. Möchten Sie den Vorgang abschließen und sich abmelden? + 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.

@@ -171,9 +171,7 @@ _submitConfirmVisible = false; await InvokeAsync(StateHasChanged); await AuthService.LogoutEnvelopeReceiverAsync(EnvelopeKey!); - Navigation.NavigateTo( - $"/envelope/login/{Uri.EscapeDataString(EnvelopeKey!)}", - forceLoad: true); + Navigation.NavigateTo("/", forceLoad: true); } protected override async Task OnInitializedAsync() From d94821433ad9c0b4afcb1106cdb87523d3b6cf07 Mon Sep 17 00:00:00 2001 From: TekH Date: Wed, 1 Jul 2026 12:58:25 +0200 Subject: [PATCH 6/6] Enable WebAssembly mode and add blazing-berry theme Added the `@rendermode InteractiveWebAssembly` directive to `IndexPage.razor` to enable interactive WebAssembly rendering. Included a `` element to reference the `blazing-berry.bs5.min.css` stylesheet from the `DevExpress.Blazor.Themes` content folder to apply the "blazing-berry" theme for enhanced styling. --- .../EnvelopeGenerator.Server.Client/Pages/IndexPage.razor | 1 + 1 file changed, 1 insertion(+) diff --git a/EnvelopeGenerator.Server/EnvelopeGenerator.Server.Client/Pages/IndexPage.razor b/EnvelopeGenerator.Server/EnvelopeGenerator.Server.Client/Pages/IndexPage.razor index be0953ea..ec1d8c86 100644 --- a/EnvelopeGenerator.Server/EnvelopeGenerator.Server.Client/Pages/IndexPage.razor +++ b/EnvelopeGenerator.Server/EnvelopeGenerator.Server.Client/Pages/IndexPage.razor @@ -1,5 +1,6 @@ @page "/" @inject IJSRuntime JS +@rendermode InteractiveWebAssembly