diff options
| author | Peter Stone <thepeterstone@gmail.com> | 2026-01-19 09:11:04 -1000 |
|---|---|---|
| committer | Peter Stone <thepeterstone@gmail.com> | 2026-01-19 09:11:04 -1000 |
| commit | 2215aaa458b318edb16337ab56cf658117023eb4 (patch) | |
| tree | 73dc62cb8ed385e8ab5d255825b03ffb8845b27e /internal/handlers | |
| parent | 791034f1b588bf679f45a0f89168515fcbde66d5 (diff) | |
Implement Unified Quick Add for Tasks tab (Phase 3 Step 8)
Add Quick Add form to create Todoist tasks or Trello cards directly
from the Tasks tab with optional due date support.
Features:
- HandleUnifiedAdd handler with due date parsing
- HandleGetListsOptions for dynamic Trello list loading
- Quick Add form with source toggle (Todoist/Trello)
- Date picker for due dates
- HX-Trigger refresh after successful creation
- Pass boards to tasks-tab template for board selector
Cleanup:
- Remove resolved issue tracking files
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Diffstat (limited to 'internal/handlers')
| -rw-r--r-- | internal/handlers/handlers.go | 87 | ||||
| -rw-r--r-- | internal/handlers/tabs.go | 6 |
2 files changed, 91 insertions, 2 deletions
diff --git a/internal/handlers/handlers.go b/internal/handlers/handlers.go index b3bc8e4..20095fe 100644 --- a/internal/handlers/handlers.go +++ b/internal/handlers/handlers.go @@ -3,6 +3,7 @@ package handlers import ( "context" "encoding/json" + "fmt" "html/template" "log" "net/http" @@ -727,3 +728,89 @@ func (h *Handler) HandleCompleteAtom(w http.ResponseWriter, r *http.Request) { // Return 200 OK with empty body to remove the element from DOM w.WriteHeader(http.StatusOK) } + +// HandleUnifiedAdd creates a task in Todoist or a card in Trello from the Quick Add form +func (h *Handler) HandleUnifiedAdd(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + + if err := r.ParseForm(); err != nil { + http.Error(w, "Failed to parse form", http.StatusBadRequest) + return + } + + title := r.FormValue("title") + source := r.FormValue("source") + dueDateStr := r.FormValue("due_date") + + if title == "" { + http.Error(w, "Title is required", http.StatusBadRequest) + return + } + + // Parse due date if provided + var dueDate *time.Time + if dueDateStr != "" { + parsed, err := time.Parse("2006-01-02", dueDateStr) + if err == nil { + dueDate = &parsed + } + } + + switch source { + case "todoist": + _, err := h.todoistClient.CreateTask(ctx, title, "", dueDate, 1) + if err != nil { + http.Error(w, "Failed to create Todoist task", http.StatusInternalServerError) + log.Printf("Error creating Todoist task: %v", err) + return + } + // Invalidate cache so fresh data is fetched + h.store.InvalidateCache("todoist_tasks") + + case "trello": + listID := r.FormValue("list_id") + if listID == "" { + http.Error(w, "List is required for Trello", http.StatusBadRequest) + return + } + _, err := h.trelloClient.CreateCard(ctx, listID, title, "", dueDate) + if err != nil { + http.Error(w, "Failed to create Trello card", http.StatusInternalServerError) + log.Printf("Error creating Trello card: %v", err) + return + } + // Invalidate cache so fresh data is fetched + h.store.InvalidateCache("trello_boards") + + default: + http.Error(w, "Invalid source", http.StatusBadRequest) + return + } + + // Trigger a refresh of the tasks tab via HTMX + w.Header().Set("HX-Trigger", "refresh-tasks") + w.WriteHeader(http.StatusOK) +} + +// HandleGetListsOptions returns HTML options for lists in a given board +func (h *Handler) HandleGetListsOptions(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + boardID := r.URL.Query().Get("board_id") + + if boardID == "" { + http.Error(w, "board_id is required", http.StatusBadRequest) + return + } + + lists, err := h.trelloClient.GetLists(ctx, boardID) + if err != nil { + http.Error(w, "Failed to fetch lists", http.StatusInternalServerError) + log.Printf("Error fetching lists for board %s: %v", boardID, err) + return + } + + w.Header().Set("Content-Type", "text/html") + for _, list := range lists { + fmt.Fprintf(w, `<option value="%s">%s</option>`, list.ID, list.Name) + } +} diff --git a/internal/handlers/tabs.go b/internal/handlers/tabs.go index ce9c34f..74dfbe8 100644 --- a/internal/handlers/tabs.go +++ b/internal/handlers/tabs.go @@ -110,9 +110,11 @@ func (h *TabsHandler) HandleTasks(w http.ResponseWriter, r *http.Request) { // Render template data := struct { - Atoms []models.Atom + Atoms []models.Atom + Boards []models.Board }{ - Atoms: atoms, + Atoms: atoms, + Boards: boards, } if err := h.templates.ExecuteTemplate(w, "tasks-tab", data); err != nil { |
