summaryrefslogtreecommitdiff
path: root/internal/handlers
diff options
context:
space:
mode:
Diffstat (limited to 'internal/handlers')
-rw-r--r--internal/handlers/handlers.go16
-rw-r--r--internal/handlers/response.go10
-rw-r--r--internal/handlers/timeline_logic.go17
3 files changed, 36 insertions, 7 deletions
diff --git a/internal/handlers/handlers.go b/internal/handlers/handlers.go
index 0e5edcc..bba12ad 100644
--- a/internal/handlers/handlers.go
+++ b/internal/handlers/handlers.go
@@ -1230,7 +1230,11 @@ func mealTypeOrder(mealType string) int {
func (h *Handler) HandleTabShopping(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
stores := h.aggregateShoppingLists(ctx)
- HTMLResponse(w, h.templates, "shopping-tab", struct{ Stores []models.ShoppingStore }{stores})
+ grouped := r.URL.Query().Get("grouped") != "false" // Default to grouped
+ HTMLResponse(w, h.templates, "shopping-tab", struct {
+ Stores []models.ShoppingStore
+ Grouped bool
+ }{stores, grouped})
}
// HandleShoppingQuickAdd adds a user shopping item
@@ -1285,7 +1289,10 @@ func (h *Handler) HandleShoppingQuickAdd(w http.ResponseWriter, r *http.Request)
}
// Return refreshed shopping tab
- HTMLResponse(w, h.templates, "shopping-tab", struct{ Stores []models.ShoppingStore }{allStores})
+ HTMLResponse(w, h.templates, "shopping-tab", struct {
+ Stores []models.ShoppingStore
+ Grouped bool
+ }{allStores, true})
}
// HandleShoppingToggle toggles a shopping item's checked state
@@ -1323,7 +1330,10 @@ func (h *Handler) HandleShoppingToggle(w http.ResponseWriter, r *http.Request) {
// Return refreshed shopping tab
stores := h.aggregateShoppingLists(r.Context())
- HTMLResponse(w, h.templates, "shopping-tab", struct{ Stores []models.ShoppingStore }{stores})
+ HTMLResponse(w, h.templates, "shopping-tab", struct {
+ Stores []models.ShoppingStore
+ Grouped bool
+ }{stores, true})
}
// HandleShoppingMode renders the focused shopping mode for a single store
diff --git a/internal/handlers/response.go b/internal/handlers/response.go
index 9a7ab45..34d4491 100644
--- a/internal/handlers/response.go
+++ b/internal/handlers/response.go
@@ -7,9 +7,17 @@ import (
"net/http"
)
+// noCacheHeaders sets headers to prevent browser caching
+func noCacheHeaders(w http.ResponseWriter) {
+ w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
+ w.Header().Set("Pragma", "no-cache")
+ w.Header().Set("Expires", "0")
+}
+
// JSONResponse writes data as JSON with appropriate headers
func JSONResponse(w http.ResponseWriter, data interface{}) {
w.Header().Set("Content-Type", "application/json")
+ noCacheHeaders(w)
_ = json.NewEncoder(w).Encode(data)
}
@@ -23,6 +31,8 @@ func JSONError(w http.ResponseWriter, status int, msg string, err error) {
// HTMLResponse renders an HTML template
func HTMLResponse(w http.ResponseWriter, tmpl *template.Template, name string, data interface{}) {
+ w.Header().Set("Content-Type", "text/html; charset=utf-8")
+ noCacheHeaders(w)
if err := tmpl.ExecuteTemplate(w, name, data); err != nil {
http.Error(w, "Failed to render template", http.StatusInternalServerError)
log.Printf("Error rendering template %s: %v", name, err)
diff --git a/internal/handlers/timeline_logic.go b/internal/handlers/timeline_logic.go
index 5ea44b5..7a85393 100644
--- a/internal/handlers/timeline_logic.go
+++ b/internal/handlers/timeline_logic.go
@@ -2,6 +2,7 @@ package handlers
import (
"context"
+ "log"
"sort"
"strings"
"time"
@@ -130,7 +131,9 @@ func BuildTimeline(ctx context.Context, s *store.Store, calendarClient api.Googl
// 4. Fetch Events
if calendarClient != nil {
events, err := calendarClient.GetEventsByDateRange(ctx, start, end)
- if err == nil {
+ if err != nil {
+ log.Printf("Warning: failed to fetch calendar events: %v", err)
+ } else {
for _, event := range events {
endTime := event.End
item := models.TimelineItem{
@@ -142,7 +145,7 @@ func BuildTimeline(ctx context.Context, s *store.Store, calendarClient api.Googl
Description: event.Description,
URL: event.HTMLLink,
OriginalItem: event,
- IsCompleted: false, // Events don't have completion status
+ IsCompleted: false,
Source: "calendar",
}
item.ComputeDaySection(now)
@@ -154,9 +157,13 @@ func BuildTimeline(ctx context.Context, s *store.Store, calendarClient api.Googl
// 5. Fetch Google Tasks
if tasksClient != nil {
gTasks, err := tasksClient.GetTasksByDateRange(ctx, start, end)
- if err == nil {
+ if err != nil {
+ log.Printf("Warning: failed to fetch Google Tasks: %v", err)
+ } else {
+ log.Printf("Google Tasks: fetched %d tasks in date range", len(gTasks))
for _, gTask := range gTasks {
- taskTime := start // Default to start of range if no due date
+ // Tasks without due date are placed in today section
+ taskTime := now
if gTask.DueDate != nil {
taskTime = *gTask.DueDate
}
@@ -176,6 +183,8 @@ func BuildTimeline(ctx context.Context, s *store.Store, calendarClient api.Googl
items = append(items, item)
}
}
+ } else {
+ log.Printf("Google Tasks client not configured")
}
// Sort items by Time