178 lines
5.0 KiB
Plaintext
178 lines
5.0 KiB
Plaintext
|
|
@page "/Account/Login"
|
||
|
|
|
||
|
|
@using System.ComponentModel.DataAnnotations
|
||
|
|
@using Microsoft.AspNetCore.Authentication
|
||
|
|
@using Microsoft.AspNetCore.Identity
|
||
|
|
@using ApplianceRepair
|
||
|
|
|
||
|
|
@inject SignInManager<IdentityUser> SignInManager
|
||
|
|
@inject ILogger<Login> Logger
|
||
|
|
@inject NavigationManager NavigationManager
|
||
|
|
@inject IdentityRedirectManager RedirectManager
|
||
|
|
@inject BusinessConfigReader ConfigReader
|
||
|
|
|
||
|
|
<PageTitle>Login</PageTitle>
|
||
|
|
|
||
|
|
<header class="hero">
|
||
|
|
<div class="login-card">
|
||
|
|
<h1><span>Login</span></h1>
|
||
|
|
|
||
|
|
<StatusMessage Message="@errorMessage" />
|
||
|
|
|
||
|
|
<EditForm Model="Input" method="post" OnValidSubmit="LoginUser" FormName="login" class="text-start login-form">
|
||
|
|
<DataAnnotationsValidator />
|
||
|
|
|
||
|
|
<div class="form-group mb-3">
|
||
|
|
<label class="form-label text-white">Email Address</label>
|
||
|
|
<InputText @bind-Value="Input.Email" class="form-control custom-input" autocomplete="username" placeholder="admin@domain.com" />
|
||
|
|
<ValidationMessage For="() => Input.Email" class="text-danger" />
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="form-group mb-3">
|
||
|
|
<label class="form-label text-white">Password</label>
|
||
|
|
<InputText type="password" @bind-Value="Input.Password" class="form-control custom-input" autocomplete="current-password" placeholder="••••••••" />
|
||
|
|
<ValidationMessage For="() => Input.Password" class="text-danger" />
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="cta-group">
|
||
|
|
<button type="submit" class="btn-login">Login</button>
|
||
|
|
</div>
|
||
|
|
</EditForm>
|
||
|
|
|
||
|
|
@* <div class="mt-4">
|
||
|
|
<a href="Account/ForgotPassword" style="color: #4cc9f0; text-decoration: none; font-size: 0.9rem;">Forgot password?</a>
|
||
|
|
</div> *@
|
||
|
|
</div>
|
||
|
|
</header>
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
<style>
|
||
|
|
body {
|
||
|
|
overflow: hidden;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Specific styles to blend the login form into your theme */
|
||
|
|
.login-card {
|
||
|
|
padding: 40px;
|
||
|
|
border-radius: 12px;
|
||
|
|
margin: 0 auto;
|
||
|
|
backdrop-filter: blur(10px);
|
||
|
|
background: #0056b3;
|
||
|
|
min-height: 500px;
|
||
|
|
width: 100%;
|
||
|
|
max-width: 450px;
|
||
|
|
display: flex;
|
||
|
|
flex-direction: column;
|
||
|
|
justify-content: center;
|
||
|
|
align-items: center;
|
||
|
|
}
|
||
|
|
|
||
|
|
.login-form .form-group {
|
||
|
|
margin-bottom: 2rem !important; /* Adjust this value to your liking */
|
||
|
|
}
|
||
|
|
|
||
|
|
.custom-input {
|
||
|
|
background: rgba(255, 255, 255, 0.9) !important;
|
||
|
|
border: none;
|
||
|
|
padding: 12px;
|
||
|
|
border-radius: 5px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.validation-errors {
|
||
|
|
list-style: none;
|
||
|
|
padding: 0;
|
||
|
|
color: #e63946;
|
||
|
|
font-weight: bold;
|
||
|
|
}
|
||
|
|
|
||
|
|
.hero {
|
||
|
|
background: linear-gradient(rgba(0,0,0,0.6), rgba(0,0,0,0.6)), url('https://images.unsplash.com/photo-1581092918056-0c4c3acd3789?auto=format&fit=crop&w=1200&q=80');
|
||
|
|
background-size: cover;
|
||
|
|
background-position: center;
|
||
|
|
color: #fff;
|
||
|
|
padding: 0;
|
||
|
|
text-align: center;
|
||
|
|
width: 100vw;
|
||
|
|
height: 100vh;
|
||
|
|
overflow: hidden;
|
||
|
|
display: flex;
|
||
|
|
flex-direction: column;
|
||
|
|
justify-content: center;
|
||
|
|
align-items: center;
|
||
|
|
overflow: hidden;
|
||
|
|
}
|
||
|
|
|
||
|
|
.btn-login {
|
||
|
|
background: #4CAF50;
|
||
|
|
color: white;
|
||
|
|
border: none;
|
||
|
|
padding: 10px 40px;
|
||
|
|
border-radius: 50px;
|
||
|
|
font-weight: 700;
|
||
|
|
cursor: pointer;
|
||
|
|
box-shadow: 0 4px 15px rgba(76, 175, 80, 0.3);
|
||
|
|
transition: all 0.3s ease;
|
||
|
|
max-width: 30vw;
|
||
|
|
}
|
||
|
|
|
||
|
|
.btn-login:hover {
|
||
|
|
transform: translateY(-2px);
|
||
|
|
background: #43a047;
|
||
|
|
}
|
||
|
|
</style>
|
||
|
|
|
||
|
|
@code {
|
||
|
|
private string? errorMessage;
|
||
|
|
|
||
|
|
[CascadingParameter]
|
||
|
|
private HttpContext HttpContext { get; set; } = default!;
|
||
|
|
|
||
|
|
[SupplyParameterFromForm]
|
||
|
|
private InputModel Input { get; set; } = default!;
|
||
|
|
|
||
|
|
[SupplyParameterFromQuery]
|
||
|
|
private string? ReturnUrl { get; set; }
|
||
|
|
|
||
|
|
protected override async Task OnInitializedAsync()
|
||
|
|
{
|
||
|
|
Input ??= new();
|
||
|
|
|
||
|
|
if (HttpMethods.IsGet(HttpContext.Request.Method))
|
||
|
|
{
|
||
|
|
await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public async Task LoginUser()
|
||
|
|
{
|
||
|
|
var result = await SignInManager.PasswordSignInAsync(Input.Email, Input.Password, Input.RememberMe, lockoutOnFailure: false);
|
||
|
|
if (result.Succeeded)
|
||
|
|
{
|
||
|
|
Logger.LogInformation("Admin user logged in.");
|
||
|
|
RedirectManager.RedirectTo(ReturnUrl);
|
||
|
|
}
|
||
|
|
else if (result.IsLockedOut)
|
||
|
|
{
|
||
|
|
Logger.LogWarning("Account locked.");
|
||
|
|
RedirectManager.RedirectTo("Account/Lockout");
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
errorMessage = "Invalid login credentials.";
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private sealed class InputModel
|
||
|
|
{
|
||
|
|
[Required]
|
||
|
|
[EmailAddress]
|
||
|
|
public string Email { get; set; } = "";
|
||
|
|
|
||
|
|
[Required]
|
||
|
|
[DataType(DataType.Password)]
|
||
|
|
public string Password { get; set; } = "";
|
||
|
|
|
||
|
|
public bool RememberMe { get; set; }
|
||
|
|
}
|
||
|
|
}
|