174 lines
6.4 KiB
Plaintext
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;
|
|
}
|
|
|
|
}
|