summaryrefslogtreecommitdiff
path: root/web/templates/partials
diff options
context:
space:
mode:
authorPeter Stone <thepeterstone@gmail.com>2026-01-23 16:10:52 -1000
committerPeter Stone <thepeterstone@gmail.com>2026-01-23 16:10:52 -1000
commit7828e19501b3ca8b2e86ca7297f580c659e5c9b8 (patch)
treee3113af67fcecc459d81b213d7f043630dccae98 /web/templates/partials
parentd11334c0999efb670a8eab93527a50f644fdfceb (diff)
Fix bugs #24-27: calendar dedup, uncomplete tasks, planning view
Bug fixes: - #24: Deduplicate calendar events across multiple calendars using summary + start time as key - #25: Change event icon from calendar to clock to avoid confusion with date display - #26: Add task uncomplete functionality via ReopenTask API for Todoist and closed=false for Trello - #27: Restructure planning view with sections for Scheduled (timed events/tasks), Today (unscheduled), Quick Add, and Upcoming (3 days) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Diffstat (limited to 'web/templates/partials')
-rw-r--r--web/templates/partials/planning-tab.html166
1 files changed, 142 insertions, 24 deletions
diff --git a/web/templates/partials/planning-tab.html b/web/templates/partials/planning-tab.html
index 77bd3d8..bfb3eee 100644
--- a/web/templates/partials/planning-tab.html
+++ b/web/templates/partials/planning-tab.html
@@ -1,43 +1,161 @@
{{define "planning-tab"}}
-<div class="space-y-6">
- <!-- Google Calendar Events -->
- {{if .Events}}
- <div class="bg-white/10 backdrop-blur-sm rounded-xl p-4 shadow-sm border border-white/10">
- <h2 class="text-xl font-semibold mb-4 flex items-center gap-2 text-shadow-sm">
- <span>📅</span> Upcoming Events
+<div class="space-y-6 text-shadow-sm"
+ hx-get="/tabs/planning"
+ hx-trigger="refresh-tasks from:body"
+ hx-target="#tab-content"
+ hx-swap="innerHTML">
+
+ <!-- Scheduled Section (Events + Timed Tasks) -->
+ {{if .Scheduled}}
+ <div>
+ <h2 class="text-lg font-semibold mb-3 flex items-center gap-2 text-white/90">
+ <span>⏰</span> Scheduled
</h2>
<div class="space-y-2">
- {{range .Events}}
- <a href="{{.HTMLLink}}" target="_blank" class="task-item border-l-4 border-blue-500 block group">
- <div class="flex items-start gap-3 p-3 sm:p-4">
- <span class="text-lg flex-shrink-0">📅</span>
+ {{range .Scheduled}}
+ <div class="bg-white/5 hover:bg-white/10 transition-colors rounded-lg border border-white/5 border-l-4 {{if eq .Type "event"}}border-l-blue-500{{else}}border-l-green-500{{end}}">
+ <div class="flex items-start gap-3 p-3">
+ <span class="text-lg flex-shrink-0 mt-0.5">{{.SourceIcon}}</span>
<div class="flex-1 min-w-0">
<div class="flex items-start justify-between gap-2">
- <h3 class="text-sm text-white font-medium break-words group-hover:underline">{{.Summary}}</h3>
- <svg class="w-4 h-4 text-white/50 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"></path>
- </svg>
+ <h3 class="text-sm text-white font-medium break-words">{{.Title}}</h3>
+ {{if .URL}}
+ <a href="{{.URL}}" target="_blank" class="text-white/50 hover:text-white flex-shrink-0">
+ <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"></path>
+ </svg>
+ </a>
+ {{end}}
</div>
- <div class="flex flex-wrap items-center gap-2 mt-1 text-xs text-white/50">
- <span>{{.Start.Format "Jan 2"}}</span>
- {{if eq (.Start.Format "15:04") "00:00"}}
- <span>All Day</span>
+ <div class="text-xs text-white/50 mt-1">
+ {{if eq .Type "event"}}
+ {{if eq (.Start.Format "15:04") "00:00"}}
+ All Day
+ {{else}}
+ {{.Start.Format "3:04 PM"}} - {{.End.Format "3:04 PM"}}
+ {{end}}
{{else}}
- <span>{{.Start.Format "3:04 PM"}} - {{.End.Format "3:04 PM"}}</span>
+ {{.Start.Format "3:04 PM"}}
+ {{end}}
+ </div>
+ </div>
+ </div>
+ </div>
+ {{end}}
+ </div>
+ </div>
+ {{end}}
+
+ <!-- Unscheduled Section (Tasks due today without time) -->
+ {{if .Unscheduled}}
+ <div>
+ <h2 class="text-lg font-semibold mb-3 flex items-center gap-2 text-white/90">
+ <span>📝</span> Today
+ </h2>
+ <div class="grid gap-2 sm:grid-cols-2">
+ {{range .Unscheduled}}
+ <div class="bg-white/5 hover:bg-white/10 transition-colors rounded-lg border border-white/5">
+ <div class="flex items-start gap-2 p-3">
+ <input type="checkbox"
+ hx-post="/complete-atom"
+ hx-vals='{"id": "{{.ID}}", "source": "{{.Source}}"}'
+ hx-target="closest div.rounded-lg"
+ hx-swap="outerHTML"
+ class="mt-1 h-5 w-5 rounded bg-black/40 border-white/30 text-white/80 focus:ring-white/30 cursor-pointer flex-shrink-0">
+ <span class="text-lg flex-shrink-0">{{.SourceIcon}}</span>
+ <div class="flex-1 min-w-0">
+ <div class="flex items-start justify-between gap-2">
+ <h3 class="text-sm text-white font-medium break-words {{if .IsOverdue}}text-amber-300{{end}}">{{.Title}}</h3>
+ {{if .URL}}
+ <a href="{{.URL}}" target="_blank" class="text-white/50 hover:text-white flex-shrink-0">
+ <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"></path>
+ </svg>
+ </a>
{{end}}
</div>
- {{if .Description}}
- <p class="text-xs text-white/40 mt-1 line-clamp-2">{{.Description}}</p>
+ {{if gt .Priority 2}}
+ <span class="text-xs text-amber-300/80">P{{.Priority}}</span>
{{end}}
</div>
</div>
- </a>
+ </div>
{{end}}
</div>
</div>
{{end}}
- <!-- Trello Boards Section -->
- {{template "trello-boards" .}}
+ <!-- Quick Add Section -->
+ <div class="bg-white/5 backdrop-blur-sm rounded-lg p-4 border border-white/10">
+ <h2 class="text-lg font-semibold mb-3 flex items-center gap-2 text-white/90">
+ <span>+</span> Quick Add
+ </h2>
+ <form hx-post="/unified-add"
+ hx-swap="none"
+ hx-on::after-request="if(event.detail.successful) { this.reset(); htmx.trigger(document.body, 'refresh-tasks'); }">
+ <div class="flex gap-2">
+ <input type="text"
+ name="title"
+ placeholder="Add a task for today..."
+ class="flex-1 bg-black/40 border border-white/20 rounded-lg px-3 py-2 text-sm text-white placeholder-white/50"
+ required>
+ <input type="hidden" name="due_date" value="{{.Today}}">
+ <input type="hidden" name="source" value="todoist">
+ <button type="submit"
+ class="bg-white/20 hover:bg-white/30 text-white px-4 py-2 rounded-lg text-sm font-medium">
+ Add
+ </button>
+ </div>
+ </form>
+ </div>
+
+ <!-- Upcoming Section (Next 3 days) -->
+ {{if .Upcoming}}
+ <div>
+ <h2 class="text-lg font-semibold mb-3 flex items-center gap-2 text-white/90">
+ <span>📆</span> Upcoming
+ </h2>
+ <div class="space-y-2">
+ {{range .Upcoming}}
+ <div class="bg-white/5 hover:bg-white/10 transition-colors rounded-lg border border-white/5 opacity-70">
+ <div class="flex items-start gap-3 p-3">
+ <span class="text-lg flex-shrink-0 mt-0.5">{{.SourceIcon}}</span>
+ <div class="flex-1 min-w-0">
+ <div class="flex items-start justify-between gap-2">
+ <h3 class="text-sm text-white/80 font-medium break-words">{{.Title}}</h3>
+ {{if .URL}}
+ <a href="{{.URL}}" target="_blank" class="text-white/40 hover:text-white/70 flex-shrink-0">
+ <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"></path>
+ </svg>
+ </a>
+ {{end}}
+ </div>
+ <div class="text-xs text-white/40 mt-1">
+ {{.Start.Format "Mon, Jan 2"}}
+ {{if eq .Type "event"}}
+ {{if ne (.Start.Format "15:04") "00:00"}}
+ at {{.Start.Format "3:04 PM"}}
+ {{end}}
+ {{else}}
+ {{if or (ne .Start.Hour 0) (ne .Start.Minute 0)}}
+ at {{.Start.Format "3:04 PM"}}
+ {{end}}
+ {{end}}
+ </div>
+ </div>
+ </div>
+ </div>
+ {{end}}
+ </div>
+ </div>
+ {{end}}
+
+ <!-- Empty state if nothing scheduled -->
+ {{if and (not .Scheduled) (not .Unscheduled) (not .Upcoming)}}
+ <div class="text-center py-8 text-white/50">
+ <p>No scheduled items for the next few days.</p>
+ </div>
+ {{end}}
</div>
{{end}}