Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 19 additions & 11 deletions src/Money.Blazor.Host/Pages/ExpenseChecklistMonth.razor
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,25 @@
<ExceptionPanel />

<div class="container-narrow">
<ul class="nav nav-pills mb-3">
<li>
<a class="nav-link" href="@Navigator.UrlOverviewIncomes(SelectedPeriod)">Incomes</a>
</li>
<li>
<a class="nav-link" href="@Navigator.UrlOverview(SelectedPeriod)">Expenses</a>
</li>
<li>
<a class="nav-link active" href="@Navigator.UrlChecklist(SelectedPeriod)">Checklist</a>
</li>
</ul>
<div class="d-flex align-items-center mb-3">
<div>
<PeriodSelector Selected="SelectedPeriod" Previous="PeriodGuesses" ExactGetter="GetMonthsAsync" LinkFactory="@(month => Navigator.UrlChecklist(month))" />
<span class="ps-2">
<Loading Context="@Loading" />
</span>
</div>
<ul class="nav nav-pills ps-3">
<li>
<a class="nav-link" href="@Navigator.UrlOverviewIncomes(SelectedPeriod)">Incomes</a>
</li>
<li>
<a class="nav-link" href="@Navigator.UrlOverview(SelectedPeriod)">Expenses</a>
</li>
<li>
<a class="nav-link active" href="@Navigator.UrlChecklist(SelectedPeriod)">Checklist</a>
</li>
</ul>
</div>

<Loading Context="@Loading">
@if (Models.Count == 0)
Expand Down
7 changes: 7 additions & 0 deletions src/Money.Blazor.Host/Pages/ExpenseChecklistMonth.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ Navigator Navigator
public int Month { get; set; }

protected MonthModel SelectedPeriod { get; set; }
protected IReadOnlyCollection<MonthModel> PeriodGuesses { get; set; }
protected List<ExpenseChecklistModel> Models { get; set; } = new();
protected LoadingContext Loading { get; set; } = new();

Expand All @@ -62,9 +63,15 @@ protected override async Task OnParametersSetAsync()
private void EnsureSelectedPeriod()
{
if (SelectedPeriod == null)
{
SelectedPeriod = new MonthModel(Year, Month);
PeriodGuesses = new MonthModel[] { SelectedPeriod - 1, SelectedPeriod - 2 };
}
}

protected async Task<IReadOnlyCollection<MonthModel>> GetMonthsAsync()
=> await Queries.QueryAsync(new ListMonthWithExpenseOrIncome());

private async Task LoadDataAsync()
{
using (Loading.Start())
Expand Down
69 changes: 39 additions & 30 deletions src/Money.Blazor.Host/Pages/Overview.razor
Original file line number Diff line number Diff line change
Expand Up @@ -25,38 +25,47 @@
var checklistUrl = ChecklistUrl();
var trendsUrl = TrendsSelectedPeriodUrl();
}
@if (incomeUrl != null || trendsUrl != null)
{
<ul class="nav nav-pills float-start">
@if (incomeUrl != null)
{
<li>
<a class="nav-link" href="@incomeUrl">Incomes</a>
</li>
}
<li>
<a class="nav-link active" href="@Navigator.UrlCurrent()">Expenses</a>
</li>
@if (checklistUrl != null)
{
<li>
<a class="nav-link" href="@checklistUrl">Checklist</a>
</li>
}
@if (trendsUrl != null)
{

<div class="d-flex align-items-center mb-3">
<div>
<PeriodSelector Selected="SelectedPeriod" Previous="PeriodGuesses" ExactGetter="GetPeriodsAsync" LinkFactory="UrlOverview" />
<span class="ps-2">
<Loading Context="@Loading" />
</span>
</div>
@if (incomeUrl != null || trendsUrl != null)
{
<ul class="nav nav-pills ps-3">
@if (incomeUrl != null)
{
<li>
<a class="nav-link" href="@incomeUrl">Incomes</a>
</li>
}
<li>
<a class="nav-link" href="@trendsUrl">Trends</a>
<a class="nav-link active" href="@Navigator.UrlCurrent()">Expenses</a>
</li>
}
</ul>
}

@if (Items?.Count > 0)
{
<SortButton TType="@OutcomeOverviewSortType" @bind-Current="@SortDescriptor" Changed="@OnSortChanged" />
}
<div class="clear"></div>
@if (checklistUrl != null)
{
<li>
<a class="nav-link" href="@checklistUrl">Checklist</a>
</li>
}
@if (trendsUrl != null)
{
<li>
<a class="nav-link" href="@trendsUrl">Trends</a>
</li>
}
</ul>
}
@if (Items?.Count > 0)
{
<span class="ms-auto">
<SortButton TType="@OutcomeOverviewSortType" @bind-Current="@SortDescriptor" Changed="@OnSortChanged" />
</span>
}
</div>

