Renamed namespaces and related identifiers from EnvelopeGenerator.WebUI to EnvelopeGenerator.Server across the project. This change affects data models, services, controllers, and configuration files to ensure consistency with the new architecture. Updated @using directives in Razor components and other files to reflect the new namespace structure. Adjusted project references in EnvelopeGenerator.Server.csproj to point to the new EnvelopeGenerator.Server.Client project. Modified middleware and logging configurations to use the new EnvelopeGenerator.Server namespace, including changes in Program.cs and appsettings.json. Updated resource and file references to use the new EnvelopeGenerator.Server path, ensuring correct resource loading. Adjusted configuration options in Program.cs to use the new namespace for options classes, such as ApiOptions and PdfViewerOptions. Updated authentication scheme names and related constants to align with the new namespace structure. Revised comments and documentation to reflect the new namespace, ensuring clarity and consistency in the codebase.
173 lines
10 KiB
Plaintext
173 lines
10 KiB
Plaintext
@page "/sender/login"
|
|
@rendermode InteractiveWebAssembly
|
|
@using EnvelopeGenerator.Server.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="M11 6a3 3 0 1 1-6 0 3 3 0 0 1 6 0z"/>
|
|
<path fill-rule="evenodd" d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8zm8-7a7 7 0 0 0-5.468 11.37C3.242 11.226 4.805 10 8 10s4.757 1.225 5.468 2.37A7 7 0 0 0 8 1z"/>
|
|
</svg>
|
|
</div>
|
|
<h5 class="mb-0 fw-semibold">Sender Anmeldung</h5>
|
|
<p class="mb-0 mt-1 opacity-75" style="font-size: 0.85rem;">Sicherer Zugang zum Sender-Dashboard</p>
|
|
</div>
|
|
|
|
<div class="card-body p-4">
|
|
|
|
<p class="text-muted mb-4" style="font-size: 0.875rem; line-height: 1.5;">
|
|
Bitte melden Sie sich mit Ihren Zugangsdaten an, um auf das Sender-Dashboard zuzugreifen.
|
|
</p>
|
|
|
|
@if (LoginResult == SenderLoginResult.InvalidCredentials) {
|
|
<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ültige Anmeldedaten.</strong><br />
|
|
<span style="font-size:0.85rem;">Benutzername oder Passwort ist falsch. Bitte versuchen Sie es erneut.</span>
|
|
</div>
|
|
</div>
|
|
} else if (LoginResult == SenderLoginResult.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-3">
|
|
<label class="form-label fw-medium" for="login-username">
|
|
Benutzername
|
|
<span class="text-danger ms-1">*</span>
|
|
</label>
|
|
<div class="input-group">
|
|
<span class="input-group-text bg-light">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#6c757d" viewBox="0 0 16 16">
|
|
<path d="M3 14s-1 0-1-1 1-4 6-4 6 3 6 4-1 1-1 1H3Zm5-6a3 3 0 1 0 0-6 3 3 0 0 0 0 6Z"/>
|
|
</svg>
|
|
</span>
|
|
<input id="login-username"
|
|
type="text"
|
|
class="form-control @(LoginResult == SenderLoginResult.InvalidCredentials ? "is-invalid" : null)"
|
|
placeholder="Benutzername eingeben"
|
|
@bind="Username"
|
|
@bind:event="oninput"
|
|
@onkeydown="OnKeyDownAsync"
|
|
disabled="@IsLoading"
|
|
autocomplete="username" />
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mb-4">
|
|
<label class="form-label fw-medium" for="login-password">
|
|
Passwort
|
|
<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="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>
|
|
<input id="login-password"
|
|
type="@(ShowPassword ? "text" : "password")"
|
|
class="form-control border-start-0 border-end-0 @(LoginResult == SenderLoginResult.InvalidCredentials ? "is-invalid" : null)"
|
|
placeholder="Passwort eingeben"
|
|
@bind="Password"
|
|
@bind:event="oninput"
|
|
@onkeydown="OnKeyDownAsync"
|
|
disabled="@IsLoading"
|
|
autocomplete="current-password" />
|
|
<button type="button"
|
|
class="btn btn-outline-secondary border-start-0"
|
|
style="border-left: none;"
|
|
tabindex="-1"
|
|
@onclick="() => ShowPassword = !ShowPassword">
|
|
@if (ShowPassword) {
|
|
<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(Username) || string.IsNullOrWhiteSpace(Password))">
|
|
@if (IsLoading) {
|
|
<span class="spinner-border spinner-border-sm me-2" role="status" aria-hidden="true"></span>
|
|
<span>Anmelden …</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 fill-rule="evenodd" d="M10 3.5a.5.5 0 0 0-.5-.5h-8a.5.5 0 0 0-.5.5v9a.5.5 0 0 0 .5.5h8a.5.5 0 0 0 .5-.5v-2a.5.5 0 0 1 1 0v2A1.5 1.5 0 0 1 9.5 14h-8A1.5 1.5 0 0 1 0 12.5v-9A1.5 1.5 0 0 1 1.5 2h8A1.5 1.5 0 0 1 11 3.5v2a.5.5 0 0 1-1 0v-2z"/>
|
|
<path fill-rule="evenodd" d="M4.146 8.354a.5.5 0 0 1 0-.708l3-3a.5.5 0 1 1 .708.708L5.707 7.5H14.5a.5.5 0 0 1 0 1H5.707l2.147 2.146a.5.5 0 0 1-.708.708l-3-3z"/>
|
|
</svg>
|
|
<span>Anmelden</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 Administrator.
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
@code {
|
|
string Username = string.Empty;
|
|
string Password = string.Empty;
|
|
bool ShowPassword;
|
|
bool IsLoading;
|
|
SenderLoginResult? LoginResult;
|
|
|
|
async Task OnKeyDownAsync(Microsoft.AspNetCore.Components.Web.KeyboardEventArgs e) {
|
|
if (e.Key == "Enter")
|
|
await SubmitAsync();
|
|
}
|
|
|
|
async Task SubmitAsync() {
|
|
if (string.IsNullOrWhiteSpace(Username) || string.IsNullOrWhiteSpace(Password) || IsLoading) return;
|
|
|
|
IsLoading = true;
|
|
LoginResult = null;
|
|
await InvokeAsync(StateHasChanged);
|
|
|
|
var result = await AuthService.LoginSenderAsync(Username.Trim(), Password.Trim());
|
|
|
|
if (result == SenderLoginResult.Success) {
|
|
Navigation.NavigateTo("/sender", forceLoad: true);
|
|
return;
|
|
}
|
|
|
|
LoginResult = result;
|
|
IsLoading = false;
|
|
await InvokeAsync(StateHasChanged);
|
|
}
|
|
}
|