summaryrefslogtreecommitdiff
path: root/web/templates/index.html
diff options
context:
space:
mode:
authorPeter Stone <thepeterstone@gmail.com>2026-01-25 17:05:49 -1000
committerPeter Stone <thepeterstone@gmail.com>2026-01-25 17:09:41 -1000
commitdedda31d064ddcb4f857f2db851c5a8c1e19deba (patch)
tree2f76f41806727afa54449cdac8672056a5f8615c /web/templates/index.html
parentec8a9c0ea46dec7d26caa763e3adefcaf3fc7552 (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/index.html')
-rw-r--r--web/templates/index.html116
1 files changed, 81 insertions, 35 deletions
diff --git a/web/templates/index.html b/web/templates/index.html
index b55f348..f4c0b59 100644
--- a/web/templates/index.html
+++ b/web/templates/index.html
@@ -7,8 +7,23 @@
<link rel="icon" type="image/svg+xml" href="/static/favicon.svg">
<link rel="stylesheet" href="/static/css/output.css">
<style>
+ :root {
+ --panel-bg: rgba(0, 0, 0, 0.4);
+ --card-bg: rgba(255, 255, 255, 0.05);
+ --card-bg-hover: rgba(255, 255, 255, 0.1);
+ --input-bg: rgba(0, 0, 0, 0.4);
+ --modal-bg: rgba(0, 0, 0, 0.8);
+ --modal-overlay: rgba(0, 0, 0, 0.7);
+ }
.text-shadow { text-shadow: 0 0 8px black, 0 0 8px black; }
.text-shadow-sm { text-shadow: 0 0 4px black; }
+ /* CSS variable-based backgrounds */
+ .bg-panel { background-color: var(--panel-bg); }
+ .bg-card { background-color: var(--card-bg); }
+ .bg-card-hover:hover { background-color: var(--card-bg-hover); }
+ .bg-input { background-color: var(--input-bg); }
+ .bg-modal { background-color: var(--modal-bg); }
+ .bg-modal-overlay { background-color: var(--modal-overlay); }
</style>
</head>
<body class="min-h-screen bg-gray-900 text-white" style="background-image: url('{{.BackgroundURL}}'); background-size: cover; background-position: center; background-attachment: fixed;" hx-headers='{"X-CSRF-Token": "{{.CSRFToken}}"}'>
@@ -31,31 +46,8 @@
<!-- Tab Navigation -->
<div class="mb-4 sm:mb-6 no-print">
- <nav class="flex space-x-1 bg-black/50 backdrop-blur-sm rounded-xl p-1 text-shadow-sm">
- <button
- class="tab-button {{if eq .ActiveTab "tasks"}}tab-button-active{{end}}"
- hx-get="/tabs/tasks"
- hx-target="#tab-content"
- hx-push-url="?tab=tasks"
- onclick="setActiveTab(this)">
- ✓ Tasks
- </button>
- <button
- class="tab-button {{if eq .ActiveTab "planning"}}tab-button-active{{end}}"
- hx-get="/tabs/planning"
- hx-target="#tab-content"
- hx-push-url="?tab=planning"
- onclick="setActiveTab(this)">
- 📋 Planning
- </button>
- <button
- class="tab-button {{if eq .ActiveTab "meals"}}tab-button-active{{end}}"
- hx-get="/tabs/meals"
- hx-target="#tab-content"
- hx-push-url="?tab=meals"
- onclick="setActiveTab(this)">
- 🍽️ Meals
- </button>
+ <nav class="flex space-x-1 bg-panel backdrop-blur-sm rounded-xl p-1 text-shadow-sm">
+ <!-- Main Tabs -->
<button
class="tab-button {{if eq .ActiveTab "timeline"}}tab-button-active{{end}}"
hx-get="/tabs/timeline"
@@ -77,6 +69,44 @@
target="_blank">
🌋 Conditions
</a>
+
+ <!-- Details Dropdown -->
+ <div class="relative" id="details-dropdown">
+ <button
+ class="tab-button {{if or (eq .ActiveTab "tasks") (eq .ActiveTab "planning") (eq .ActiveTab "meals")}}tab-button-active{{end}}"
+ onclick="toggleDetailsDropdown(event)">
+ 📁 Details
+ <svg class="w-3 h-3 ml-1 inline" 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>
+ <div id="details-menu" class="hidden absolute top-full left-0 mt-1 bg-panel backdrop-blur-sm rounded-lg p-1 min-w-[140px] z-20">
+ <button
+ class="w-full text-left tab-button {{if eq .ActiveTab "tasks"}}tab-button-active{{end}}"
+ hx-get="/tabs/tasks"
+ hx-target="#tab-content"
+ hx-push-url="?tab=tasks"
+ onclick="setActiveTab(this); closeDetailsDropdown();">
+ ✓ Tasks
+ </button>
+ <button
+ class="w-full text-left tab-button {{if eq .ActiveTab "planning"}}tab-button-active{{end}}"
+ hx-get="/tabs/planning"
+ hx-target="#tab-content"
+ hx-push-url="?tab=planning"
+ onclick="setActiveTab(this); closeDetailsDropdown();">
+ 📋 Planning
+ </button>
+ <button
+ class="w-full text-left tab-button {{if eq .ActiveTab "meals"}}tab-button-active{{end}}"
+ hx-get="/tabs/meals"
+ hx-target="#tab-content"
+ hx-push-url="?tab=meals"
+ onclick="setActiveTab(this); closeDetailsDropdown();">
+ 🍽️ Meals
+ </button>
+ </div>
+ </div>
</nav>
</div>
@@ -102,8 +132,8 @@
</button>
<!-- Unified Action Modal -->
- <div id="action-modal" class="hidden fixed inset-0 bg-black/70 flex items-center justify-center p-4 z-50">
- <div class="bg-black/80 backdrop-blur-sm rounded-lg max-w-md w-full max-h-[80vh] overflow-hidden" style="box-shadow: 0 0 20px black;">
+ <div id="action-modal" class="hidden fixed inset-0 bg-modal-overlay flex items-center justify-center p-4 z-50">
+ <div class="bg-modal backdrop-blur-sm rounded-lg max-w-md w-full max-h-[80vh] overflow-hidden" style="box-shadow: 0 0 20px black;">
<div class="p-4 border-b border-white/10 flex justify-between items-center">
<div class="flex gap-2">
<button onclick="switchActionTab('add')" id="tab-add"
@@ -130,15 +160,15 @@
<input type="text"
name="title"
placeholder="Task name..."
- class="w-full bg-black/40 border border-white/20 rounded-lg px-3 py-2 text-sm text-white placeholder-white/50 mb-3"
+ class="w-full bg-input border border-white/20 rounded-lg px-3 py-2 text-sm text-white placeholder-white/50 mb-3"
required
autofocus>
<div class="flex gap-2 mb-3">
<input type="date"
name="due_date"
id="modal-add-date"
- class="flex-1 bg-black/40 border border-white/20 rounded-lg px-3 py-2 text-sm text-white">
- <select name="source" class="bg-black/40 border border-white/20 rounded-lg px-3 py-2 text-sm text-white">
+ class="flex-1 bg-input border border-white/20 rounded-lg px-3 py-2 text-sm text-white">
+ <select name="source" class="bg-input border border-white/20 rounded-lg px-3 py-2 text-sm text-white">
<option value="todoist">Todoist</option>
<option value="trello">Trello</option>
</select>
@@ -159,11 +189,11 @@
<input type="text"
name="title"
placeholder="Item name..."
- class="w-full bg-black/40 border border-white/20 rounded-lg px-3 py-2 text-sm text-white placeholder-white/50 mb-3"
+ class="w-full bg-input border border-white/20 rounded-lg px-3 py-2 text-sm text-white placeholder-white/50 mb-3"
required>
<select name="list_id"
id="shopping-list-select"
- class="w-full bg-black/40 border border-white/20 rounded-lg px-3 py-2 text-sm text-white mb-3"
+ class="w-full bg-input border border-white/20 rounded-lg px-3 py-2 text-sm text-white mb-3"
required>
<option value="">Loading stores...</option>
</select>
@@ -182,7 +212,7 @@
hx-on::after-request="if(event.detail.successful) { this.reset(); closeActionModal(); }">
<textarea name="description"
placeholder="Describe the bug..."
- class="w-full bg-black/40 border border-white/20 rounded-lg px-3 py-2 text-sm text-white placeholder-white/50 mb-3 h-24"
+ class="w-full bg-input border border-white/20 rounded-lg px-3 py-2 text-sm text-white placeholder-white/50 mb-3 h-24"
required></textarea>
<button type="submit"
class="w-full bg-red-900/50 hover:bg-red-900/70 text-red-300 px-4 py-2 rounded-lg text-sm font-medium">
@@ -272,11 +302,27 @@
function closeTaskModal() {
document.getElementById('task-edit-modal').classList.add('hidden');
}
+ // Details dropdown functions
+ function toggleDetailsDropdown(e) {
+ e.stopPropagation();
+ var menu = document.getElementById('details-menu');
+ menu.classList.toggle('hidden');
+ }
+ function closeDetailsDropdown() {
+ document.getElementById('details-menu').classList.add('hidden');
+ }
+ // Close dropdown when clicking outside
+ document.addEventListener('click', function(e) {
+ var dropdown = document.getElementById('details-dropdown');
+ if (dropdown && !dropdown.contains(e.target)) {
+ closeDetailsDropdown();
+ }
+ });
</script>
<!-- Task Edit Modal -->
- <div id="task-edit-modal" class="hidden fixed inset-0 bg-black/70 flex items-center justify-center p-4 z-50">
- <div class="bg-black/80 backdrop-blur-sm rounded-lg max-w-md w-full max-h-[80vh] overflow-hidden" style="box-shadow: 0 0 20px black;">
+ <div id="task-edit-modal" class="hidden fixed inset-0 bg-modal-overlay flex items-center justify-center p-4 z-50">
+ <div class="bg-modal backdrop-blur-sm rounded-lg max-w-md w-full max-h-[80vh] overflow-hidden" style="box-shadow: 0 0 20px black;">
<div class="p-4 border-b border-white/10 flex justify-between items-center">
<h2 class="font-medium text-white">Edit Task</h2>
<button onclick="closeTaskModal()" class="text-white/40 hover:text-white">✕</button>