Files
ApplianceRepair/Components/Account/Pages/Login.razor
2026-04-25 22:45:59 -05:00

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; }
}
}