Files
ChronoCCG/Chrono/Web/Pages/Login.razor
T
6d486f49 1d6207fbfe API Test
2026-08-17 00:45:08 -04:00

174 lines
6.4 KiB
Plaintext

@page "/login"
@inject AuthService Auth
@inject NetworkStatusService NetworkStatus
@inject NavigationManager Navigation
@implements IDisposable
<PageTitle>Login - Chrono CCG</PageTitle>
<div class="container py-5" style="max-width: 500px;">
<div class="card bg-dark text-white border-secondary shadow">
<div class="card-header border-secondary text-center py-3">
<h4 class="mb-0 fw-bold">
<i class="bi bi-shield-lock-fill text-warning me-2"></i> Chrono API Account
</h4>
</div>
<div class="card-body p-4">
@if (!NetworkStatus.IsOnline)
{
<div class="alert alert-warning d-flex align-items-center mb-0" role="alert">
<i class="bi bi-wifi-off fs-3 me-3"></i>
<div>
<h6 class="alert-heading fw-bold mb-1">Offline Mode</h6>
<p class="small mb-0">Login is only available when you are online. Please check your network
connection to access the Chrono CCG API and sync notes.</p>
</div>
</div>
}
else if (Auth.IsLoggedIn)
{
<div class="text-center py-3">
<div class="mb-3">
<i class="bi bi-person-check-fill text-success" style="font-size: 3rem;"></i>
</div>
<h5 class="fw-bold mb-1">Logged In</h5>
<p class="text-secondary small mb-4">
You are signed in as <span
class="text-warning fw-bold font-monospace">@Auth.CurrentUsername</span>. Your private card
notes and decks are active.
</p>
<div class="d-grid gap-2">
<a href="" class="btn btn-warning fw-semibold">
<i class="bi bi-collection-fill me-1"></i> Browse Cards
</a>
<button class="btn btn-outline-danger" @onclick="HandleLogout">
<i class="bi bi-box-arrow-right me-1"></i> Log Out
</button>
</div>
</div>
}
else
{
@if (!string.IsNullOrEmpty(errorMessage))
{
<div class="alert alert-danger py-2 small" role="alert">
<i class="bi bi-exclamation-triangle-fill me-2"></i> @errorMessage
</div>
}
@if (!string.IsNullOrEmpty(successMessage))
{
<div class="alert alert-success py-2 small" role="alert">
<i class="bi bi-check-circle-fill me-2"></i> @successMessage
</div>
}
<form @onsubmit="HandleLogin">
<div class="mb-3">
<label class="form-label text-secondary small fw-semibold">USERNAME</label>
<div class="input-group">
<span class="input-group-text bg-dark border-secondary text-secondary"><i
class="bi bi-person-fill"></i></span>
<input type="text" class="form-control bg-dark border-secondary text-white"
placeholder="e.g. player1 or admin" @bind="username" disabled="@isLoading" required/>
</div>
</div>
<div class="mb-4">
<label class="form-label text-secondary small fw-semibold">PASSWORD</label>
<div class="input-group">
<span class="input-group-text bg-dark border-secondary text-secondary"><i
class="bi bi-key-fill"></i></span>
<input type="password" class="form-control bg-dark border-secondary text-white"
placeholder="Enter password" @bind="password" disabled="@isLoading" required/>
</div>
</div>
<div class="d-grid">
<button type="submit" class="btn btn-warning fw-bold" disabled="@isLoading">
@if (isLoading)
{
<span class="spinner-border spinner-border-sm me-2" role="status"></span>
<span>Logging In...</span>
}
else
{
<i class="bi bi-box-arrow-in-right me-1"></i>
<span>Log In</span>
}
</button>
</div>
</form>
}
</div>
</div>
</div>
@code {
private string username = "";
private string password = "";
private bool isLoading;
private string? errorMessage;
private string? successMessage;
protected override async Task OnInitializedAsync()
{
NetworkStatus.StatusChanged += OnStatusChanged;
Auth.AuthStateChanged += OnAuthStateChanged;
await Auth.InitializeAsync();
}
private void OnStatusChanged(bool isOnline)
{
InvokeAsync(StateHasChanged);
}
private void OnAuthStateChanged()
{
InvokeAsync(StateHasChanged);
}
private async Task HandleLogin()
{
errorMessage = null;
successMessage = null;
if (string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(password))
{
errorMessage = "Please enter both username and password.";
return;
}
isLoading = true;
try
{
var result = await Auth.LoginAsync(username.Trim(), password);
if (result.Success)
{
successMessage = result.Message;
Navigation.NavigateTo("");
}
else
{
errorMessage = result.Message;
}
}
finally
{
isLoading = false;
}
}
private async Task HandleLogout()
{
await Auth.LogoutAsync();
}
public void Dispose()
{
NetworkStatus.StatusChanged -= OnStatusChanged;
Auth.AuthStateChanged -= OnAuthStateChanged;
}
}