package templates
import (
"fmt"
"veola/internal/models"
)
type ItemsData struct {
Page
Items []models.Item
Categories []string
SelectedCategory string
}
templ itemsBody(d ItemsData) {
if len(d.Categories) > 0 {
}
if len(d.Items) == 0 {
@itemsEmpty()
} else {
| Name |
Category |
Target |
Best Price |
Last Polled |
Status |
|
for _, it := range d.Items {
@itemRow(it, d.CSRFToken)
}
}
}
templ itemsEmpty() {
Nothing on the watchlist.
Add an item and Veola will keep an eye on it.
Add the first item
}
templ itemRow(it models.Item, csrf string) {
|
{ it.Name }
if it.LastPollError != "" {
}
|
{ it.Category } |
if it.TargetPrice != nil {
{ fmtPrice(it.TargetPrice, "USD") }
} else {
—
}
|
if it.BestPrice != nil {
{ fmtPrice(it.BestPrice, it.BestPriceCurrency) }
if it.BestPriceURL != "" {
{ it.BestPriceStore }
} else if it.BestPriceStore != "" {
{ it.BestPriceStore }
}
} else {
not yet
}
|
if it.LastPolledAt != nil {
{ humanTime(*it.LastPolledAt) }
} else {
—
}
|
if it.Active {
active
} else {
paused
}
|
Edit
|
}
func priceClass(best, target *float64) string {
if best == nil || target == nil {
return ""
}
if *best <= *target {
return "v-price-target"
}
return ""
}
templ Items(d ItemsData) {
@Layout(d.Page, itemsBody(d))
}
// ItemRow renders a single row partial, used by HTMX endpoints.
templ ItemRow(it models.Item, csrf string) {
@itemRow(it, csrf)
}
// EmptyRow lets a delete handler return a row replacement that vanishes.
templ EmptyRow() {
}