diff --git a/EnvelopeGenerator.Server/EnvelopeGenerator.Server.Client/Components/Sender/CreateEnvelopeWizardPopup.razor b/EnvelopeGenerator.Server/EnvelopeGenerator.Server.Client/Components/Sender/CreateEnvelopeWizardPopup.razor index e7a639ff..545ef8b0 100644 --- a/EnvelopeGenerator.Server/EnvelopeGenerator.Server.Client/Components/Sender/CreateEnvelopeWizardPopup.razor +++ b/EnvelopeGenerator.Server/EnvelopeGenerator.Server.Client/Components/Sender/CreateEnvelopeWizardPopup.razor @@ -9,6 +9,7 @@ @inject IStringLocalizer ModelLocalizer @inject IStringLocalizer UiLocalizer @inject ReceiverService ReceiverService +@inject PdfRenderService PdfRenderService -
@_documentFileName
-
@_documentSizeText
+
+
+
@_documentFileName
+
@_documentSizeText
+
+
+ +
} else @@ -331,10 +345,14 @@ private byte[]? _documentBytes; private string? _documentFileName; private string _documentSizeText = string.Empty; + private int _documentPreviewPageCount; + private List _documentPreviewPages = []; private bool _isDocumentUploading; private bool _isStepActionRunning; private bool _isFinishing; + private readonly IReadOnlyList _documentPreviewFieldOverlays = []; + private string? _validationMessage; private bool IsActionLocked => _isDocumentUploading || _isStepActionRunning || _isFinishing; @@ -346,6 +364,10 @@ private IReadOnlyList FilteredRecentSuggestions => BuildFilteredRecentSuggestions(); + private string? DocumentPreviewDataUrl => _documentBytes is { Length: > 0 } + ? $"data:application/pdf;base64,{Convert.ToBase64String(_documentBytes)}" + : null; + private string CurrentStepTitle => _currentStep switch { 0 => L("SenderWizard_Step_Basics", "Grunddaten"), @@ -525,6 +547,22 @@ _documentBytes = ms.ToArray(); _documentFileName = file.Name; _documentSizeText = FormatSize(_documentBytes.Length); + + _documentPreviewPages = []; + try + { + _documentPreviewPages = (await PdfRenderService.RenderPagesAsync(_documentBytes)) + .OrderBy(x => x.PageNumber) + .ToList(); + } + catch + { + _documentPreviewPages = []; + } + + _documentPreviewPageCount = _documentPreviewPages.Count > 0 + ? _documentPreviewPages.Count + : EstimatePdfPageCount(_documentBytes) ?? 1; } finally { @@ -771,6 +809,51 @@ return $"{bytes} B"; } + private static int? EstimatePdfPageCount(byte[]? documentBytes) + { + if (documentBytes is null || documentBytes.Length == 0) + return null; + + try + { + var text = System.Text.Encoding.ASCII.GetString(documentBytes); + const string marker = "/Type /Page"; + var count = 0; + var index = 0; + + while (true) + { + index = text.IndexOf(marker, index, StringComparison.Ordinal); + if (index < 0) + break; + + count++; + index += marker.Length; + } + + return count > 0 ? count : null; + } + catch + { + return null; + } + } + + private Task OnDocumentPreviewEditorClickAsync(MouseEventArgs _) + { + return Task.CompletedTask; + } + + private Task OnDocumentPreviewRemoveFieldAsync(int _) + { + return Task.CompletedTask; + } + + private Task OnDocumentPreviewMoveFieldAsync(SenderPdfFieldMoveRequest _) + { + return Task.CompletedTask; + } + private void ResetWizardState() { _currentStep = 0; @@ -792,6 +875,8 @@ _documentBytes = null; _documentFileName = null; _documentSizeText = string.Empty; + _documentPreviewPageCount = 0; + _documentPreviewPages = []; } private int? GetDefaultEnvelopeTypeId() diff --git a/EnvelopeGenerator.Server/EnvelopeGenerator.Server/wwwroot/css/sender-page.css b/EnvelopeGenerator.Server/EnvelopeGenerator.Server/wwwroot/css/sender-page.css index 3bac4f22..318bcadc 100644 --- a/EnvelopeGenerator.Server/EnvelopeGenerator.Server/wwwroot/css/sender-page.css +++ b/EnvelopeGenerator.Server/EnvelopeGenerator.Server/wwwroot/css/sender-page.css @@ -1533,6 +1533,28 @@ padding: 0.55rem 0.7rem; } +.sender-create-wizard__document-preview-card { + display: flex; + flex-direction: column; + gap: 0.65rem; +} + +.sender-create-wizard__document-preview-wrap { + border: 1px solid rgba(148, 163, 184, 0.38); + border-radius: 10px; + background: rgba(248, 250, 252, 0.96); + height: 320px; + overflow: hidden; +} + +.sender-create-wizard__document-preview-wrap .sender-image-editor-shell { + height: 100%; +} + +.sender-create-wizard__document-preview-wrap .sender-image-editor { + min-height: 0; +} + .sender-create-wizard__document-name { color: #064e3b; font-size: 0.85rem;