Skip to content
Merged
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
18 changes: 14 additions & 4 deletions CulinaryCommandApp/Data/Enums/Category.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,21 @@ namespace CulinaryCommandApp.Data.Enums
public class Category
{
public const string Produce = "Produce";
public const string Dairy = "Dairy";
public const string Meat = "Meat";
public const string DairyEggs = "Dairy & Eggs";
public const string Cheese = "Cheese";
public const string MeatPoultry = "Meat & Poultry";
public const string Seafood = "Seafood";
public const string Bakery = "Bakery";
public const string PastaGrains = "Pasta & Grains";
public const string DryGoods = "Dry Goods";
public const string Beverages = "Beverages";
public const string Condiments = "Condiments";
public const string Spices = "Spices";
public const string Condiments = "Condiments";
public const string SyrupsMixes = "Syrups & Mixes";
public const string Desserts = "Desserts";
public const string Beer = "Beer";
public const string Wine = "Wine";
public const string Spirits = "Spirits";
public const string Beverages = "Beverages";
public const string Prepared = "Prepared";
}
}
93 changes: 70 additions & 23 deletions CulinaryCommandApp/Inventory/Pages/Inventory/InventoryCatalog.razor
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
@inject EnumService EnumService
@inject IUserContextService UserCtx
@inject NavigationManager Nav
@inject IJSRuntime JS

<div class="inventory-container">
@if (!_ready)
Expand All @@ -32,7 +33,7 @@
<div class="inventory-header">
<div class="header-text">
<h1>Inventory Catalog</h1>
<p>@(LocationState.CurrentLocation is not null ? $"{LocationState.CurrentLocation.Name} — ingredient catalog" : "Manage your ingredient catalog")</p>
<p>@(LocationState.CurrentLocation is not null ? $"{LocationState.CurrentLocation.Name}" : "Manage your ingredient catalog")</p>
</div>
</div>

Expand Down Expand Up @@ -85,18 +86,17 @@
</th>
<th @onclick='() => SortBy("name")'>Item Name <i class="bi bi-arrow-down-up"></i></th>
<th>Category</th>
<th>Unit</th>
<th @onclick='() => SortBy("price")'>Cost/Unit <i class="bi bi-arrow-down-up"></i></th>
<th class="unit-col">Unit</th>
<th @onclick='() => SortBy("supplier")'>Supplier <i class="bi bi-arrow-down-up"></i></th>
<th>Notes</th>
<th class="actions-col">Actions</th>
<th class="ellipsis-col"></th>
</tr>
</thead>
<tbody>
@if (isLoading)
{
<tr>
<td colspan="8" class="text-center py-4">
<td colspan="6" class="text-center py-4">
<div class="spinner-border" role="status">
<span class="visually-hidden">Loading...</span>
</div>
Expand All @@ -106,7 +106,7 @@
else if (!pagedItems.Any())
{
<tr>
<td colspan="8" class="text-center py-4">
<td colspan="6" class="text-center py-4">
<p class="text-muted">No items found</p>
</td>
</tr>
Expand All @@ -115,7 +115,7 @@
{
@foreach (var item in pagedItems)
{
<tr>
<tr class="data-row">
<td class="checkbox-col">
<input type="checkbox" checked="@selectedIds.Contains(item.Id)" @onchange="(e) => ToggleSelection(item.Id, e)" />
</td>
Expand All @@ -128,19 +128,13 @@
<td>
<span class="category-pill @GetCategoryClass(item.Category)">@item.Category</span>
</td>
<td>@item.Unit</td>
<td>$@item.Price.ToString("F2")</td>
<td class="unit-col"><span class="unit-badge">@item.Unit</span></td>
<td>@(item.VendorName ?? "—")</td>
<td>@(string.IsNullOrWhiteSpace(item.Notes) ? "-" : item.Notes)</td>
<td class="actions-col">
<div class="action-buttons">
<button class="btn-action" @onclick="() => EditItem(item)" title="Edit">
<i class="bi bi-pencil"></i>
</button>
<button class="btn-action delete" @onclick="() => DeleteItem(item)" title="Delete">
<i class="bi bi-trash"></i>
</button>
</div>
<td class="ellipsis-col">
<button class="ellipsis-btn" @onclick="(e) => ToggleMenu(item.Id, e)" @onclick:stopPropagation="true">
<i class="bi bi-three-dots-vertical"></i>
</button>
</td>
</tr>
}
Expand Down Expand Up @@ -171,6 +165,24 @@
</div>
</div>

@if (_openMenuId is not null)
{
<div class="row-menu-backdrop" @onclick="CloseMenu"></div>
<div class="row-menu-dialog" style="top: @(_menuY)px; left: @(_menuX)px;">
@{ var _menuItem = pagedItems.FirstOrDefault(i => i.Id == _openMenuId); }
@if (_menuItem is not null)
{
<div class="row-menu-label">@_menuItem.Name</div>
<button class="row-menu-action" @onclick="() => { EditItem(_menuItem); CloseMenu(); }">
<i class="bi bi-pencil-square"></i> Edit Item
</button>
<button class="row-menu-action delete" @onclick="() => { _ = DeleteItem(_menuItem); CloseMenu(); }">
<i class="bi bi-trash3"></i> Delete Item
</button>
}
</div>
}

} @* end @if (LocationState.CurrentLocation is not null) *@

} @* end else (_allowed) *@
Expand Down Expand Up @@ -264,6 +276,29 @@
private HashSet<int> selectedIds = new();
private List<string> categories = new();

private int? _openMenuId = null;
private double _menuX = 0;
private double _menuY = 0;

private async Task ToggleMenu(int id, MouseEventArgs e)
{
if (_openMenuId == id)
{
_openMenuId = null;
return;
}
_openMenuId = id;
// Clamp to viewport so the dialog never clips off-screen
var dialogWidth = 190;
var dialogHeight = 110;
var viewportWidth = await JS.InvokeAsync<double>("eval", "window.innerWidth");
var viewportHeight = await JS.InvokeAsync<double>("eval", "window.innerHeight");
_menuX = Math.Min(e.ClientX - dialogWidth, viewportWidth - dialogWidth - 8);
_menuY = Math.Min(e.ClientY, viewportHeight - dialogHeight - 8);
}

private void CloseMenu() => _openMenuId = null;

private bool showModal = false;
private bool _saving = false;
private bool _ready = false;
Expand Down Expand Up @@ -399,12 +434,24 @@

private string GetCategoryClass(string? category) => category switch
{
"Grains & Pasta" => "category-grains",
"Dairy" => "category-dairy",
"Oils & Sauces" => "category-oils",
"Vegetables" => "category-vegetables",
"Produce" => "category-produce",
"Dairy & Eggs" => "category-dairy-eggs",
"Cheese" => "category-cheese",
"Meat & Poultry" => "category-meat",
_ => "category-default"
"Seafood" => "category-seafood",
"Bakery" => "category-bakery",
"Pasta & Grains" => "category-pasta-grains",
"Dry Goods" => "category-dry-goods",
"Spices" => "category-spices",
"Condiments" => "category-condiments",
"Syrups & Mixes" => "category-syrups",
"Desserts" => "category-desserts",
"Beer" => "category-beer",
"Wine" => "category-wine",
"Spirits" => "category-spirits",
"Beverages" => "category-beverages",
"Prepared" => "category-prepared",
_ => "category-default"
};

private bool IsPageSelected => pagedItems.Count > 0 && pagedItems.All(i => selectedIds.Contains(i.Id));
Expand Down
Loading
Loading