Files
Budgeteer/BudgetApp/Components/Layout/NavMenu.razor
T
2026-03-02 16:00:18 +00:00

120 lines
4.2 KiB
Plaintext

@inject AccountService AccountService
@inject AuthenticationStateProvider AuthStateProvider
@inject AppState AppState
@inject NavigationManager Navigation
@implements IDisposable
@rendermode InteractiveServer
<div class="top-row ps-3 navbar navbar-dark">
<div class="container-fluid">
<a class="navbar-brand" href="">💰 Budgeteer <span class="badge bg-warning text-dark" style="font-size: 0.55em; vertical-align: middle;">beta</span></a>
</div>
</div>
<input type="checkbox" title="Navigation menu" class="navbar-toggler" />
<div class="nav-scrollable" onclick="document.querySelector('.navbar-toggler').click()">
<nav class="nav flex-column">
<div class="nav-item px-3">
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
<span class="bi bi-house-door-fill-nav-menu" aria-hidden="true"></span> Dashboard
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="accounts">
<span class="bi bi-plus-square-fill-nav-menu" aria-hidden="true"></span> Accounts
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="transactions">
<span class="bi bi-arrow-left-right-nav-menu" aria-hidden="true"></span> Transactions
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="categories">
<span class="bi bi-tag-nav-menu" aria-hidden="true"></span> Categories
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="settings">
<span class="bi bi-gear-nav-menu" aria-hidden="true"></span> Settings
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="help">
<span class="bi bi-question-circle-nav-menu" aria-hidden="true"></span> Help
</NavLink>
</div>
<div class="nav-item px-3 mt-auto">
<NavLink class="nav-link" href="logout">
<span class="bi bi-box-arrow-right-nav-menu" aria-hidden="true"></span> Logout
</NavLink>
</div>
</nav>
@if (accounts is not null && accounts.Count > 0)
{
<div class="nav-balances px-3">
<div class="balances-header">Balances</div>
@foreach (var account in accounts)
{
<div class="balance-item" style="cursor: pointer;" title="Click to manage accounts" @onclick="NavigateToAccounts">
<div class="balance-color" style="background-color: @account.Color;"></div>
<div class="balance-details">
<span class="balance-name">@account.Name</span>
<span class="balance-amount @(account.CurrentBalance >= 0 ? "text-success" : "text-danger")">
@account.FormatAmount(account.CurrentBalance)
</span>
</div>
</div>
}
</div>
}
</div>
@code {
private List<Account>? accounts;
protected override async Task OnInitializedAsync()
{
AppState.OnAccountsChanged += HandleAccountsChanged;
var authState = await AuthStateProvider.GetAuthenticationStateAsync();
var userId = authState.User.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)?.Value;
if (userId is not null)
{
accounts = await AccountService.GetAccountsAsync(userId);
}
}
private async void HandleAccountsChanged()
{
var authState = await AuthStateProvider.GetAuthenticationStateAsync();
var userId = authState.User.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)?.Value;
if (userId is not null)
{
accounts = await AccountService.GetAccountsAsync(userId);
await InvokeAsync(StateHasChanged);
}
}
public void Dispose()
{
AppState.OnAccountsChanged -= HandleAccountsChanged;
}
private void NavigateToAccounts()
{
Navigation.NavigateTo("accounts");
}
}