// Package handlers provides HTTP request handlers for NextReceipt. // // This file implements the dashboard handler showing all purchases // for the authenticated user. package handlers import ( "database/sql" "log" "net/http" "time" "github.com/cclohmar/NextReceipt/internal/database" ) // --------------------------------------------------------------------------- // DashboardHandler // --------------------------------------------------------------------------- // DashboardHandler groups HTTP handlers related to the main dashboard view. type DashboardHandler struct { DB *sql.DB } // NewDashboardHandler creates a new DashboardHandler with the given database handle. func NewDashboardHandler(db *sql.DB) *DashboardHandler { return &DashboardHandler{DB: db} } // --------------------------------------------------------------------------- // GET /dashboard — Dashboard // --------------------------------------------------------------------------- // Dashboard renders the main dashboard page showing all purchases belonging // to the authenticated user, along with the receipt upload controls. func (h *DashboardHandler) Dashboard(w http.ResponseWriter, r *http.Request) { userID := getUserID(r) if userID == "" { log.Printf("ERROR [%s] handlers: Dashboard: missing user ID", time.Now().Format(time.RFC3339)) http.Error(w, "Unauthorized", http.StatusUnauthorized) return } purchases, err := database.GetPurchasesByUser(h.DB, userID) if err != nil { log.Printf("ERROR [%s] handlers: Dashboard: GetPurchasesByUser: %v", time.Now().Format(time.RFC3339), err) http.Error(w, "Failed to load purchases", http.StatusInternalServerError) return } // Normalize ImagePath for all purchases. for i := range purchases { purchases[i].ImagePath = normalizeImagePath(purchases[i].ImagePath) } tmpl := getTemplate("dashboard.html") data := map[string]interface{}{ "Purchases": purchases, } w.Header().Set("Content-Type", "text/html; charset=utf-8") if err := tmpl.Execute(w, data); err != nil { log.Printf("ERROR [%s] handlers: Dashboard: execute template: %v", time.Now().Format(time.RFC3339), err) } }