Refactor Home page to Razor component

This commit is contained in:
James Chapman 2023-12-02 22:21:17 +00:00
parent f070acef41
commit 595a691da2
Signed by: jamsch0
GPG Key ID: 765FE58130277547
4 changed files with 84 additions and 80 deletions

View File

@ -15,7 +15,7 @@
</NavLink>
</li>
<li>
<NavLink class="sidebar__item" href="/" Match="NavLinkMatch.All">
<NavLink class="sidebar__item">
@* receipt long icon *@
<svg class="icon" xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" viewBox="0 0 24 24"><path d="M0,0h24v24H0V0z" fill="none"/><g><path d="M19.5,3.5L18,2l-1.5,1.5L15,2l-1.5,1.5L12,2l-1.5,1.5L9,2L7.5,3.5L6,2v14H3v3c0,1.66,1.34,3,3,3h12c1.66,0,3-1.34,3-3V2 L19.5,3.5z M15,20H6c-0.55,0-1-0.45-1-1v-1h10V20z M19,19c0,0.55-0.45,1-1,1s-1-0.45-1-1v-3H8V5h11V19z"/><rect height="2" width="6" x="9" y="7"/><rect height="2" width="2" x="16" y="7"/><rect height="2" width="6" x="9" y="10"/><rect height="2" width="2" x="16" y="10"/></g></svg>
Lists

View File

@ -1,47 +1,14 @@
namespace Groceries.Home;
using Groceries.Data;
using Microsoft.AspNetCore.Http.HttpResults;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
[Route("/")]
public class HomeController : Controller
public class HomeController : ControllerBase
{
private readonly AppDbContext dbContext;
public HomeController(AppDbContext dbContext)
{
this.dbContext = dbContext;
}
[HttpGet]
public async Task<IActionResult> IndexAsync()
public IResult Index()
{
var randomTagQuantity = await dbContext.ItemTagQuantities
.FromSql($"""
SELECT tag, quantity, coalesce(unit_name, unit) AS unit, is_metric, is_divisible
FROM (
SELECT
unnest(tags) AS tag,
round(sum((item_quantity->'amount')::numeric * quantity), 1) AS quantity,
item_quantity->>'unit' AS unit,
(item_quantity->'is_metric')::boolean AS is_metric,
(item_quantity->'is_divisible')::boolean AS is_divisible
FROM item_purchases
JOIN items USING (item_id)
CROSS JOIN item_quantity(name)
WHERE array_length(tags, 1) > 0
AND age(created_at) <= '90 days'
AND item_quantity IS NOT NULL
GROUP BY tag, item_quantity->>'unit', item_quantity->'is_metric', item_quantity->'is_divisible'
ORDER BY random()
FETCH FIRST ROW ONLY
) AS random_item_tag_quantity
LEFT JOIN item_tags USING (tag)
""")
.FirstOrDefaultAsync();
return View(randomTagQuantity);
return new RazorComponentResult<HomePage>();
}
}

View File

@ -0,0 +1,79 @@
@using Groceries.Data
@using Humanizer
@using Microsoft.EntityFrameworkCore
@layout Layout
@inject AppDbContext DbContext
@inject IHttpContextAccessor HttpContextAccessor
<HeadContent>
<meta name="turbo-cache-control" content="no-preview" />
</HeadContent>
<PageTitle>Groceries</PageTitle>
<section class="card">
<header class="card__header">
<h2>Item Quantity (last 90 days)</h2>
</header>
<div class="card__content">
@if (model != null)
{
if (model.IsDivisible)
{
var quantity = Convert.ToDouble(model.Quantity);
var weekQuantity = Math.Round(quantity / 12);
<strong>@(model.IsMetric ? quantity.ToMetric() : quantity)@model.Unit @model.Tag</strong>
<small>(@(model.IsMetric ? weekQuantity.ToMetric() : weekQuantity)@model.Unit per week)</small>
}
else
{
var name = model.Unit != null ? $"{model.Tag} {model.Unit}" : model.Tag;
var averageQuantity = model.Quantity / 12;
var averagePeriod = "week";
if (averageQuantity < 1)
{
averageQuantity *= 4;
averagePeriod = "month";
}
<strong>@name.ToQuantity(Convert.ToInt32(model.Quantity))</strong>
<small>(@name.ToQuantity(Convert.ToInt32(averageQuantity)) per @averagePeriod)</small>
}
}
</div>
</section>
@code {
private ItemTagQuantity? model;
protected override async Task OnInitializedAsync()
{
model = await DbContext.ItemTagQuantities
.FromSqlRaw(@"
SELECT tag, quantity, coalesce(unit_name, unit) AS unit, is_metric, is_divisible
FROM (
SELECT
unnest(tags) AS tag,
round(sum((item_quantity->'amount')::numeric * quantity), 1) AS quantity,
item_quantity->>'unit' AS unit,
(item_quantity->'is_metric')::boolean AS is_metric,
(item_quantity->'is_divisible')::boolean AS is_divisible
FROM item_purchases
JOIN items USING (item_id)
CROSS JOIN item_quantity(name)
WHERE array_length(tags, 1) > 0
AND age(created_at) <= '90 days'
AND item_quantity IS NOT NULL
GROUP BY tag, item_quantity->>'unit', item_quantity->'is_metric', item_quantity->'is_divisible'
ORDER BY random()
FETCH FIRST ROW ONLY
) AS random_item_tag_quantity
LEFT JOIN item_tags USING (tag)
")
.FirstOrDefaultAsync(HttpContextAccessor.HttpContext!.RequestAborted);
}
}

View File

@ -1,42 +0,0 @@
@using Groceries.Data
@using Humanizer
@model ItemTagQuantity?
@section head {
@*<meta name="turbo-cache-control" content="no-preview" />*@
}
<section class="card">
<header class="card__header">
<h2>Item Quantity (last 90 days)</h2>
</header>
<div class="card__content">
@if (Model != null)
{
@if (Model.IsDivisible)
{
var quantity = Convert.ToDouble(Model.Quantity);
var weekQuantity = Math.Round(quantity / 12);
<strong>@(Model.IsMetric ? quantity.ToMetric() : quantity)@Model.Unit @Model.Tag</strong>
<small>(@(Model.IsMetric ? weekQuantity.ToMetric() : weekQuantity)@Model.Unit per week)</small>
}
else
{
var name = Model.Unit != null ? $"{Model.Tag} {Model.Unit}" : Model.Tag;
var avgQuantity = Model.Quantity / 12;
var avgPeriod = "week";
if (avgQuantity < 1)
{
avgQuantity *= 4;
avgPeriod = "month";
}
<strong>@name.ToQuantity(Convert.ToInt32(Model.Quantity))</strong>
<small>(@name.ToQuantity(Convert.ToInt32(avgQuantity)) per @avgPeriod)</small>
}
}
</div>
</section>