diff options
| author | Peter Stone <thepeterstone@gmail.com> | 2026-01-25 17:05:49 -1000 |
|---|---|---|
| committer | Peter Stone <thepeterstone@gmail.com> | 2026-01-25 17:09:41 -1000 |
| commit | dedda31d064ddcb4f857f2db851c5a8c1e19deba (patch) | |
| tree | 2f76f41806727afa54449cdac8672056a5f8615c /web/templates/partials/timeline-tab.html | |
| parent | ec8a9c0ea46dec7d26caa763e3adefcaf3fc7552 (diff) | |
Implement architectural refactors for feature requests #28, #30, #31, #33-38
Phase 1: Bugs as First-Class Atoms (#28)
- Add resolved_at column to bugs table (migration 007)
- Add GetUnresolvedBugs(), ResolveBug(), UnresolveBug() store methods
- Include bugs in Tasks tab via BugToAtom() with completion toggle
- Add unit tests for bug resolution
Phase 2: Timeline as Default + Enhancements (#35, #37)
- Change default tab from tasks to timeline
- Add IsCompleted, DaySection, Source fields to TimelineItem
- Group timeline items by today/tomorrow/later sections
- Add completion checkboxes for tasks/cards, grey completed items
- Collapse tomorrow/later sections by default
Phase 3: Shopping Quick-Add (#33)
- Add user_shopping_items table (migration 008)
- Add SaveUserShoppingItem(), GetUserShoppingItems(), ToggleUserShoppingItem()
- Add HandleShoppingQuickAdd() and HandleShoppingToggle() handlers
- Add quick-add form to shopping tab
Phase 4: Mobile Swipe Navigation (#38)
- Add touch event handlers for swipe left/right tab switching
- 50px threshold triggers tab change
Phase 5: Consistent Background Opacity (#30)
- Add CSS variables for panel/card/input/modal backgrounds
- Update templates to use consistent opacity classes
Phase 6: Tab Reorganization (#37)
- Reorganize tabs: Timeline, Shopping, Conditions as main tabs
- Move Tasks, Planning, Meals under Details dropdown
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Diffstat (limited to 'web/templates/partials/timeline-tab.html')
| -rw-r--r-- | web/templates/partials/timeline-tab.html | 162 |
1 files changed, 105 insertions, 57 deletions
diff --git a/web/templates/partials/timeline-tab.html b/web/templates/partials/timeline-tab.html index e73a643..aeaba40 100644 --- a/web/templates/partials/timeline-tab.html +++ b/web/templates/partials/timeline-tab.html @@ -5,70 +5,118 @@ hx-target="#tab-content" hx-swap="innerHTML"> - {{$currentDay := ""}} - {{range .Items}} - {{$day := .Time.Format "Monday, January 2"}} - {{if ne $day $currentDay}} - {{if ne $currentDay ""}} - </div> <!-- Close previous day items --> - </div> <!-- Close previous day container --> + <!-- Today Section --> + {{if .TodayItems}} + <div> + <h2 class="text-lg font-semibold mb-3 flex items-center gap-2 text-white/90 sticky top-0 bg-black/20 backdrop-blur-md py-2 z-10 rounded-lg px-2"> + <span>📅</span> Today + </h2> + <div class="space-y-2 relative pl-4 border-l border-white/10 ml-2"> + {{range .TodayItems}} + {{template "timeline-item" .}} {{end}} - {{$currentDay = $day}} - <div> - <h2 class="text-lg font-semibold mb-3 flex items-center gap-2 text-white/90 sticky top-0 bg-black/20 backdrop-blur-md py-2 z-10 rounded-lg px-2"> - <span>🗓️</span> {{$day}} - </h2> - <div class="space-y-2 relative pl-4 border-l border-white/10 ml-2"> + </div> + </div> + {{end}} + + <!-- Tomorrow Section (Collapsed) --> + {{if .TomorrowItems}} + <details class="group"> + <summary class="text-lg font-semibold mb-3 flex items-center gap-2 text-white/70 cursor-pointer hover:text-white/90 sticky top-0 bg-black/20 backdrop-blur-md py-2 z-10 rounded-lg px-2 list-none"> + <span>🗓️</span> Tomorrow + <span class="text-sm font-normal text-white/50">({{len .TomorrowItems}} items)</span> + <svg class="w-4 h-4 ml-auto transform transition-transform group-open:rotate-180" fill="none" stroke="currentColor" viewBox="0 0 24 24"> + <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path> + </svg> + </summary> + <div class="space-y-2 relative pl-4 border-l border-white/10 ml-2"> + {{range .TomorrowItems}} + {{template "timeline-item" .}} + {{end}} + </div> + </details> + {{end}} + + <!-- Later Section (Collapsed) --> + {{if .LaterItems}} + <details class="group"> + <summary class="text-lg font-semibold mb-3 flex items-center gap-2 text-white/60 cursor-pointer hover:text-white/80 sticky top-0 bg-black/20 backdrop-blur-md py-2 z-10 rounded-lg px-2 list-none"> + <span>📆</span> Later + <span class="text-sm font-normal text-white/40">({{len .LaterItems}} items)</span> + <svg class="w-4 h-4 ml-auto transform transition-transform group-open:rotate-180" fill="none" stroke="currentColor" viewBox="0 0 24 24"> + <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path> + </svg> + </summary> + <div class="space-y-2 relative pl-4 border-l border-white/10 ml-2"> + {{range .LaterItems}} + {{template "timeline-item" .}} + {{end}} + </div> + </details> + {{end}} + + {{if and (not .TodayItems) (not .TomorrowItems) (not .LaterItems)}} + <div class="text-center py-8 text-white/50"> + <p>No items found for the selected range.</p> + </div> + {{end}} + +</div> +{{end}} + +{{define "timeline-item"}} +<div class="bg-card bg-card-hover transition-colors rounded-lg border border-white/5 relative {{if .IsCompleted}}opacity-60{{end}}"> + <!-- Time Indicator --> + <div class="absolute -left-[21px] top-4 w-2.5 h-2.5 rounded-full + {{if eq .Type "event"}}bg-blue-500{{else if eq .Type "meal"}}bg-orange-500{{else if eq .Type "task"}}bg-green-500{{else}}bg-purple-500{{end}}"> + </div> + + <div class="flex items-start gap-3 p-3"> + <!-- Checkbox for tasks/cards --> + {{if or (eq .Type "task") (eq .Type "card")}} + <input type="checkbox" + {{if .IsCompleted}}checked{{end}} + hx-post="{{if .IsCompleted}}/uncomplete-atom{{else}}/complete-atom{{end}}" + 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"> {{end}} - <div class="bg-white/5 hover:bg-white/10 transition-colors rounded-lg border border-white/5 relative"> - <!-- Time Indicator --> - <div class="absolute -left-[21px] top-4 w-2.5 h-2.5 rounded-full - {{if eq .Type "event"}}bg-blue-500{{else if eq .Type "meal"}}bg-orange-500{{else if eq .Type "task"}}bg-green-500{{else}}bg-purple-500{{end}}"> + <div class="flex flex-col items-center min-w-[60px] text-xs text-white/50 pt-0.5"> + <span class="font-medium text-white/80">{{.Time.Format "3:04 PM"}}</span> + {{if .EndTime}} + <span class="text-[10px] opacity-70">{{.EndTime.Format "3:04 PM"}}</span> + {{end}} + </div> + + <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 .IsCompleted}}line-through text-white/50{{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> - <div class="flex items-start gap-3 p-3"> - <div class="flex flex-col items-center min-w-[60px] text-xs text-white/50 pt-0.5"> - <span class="font-medium text-white/80">{{.Time.Format "3:04 PM"}}</span> - {{if .EndTime}} - <span class="text-[10px] opacity-70">{{.EndTime.Format "3:04 PM"}}</span> - {{end}} - </div> - - <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">{{.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/50 mt-1 line-clamp-2">{{.Description}}</p> - {{end}} + {{if .Description}} + <p class="text-xs text-white/50 mt-1 line-clamp-2">{{.Description}}</p> + {{end}} - <div class="flex items-center gap-2 mt-2"> - <span class="text-[10px] px-1.5 py-0.5 rounded bg-white/10 text-white/60 uppercase tracking-wider"> - {{.Type}} - </span> - </div> - </div> + <div class="flex items-center gap-2 mt-2"> + <span class="text-[10px] px-1.5 py-0.5 rounded bg-white/10 text-white/60 uppercase tracking-wider"> + {{.Type}} + </span> + {{if .IsCompleted}} + <span class="text-[10px] px-1.5 py-0.5 rounded bg-green-500/20 text-green-400 uppercase tracking-wider"> + done + </span> + {{end}} </div> </div> - {{end}} - - {{if ne $currentDay ""}} - </div> <!-- Close last day items --> - </div> <!-- Close last day container --> - {{else}} - <div class="text-center py-8 text-white/50"> - <p>No items found for the selected range.</p> - </div> - {{end}} - + </div> </div> {{end}} |
