summaryrefslogtreecommitdiff
path: root/web/templates/partials
diff options
context:
space:
mode:
authorPeter Stone <thepeterstone@gmail.com>2026-01-21 22:53:37 -1000
committerPeter Stone <thepeterstone@gmail.com>2026-01-21 22:53:37 -1000
commit583f90c5dedf0235fa45557359b0e6e7dd62b0f0 (patch)
tree304e4527b6668669197fc9ffdf2ffc87566478f0 /web/templates/partials
parentdd4689a71de8f1c0b5a2d483827411a9645ad66a (diff)
Implement 10 UI/UX improvements and bug fixes
- Fix outdated Todoist task URL format (showTask -> app/task) - Fix quick-add date defaulting to tomorrow in evening (client-side JS) - Add tap-to-expand for task descriptions with checkbox completion - Add visual differentiation: overdue (red), future (gray), today (normal) - Sort tasks by urgency: overdue > today-timed > today-allday > future - Keep completed tasks visible with strikethrough until refresh - Add random Unsplash landscape background with content overlay - Hide future tasks behind collapsible fold with count badge - Unified modal menu for Quick Add + Bug Report (Ctrl+K shortcut) - Click task title to edit description in modal Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Diffstat (limited to 'web/templates/partials')
-rw-r--r--web/templates/partials/tasks-tab.html89
1 files changed, 76 insertions, 13 deletions
diff --git a/web/templates/partials/tasks-tab.html b/web/templates/partials/tasks-tab.html
index 2a89a40..afbbe2c 100644
--- a/web/templates/partials/tasks-tab.html
+++ b/web/templates/partials/tasks-tab.html
@@ -10,7 +10,7 @@
onclick="document.getElementById('quick-add-form').classList.toggle('hidden')"
class="w-full p-3 sm:p-4 text-left flex justify-between items-center">
<span class="font-semibold text-gray-900">+ Quick Add</span>
- <span class="text-gray-400 text-sm">tap to expand</span>
+ <svg class="w-4 h-4 text-gray-400" 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>
</button>
<form id="quick-add-form"
class="hidden p-3 sm:p-4 pt-0 border-t border-gray-100"
@@ -28,8 +28,15 @@
<div>
<input type="date"
name="due_date"
- value="{{.Today}}"
+ id="quick-add-date"
class="border border-gray-300 rounded-lg px-2 py-2 text-sm focus:ring-2 focus:ring-primary-500">
+ <script>
+ (function() {
+ var d = new Date();
+ var dateStr = d.getFullYear() + '-' + String(d.getMonth() + 1).padStart(2, '0') + '-' + String(d.getDate()).padStart(2, '0');
+ document.getElementById('quick-add-date').value = dateStr;
+ })();
+ </script>
</div>
<div>
<select name="source"
@@ -73,18 +80,23 @@
{{if .Atoms}}
<div class="space-y-2">
{{range .Atoms}}
- <div class="task-item bg-white rounded-lg p-3 sm:p-4 shadow-sm hover:shadow-md transition-shadow border-l-4 {{.ColorClass}} {{if .IsOverdue}}opacity-50{{end}}"
- hx-post="/complete-atom"
- hx-trigger="click"
- hx-vals='{"id": "{{.ID}}", "source": "{{.Source}}"}'
- hx-target="this"
- hx-swap="outerHTML"
- hx-confirm="Mark as complete?">
- <div class="flex items-start gap-2 sm:gap-3">
+ <div class="task-item bg-white rounded-lg shadow-sm hover:shadow-md transition-shadow border-l-4 {{.ColorClass}} {{if .IsFuture}}opacity-60{{end}}">
+ <div class="flex items-start gap-2 sm:gap-3 p-3 sm:p-4">
+ <!-- Checkbox for completing -->
+ <input type="checkbox"
+ hx-post="/complete-atom"
+ hx-vals='{"id": "{{.ID}}", "source": "{{.Source}}"}'
+ hx-target="closest .task-item"
+ hx-swap="outerHTML"
+ class="mt-1 h-5 w-5 rounded border-gray-300 text-primary-600 focus:ring-primary-500 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 font-medium {{if .IsOverdue}}text-gray-500{{else}}text-gray-900{{end}} break-words">{{.Title}}</h3>
+ <h3 class="text-sm {{if .IsOverdue}}text-red-600 font-semibold{{else if .IsFuture}}text-gray-400 font-normal{{else}}text-gray-900 font-medium{{end}} break-words cursor-pointer hover:underline"
+ hx-get="/tasks/detail?id={{.ID}}&source={{.Source}}"
+ hx-target="#task-edit-content"
+ hx-swap="innerHTML"
+ onclick="document.getElementById('task-edit-modal').classList.remove('hidden')">{{.Title}}</h3>
{{if .URL}}
<a href="{{.URL}}" target="_blank" class="text-primary-600 hover:text-primary-800 flex-shrink-0" onclick="event.stopPropagation()">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
@@ -95,21 +107,72 @@
</div>
<div class="flex flex-wrap items-center gap-2 mt-1 text-xs text-gray-400">
{{if .DueDate}}
- <span class="{{if .IsOverdue}}text-red-400{{end}}">{{.DueDate.Format "Jan 2"}}{{if .HasSetTime}}, {{.DueDate.Format "3:04pm"}}{{end}}</span>
+ <span class="{{if .IsOverdue}}text-red-500 font-medium{{end}}">{{.DueDate.Format "Jan 2"}}{{if .HasSetTime}}, {{.DueDate.Format "3:04pm"}}{{end}}</span>
{{end}}
{{if gt .Priority 2}}
<span class="text-red-500 font-medium">P{{.Priority}}</span>
{{end}}
+ {{if .Description}}
+ <span class="text-gray-400">+details</span>
+ {{end}}
</div>
</div>
</div>
+ {{if .Description}}
+ <details class="border-t border-gray-100">
+ <summary class="px-3 sm:px-4 py-2 text-xs text-gray-500 cursor-pointer hover:bg-gray-50">Tap to expand</summary>
+ <div class="px-3 sm:px-4 pb-3 text-sm text-gray-600">{{.Description}}</div>
+ </details>
+ {{end}}
</div>
{{end}}
</div>
{{else}}
<div class="bg-white/50 rounded-lg p-6 text-center">
- <p class="text-gray-500 text-sm">No tasks found.</p>
+ <p class="text-gray-500 text-sm">No current tasks.</p>
</div>
{{end}}
+
+ <!-- Future Tasks (Collapsed by default) -->
+ {{if .FutureAtoms}}
+ <details class="mt-4">
+ <summary class="bg-white/70 rounded-lg p-3 cursor-pointer hover:bg-white/90 transition-colors text-sm text-gray-600 flex items-center justify-between">
+ <span>+{{len .FutureAtoms}} later</span>
+ <svg class="w-4 h-4 transform transition-transform" 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 mt-2">
+ {{range .FutureAtoms}}
+ <div class="task-item bg-white rounded-lg shadow-sm hover:shadow-md transition-shadow border-l-4 {{.ColorClass}} opacity-60">
+ <div class="flex items-start gap-2 sm:gap-3 p-3 sm:p-4">
+ <input type="checkbox"
+ hx-post="/complete-atom"
+ hx-vals='{"id": "{{.ID}}", "source": "{{.Source}}"}'
+ hx-target="closest .task-item"
+ hx-swap="outerHTML"
+ class="mt-1 h-5 w-5 rounded border-gray-300 text-primary-600 focus:ring-primary-500 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-gray-400 font-normal break-words">{{.Title}}</h3>
+ {{if .URL}}
+ <a href="{{.URL}}" target="_blank" class="text-primary-600 hover:text-primary-800 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-gray-400">
+ {{if .DueDate}}
+ <span>{{.DueDate.Format "Jan 2"}}{{if .HasSetTime}}, {{.DueDate.Format "3:04pm"}}{{end}}</span>
+ {{end}}
+ </div>
+ </div>
+ </div>
+ </div>
+ {{end}}
+ </div>
+ </details>
+ {{end}}
</div>
{{end}}