summaryrefslogtreecommitdiff
path: root/internal/handlers/widget.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/handlers/widget.go')
-rw-r--r--internal/handlers/widget.go63
1 files changed, 61 insertions, 2 deletions
diff --git a/internal/handlers/widget.go b/internal/handlers/widget.go
index 05c0bdb..bff7dd7 100644
--- a/internal/handlers/widget.go
+++ b/internal/handlers/widget.go
@@ -3,6 +3,7 @@ package handlers
import (
"encoding/json"
"errors"
+ "log"
"net/http"
"strings"
"time"
@@ -126,15 +127,73 @@ func (h *Handler) HandleWidgetGet(w http.ResponseWriter, r *http.Request) {
}
}
+ budgetStatus, err := h.computeBudgetStatus(now)
+ if err != nil {
+ log.Printf("Warning: failed to compute budget status: %v", err)
+ }
+
resp := models.WidgetResponse{
- Now: now,
- Items: widgetItems,
+ Now: now,
+ Items: widgetItems,
+ BudgetStatus: budgetStatus,
}
w.Header().Set("Content-Type", "application/json")
_ = json.NewEncoder(w).Encode(resp)
}
+// computeBudgetStatus returns budget status for "today" and a rolling
+// 7-day "week" window starting today, or nil if no budget-tracked task
+// falls in the week window (per the spec: the field is absent unless
+// budget-tracked tasks exist, so an unconfigured user sees no new UI).
+func (h *Handler) computeBudgetStatus(now time.Time) (*models.BudgetStatus, error) {
+ tz := config.GetDisplayTimezone()
+ todayStart := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, tz)
+ todayEnd := todayStart.Add(24 * time.Hour)
+ weekEnd := todayStart.AddDate(0, 0, 7)
+
+ blocks, err := h.store.GetAvailabilityBlocks()
+ if err != nil {
+ return nil, err
+ }
+ trackedProjects, err := h.store.GetBudgetTrackedProjectIDs()
+ if err != nil {
+ return nil, err
+ }
+ trackedLabels, err := h.store.GetBudgetTrackedLabelNames()
+ if err != nil {
+ return nil, err
+ }
+ events, err := h.store.GetCalendarEventsByDateRange(todayStart, weekEnd)
+ if err != nil {
+ return nil, err
+ }
+ overdue, err := h.store.GetOverdueNativeTasks(todayStart)
+ if err != nil {
+ return nil, err
+ }
+ weekTasks, err := h.store.GetNativeTasksByDateRange(todayStart, weekEnd)
+ if err != nil {
+ return nil, err
+ }
+ allTasks := append(append([]models.Task{}, overdue...), weekTasks...)
+
+ hasTracked := false
+ for _, task := range allTasks {
+ if isBudgetTracked(task, trackedProjects, trackedLabels) && !task.Completed {
+ hasTracked = true
+ break
+ }
+ }
+ if !hasTracked {
+ return nil, nil
+ }
+
+ today := ComputeBudgetPeriod(blocks, events, allTasks, trackedProjects, trackedLabels, todayStart, todayEnd)
+ week := ComputeBudgetPeriod(blocks, events, allTasks, trackedProjects, trackedLabels, todayStart, weekEnd)
+ return &models.BudgetStatus{Today: today, Week: week}, nil
+}
+
type widgetCompleteRequest struct {
ID string `json:"id"`
Source string `json:"source"`