Files
RpgRoller/RpgRoller/Components/Pages/HomeControls/AuthSection.razor

133 lines
5.2 KiB
Plaintext

@using System.Diagnostics.CodeAnalysis
@using RpgRoller.Components.Pages
@attribute [ExcludeFromCodeCoverage]
<main class="auth-shell">
<h1>RpgRoller</h1>
<p class="auth-subtitle">Register or log in to join a campaign session.</p>
@if (!string.IsNullOrWhiteSpace(StatusMessage))
{
<p class="status-message @(StatusIsError ? "error" : "success")">@StatusMessage</p>
}
<div class="auth-grid">
<section class="card auth-card">
<h2>Register</h2>
@if (!string.IsNullOrWhiteSpace(RegisterState.ErrorMessage))
{
<p class="form-error">@RegisterState.ErrorMessage</p>
}
<form class="form-grid" @onsubmit="SubmitRegisterAsync" @onsubmit:preventDefault>
<label for="register-username">Username</label>
<input id="register-username" @bind="RegisterState.Model.Username" @bind:event="oninput" autocomplete="username" />
@if (RegisterState.Errors.TryGetValue("username", out var registerUsernameError))
{
<p class="field-error">@registerUsernameError</p>
}
<label for="register-display-name">Display name</label>
<input id="register-display-name" @bind="RegisterState.Model.DisplayName" @bind:event="oninput" autocomplete="name" />
@if (RegisterState.Errors.TryGetValue("displayName", out var registerDisplayNameError))
{
<p class="field-error">@registerDisplayNameError</p>
}
<label for="register-password">Password</label>
<input id="register-password" type="password" @bind="RegisterState.Model.Password" @bind:event="oninput" autocomplete="new-password" />
@if (RegisterState.Errors.TryGetValue("password", out var registerPasswordError))
{
<p class="field-error">@registerPasswordError</p>
}
<button type="submit" disabled="@IsMutating">@(IsMutating ? "Registering..." : "Register")</button>
</form>
</section>
<section class="card auth-card">
<h2>Login</h2>
@if (!string.IsNullOrWhiteSpace(LoginState.ErrorMessage))
{
<p class="form-error">@LoginState.ErrorMessage</p>
}
<form class="form-grid" @onsubmit="SubmitLoginAsync" @onsubmit:preventDefault>
<label for="login-username">Username</label>
<input id="login-username" @bind="LoginState.Model.Username" @bind:event="oninput" autocomplete="username" />
@if (LoginState.Errors.TryGetValue("username", out var loginUsernameError))
{
<p class="field-error">@loginUsernameError</p>
}
<label for="login-password">Password</label>
<input id="login-password" type="password" @bind="LoginState.Model.Password" @bind:event="oninput" autocomplete="current-password" />
@if (LoginState.Errors.TryGetValue("password", out var loginPasswordError))
{
<p class="field-error">@loginPasswordError</p>
}
<button type="submit" disabled="@IsMutating">@(IsMutating ? "Logging in..." : "Login")</button>
</form>
</section>
</div>
</main>
@code {
private FormState<RegisterFormModel> RegisterState { get; } = new();
private FormState<LoginFormModel> LoginState { get; } = new();
[Parameter]
public bool IsMutating { get; set; }
[Parameter]
public string? StatusMessage { get; set; }
[Parameter]
public bool StatusIsError { get; set; }
[Parameter]
public Func<RegisterFormModel, Task<FormSubmissionResult>> RegisterSubmitted { get; set; } = _ => Task.FromResult(new FormSubmissionResult());
[Parameter]
public Func<LoginFormModel, Task<FormSubmissionResult>> LoginSubmitted { get; set; } = _ => Task.FromResult(new FormSubmissionResult());
private async Task SubmitRegisterAsync()
{
RegisterState.ResetValidation();
var result = await RegisterSubmitted.Invoke(new RegisterFormModel
{
Username = RegisterState.Model.Username,
DisplayName = RegisterState.Model.DisplayName,
Password = RegisterState.Model.Password
});
ApplyResult(RegisterState, result);
if (result.IsSuccess)
{
RegisterState.Model.Password = string.Empty;
}
}
private async Task SubmitLoginAsync()
{
LoginState.ResetValidation();
var result = await LoginSubmitted.Invoke(new LoginFormModel
{
Username = LoginState.Model.Username,
Password = LoginState.Model.Password
});
ApplyResult(LoginState, result);
if (result.IsSuccess)
{
LoginState.Model.Password = string.Empty;
}
}
private static void ApplyResult<TModel>(FormState<TModel> state, FormSubmissionResult result)
where TModel : new()
{
state.Errors.Clear();
foreach (var (key, value) in result.Errors)
{
state.Errors[key] = value;
}
state.ErrorMessage = result.ErrorMessage;
}
}