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 diff --git a/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Components/Pages/EnvelopeReceiverReportSignedPage.razor b/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Components/Pages/EnvelopeReceiverReportSignedPage.razor index 120de638..eed5d77d 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 *@ + + +
+
+ + + +
+
+

+ 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. +

+
+
+
+ +
+ + +
+
+
+ @code { [Parameter] public string? EnvelopeKey { get; set; } @@ -96,6 +158,22 @@ 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("/", forceLoad: true); + } + protected override async Task OnInitializedAsync() { if (string.IsNullOrWhiteSpace(EnvelopeKey)) @@ -120,6 +198,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); @@ -206,15 +296,19 @@ 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.60; // top 60% = image - const double textRatio = 0.38; // bottom 38% = text (2% padding) + 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); + var bgColor = PdfSharp.Drawing.XColor.FromArgb(255, 255, 253, 240); + var bgBrush = new PdfSharp.Drawing.XSolidBrush(bgColor); + 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,40 +333,52 @@ double x = field.X; double y = field.Y; - // --- Image area --- - double imgH = sigH * imgRatio; - var imgRect = new PdfSharp.Drawing.XRect(x, y, sigW, imgH); + // --- 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 --- + 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.01; gfx.DrawLine(linePen, x + 2, lineY, x + sigW - 2, lineY); - // --- Text area --- - double textY = lineY + 2; - double textH = sigH * textRatio; - double lineH = textH / 3.5; // max 3 text rows - 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); }