<div class="cards">
<ExpenseCardContext>
Expand Down
14 changes: 14 additions & 0 deletions src/Money.Blazor.Host/Pages/Overview.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public partial class Overview<T>(
protected string SubTitle { get; set; } = subTitle;

protected T SelectedPeriod { get; set; }
protected IReadOnlyCollection<T> PeriodGuesses { get; set; }
protected IKey CategoryKey { get; set; }
protected string CategoryName { get; set; }
protected List<OutcomeOverviewModel> Items { get; set; }
Expand Down Expand Up @@ -73,6 +74,7 @@ protected async override Task OnParametersSetAsync()
{
CategoryKey = CreateSelectedCategoryFromParameters();
SelectedPeriod = CreateSelectedItemFromParameters();
PeriodGuesses = CreatePeriodGuesses();

if (!CategoryKey.IsEmpty)
{
Expand All @@ -96,6 +98,9 @@ protected virtual IKey CreateSelectedCategoryFromParameters()
protected virtual T CreateSelectedItemFromParameters()
=> throw Ensure.Exception.NotImplemented($"Missing override for method '{nameof(CreateSelectedItemFromParameters)}'.");

protected virtual IReadOnlyCollection<T> CreatePeriodGuesses()
=> throw Ensure.Exception.NotImplemented($"Missing override for method '{nameof(CreatePeriodGuesses)}'.");

protected virtual string ListIncomeUrl()
=> null;

Expand Down Expand Up @@ -152,6 +157,15 @@ protected async Task<PagingLoadStatus> LoadDataAsync()
protected virtual IQuery<List<OutcomeOverviewModel>> CreateItemsQuery(int pageIndex)
=> throw Ensure.Exception.NotImplemented($"Missing override for method '{nameof(CreateItemsQuery)}'.");

protected virtual IQuery<List<T>> CreatePeriodsQuery()
=> throw Ensure.Exception.NotImplemented($"Missing override for method '{nameof(CreatePeriodsQuery)}'.");

protected async Task<IReadOnlyCollection<T>> GetPeriodsAsync()
=> await Queries.QueryAsync(CreatePeriodsQuery());

protected virtual string UrlOverview(T period)
=> throw Ensure.Exception.NotImplemented($"Missing override for method '{nameof(UrlOverview)}'.");

protected async void OnSortChanged()
{
Items = null;
Expand Down
52 changes: 29 additions & 23 deletions src/Money.Blazor.Host/Pages/OverviewIncome.razor
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,14 @@
<IncomeCreate @ref="CreateModal" />

<div class="container-narrow">
<Loading Context="@Loading" IsOverlay="true">
<ul class="nav nav-pills float-start">
<div class="d-flex align-items-center mb-3">
<div>
<PeriodSelector Selected="SelectedPeriod" Previous="PeriodGuesses" ExactGetter="GetPeriodsAsync" LinkFactory="UrlOverviewIncomes" />
<span class="ps-2">
<Loading Context="@Loading" IsOverlay="true" />
</span>
</div>
<ul class="nav nav-pills ps-3">
<li>
<a class="nav-link active" href="@Navigator.UrlCurrent()">Incomes</a>
</li>
Expand All @@ -28,32 +34,32 @@
</li>
}
</ul>

@if (Items?.Count > 0)
{
<SortButton TType="@IncomeOverviewSortType" @bind-Current="@SortDescriptor" Changed="@OnSortChanged" />
<span class="ms-auto">
<SortButton TType="@IncomeOverviewSortType" @bind-Current="@SortDescriptor" Changed="@OnSortChanged" />
</span>
}
<div class="clear"></div>
</div>

@if (Items != null)
@if (Items != null)
{
if (Items.Count > 0)
{
if (Items.Count > 0)
{
<div class="cards">
<IncomeCardContext>
@foreach (var item in Items)
{
<IncomeCard Model="@item" />
}
</IncomeCardContext>
</div>
<div class="cards">
<IncomeCardContext>
@foreach (var item in Items)
{
<IncomeCard Model="@item" />
}
</IncomeCardContext>
</div>

<Paging Context="@PagingContext" />
}
else
{
<Alert Title="No data." Message="Let's add some incomes." Mode="@AlertMode.Warning" CssClass="mt-3" />
}
<Paging Context="@PagingContext" />
}
else
{
<Alert Title="No data." Message="Let's add some incomes." Mode="@AlertMode.Warning" CssClass="mt-3" />
}
</Loading>
}
</div>
14 changes: 14 additions & 0 deletions src/Money.Blazor.Host/Pages/OverviewIncome.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public partial class OverviewIncome<T>(
protected string SubTitle { get; set; } = subTitle;

protected T SelectedPeriod { get; set; }
protected IReadOnlyCollection<T> PeriodGuesses { get; set; }
protected List<IncomeOverviewModel> Items { get; set; }

protected IncomeCreate CreateModal { get; set; }
Expand Down Expand Up @@ -68,6 +69,7 @@ protected override void OnParametersSet()
base.OnParametersSet();

SelectedPeriod = CreateSelectedItemFromParameters();
PeriodGuesses = CreatePeriodGuesses();
Reload();
}

Expand All @@ -80,6 +82,18 @@ protected virtual T CreateSelectedItemFromParameters()
protected virtual IQuery<List<IncomeOverviewModel>> CreateItemsQuery(int pageIndex)
=> throw Ensure.Exception.NotImplemented($"Missing override for method '{nameof(CreateItemsQuery)}'.");

protected virtual IReadOnlyCollection<T> CreatePeriodGuesses()
=> throw Ensure.Exception.NotImplemented($"Missing override for method '{nameof(CreatePeriodGuesses)}'.");

protected virtual IQuery<List<T>> CreatePeriodsQuery()
=> throw Ensure.Exception.NotImplemented($"Missing override for method '{nameof(CreatePeriodsQuery)}'.");

protected async Task<IReadOnlyCollection<T>> GetPeriodsAsync()
=> await Queries.QueryAsync(CreatePeriodsQuery());

protected virtual string UrlOverviewIncomes(T period)
=> throw Ensure.Exception.NotImplemented($"Missing override for method '{nameof(UrlOverviewIncomes)}'.");

protected virtual string ListExpenseUrl()
=> null;

Expand Down
9 changes: 9 additions & 0 deletions src/Money.Blazor.Host/Pages/OverviewMonth.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,15 @@ protected override void ClearPreviousParameters()
protected override MonthModel CreateSelectedItemFromParameters()
=> new MonthModel(Year.Value, Month.Value);

protected override IReadOnlyCollection<MonthModel> CreatePeriodGuesses()
=> new MonthModel[] { SelectedPeriod - 1, SelectedPeriod - 2 };

protected override IQuery<List<MonthModel>> CreatePeriodsQuery()
=> new ListMonthWithExpenseOrIncome();

protected override string UrlOverview(MonthModel period)
=> CategoryKey.IsEmpty ? Navigator.UrlOverview(period) : Navigator.UrlOverview(period, CategoryKey);

protected override IKey CreateSelectedCategoryFromParameters()
=> CategoryGuid != null ? GuidKey.Create(CategoryGuid.Value, KeyFactory.Empty(typeof(Category)).Type) : KeyFactory.Empty(typeof(Category));

Expand Down
9 changes: 9 additions & 0 deletions src/Money.Blazor.Host/Pages/OverviewMonthIncome.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,15 @@ protected override void ClearPreviousParameters()
protected override MonthModel CreateSelectedItemFromParameters()
=> new MonthModel(Year.Value, Month.Value);

protected override IReadOnlyCollection<MonthModel> CreatePeriodGuesses()
=> new MonthModel[] { SelectedPeriod - 1, SelectedPeriod - 2 };

protected override IQuery<List<MonthModel>> CreatePeriodsQuery()
=> new ListMonthWithExpenseOrIncome();

protected override string UrlOverviewIncomes(MonthModel period)
=> Navigator.UrlOverviewIncomes(period);

protected override IQuery<List<IncomeOverviewModel>> CreateItemsQuery(int pageIndex)
=> new ListMonthIncome(SelectedPeriod, SortDescriptor, pageIndex);

Expand Down
9 changes: 9 additions & 0 deletions src/Money.Blazor.Host/Pages/OverviewYear.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,15 @@ protected override void ClearPreviousParameters()
protected override YearModel CreateSelectedItemFromParameters()
=> new YearModel(Year.Value);

protected override IReadOnlyCollection<YearModel> CreatePeriodGuesses()
=> new YearModel[] { SelectedPeriod - 1, SelectedPeriod - 2 };

protected override IQuery<List<YearModel>> CreatePeriodsQuery()
=> new ListYearWithExpenseOrIncome();

protected override string UrlOverview(YearModel period)
=> CategoryKey.IsEmpty ? Navigator.UrlOverview(period) : Navigator.UrlOverview(period, CategoryKey);

protected override IKey CreateSelectedCategoryFromParameters()
=> CategoryGuid != null ? GuidKey.Create(CategoryGuid.Value, KeyFactory.Empty(typeof(Category)).Type) : KeyFactory.Empty(typeof(Category));

Expand Down
9 changes: 9 additions & 0 deletions src/Money.Blazor.Host/Pages/OverviewYearIncome.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,15 @@ protected override void ClearPreviousParameters()
protected override YearModel CreateSelectedItemFromParameters()
=> new YearModel(Year.Value);

protected override IReadOnlyCollection<YearModel> CreatePeriodGuesses()
=> new YearModel[] { SelectedPeriod - 1, SelectedPeriod - 2 };

protected override IQuery<List<YearModel>> CreatePeriodsQuery()
=> new ListYearWithExpenseOrIncome();

protected override string UrlOverviewIncomes(YearModel period)
=> Navigator.UrlOverviewIncomes(period);

protected override IQuery<List<IncomeOverviewModel>> CreateItemsQuery(int pageIndex)
=> new ListYearIncome(SelectedPeriod, SortDescriptor, pageIndex);

Expand Down
27 changes: 16 additions & 11 deletions src/Money.Blazor.Host/Pages/TrendsMonth.razor
Original file line number Diff line number Diff line change
@@ -1,27 +1,32 @@
@attribute [Authorize]
@page "/{Year:int}/trends/{CategoryGuid:guid}"

<Title Icon="chart-line" Main="@($"{CategoryName} trends in {Year}")" Sub="See how the category expenses change in time">
<ButtonContent>
<button class="btn btn-secondary" @onclick="(() => Navigator.OpenOverview(SelectedPeriod, CategoryKey))">
<Icon Prefix="fas" Identifier="list-ul" />
<span class="d-none d-lg-inline">
Year overview
</span>
</button>
</ButtonContent>
</Title>
<Title Icon="chart-line" Main="@($"{CategoryName} trends in {Year}")" Sub="See how the category expenses change in time" />

@if (Models == null)
{
<Loading />
}
else
{
<div class="d-flex align-items-center mb-3">
<div>
<PeriodSelector Selected="SelectedPeriod" Previous="PeriodGuesses" ExactGetter="GetYearsAsync" LinkFactory="@(year => Navigator.UrlTrends(year, CategoryKey))" />
</div>
<ul class="nav nav-pills ps-3">
<li>
<a class="nav-link" href="@Navigator.UrlOverview(SelectedPeriod, CategoryKey)">Overview</a>
</li>
<li>
<a class="nav-link active" href="@Navigator.UrlTrends(SelectedPeriod, CategoryKey)">Trends</a>
</li>
</ul>
</div>

<div class="row no-gutters" style="min-height: calc(100vh - 312px)">
@foreach (var model in Models)
{
var size = model.TotalAmount.Value / MaxAmount * 100;
var size = MaxAmount > 0 ? model.TotalAmount.Value / MaxAmount * 100 : 0;

<div class="col-12 col-lg-1 @(model > AppDateTime.Today ? "text-muted" : String.Empty)">
<div class="d-none d-lg-flex p-1 p-lg-3 h-100 w-100 vertical-bar">
Expand Down
Loading