This commit is contained in:
rossmill76 committed 2026-03-02 16:00:18 +00:00
1 parent 67a2bd527a
commit 8313d8e85a
9 files changed
+122 -7

No files matched your search

+110 -1
View File
@@ -7,11 +7,15 @@
@inject AuthenticationStateProvider AuthStateProvider
@inject ApplicationDbContext DbContext
@inject NavigationManager Navigation
@inject AppState AppState
@rendermode InteractiveServer
<PageTitle>Settings</PageTitle>
<h3 class="mb-4">Settings</h3>
<h3 class="mb-4">
Settings
<span class="badge bg-warning text-dark ms-2" style="font-size: 0.4em; vertical-align: middle;">beta</span>
</h3>
@* ── Change Password ── *@
<div class="card mb-4">
@@ -52,6 +56,49 @@
</div>
</div>
@* ── Reset Data ── *@
<div class="card mb-4 border-warning">
<div class="card-header bg-warning">
<h5 class="mb-0">Reset Data</h5>
</div>
<div class="card-body">
<p class="fw-semibold">
This will permanently delete all your accounts, transactions and categories, giving you a clean slate. Your user account and password will be kept.
</p>
@if (resetSuccess)
{
<div class="alert alert-success">All data has been reset successfully.</div>
}
@if (!string.IsNullOrEmpty(resetError))
{
<div class="alert alert-danger">@resetError</div>
}
@if (!confirmingReset)
{
<button class="btn btn-outline-warning" @onclick="() => confirmingReset = true">
Reset All Data
</button>
}
else
{
<div class="alert alert-warning">
<strong>Are you sure?</strong> This cannot be undone. Type <code>I UNDERSTAND</code> and enter your password to confirm.
</div>
<div class="mb-3" style="max-width: 400px;">
<input type="text" class="form-control mb-2" placeholder="Type I UNDERSTAND to confirm" @bind="resetConfirmation" />
<input type="password" class="form-control mb-2" placeholder="Enter your password" @bind="resetPassword" />
<div class="d-flex gap-2">
<button class="btn btn-warning" @onclick="ResetData">Confirm Reset</button>
<button class="btn btn-secondary" @onclick="CancelReset">Cancel</button>
</div>
</div>
}
</div>
</div>
@* ── Delete Account ── *@
<div class="card border-danger">
<div class="card-header bg-danger text-white">
@@ -88,6 +135,9 @@
</div>
@code {
private static readonly string appVersion =
typeof(Program).Assembly.GetName().Version?.ToString(3) ?? "0.0.0";
private ChangePasswordForm passwordForm = new();
private bool passwordSuccess;
private string? passwordError;
@@ -96,6 +146,12 @@
private string deletePassword = string.Empty;
private string? deleteError;
private bool confirmingReset;
private string resetConfirmation = string.Empty;
private string resetPassword = string.Empty;
private string? resetError;
private bool resetSuccess;
private async Task ChangePassword()
{
passwordSuccess = false;
@@ -166,6 +222,59 @@
deleteError = null;
}
private async Task ResetData()
{
resetError = null;
resetSuccess = false;
var authState = await AuthStateProvider.GetAuthenticationStateAsync();
var userIdClaim = authState.User.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)?.Value;
if (userIdClaim is null) return;
var user = await UserManager.FindByIdAsync(userIdClaim);
if (user is null) return;
if (!string.Equals(resetConfirmation?.Trim(), "I UNDERSTAND", StringComparison.Ordinal))
{
resetError = "Please type 'I UNDERSTAND' exactly to confirm.";
return;
}
var passwordValid = await UserManager.CheckPasswordAsync(user, resetPassword);
if (!passwordValid)
{
resetError = "Incorrect password.";
return;
}
await DbContext.Transactions
.Where(t => t.Account.UserId == userIdClaim)
.ExecuteDeleteAsync();
await DbContext.Accounts
.Where(a => a.UserId == userIdClaim)
.ExecuteDeleteAsync();
await DbContext.Categories
.Where(c => c.UserId == userIdClaim)
.ExecuteDeleteAsync();
confirmingReset = false;
resetConfirmation = string.Empty;
resetPassword = string.Empty;
resetSuccess = true;
AppState.NotifyAccountsChanged();
}
private void CancelReset()
{
confirmingReset = false;
resetConfirmation = string.Empty;
resetPassword = string.Empty;
resetError = null;
}
private sealed class ChangePasswordForm
{
[System.ComponentModel.DataAnnotations.Required(ErrorMessage = "Current password is required")]