package templates
import (
"fmt"
"time"
"veola/internal/db"
"veola/internal/models"
)
type DashboardData struct {
Page
Stats *db.DashboardStats
RecentResults []ResultRow
RecentAlerts []AlertRow
}
type ResultRow struct {
ItemID int64
ItemName string
Title string
Price *float64
Currency string
Source string
URL string
FoundAt time.Time
Alerted bool
}
type AlertRow struct {
ItemName string
Price *float64
Currency string
FoundAt time.Time
}
templ dashboardBody(d DashboardData) {
Dashboard
@statCard("Total Items", fmt.Sprintf("%d", d.Stats.TotalItems), "")
@statCard("Active", fmt.Sprintf("%d", d.Stats.ActiveItems), "")
@statCard("Results Today", fmt.Sprintf("%d", d.Stats.ResultsToday), "")
@statCard("Alerts Today", fmt.Sprintf("%d", d.Stats.AlertsToday), "")
Potential Spend
{ fmt.Sprintf("$%.2f", d.Stats.PotentialSpend) }
across { fmt.Sprintf("%d", d.Stats.PricedItemCount) } items
if d.Stats.UnpricedCount > 0 {
{ fmt.Sprintf("%d items not yet priced.", d.Stats.UnpricedCount) }
}
Money Saved
{ fmt.Sprintf("$%.2f", d.Stats.MoneySaved) }
across { fmt.Sprintf("%d", d.Stats.SavedItemCount) } items
Recent Results
if len(d.RecentResults) == 0 {
No results yet.
} else {
| Item | Price | Source | Found |
for _, r := range d.RecentResults {
| { r.ItemName } |
{ fmtPrice(r.Price, r.Currency) } |
{ r.Source } |
{ humanTime(r.FoundAt) } |
}
}
Recent Alerts
if len(d.RecentAlerts) == 0 {
No alerts sent yet.
} else {
for _, a := range d.RecentAlerts {
-
{ a.ItemName }
{ fmtPrice(a.Price, a.Currency) }
}
}
}
templ statCard(label, value, sub string) {