diff --git a/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Components/Pages/Test/EnvelopeReceiverPage.razor b/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Components/Pages/Test/EnvelopeReceiverPage.razor deleted file mode 100644 index 0f591a24..00000000 --- a/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Components/Pages/Test/EnvelopeReceiverPage.razor +++ /dev/null @@ -1,1207 +0,0 @@ -@page "/envelope/{EnvelopeKey}/deprc" -@rendermode InteractiveServer -@using EnvelopeGenerator.Server.Client.Models -@using EnvelopeGenerator.Server.Client.Models.Constants -@using EnvelopeGenerator.Server.Client.Services -@using EnvelopeGenerator.Application.Common.Dto.EnvelopeReceiver -@using System.Security.Claims -@using Microsoft.Extensions.Options -@using EnvelopeGenerator.Server.Client.Options -@using Microsoft.JSInterop -@using DevExpress.Blazor -@inject NavigationManager Navigation -@inject IOptions PdfViewerOptions -@inject IJSRuntime JSRuntime -@inject EnvelopeGenerator.Server.Client.Services.AuthService AuthService -@inject AppVersionService AppVersion -@inject EnvelopeGenerator.Server.Services.EnvelopeReceiverAuthorizationService ReceiverAuthorizationService -@inject EnvelopeGenerator.Server.Services.EnvelopeReceiverPageDataService PageDataService -@inject ILogger logger -@implements IAsyncDisposable - - - - - - - - -
-
-
- @* Row 1: Title + Sender + Badges + Logout *@ -
- @* Left: Title + Sender *@ -
- @if (_envelopeReceiver is not null) - { -
- @(_envelopeReceiver.Envelope?.Title ?? "Dokument") -
- @if (!string.IsNullOrWhiteSpace(_envelopeReceiver.Envelope?.User?.FullName) || !string.IsNullOrWhiteSpace(_envelopeReceiver.Envelope?.User?.Email)) - { - - Von - @if (!string.IsNullOrWhiteSpace(_envelopeReceiver.Envelope?.User?.FullName)) - { - @_envelopeReceiver.Envelope.User.FullName - } - @if (!string.IsNullOrWhiteSpace(_envelopeReceiver.Envelope?.User?.Email)) - { - <@_envelopeReceiver.Envelope.User.Email> - } - @if (_envelopeReceiver.Envelope?.AddedWhen != null) - { -  · @_envelopeReceiver.Envelope.AddedWhen.ToString("dd.MM.yyyy") - } - - } - } - else - { -
Dokumentenansicht
- } -
- - @* Right: Badges + Logout *@ -
- @if (_envelopeReceiver is not null) - { -
- @if (!string.IsNullOrWhiteSpace(_envelopeReceiver.Name)) - { - - - - - @_envelopeReceiver.Name - - } - @if (!string.IsNullOrWhiteSpace(_envelopeReceiver.Envelope?.User?.FullName)) - { - - Von @_envelopeReceiver.Envelope.User.FullName - - } - @{ - int sigCount = _signatures.Count; - } - @if (sigCount > 0) - { - - - - - @sigCount - - } - @if (_envelopeReceiver.Envelope?.UseAccessCode ?? false) - { - - - - - Code - - } - @if (_envelopeReceiver.Envelope?.TFAEnabled ?? false) - { - - - - - - 2FA - - } -
- - } - - @* Logout button *@ - @if (!string.IsNullOrWhiteSpace(EnvelopeKey)) - { - - } -
-
- - @* Row 2: Messages (visible text) *@ - @if (_envelopeReceiver is not null && (!string.IsNullOrWhiteSpace(_envelopeReceiver.Envelope?.Message) || !string.IsNullOrWhiteSpace(_envelopeReceiver.PrivateMessage))) - { -
- @if (!string.IsNullOrWhiteSpace(_envelopeReceiver.Envelope?.Message)) - { -
- 📧 - @_envelopeReceiver.Envelope.Message -
- } - @if (!string.IsNullOrWhiteSpace(_envelopeReceiver.PrivateMessage)) - { -
- 🔒 - @_envelopeReceiver.PrivateMessage -
- } -
- } -
-
- -
- @if (_isLoading) - { -
-
-
- L�dt... -
-

Dokument wird geladen...

-
-
- } - else if (_errorMessage is not null) - { -
-
-
- - - - -
-
Fehler beim Laden des Dokuments
-

@_errorMessage

-
-
-
-
- } - else if (!string.IsNullOrWhiteSpace(_pdfDataUrl)) - { -
- @if (_pdfLoaded) - { -
-
- -
- -
- -
- -
- - / @_totalPages -
- -
- -
- -
- -
- -
@(_currentZoom)%
-
- -
- -
- - @if (_totalSignatures > 0) - { -
- -
- -
- -
- - -
- - - - - @if (_currentSignatureIndex > 0) - { - #@_currentSignatureIndex - | - } - @_signedSignatures -  /  - @_totalSignatures - - @if (_unsignedSignatures > 0) - { - @_unsignedSignatures offen - } - else - { - ✓ Komplett - } -
- - -
- -
- - @* Reset button - only show when signatures are signed *@ - @if (_signedSignatures > 0) - { -
- -
- } - } -
- } -
- @if (_pdfLoaded && _showThumbnails) - { - -
-
- @for (int i = 1; i <= _totalPages; i++) - { - var pageNum = i; -
-
- -
-
@pageNum
-
- } -
-
- -
-
- } -
-
- -
-
-
-
-
-
- } - else - { -
-
-
- - - - Dokument konnte nicht geladen werden. -
-
-
- } -
-
- - - - - - @if (_activeSignatureTab == SignatureTabDraw) - { -

Bitte unterschreiben Sie im folgenden Feld.

- - } - else if (_activeSignatureTab == SignatureTabText) - { -

Geben Sie Ihre Unterschrift als Text ein und wählen Sie eine Schriftart.

-
-
- -
-
- -
-
- - } - else - { -

Laden Sie ein Bild Ihrer Unterschrift hoch.

- - - } - -
-
-
- - -
-
- - -
-
- - -
-
-
- - @if (!string.IsNullOrWhiteSpace(_popupValidationMessage)) - { -
- @_popupValidationMessage -
- } -
- -
- - -
-
-
- -@code { - // Signature tab constants - const string SignatureTabDraw = "draw"; - const string SignatureTabText = "text"; - const string SignatureTabImage = "image"; - const string DrawCanvasId = "envelope-signature-pad"; - const string TypedCanvasId = "envelope-typed-signature-pad"; - const string ImageInputId = "envelope-signature-image-input"; - const string ImageCanvasId = "envelope-image-signature-pad"; - - readonly (string Text, string Value)[] TypedSignatureFonts = { - ("Brush Script", "'Brush Script MT', cursive"), - ("Segoe Script", "'Segoe Script', cursive"), - ("Lucida Handwriting", "'Lucida Handwriting', cursive"), - ("Comic Sans", "'Comic Sans MS', cursive"), - ("Cursive", "cursive") -}; - - [Parameter] public string? EnvelopeKey { get; set; } - - bool _isLoading = true; - string? _errorMessage; - string? _pdfDataUrl; - bool _pdfLoaded = false; - int _currentPage = 1; - int _totalPages = 0; - int _currentZoom = 150; - bool _showThumbnails = true; - bool _isLoggingOut = false; - DotNetObjectReference? _dotNetRef; - IReadOnlyList _signatures = []; - EnvelopeGenerator.Application.Common.Dto.EnvelopeReceiver.EnvelopeReceiverDto? _envelopeReceiver; - ClaimsPrincipal? _receiverUser; - - // Signature navigation state - int _totalSignatures = 0; - int _signedSignatures = 0; - int _unsignedSignatures = 0; - int _currentSignatureIndex = 0; // Current signature index (1-based) - - // Signature state - SignatureCaptureDto? _capturedSignature; - bool _signaturePopupVisible = false; - string? _popupValidationMessage; - string _activeSignatureTab = SignatureTabDraw; - string _typedSignatureText = string.Empty; - string _typedSignatureFont = "'Brush Script MT', cursive"; - string _signerFullName = string.Empty; - string _signerPosition = string.Empty; - string _signaturePlace = string.Empty; - - // Resizable splitter state - int _thumbnailWidth = 260; - bool _isResizing = false; - int _resizeStartX = 0; - int _resizeStartWidth = 0; - const int MinThumbnailWidth = 150; - const int MaxThumbnailWidth = 400; - - async Task LogoutAsync() - { - if (string.IsNullOrWhiteSpace(EnvelopeKey) || _isLoggingOut) return; - _isLoggingOut = true; - 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)) - { - _errorMessage = "Envelope-Schlüssel fehlt."; - _isLoading = false; - return; - } - - _receiverUser = await ReceiverAuthorizationService.AuthorizeAsync(EnvelopeKey); - if (_receiverUser is null) - { - Navigation.NavigateTo($"/envelope/login/{Uri.EscapeDataString(EnvelopeKey)}"); - return; - } - - try - { - var pdfBytes = await PageDataService.GetDocumentOfReceiverAsync(_receiverUser); - - if (pdfBytes is { Length: > 0 }) - { - var base64 = Convert.ToBase64String(pdfBytes); - _pdfDataUrl = $"data:application/pdf;base64,{base64}"; - } - else - { - _errorMessage = "Dokument konnte nicht geladen werden: Keine Daten empfangen."; - } - - _signatures = await PageDataService.GetSignaturesAsync(_receiverUser); - - _envelopeReceiver = await PageDataService.GetEnvelopeReceiverAsync(EnvelopeKey); - if (_envelopeReceiver is null) - { - logger.LogWarning("Envelope receiver data is null for envelope {EnvelopeKey}", EnvelopeKey); - } - - logger.LogInformation("Loaded {SignatureCount} signatures for envelope {EnvelopeKey}", _signatures.Count, EnvelopeKey); - - // Try to load cached signature first - try - { - var cachedSignature = await PageDataService.GetCachedSignatureAsync(_receiverUser); - if (cachedSignature is not null) - { - _capturedSignature = cachedSignature; - _signerFullName = cachedSignature.FullName; - _signerPosition = cachedSignature.Position; - _signaturePlace = cachedSignature.Place; - _signaturePopupVisible = false; - - logger.LogInformation("Cached signature loaded for envelope {EnvelopeKey}", EnvelopeKey); - } - else - { - _activeSignatureTab = SignatureTabDraw; - _signaturePopupVisible = true; - _popupValidationMessage = null; - } - } - catch (Exception ex) - { - logger.LogWarning(ex, "Failed to load cached signature, showing popup"); - _activeSignatureTab = SignatureTabDraw; - _signaturePopupVisible = true; - _popupValidationMessage = null; - } - - } - catch (HttpRequestException ex) - { - _errorMessage = $"Dokument konnte nicht geladen werden: {ex.Message}"; - logger.LogError(ex, "Failed to load document for envelope {EnvelopeKey}", EnvelopeKey); - } - catch (Exception ex) - { - _errorMessage = $"Fehler: {ex.Message}"; - logger.LogError(ex, "Unexpected error during initialization for envelope {EnvelopeKey}", EnvelopeKey); - } - - _isLoading = false; - await InvokeAsync(StateHasChanged); - } - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - // Load saved thumbnail width from localStorage - try - { - var savedWidth = await JSRuntime.InvokeAsync("localStorage.getItem", "envelopeViewer_thumbnailWidth"); - if (!string.IsNullOrEmpty(savedWidth) && int.TryParse(savedWidth, out var width)) - { - _thumbnailWidth = Math.Clamp(width, MinThumbnailWidth, MaxThumbnailWidth); - await InvokeAsync(StateHasChanged); - } - } - catch - { - // Ignore localStorage errors - } - } - - if (!_pdfLoaded && !string.IsNullOrWhiteSpace(_pdfDataUrl)) - { - await Task.Delay(500); - - try - { - _dotNetRef = DotNetObjectReference.Create(this); - - // Send quality options to JavaScript - var options = PdfViewerOptions.Value; - await JSRuntime.InvokeVoidAsync("pdfViewer.setQualityOptions", new - { - options.ThumbnailBaseScale, - options.ThumbnailEnableHiDPI, - options.ThumbnailMaxDPR, - options.MainCanvasEnableHiDPI, - options.MainCanvasMaxDPR, - options.EnableSmoothZoom, - options.ZoomTransitionDuration, - options.RenderingOpacity, - options.ZoomStepPercentage - }); - - var success = await JSRuntime.InvokeAsync("pdfViewer.initialize", "pdf-canvas", _pdfDataUrl, _dotNetRef); - - if (success) - { - _pdfLoaded = true; - _totalPages = await JSRuntime.InvokeAsync("pdfViewer.getTotalPages"); - _currentPage = await JSRuntime.InvokeAsync("pdfViewer.getCurrentPage"); - - // Attach resize listeners - await JSRuntime.InvokeVoidAsync("pdfViewer.attachResizeListeners", _dotNetRef); - - - await InvokeAsync(StateHasChanged); - - // Wait for DOM to be ready, then render thumbnails - await Task.Delay(100); - await RenderThumbnailsAsync(); - - // Render signature buttons - await RenderSignatureButtonsAsync(); - } - } - catch (Exception ex) - { - _errorMessage = $"PDF.js Fehler: {ex.Message}"; - await InvokeAsync(StateHasChanged); - } - } - } - - [JSInvokable] - public async Task OnZoomChanged(double scale) - { - _currentZoom = (int)(scale * 100); - await InvokeAsync(StateHasChanged); - - // Small delay for canvas render to complete (reduced from 100ms to 10ms) - await Task.Delay(10); - await RenderSignatureButtonsAsync(); - } - - async Task NextPage() - { - if (await JSRuntime.InvokeAsync("pdfViewer.nextPage")) - { - _currentPage = await JSRuntime.InvokeAsync("pdfViewer.getCurrentPage"); - await RenderSignatureButtonsAsync(); - } - } - - async Task PreviousPage() - { - if (await JSRuntime.InvokeAsync("pdfViewer.previousPage")) - { - _currentPage = await JSRuntime.InvokeAsync("pdfViewer.getCurrentPage"); - await RenderSignatureButtonsAsync(); - } - } - - async Task ZoomIn() - { - if (_currentZoom >= 300) return; - await JSRuntime.InvokeVoidAsync("pdfViewer.zoomIn"); - var scale = await JSRuntime.InvokeAsync("pdfViewer.getScale"); - _currentZoom = (int)(scale * 100); - - // Update signature overlay positions after zoom - await RenderSignatureButtonsAsync(); - } - - async Task ZoomOut() - { - if (_currentZoom <= 50) return; - await JSRuntime.InvokeVoidAsync("pdfViewer.zoomOut"); - var scale = await JSRuntime.InvokeAsync("pdfViewer.getScale"); - _currentZoom = (int)(scale * 100); - - // Update signature overlay positions after zoom - await RenderSignatureButtonsAsync(); - } - - async Task SetZoom(int percentage) - { - var scale = percentage / 100.0; - await JSRuntime.InvokeVoidAsync("pdfViewer.setScale", scale); - _currentZoom = percentage; - } - - async Task OnZoomSliderChanged(ChangeEventArgs e) - { - if (int.TryParse(e.Value?.ToString(), out var zoom)) - { - await SetZoom(zoom); - - // Update signature overlay positions after zoom - await RenderSignatureButtonsAsync(); - } - } - - async Task OnPageInputChanged(ChangeEventArgs e) - { - if (int.TryParse(e.Value?.ToString(), out var pageNum) && pageNum >= 1 && pageNum <= _totalPages) - { - if (await JSRuntime.InvokeAsync("pdfViewer.goToPage", pageNum)) - { - _currentPage = pageNum; - } - } - } - - async Task FitToWidth() - { - await JSRuntime.InvokeVoidAsync("pdfViewer.fitToWidth"); - var scale = await JSRuntime.InvokeAsync("pdfViewer.getScale"); - _currentZoom = (int)(scale * 100); - } - - async Task ToggleThumbnails() - { - _showThumbnails = !_showThumbnails; - - // Re-render thumbnails when showing them - if (_showThumbnails && _pdfLoaded) - { - await InvokeAsync(StateHasChanged); // Force UI update first - await Task.Delay(150); // Wait for DOM to render canvas elements - await RenderThumbnailsAsync(); - } - } - - async Task GoToPageFromThumbnail(int pageNum) - { - if (await JSRuntime.InvokeAsync("pdfViewer.goToPage", pageNum)) - { - _currentPage = pageNum; - await RenderSignatureButtonsAsync(); - } - } - - async Task RenderSignatureButtonsAsync() - { - if (_signatures.Count == 0 || !_pdfLoaded) return; - - try - { - await JSRuntime.InvokeVoidAsync("pdfViewer.renderSignatureButtons", _signatures, _currentPage, _dotNetRef); - await UpdateSignatureCounterAsync(); - } - catch (Exception ex) - { - System.Diagnostics.Debug.WriteLine($"Signature button rendering error: {ex.Message}"); - } - } - - [JSInvokable] - public async Task OnSignatureButtonClick(int signatureId) - { - if (_capturedSignature == null) - { - // No signature captured yet - should not happen as popup is shown on page load - return; - } - - // Apply signature to PDF canvas - await JSRuntime.InvokeVoidAsync("pdfViewer.applySignature", - signatureId, - _capturedSignature.DataUrl, - _capturedSignature.FullName, - _capturedSignature.Position, - _capturedSignature.Place); - - // Update counter - await UpdateSignatureCounterAsync(); - } - - [JSInvokable] - public async Task OnSignatureNavChanged() - { - await UpdateSignatureCounterAsync(); - } - - [JSInvokable] - public async Task OnPageChangedBySignatureNav(int newPage) - { - _currentPage = newPage; - await RenderSignatureButtonsAsync(); - } - - async Task UpdateSignatureCounterAsync() - { - try - { - var state = await JSRuntime.InvokeAsync("pdfViewer.getSignatureNavState"); - _totalSignatures = state.Total; - _signedSignatures = state.Signed; - _unsignedSignatures = state.Unsigned; - _currentSignatureIndex = state.CurrentIndex; // Current signature - await InvokeAsync(StateHasChanged); - } - catch - { - // Ignore errors during counter update - } - } - - async Task GoToPreviousSignature() - { - await JSRuntime.InvokeVoidAsync("pdfViewer.goToPreviousSignature", _dotNetRef); - } - - async Task GoToNextSignature() - { - await JSRuntime.InvokeVoidAsync("pdfViewer.goToNextSignature", _dotNetRef); - } - - void RestartSigning() - { - // Force page reload to reset all signatures and state - Navigation.NavigateTo(Navigation.Uri, forceLoad: true); - } - - record SignatureNavState(int Total, int Signed, int Unsigned, int CurrentIndex, bool CanGoPrev, bool CanGoNext); - - string GetSignatureButtonTitle() - { - if (_signedSignatures > 0) - return "Unterschrift ist gesperrt – bitte Seite neu laden, um zu ändern"; - - return _capturedSignature is not null - ? "Unterschrift ändern" - : "Unterschrift erstellen"; - } - - void HandleSignatureChangeClick() - { - // If any signature is applied, button is disabled - this won't be called - // But just in case, do nothing - if (_signedSignatures > 0) - return; - - // No signatures applied - open popup normally - OpenSignaturePopup(); - } - - // Signature popup methods - void OpenSignaturePopup() - { - // Open popup with current signature (edit mode) - _activeSignatureTab = SignatureTabDraw; - _signaturePopupVisible = true; - _popupValidationMessage = null; - - // Load current signature info into form fields - if (_capturedSignature is not null) - { - _signerFullName = _capturedSignature.FullName; - _signerPosition = _capturedSignature.Position; - _signaturePlace = _capturedSignature.Place; - } - } - - async Task OnPopupShownAsync() - { - await InitializeActiveSignatureTabAsync(); - - // If there's an existing signature and we're on draw tab, load it to canvas - if (_capturedSignature is not null && _activeSignatureTab == SignatureTabDraw) - { - await Task.Delay(100); // Wait for canvas to be ready - await JSRuntime.InvokeVoidAsync("receiverSignature.loadExistingSignature", DrawCanvasId, _capturedSignature.DataUrl); - } - } - - async Task SetSignatureTabAsync(string tab) - { - _activeSignatureTab = tab; - _popupValidationMessage = null; - await InvokeAsync(StateHasChanged); - await Task.Delay(50); - await InitializeActiveSignatureTabAsync(); - } - - async Task InitializeActiveSignatureTabAsync() - { - if (_activeSignatureTab == SignatureTabDraw) - { - await JSRuntime.InvokeVoidAsync("receiverSignature.initialize", DrawCanvasId); - } - else if (_activeSignatureTab == SignatureTabText) - { - await JSRuntime.InvokeVoidAsync("receiverSignature.initializeTyped", TypedCanvasId); - await RenderTypedSignatureAsync(); - } - else - { - await JSRuntime.InvokeVoidAsync("receiverSignature.initializeImage", ImageInputId, ImageCanvasId); - } - } - - async Task RenewSignatureAsync() - { - _popupValidationMessage = null; - - if (_activeSignatureTab == SignatureTabDraw) - { - await JSRuntime.InvokeVoidAsync("receiverSignature.clear", DrawCanvasId); - } - else if (_activeSignatureTab == SignatureTabText) - { - _typedSignatureText = string.Empty; - await JSRuntime.InvokeVoidAsync("receiverSignature.clearTyped", TypedCanvasId); - } - else - { - await JSRuntime.InvokeVoidAsync("receiverSignature.clearImage", ImageInputId, ImageCanvasId); - } - } - - async Task OnTypedSignatureChanged(Microsoft.AspNetCore.Components.ChangeEventArgs args) - { - _typedSignatureText = args.Value?.ToString() ?? string.Empty; - await RenderTypedSignatureAsync(); - } - - async Task OnTypedSignatureFontChanged(Microsoft.AspNetCore.Components.ChangeEventArgs args) - { - _typedSignatureFont = args.Value?.ToString() ?? _typedSignatureFont; - await RenderTypedSignatureAsync(); - } - - async Task RenderTypedSignatureAsync() - { - await JSRuntime.InvokeVoidAsync("receiverSignature.renderTypedSignature", TypedCanvasId, _typedSignatureText, _typedSignatureFont); - } - - async Task SaveSignatureAsync() - { - if (string.IsNullOrWhiteSpace(_signerFullName)) - { - _popupValidationMessage = "Bitte geben Sie Vor- und Nachname ein."; - return; - } - if (string.IsNullOrWhiteSpace(_signaturePlace)) - { - _popupValidationMessage = "Bitte geben Sie den Ort ein."; - return; - } - var signatureDataUrl = await GetActiveSignatureDataUrlAsync(); - if (string.IsNullOrWhiteSpace(signatureDataUrl)) - { - _popupValidationMessage = "Die Unterschrift ist erforderlich."; - return; - } - - _popupValidationMessage = null; - _capturedSignature = new SignatureCaptureDto - { - DataUrl = signatureDataUrl, - FullName = _signerFullName.Trim(), - Position = _signerPosition.Trim(), - Place = _signaturePlace.Trim() - }; - _signaturePopupVisible = false; - - // Save to cache (fire-and-forget, ignore errors) - if (!string.IsNullOrWhiteSpace(EnvelopeKey)) - { - _ = Task.Run(async () => - { - try - { - if (_receiverUser is not null) - { - await PageDataService.SaveCachedSignatureAsync(_receiverUser, _capturedSignature); - } - } - catch - { - // Ignore cache errors - } - }); - } - - await InvokeAsync(StateHasChanged); - Console.WriteLine($"Signature saved: {_signerFullName}, {_signaturePlace}"); - } - - async Task GetActiveSignatureDataUrlAsync() - { - if (_activeSignatureTab == SignatureTabDraw) - return await JSRuntime.InvokeAsync("receiverSignature.getDataUrl", DrawCanvasId); - - if (_activeSignatureTab == SignatureTabText) - { - await RenderTypedSignatureAsync(); - return await JSRuntime.InvokeAsync("receiverSignature.getTypedDataUrl", TypedCanvasId); - } - - return await JSRuntime.InvokeAsync("receiverSignature.getImageDataUrl", ImageCanvasId); - } - - async Task RenderThumbnailsAsync() - { - try - { - var delay = PdfViewerOptions.Value.ThumbnailRenderDelay; - - // Sequential rendering to avoid overwhelming the browser - for (int i = 1; i <= _totalPages; i++) - { - await JSRuntime.InvokeVoidAsync("pdfViewer.renderThumbnail", i, $"thumb-canvas-{i}"); - - // Configurable delay between renders - if (i < _totalPages) - { - await Task.Delay(delay); - } - } - } - catch (Exception ex) - { - // Thumbnail rendering is not critical - System.Diagnostics.Debug.WriteLine($"Thumbnail rendering error: {ex.Message}"); - } - } - - // Resizable splitter methods - void OnSplitterMouseDown(MouseEventArgs e) - { - _isResizing = true; - _resizeStartX = (int)e.ClientX; - _resizeStartWidth = _thumbnailWidth; - - // Add resizing class to body to prevent text selection - _ = JSRuntime.InvokeVoidAsync("eval", "document.body.classList.add('resizing')"); - _ = JSRuntime.InvokeVoidAsync("pdfViewer.startResize"); - } - - [JSInvokable] - public async Task OnSplitterMouseMove(int clientX) - { - if (!_isResizing) return; - - var delta = clientX - _resizeStartX; - var newWidth = _resizeStartWidth + delta; - - // Clamp to min/max - _thumbnailWidth = Math.Clamp(newWidth, MinThumbnailWidth, MaxThumbnailWidth); - - await InvokeAsync(StateHasChanged); - } - - [JSInvokable] - public async Task OnSplitterMouseUp() - { - if (!_isResizing) return; - - _isResizing = false; - - // Remove resizing class from body - await JSRuntime.InvokeVoidAsync("eval", "document.body.classList.remove('resizing')"); - - // Save preference to localStorage - await JSRuntime.InvokeVoidAsync("localStorage.setItem", "envelopeViewer_thumbnailWidth", _thumbnailWidth.ToString()); - - await InvokeAsync(StateHasChanged); - } - - public async ValueTask DisposeAsync() - { - if (_pdfLoaded) - { - try - { - await JSRuntime.InvokeVoidAsync("pdfViewer.dispose"); - } - catch - { - // Ignore errors during disposal - } - } - _dotNetRef?.Dispose(); - } -} diff --git a/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Components/Pages/Test/EnvelopeReceiverPage_DxPdfViewer.razor b/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Components/Pages/Test/EnvelopeReceiverPage_DxPdfViewer.razor deleted file mode 100644 index a9a3d66f..00000000 --- a/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Components/Pages/Test/EnvelopeReceiverPage_DxPdfViewer.razor +++ /dev/null @@ -1,114 +0,0 @@ -@page "/envelope/DxPdfViewer" -@rendermode InteractiveServer -@using System.IO -@using DevExpress.Blazor -@using System.Reflection -@using DevExpress.Blazor.PdfViewer - - - - - -
- - Drag and Drop File Hereor - -
- - - -@if (DocumentContent != null && DocumentContent.Length > 0) -{ -
- PDF loaded: @DocumentContent.Length bytes -
- -} -else -{ -
- Please upload a PDF file to view it. -
-} - -@code { - readonly List ALLOWED_FILE_TYPES = new List { ".pdf" }; - DxFileInput fileInput; - byte[] DocumentContent { get; set; } - protected override void OnInitialized() - { - Assembly assembly = Assembly.GetExecutingAssembly(); - Stream stream = assembly.GetManifestResourceStream("EnvelopeGenerator.Server.Resources.Invoice.pdf"); - if (stream != null) - { - using (stream) - using (var binaryReader = new BinaryReader(stream)) - DocumentContent = binaryReader.ReadBytes((int)stream.Length); - } - } - protected async Task OnFilesUploading(FilesUploadingEventArgs args) - { - using (MemoryStream stream = new MemoryStream()) - { - IFileInputSelectedFile file = args.Files[0]; - await file.OpenReadStream(file.Size).CopyToAsync(stream); - DocumentContent = stream.ToArray(); - await InvokeAsync(StateHasChanged); - } - } -} - diff --git a/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Components/Pages/Test/EnvelopeReceiverPage_DxReportViewer.razor b/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Components/Pages/Test/EnvelopeReceiverPage_DxReportViewer.razor deleted file mode 100644 index 1eb5d9ab..00000000 --- a/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Components/Pages/Test/EnvelopeReceiverPage_DxReportViewer.razor +++ /dev/null @@ -1,50 +0,0 @@ -@page "/envelope/{EnvelopeKey}/DxReportViewer" -@rendermode InteractiveServer -@using XtraReport = DevExpress.XtraReports.UI.XtraReport -@using DevExpress.Blazor.Reporting -@using Microsoft.Extensions.Options -@using EnvelopeGenerator.Server.Client.Options -@using EnvelopeGenerator.Server.Client.Services -@inject InMemoryReportStorageWebExtension ReportStorage -@inject DocumentService DocumentService -@inject IOptions AppOptions - - - - - -@if (_report is not null) { - -} - -@code { - [Parameter] public string EnvelopeKey { get; init; } = null!; - - XtraReport? _report = null; - - protected override async Task OnInitializedAsync() - { - _report = await CreateReport(); - } - - async Task CreateReport() - { - if (AppOptions.Value.UsePredefinedReports) - { - return Client.PredefinedReports.ReportsFactory.GetReport("LargeDatasetReport"); - } - else - { - - var pdfBytes = await DocumentService.GetDocumentAsync(EnvelopeKey); - if (pdfBytes is null || pdfBytes.Length == 0) - throw new InvalidOperationException($"No PDF bytes found for EnvelopeKey: {EnvelopeKey}"); - - var report = new XtraReport(); - var detail = new DevExpress.XtraReports.UI.DetailBand(); - report.Bands.Add(detail); - detail.Controls.Add(new DevExpress.XtraReports.UI.XRPdfContent { Source = pdfBytes, GenerateOwnPages = true }); - return report; - } - } -} \ No newline at end of file diff --git a/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Components/Pages/Test/EnvelopeReceiverPage_embed.razor b/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Components/Pages/Test/EnvelopeReceiverPage_embed.razor deleted file mode 100644 index e5d61ee3..00000000 --- a/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Components/Pages/Test/EnvelopeReceiverPage_embed.razor +++ /dev/null @@ -1,124 +0,0 @@ -@page "/envelope/Embed" -@rendermode InteractiveServer -@using System.IO -@using DevExpress.Blazor -@using System.Reflection - - - - - -
- - Drag and Drop File Hereor - -
- - - -@if (DocumentContent != null && DocumentContent.Length > 0) -{ -
- PDF loaded: @DocumentContent.Length bytes -
- -} -else -{ -
- Please upload a PDF file to view it. -
-} - -@code { - readonly List ALLOWED_FILE_TYPES = new List { ".pdf" }; - DxFileInput fileInput; - byte[] DocumentContent { get; set; } - - protected override void OnInitialized() - { - Assembly assembly = Assembly.GetExecutingAssembly(); - Stream stream = assembly.GetManifestResourceStream("EnvelopeGenerator.Server.Resources.Invoice.pdf"); - if (stream != null) - { - using (stream) - using (var binaryReader = new BinaryReader(stream)) - DocumentContent = binaryReader.ReadBytes((int)stream.Length); - } - } - - protected async Task OnFilesUploading(FilesUploadingEventArgs args) - { - using (MemoryStream stream = new MemoryStream()) - { - IFileInputSelectedFile file = args.Files[0]; - await file.OpenReadStream(file.Size).CopyToAsync(stream); - DocumentContent = stream.ToArray(); - await InvokeAsync(StateHasChanged); - } - } - - private string GetPdfDataUrl() - { - if (DocumentContent == null || DocumentContent.Length == 0) - return string.Empty; - - string base64 = Convert.ToBase64String(DocumentContent); - return $"data:application/pdf;base64,{base64}#toolbar=0&navpanes=0&scrollbar=1"; - } -} -