summaryrefslogtreecommitdiff
path: root/internal/handlers/tabs.go
diff options
context:
space:
mode:
authorPeter Stone <thepeterstone@gmail.com>2026-01-22 15:28:06 -1000
committerPeter Stone <thepeterstone@gmail.com>2026-01-22 15:31:50 -1000
commite97a1bc259d3aa91956ec73a522421cdb621ae57 (patch)
treea9f424ef97673c0dd7da8cee6044413e6417b626 /internal/handlers/tabs.go
parentdb5deb2330448c75ba6b719e6a397832362b222a (diff)
Add Google Calendar integration
- Add GoogleCalendarClient for fetching upcoming events - Add GoogleCalendarAPI interface and CalendarEvent model - Add config for GOOGLE_CREDENTIALS_FILE and GOOGLE_CALENDAR_ID - Display events in Planning tab with date/time formatting - Update handlers and tests to support optional calendar client Config env vars: - GOOGLE_CREDENTIALS_FILE: Path to service account JSON - GOOGLE_CALENDAR_ID: Calendar ID (defaults to "primary") Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Diffstat (limited to 'internal/handlers/tabs.go')
-rw-r--r--internal/handlers/tabs.go26
1 files changed, 21 insertions, 5 deletions
diff --git a/internal/handlers/tabs.go b/internal/handlers/tabs.go
index 2f22c44..b651dac 100644
--- a/internal/handlers/tabs.go
+++ b/internal/handlers/tabs.go
@@ -9,6 +9,7 @@ import (
"strings"
"time"
+ "task-dashboard/internal/api"
"task-dashboard/internal/models"
"task-dashboard/internal/store"
)
@@ -46,12 +47,13 @@ func atomUrgencyTier(a models.Atom) int {
// TabsHandler handles tab-specific rendering with Atom model
type TabsHandler struct {
- store *store.Store
- templates *template.Template
+ store *store.Store
+ googleCalendarClient api.GoogleCalendarAPI
+ templates *template.Template
}
// NewTabsHandler creates a new TabsHandler instance
-func NewTabsHandler(store *store.Store, templateDir string) *TabsHandler {
+func NewTabsHandler(store *store.Store, googleCalendarClient api.GoogleCalendarAPI, templateDir string) *TabsHandler {
// Parse templates including partials
tmpl, err := template.ParseGlob(filepath.Join(templateDir, "*.html"))
if err != nil {
@@ -65,8 +67,9 @@ func NewTabsHandler(store *store.Store, templateDir string) *TabsHandler {
}
return &TabsHandler{
- store: store,
- templates: tmpl,
+ store: store,
+ googleCalendarClient: googleCalendarClient,
+ templates: tmpl,
}
}
@@ -178,12 +181,25 @@ func (h *TabsHandler) HandlePlanning(w http.ResponseWriter, r *http.Request) {
return
}
+ // Fetch Google Calendar events
+ var events []models.CalendarEvent
+ if h.googleCalendarClient != nil {
+ var err error
+ events, err = h.googleCalendarClient.GetUpcomingEvents(r.Context(), 10)
+ if err != nil {
+ log.Printf("Error fetching calendar events: %v", err)
+ // Don't fail the whole request, just show empty events
+ }
+ }
+
data := struct {
Boards []models.Board
Projects []models.Project
+ Events []models.CalendarEvent
}{
Boards: boards,
Projects: []models.Project{}, // Empty for now
+ Events: events,
}
if err := h.templates.ExecuteTemplate(w, "planning-tab", data); err != nil {