package handlers import ( "net/http" "strconv" "time" "task-dashboard/internal/config" "task-dashboard/internal/models" ) // TimelineData holds grouped timeline items for the template type TimelineData struct { TodayItems []models.TimelineItem TomorrowItems []models.TimelineItem LaterItems []models.TimelineItem Start time.Time Days int } // HandleTimeline renders the timeline view func (h *Handler) HandleTimeline(w http.ResponseWriter, r *http.Request) { // Parse query params startStr := r.URL.Query().Get("start") daysStr := r.URL.Query().Get("days") var start time.Time if startStr != "" { parsed, err := config.ParseDateInDisplayTZ(startStr) if err == nil { start = parsed } else { start = config.Today() } } else { start = config.Today() } days := 3 // Default if daysStr != "" { if d, err := strconv.Atoi(daysStr); err == nil && d > 0 { days = d } } end := start.AddDate(0, 0, days) // Call BuildTimeline items, err := BuildTimeline(r.Context(), h.store, h.googleCalendarClient, start, end) if err != nil { JSONError(w, http.StatusInternalServerError, "Failed to build timeline", err) return } // Group items by day section data := TimelineData{ Start: start, Days: days, } for _, item := range items { switch item.DaySection { case models.DaySectionToday: data.TodayItems = append(data.TodayItems, item) case models.DaySectionTomorrow: data.TomorrowItems = append(data.TomorrowItems, item) case models.DaySectionLater: data.LaterItems = append(data.LaterItems, item) } } HTMLResponse(w, h.templates, "timeline-tab", data) }