templates, handlers, CSS, JS: special cakes UI, HTMX nav, dashboard overhaul

Special cakes UI: overlay drawer, basket integration, catalogue tag
filter, form parsing, JS save/edit/remove.
HTMX navigation: MainContent component, nav links with hx-get,
handlers return partial on HX-Request.
Dashboard: metrics grid, CakeBreakdown, OrderRow with status select,
CakeCounts/OrderCounts, torty filter, tort badge, results-pane.
Collapsible sidebar: toggle button, localStorage, CSS transitions.
Location field: dropdown replaced with pill toggle.
Inline style cleanup: moved to CSS classes (tag-grid, grow, icon.sm,
header-actions, toggle-group, success-icon, etc.).
Dead CSS removal: pagination, status-chip, badge-pill, login-page.
Helpers: exported CakeTitle/OrderTitle, added tagNames, tagIDsComma,
orderItemsDesc, specialCakeDetail, removed unused helpers.
This commit is contained in:
bronkuu 2026-06-15 18:50:21 +02:00
parent 17b92a706a
commit 5a5372b831
18 changed files with 1153 additions and 422 deletions

View file

@ -6,11 +6,11 @@ import (
"git.bronku.xyz/bronku/cake-order-tracker/models"
)
templ CakesPage(cakes []models.Cake) {
@Layout("Katalog", templ.NopComponent, CakesMain(cakes))
templ CakesPage(cakes []models.Cake, allTags []models.Tag) {
@Layout("Katalog", templ.NopComponent, CakesMain(cakes, allTags))
}
templ CakesMain(cakes []models.Cake) {
templ CakesMain(cakes []models.Cake, allTags []models.Tag) {
<section class="card">
<header>
<h2>
@ -22,27 +22,41 @@ templ CakesMain(cakes []models.Cake) {
Nowe ciasto
</a>
</header>
if len(allTags) > 0 {
<div class="filter-bar">
<span class="filter-label">Tagi:</span>
for _, t := range allTags {
<button type="button" class="tag-chip" data-tag={ t.Name } onclick="toggleCakeTagFilter(this)">{ t.Name }</button>
}
</div>
}
<div class="table-container">
<table class="data-table">
<table class="data-table" id="cakes-table">
<thead>
<tr>
<th style="width:2rem"></th>
<th>Nazwa</th>
<th>SKU</th>
<th>Tagi</th>
<th class="right">Cena bazowa</th>
<th class="center"></th>
</tr>
</thead>
<tbody>
for _, c := range cakes {
<tr>
<tr data-tags={ tagNames(c.Tags) }>
<td>
<div class="icon cake" style="width:1.75rem;height:1.75rem">
<span class="material-symbols-outlined" style="font-size:1rem">cake</span>
<div class="icon cake sm">
<span class="material-symbols-outlined">cake</span>
</div>
</td>
<td style="font-weight:500">{ c.Name }</td>
<td class="font-medium">{ c.Name }</td>
<td class="text-muted">#{ strconv.Itoa(c.ID) }</td>
<td>
for _, t := range c.Tags {
<span class="tag-chip">{ t.Name }</span>
}
</td>
<td class="text-right">{ c.Price.String() } PLN</td>
<td class="text-center">
<a href={ templ.URL("/cake/" + strconv.Itoa(c.ID)) } class="action-btn">
@ -55,4 +69,23 @@ templ CakesMain(cakes []models.Cake) {
</table>
</div>
</section>
<script>
var activeCakeTags = [];
function toggleCakeTagFilter(btn) {
var tag = btn.getAttribute('data-tag');
var idx = activeCakeTags.indexOf(tag);
if (idx >= 0) { activeCakeTags.splice(idx, 1); btn.classList.remove('active'); }
else { activeCakeTags.push(tag); btn.classList.add('active'); }
var rows = document.querySelectorAll('#cakes-table tbody tr');
for (var i = 0; i < rows.length; i++) {
if (activeCakeTags.length === 0) { rows[i].style.display = ''; continue; }
var rowTags = (rows[i].getAttribute('data-tags') || '').split(',');
var match = false;
for (var j = 0; j < activeCakeTags.length; j++) {
if (rowTags.indexOf(activeCakeTags[j]) >= 0) { match = true; break; }
}
rows[i].style.display = match ? '' : 'none';
}
}
</script>
}