This commit is contained in:
rossmill76 committed 2026-03-02 11:50:08 +00:00
1 parent 2cf6128a85
commit 45a5e3fc5e
11 files changed
+428 -40

No files matched your search

+54 -20
View File
@@ -137,8 +137,8 @@ else
}
<div class="card mb-4">
<div class="card-header d-flex justify-content-between align-items-center">
<ul class="nav nav-tabs card-header-tabs">
<div class="card-header d-flex justify-content-between align-items-center flex-wrap gap-2">
<ul class="nav nav-tabs card-header-tabs" style="flex-grow: 0;">
<li class="nav-item">
<button class="nav-link @(activeTab == "recent" ? "active" : "")" @onclick='() => { activeTab = "recent"; recentPage = 1; }'>
Recent <span class="badge bg-secondary ms-1">@filteredRecent.Count</span>
@@ -150,7 +150,11 @@ else
</button>
</li>
</ul>
<button class="btn btn-sm btn-primary" @onclick="OpenAddModal">+ Add</button>
<div class="d-flex align-items-center gap-2">
<input type="search" class="form-control form-control-sm" style="max-width: 180px;"
placeholder="Search..." @bind="dashboardSearchQuery" @bind:event="oninput" @bind:after="OnDashboardSearchChanged" />
<button class="btn btn-sm btn-primary" @onclick="OpenAddModal">+ Add</button>
</div>
</div>
@if (data.Accounts.Count > 1)
{
@@ -303,19 +307,31 @@ else
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Delete Recurring Transaction</h5>
<h5 class="modal-title">@(pendingDeleteIsRecurring ? "Delete Recurring Transaction" : "Delete Transaction")</h5>
<button type="button" class="btn-close" @onclick="CancelDelete"></button>
</div>
<div class="modal-body">
<p>
<strong>@pendingDeleteTransaction.Description</strong> is part of a recurring series.
</p>
<p>Would you like to delete just this transaction, or all future transactions in the series?</p>
<p>Are you sure you want to delete <strong>@pendingDeleteTransaction.Description</strong>?</p>
@if (pendingDeleteIsRecurring)
{
<p>This transaction is part of a recurring series. Would you like to delete just this one, or all future transactions in the series?</p>
}
else
{
<p class="text-danger mb-0">This action cannot be undone.</p>
}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" @onclick="CancelDelete">Cancel</button>
<button type="button" class="btn btn-outline-danger" @onclick="DeleteSingle">This One Only</button>
<button type="button" class="btn btn-danger" @onclick="DeleteSeries">All Future in Series</button>
@if (pendingDeleteIsRecurring)
{
<button type="button" class="btn btn-outline-danger" @onclick="DeleteSingle">This One Only</button>
<button type="button" class="btn btn-danger" @onclick="DeleteSeries">All Future in Series</button>
}
else
{
<button type="button" class="btn btn-danger" @onclick="DeleteSingle">Delete</button>
}
</div>
</div>
</div>
@@ -347,12 +363,29 @@ else
// Account filter
private HashSet<int> hiddenAccountIds = [];
private string dashboardSearchQuery = string.Empty;
private List<Transaction> filteredRecent => data is null ? []
: data.RecentTransactions.Where(t => !hiddenAccountIds.Contains(t.AccountId)).ToList();
: data.RecentTransactions
.Where(t => !hiddenAccountIds.Contains(t.AccountId))
.Where(t => MatchesSearch(t))
.ToList();
private List<Transaction> filteredUpcoming => data is null ? []
: data.UpcomingTransactions.Where(t => !hiddenAccountIds.Contains(t.AccountId)).ToList();
: data.UpcomingTransactions
.Where(t => !hiddenAccountIds.Contains(t.AccountId))
.Where(t => MatchesSearch(t))
.ToList();
private bool MatchesSearch(Transaction t)
{
if (string.IsNullOrWhiteSpace(dashboardSearchQuery)) return true;
var q = dashboardSearchQuery.Trim();
return t.Description.Contains(q, StringComparison.OrdinalIgnoreCase)
|| t.Account.Name.Contains(q, StringComparison.OrdinalIgnoreCase)
|| (t.Category?.Name?.Contains(q, StringComparison.OrdinalIgnoreCase) ?? false)
|| t.Amount.ToString("F2").Contains(q, StringComparison.OrdinalIgnoreCase);
}
private void ToggleAccountFilter(int accountId)
{
@@ -362,6 +395,12 @@ else
upcomingPage = 1;
}
private void OnDashboardSearchChanged()
{
recentPage = 1;
upcomingPage = 1;
}
// Pagination
private int recentPage = 1;
private int upcomingPage = 1;
@@ -509,18 +548,13 @@ else
// Delete confirmation state
private bool showDeleteModal;
private Transaction? pendingDeleteTransaction;
private bool pendingDeleteIsRecurring;
private void ConfirmDelete(Transaction t)
{
pendingDeleteTransaction = t;
if (t.RecurrenceType != RecurrenceType.None || t.ParentTransactionId is not null)
{
showDeleteModal = true;
}
else
{
_ = DeleteSingle();
}
pendingDeleteIsRecurring = t.RecurrenceType != RecurrenceType.None || t.ParentTransactionId is not null;
showDeleteModal = true;
}
private async Task DeleteSingle()