Replaced "EnvelopeGenerator.WebUI" with "EnvelopeGenerator.Server" and "EnvelopeGenerator.WebUI.Client" with "EnvelopeGenerator.Server.Client". Updated project entries, solution configuration platforms, and nested projects to reflect these changes.
159 lines
9.6 KiB
Plaintext
159 lines
9.6 KiB
Plaintext
@page "/envelope/login/{EnvelopeKey}"
|
|
@rendermode InteractiveWebAssembly
|
|
@using EnvelopeGenerator.WebUI.Client.Services
|
|
@inject AuthService AuthService
|
|
@inject NavigationManager Navigation
|
|
|
|
<link href="_content/DevExpress.Blazor.Themes/blazing-berry.bs5.min.css" rel="stylesheet" />
|
|
|
|
<div class="login-page-wrapper d-flex align-items-center justify-content-center min-vh-100">
|
|
<div class="login-card card shadow border-0" style="max-width: 440px; width: 100%;">
|
|
|
|
<div class="card-header text-white text-center py-4 border-0" style="background: linear-gradient(135deg, #2c3e50 0%, #3498db 100%); border-radius: calc(0.375rem - 1px) calc(0.375rem - 1px) 0 0;">
|
|
<div class="mb-2">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" fill="currentColor" viewBox="0 0 16 16">
|
|
<path d="M8 1a2 2 0 0 1 2 2v4H6V3a2 2 0 0 1 2-2zm3 6V3a3 3 0 0 0-6 0v4a2 2 0 0 0-2 2v5a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2z"/>
|
|
</svg>
|
|
</div>
|
|
<h5 class="mb-0 fw-semibold">Dokument öffnen</h5>
|
|
<p class="mb-0 mt-1 opacity-75" style="font-size: 0.85rem;">Sicherer Zugang mit Zugangscode</p>
|
|
</div>
|
|
|
|
<div class="card-body p-4">
|
|
|
|
<p class="text-muted mb-4" style="font-size: 0.875rem; line-height: 1.5;">
|
|
Bitte geben Sie den Zugangscode ein, den Sie per E-Mail erhalten haben, um das Dokument sicher zu öffnen.
|
|
</p>
|
|
|
|
@if (LoginResult == EnvelopeLoginResult.NotFound) {
|
|
<div class="alert alert-warning d-flex align-items-start gap-2 py-2" role="alert">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="currentColor" class="flex-shrink-0 mt-1" viewBox="0 0 16 16">
|
|
<path d="M8.982 1.566a1.13 1.13 0 0 0-1.96 0L.165 13.233c-.457.778.091 1.767.98 1.767h13.713c.889 0 1.438-.99.98-1.767L8.982 1.566zM8 5c.535 0 .954.462.9.995l-.35 3.507a.552.552 0 0 1-1.1 0L7.1 5.995A.905.905 0 0 1 8 5zm.002 6a1 1 0 1 1 0 2 1 1 0 0 1 0-2z"/>
|
|
</svg>
|
|
<div>
|
|
<strong>Dokument nicht gefunden.</strong><br />
|
|
<span style="font-size:0.85rem;">Der angegebene Zugangscode konnte keinem Dokument zugeordnet werden. Bitte prüfen Sie den Link in Ihrer E-Mail.</span>
|
|
</div>
|
|
</div>
|
|
} else if (LoginResult == EnvelopeLoginResult.InvalidCode) {
|
|
<div class="alert alert-danger d-flex align-items-start gap-2 py-2" role="alert">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="currentColor" class="flex-shrink-0 mt-1" viewBox="0 0 16 16">
|
|
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM5.354 4.646a.5.5 0 1 0-.708.708L7.293 8l-2.647 2.646a.5.5 0 0 0 .708.708L8 8.707l2.646 2.647a.5.5 0 0 0 .708-.708L8.707 8l2.647-2.646a.5.5 0 0 0-.708-.708L8 7.293 5.354 4.646z"/>
|
|
</svg>
|
|
<div>
|
|
<strong>Ungültiger Zugangscode.</strong><br />
|
|
<span style="font-size:0.85rem;">Der eingegebene Code ist falsch. Bitte versuchen Sie es erneut.</span>
|
|
</div>
|
|
</div>
|
|
} else if (LoginResult == EnvelopeLoginResult.Error) {
|
|
<div class="alert alert-secondary d-flex align-items-start gap-2 py-2" role="alert">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="currentColor" class="flex-shrink-0 mt-1" viewBox="0 0 16 16">
|
|
<path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z"/>
|
|
<path d="M7.002 11a1 1 0 1 1 2 0 1 1 0 0 1-2 0zM7.1 4.995a.905.905 0 1 1 1.8 0l-.35 3.507a.552.552 0 0 1-1.1 0L7.1 4.995z"/>
|
|
</svg>
|
|
<div>
|
|
<strong>Serverfehler.</strong><br />
|
|
<span style="font-size:0.85rem;">Ein unerwarteter Fehler ist aufgetreten. Bitte versuchen Sie es später erneut.</span>
|
|
</div>
|
|
</div>
|
|
}
|
|
|
|
<div class="mb-4">
|
|
<label class="form-label fw-medium" for="login-access-code">
|
|
Zugangscode
|
|
<span class="text-danger ms-1">*</span>
|
|
</label>
|
|
<div class="input-group">
|
|
<span class="input-group-text bg-light border-end-0">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#6c757d" viewBox="0 0 16 16">
|
|
<path d="M3.5 11.5a3.5 3.5 0 1 1 3.163-5H14L15.5 8 14 9.5l-1-1-1 1-1-1-1 1-1-1-1.837 1.337A3.5 3.5 0 0 1 3.5 11.5zm0-1a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5z"/>
|
|
</svg>
|
|
</span>
|
|
<input id="login-access-code"
|
|
type="@(ShowCode ? "text" : "password")"
|
|
class="form-control border-start-0 border-end-0 @(LoginResult == EnvelopeLoginResult.InvalidCode ? "is-invalid" : null)"
|
|
placeholder="Zugangscode eingeben"
|
|
@bind="AccessCode"
|
|
@bind:event="oninput"
|
|
@onkeydown="OnKeyDownAsync"
|
|
disabled="@IsLoading"
|
|
autocomplete="one-time-code" />
|
|
<button type="button"
|
|
class="btn btn-outline-secondary border-start-0"
|
|
style="border-left: none;"
|
|
tabindex="-1"
|
|
@onclick="() => ShowCode = !ShowCode">
|
|
@if (ShowCode) {
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
|
|
<path d="M13.359 11.238C15.06 9.72 16 8 16 8s-3-5.5-8-5.5a7.028 7.028 0 0 0-2.79.588l.77.771A5.944 5.944 0 0 1 8 3.5c2.12 0 3.879 1.168 5.168 2.457A13.134 13.134 0 0 1 14.828 8c-.058.087-.122.183-.195.288-.335.48-.83 1.12-1.465 1.755-.165.165-.337.328-.517.486l.708.709z"/>
|
|
<path d="M11.297 9.176a3.5 3.5 0 0 0-4.474-4.474l.823.823a2.5 2.5 0 0 1 2.829 2.829l.822.822zm-2.943 1.299.822.822a3.5 3.5 0 0 1-4.474-4.474l.823.823a2.5 2.5 0 0 0 2.829 2.829z"/>
|
|
<path d="M3.35 5.47c-.18.16-.353.322-.518.487A13.134 13.134 0 0 0 1.172 8l.195.288c.335.48.83 1.12 1.465 1.755C4.121 11.332 5.881 12.5 8 12.5c.716 0 1.39-.133 2.02-.36l.77.772A7.029 7.029 0 0 1 8 13.5C3 13.5 0 8 0 8s.939-1.721 2.641-3.238l.708.709z"/>
|
|
<path fill-rule="evenodd" d="M13.646 14.354l-12-12 .708-.708 12 12-.708.708z"/>
|
|
</svg>
|
|
} else {
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
|
|
<path d="M16 8s-3-5.5-8-5.5S0 8 0 8s3 5.5 8 5.5S16 8 16 8zM1.173 8a13.133 13.133 0 0 1 1.66-2.043C4.12 4.668 5.88 3.5 8 3.5c2.12 0 3.879 1.168 5.168 2.457A13.133 13.133 0 0 1 14.828 8c-.058.087-.122.183-.195.288-.335.48-.83 1.12-1.465 1.755C11.879 11.332 10.119 12.5 8 12.5c-2.12 0-3.879-1.168-5.168-2.457A13.134 13.134 0 0 1 1.172 8z"/>
|
|
<path d="M8 5.5a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5zM4.5 8a3.5 3.5 0 1 1 7 0 3.5 3.5 0 0 1-7 0z"/>
|
|
</svg>
|
|
}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<button class="btn btn-primary w-100 py-2 fw-medium"
|
|
style="background: linear-gradient(135deg, #2c3e50 0%, #3498db 100%); border: none;"
|
|
@onclick="SubmitAsync"
|
|
disabled="@(IsLoading || string.IsNullOrWhiteSpace(AccessCode))">
|
|
@if (IsLoading) {
|
|
<span class="spinner-border spinner-border-sm me-2" role="status" aria-hidden="true"></span>
|
|
<span>Überprüfen …</span>
|
|
} else {
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="me-2" viewBox="0 0 16 16">
|
|
<path d="M8 1a2 2 0 0 1 2 2v4H6V3a2 2 0 0 1 2-2zm3 6V3a3 3 0 0 0-6 0v4a2 2 0 0 0-2 2v5a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2z"/>
|
|
</svg>
|
|
<span>Dokument öffnen</span>
|
|
}
|
|
</button>
|
|
|
|
</div>
|
|
|
|
<div class="card-footer text-center text-muted py-3 border-0 bg-transparent" style="font-size: 0.78rem;">
|
|
Bei Problemen wenden Sie sich bitte an den Absender des Dokuments.
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
@code {
|
|
[Parameter] public string EnvelopeKey { get; set; } = string.Empty;
|
|
|
|
string AccessCode = string.Empty;
|
|
bool ShowCode;
|
|
bool IsLoading;
|
|
EnvelopeLoginResult? LoginResult;
|
|
|
|
async Task OnKeyDownAsync(Microsoft.AspNetCore.Components.Web.KeyboardEventArgs e) {
|
|
if (e.Key == "Enter")
|
|
await SubmitAsync();
|
|
}
|
|
|
|
async Task SubmitAsync() {
|
|
if (string.IsNullOrWhiteSpace(AccessCode) || IsLoading) return;
|
|
|
|
IsLoading = true;
|
|
LoginResult = null;
|
|
await InvokeAsync(StateHasChanged);
|
|
|
|
var result = await AuthService.LoginEnvelopeReceiverAsync(EnvelopeKey, AccessCode.Trim());
|
|
|
|
if (result == EnvelopeLoginResult.Success) {
|
|
Navigation.NavigateTo($"/envelope/{Uri.EscapeDataString(EnvelopeKey)}", forceLoad: true);
|
|
return;
|
|
}
|
|
|
|
LoginResult = result;
|
|
IsLoading = false;
|
|
await InvokeAsync(StateHasChanged);
|
|
}
|
|
}
|