Add PdfFileDropZone for interactive PDF uploads
Replaced static upload message in `CreateEnvelopeWizardPopup.razor` with a new `PdfFileDropZone` component to enhance user experience. The component supports drag-and-drop functionality, file selection, and dynamic states (e.g., disabled, drag-active). Introduced `PdfFileDropZone.razor` with customizable parameters such as `Disabled`, `HasDocument`, `UploadText`, and `DragDropHintText`. Added event handling for drag-and-drop interactions and file selection. Updated `sender-page.css` to include styles for the new component, ensuring seamless integration with the existing layout. Adjusted styles for hover effects, drag-active state, and disabled state. These changes improve usability and make PDF uploads more intuitive.
This commit is contained in:
@@ -245,9 +245,11 @@
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<div class="sender-create-wizard__empty-list">
|
<PdfFileDropZone Disabled="@IsActionLocked"
|
||||||
@L("SenderWizard_DocumentRequiredHint", "Bitte laden Sie ein PDF-Dokument hoch, um fortzufahren.")
|
HasDocument="false"
|
||||||
</div>
|
UploadText='@L("SenderWizard_DocumentRequiredHint", "Bitte laden Sie ein PDF-Dokument hoch, um fortzufahren.")'
|
||||||
|
DragDropHintText='@L("SenderWizard_DragDropPdfHint", "Oder ziehen Sie die PDF-Datei hierher.")'
|
||||||
|
FileSelected="OnDocumentSelectedAsync" />
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,104 @@
|
|||||||
|
@using Microsoft.AspNetCore.Components.Forms
|
||||||
|
|
||||||
|
<div class="sender-pdf-dropzone @DropZoneClass">
|
||||||
|
<div class="sender-pdf-dropzone__content">
|
||||||
|
<div class="sender-pdf-dropzone__title">@CurrentActionText</div>
|
||||||
|
@if (!string.IsNullOrWhiteSpace(DragDropHintText))
|
||||||
|
{
|
||||||
|
<div class="sender-pdf-dropzone__hint">@DragDropHintText</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<InputFile OnChange="OnFileSelectedAsync"
|
||||||
|
accept="@Accept"
|
||||||
|
disabled="@Disabled"
|
||||||
|
@ondragenter="OnDragEnter"
|
||||||
|
@ondragleave="OnDragLeave"
|
||||||
|
@ondragover="OnDragOver"
|
||||||
|
@ondrop="OnDrop"
|
||||||
|
class="sender-pdf-dropzone__input" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@code {
|
||||||
|
[Parameter]
|
||||||
|
public bool Disabled { get; set; }
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public bool HasDocument { get; set; }
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public string Accept { get; set; } = ".pdf";
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public string UploadText { get; set; } = "PDF hochladen";
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public string ReplaceText { get; set; } = "PDF ersetzen";
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public string DragDropHintText { get; set; } = "Datei hierhin ziehen oder klicken";
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public EventCallback<InputFileChangeEventArgs> FileSelected { get; set; }
|
||||||
|
|
||||||
|
private int _dragDepth;
|
||||||
|
private bool _isDragActive;
|
||||||
|
|
||||||
|
private string CurrentActionText => HasDocument ? ReplaceText : UploadText;
|
||||||
|
|
||||||
|
private string DropZoneClass
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (Disabled)
|
||||||
|
return "sender-pdf-dropzone--disabled";
|
||||||
|
|
||||||
|
return _isDragActive ? "sender-pdf-dropzone--drag-active" : string.Empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDragEnter(DragEventArgs _)
|
||||||
|
{
|
||||||
|
if (Disabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_dragDepth++;
|
||||||
|
_isDragActive = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDragLeave(DragEventArgs _)
|
||||||
|
{
|
||||||
|
if (Disabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_dragDepth = Math.Max(0, _dragDepth - 1);
|
||||||
|
if (_dragDepth == 0)
|
||||||
|
_isDragActive = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDragOver(DragEventArgs _)
|
||||||
|
{
|
||||||
|
if (Disabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_isDragActive = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDrop(DragEventArgs _)
|
||||||
|
{
|
||||||
|
_dragDepth = 0;
|
||||||
|
_isDragActive = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task OnFileSelectedAsync(InputFileChangeEventArgs args)
|
||||||
|
{
|
||||||
|
_dragDepth = 0;
|
||||||
|
_isDragActive = false;
|
||||||
|
|
||||||
|
if (Disabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (FileSelected.HasDelegate)
|
||||||
|
await FileSelected.InvokeAsync(args);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1466,6 +1466,66 @@
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.sender-pdf-dropzone {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
min-height: 92px;
|
||||||
|
border: 1px dashed rgba(100, 116, 139, 0.5);
|
||||||
|
border-radius: 8px;
|
||||||
|
background: rgba(248, 250, 252, 0.9);
|
||||||
|
color: #334155;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: border-color 120ms ease, background-color 120ms ease, box-shadow 120ms ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sender-pdf-dropzone:hover {
|
||||||
|
border-color: rgba(126, 34, 206, 0.45);
|
||||||
|
background: rgba(241, 245, 249, 0.95);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sender-pdf-dropzone--drag-active {
|
||||||
|
border-color: rgba(16, 185, 129, 0.75);
|
||||||
|
background: linear-gradient(180deg, rgba(16, 185, 129, 0.14), rgba(16, 185, 129, 0.08));
|
||||||
|
box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.16);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sender-pdf-dropzone--disabled {
|
||||||
|
opacity: 0.55;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sender-pdf-dropzone__content {
|
||||||
|
text-align: center;
|
||||||
|
display: grid;
|
||||||
|
gap: 0.2rem;
|
||||||
|
padding: 0.75rem 0.9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sender-pdf-dropzone__title {
|
||||||
|
font-size: 0.86rem;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sender-pdf-dropzone__hint {
|
||||||
|
font-size: 0.78rem;
|
||||||
|
color: #64748b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sender-pdf-dropzone__input {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
opacity: 0;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sender-pdf-dropzone--disabled .sender-pdf-dropzone__input {
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
.sender-create-wizard__document-meta {
|
.sender-create-wizard__document-meta {
|
||||||
border: 1px solid rgba(16, 185, 129, 0.3);
|
border: 1px solid rgba(16, 185, 129, 0.3);
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
@@ -1524,6 +1584,10 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.sender-pdf-dropzone {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.sender-create-wizard__upload-btn {
|
.sender-create-wizard__upload-btn {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user