Roll out refined-minimal styling and product thumbnails across pages

Apply the dashboard's refined direction to the rest of the app:
- Items: page-title header, product thumbnail (best-price image) beside
  each item name via the shared thumbSm component.
- Results: refined headers; per-item and global tables get standardized
  thumbnails (global table gains a thumbnail column).
- Settings: page-title + subtitle, section headings restyled.
- Item form: page-title header.
- Shared: thumbSm component + compact thumbnail CSS variant.
This commit is contained in:
prosolis
2026-06-20 12:47:13 -07:00
parent 9a7f8b47a3
commit 3760571d84
12 changed files with 686 additions and 599 deletions

View File

@@ -96,9 +96,12 @@ func isDeal(it models.Item) bool {
templ itemsBody(d ItemsData) {
<div>
<div class="flex items-center justify-between mb-6">
<h1 class="text-3xl font-semibold">Items</h1>
<a class="v-btn" href="/items/new">+ Add Item</a>
<div class="flex items-end justify-between mb-8">
<div>
<h1 class="v-page-title">Items</h1>
<p class="v-page-sub">{ fmt.Sprintf("%d on the watchlist", len(d.Items)) }</p>
</div>
<a class="v-btn" href="/items/new">Add item</a>
</div>
if len(d.Categories) > 0 {
<form method="get" action="/items" class="mb-4 flex items-center gap-2">
@@ -155,16 +158,21 @@ templ itemsEmpty() {
templ itemRow(it models.Item, csrf string, history []models.PricePoint) {
<tr id={ fmt.Sprintf("item-row-%d", it.ID) }>
<td>
<div class="flex items-center gap-2">
if isDeal(it) {
<img class="v-deal-mascot" src="/static/img/veola.avif" alt="" title={ fmt.Sprintf("Deal! Best %s ≤ target %s", fmtPrice(it.BestPrice, it.BestPriceCurrency), fmtPrice(it.TargetPrice, "USD")) }/>
}
<a href={ templ.SafeURL(fmt.Sprintf("/items/%d/results", it.ID)) }>{ it.Name }</a>
<div class="flex items-center gap-3">
@thumbSm(it.BestPriceImageURL)
<div class="min-w-0">
<div class="flex items-center gap-2">
if isDeal(it) {
<img class="v-deal-mascot" src="/static/img/veola.avif" alt="" title={ fmt.Sprintf("Deal! Best %s ≤ target %s", fmtPrice(it.BestPrice, it.BestPriceCurrency), fmtPrice(it.TargetPrice, "USD")) }/>
}
<a href={ templ.SafeURL(fmt.Sprintf("/items/%d/results", it.ID)) }>{ it.Name }</a>
</div>
if it.LastPollError != "" {
<button class="v-pill v-pill-error mt-1" hx-get={ fmt.Sprintf("/items/%d/error", it.ID) } hx-target={ fmt.Sprintf("#item-error-%d", it.ID) } hx-swap="innerHTML">!</button>
<div id={ fmt.Sprintf("item-error-%d", it.ID) } class="v-error-text mt-1"></div>
}
</div>
</div>
if it.LastPollError != "" {
<button class="v-pill v-pill-error ml-2" hx-get={ fmt.Sprintf("/items/%d/error", it.ID) } hx-target={ fmt.Sprintf("#item-error-%d", it.ID) } hx-swap="innerHTML">!</button>
<div id={ fmt.Sprintf("item-error-%d", it.ID) } class="v-error-text mt-1"></div>
}
</td>
<td class="v-muted">{ it.Category }</td>
<td class="font-mono">