summaryrefslogtreecommitdiff
path: root/web
diff options
context:
space:
mode:
authorPeter Stone <thepeterstone@gmail.com>2026-01-20 20:32:22 -1000
committerPeter Stone <thepeterstone@gmail.com>2026-01-20 20:32:22 -1000
commitb412b2a7e6b475d77d215374eafbabc086ba1534 (patch)
tree13e2210cb4fb62426af6b94b81b62a277352e838 /web
parent6cdfc55e5712075fef24a559138c054ef58e1ac1 (diff)
Improve mobile responsiveness
- Hide full header on mobile, show compact version - Make Quick Add collapsible to save space - Compact task cards: smaller padding, text, and gaps - Remove checkbox decoration, tap card to complete - Reduce side padding on mobile - Smaller tab buttons on mobile Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Diffstat (limited to 'web')
-rw-r--r--web/static/css/input.css4
-rw-r--r--web/templates/index.html19
-rw-r--r--web/templates/partials/tasks-tab.html98
3 files changed, 55 insertions, 66 deletions
diff --git a/web/static/css/input.css b/web/static/css/input.css
index 5c062c0..f2bbca8 100644
--- a/web/static/css/input.css
+++ b/web/static/css/input.css
@@ -30,7 +30,7 @@
/* Navigation Pills */
.tab-button {
- @apply px-4 py-2 rounded-lg text-sm font-medium text-gray-600 transition-all duration-200;
+ @apply px-2 sm:px-4 py-2 rounded-lg text-xs sm:text-sm font-medium text-gray-600 transition-all duration-200;
}
.tab-button:hover {
@@ -79,7 +79,7 @@
/* Custom utilities */
@layer utilities {
.section-spacing { @apply mb-10; }
- .content-max-width { @apply max-w-7xl mx-auto px-6 lg:px-8; }
+ .content-max-width { @apply max-w-7xl mx-auto px-3 sm:px-6 lg:px-8; }
.card-grid { @apply grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6; }
/* Scrollbar styling */
diff --git a/web/templates/index.html b/web/templates/index.html
index c270b48..3c91e63 100644
--- a/web/templates/index.html
+++ b/web/templates/index.html
@@ -7,9 +7,9 @@
<link rel="stylesheet" href="/static/css/output.css">
</head>
<body class="min-h-screen" hx-headers='{"X-CSRF-Token": "{{.CSRFToken}}"}'>
- <div class="content-max-width py-8">
- <!-- Header -->
- <header class="mb-8 flex flex-col sm:flex-row justify-between items-start sm:items-center gap-4">
+ <div class="content-max-width py-4 sm:py-8">
+ <!-- Header - Hidden on mobile -->
+ <header class="hidden sm:flex mb-8 flex-row justify-between items-center gap-4">
<h1 class="text-4xl font-bold text-gray-900">Personal Dashboard</h1>
<div class="flex items-center gap-4">
<span class="text-sm text-gray-600">
@@ -29,6 +29,19 @@
</div>
</header>
+ <!-- Mobile Header - Compact -->
+ <header class="flex sm:hidden mb-4 justify-between items-center">
+ <button onclick="refreshData()"
+ class="text-primary-600 p-2 no-print">
+ <span id="refresh-text-mobile">↻</span>
+ </button>
+ <span class="text-xs text-gray-500" id="last-updated-mobile">{{.LastUpdated.Format "3:04 PM"}}</span>
+ <form method="POST" action="/logout" class="no-print">
+ <input type="hidden" name="csrf_token" value="{{.CSRFToken}}">
+ <button type="submit" class="text-gray-500 text-sm p-2">Logout</button>
+ </form>
+ </header>
+
<!-- Tab Navigation -->
<div class="mb-8 no-print">
<nav class="flex space-x-1 bg-white/30 backdrop-blur-md rounded-xl p-1">
diff --git a/web/templates/partials/tasks-tab.html b/web/templates/partials/tasks-tab.html
index 7c94849..3f0d5bf 100644
--- a/web/templates/partials/tasks-tab.html
+++ b/web/templates/partials/tasks-tab.html
@@ -4,36 +4,43 @@
hx-trigger="refresh-tasks from:body"
hx-target="#tab-content"
hx-swap="innerHTML">
- <!-- Quick Add Form -->
- <section class="bg-white rounded-lg p-4 shadow-sm">
- <h3 class="text-lg font-semibold text-gray-900 mb-3">Quick Add</h3>
- <form hx-post="/unified-add"
+ <!-- Quick Add Form - Collapsible -->
+ <section class="bg-white rounded-lg shadow-sm">
+ <button type="button"
+ 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>
+ </button>
+ <form id="quick-add-form"
+ class="hidden p-3 sm:p-4 pt-0 border-t border-gray-100"
+ hx-post="/unified-add"
hx-swap="none"
hx-on::after-request="if(event.detail.successful) { this.reset(); document.getElementById('trello-fields').style.display = 'none'; }">
<div class="flex flex-wrap gap-2 items-end">
- <div class="flex-1 min-w-[200px]">
+ <div class="flex-1 min-w-[150px]">
<input type="text"
name="title"
placeholder="Task name..."
- class="w-full border border-gray-300 rounded-lg px-3 py-2 focus:ring-2 focus:ring-primary-500 focus:border-primary-500"
+ class="w-full border border-gray-300 rounded-lg px-3 py-2 text-sm focus:ring-2 focus:ring-primary-500 focus:border-primary-500"
required>
</div>
<div>
<input type="date"
name="due_date"
value="{{.Today}}"
- class="border border-gray-300 rounded-lg px-3 py-2 focus:ring-2 focus:ring-primary-500">
+ class="border border-gray-300 rounded-lg px-2 py-2 text-sm focus:ring-2 focus:ring-primary-500">
</div>
<div>
<select name="source"
- class="border border-gray-300 rounded-lg px-3 py-2 focus:ring-2 focus:ring-primary-500"
+ class="border border-gray-300 rounded-lg px-2 py-2 text-sm focus:ring-2 focus:ring-primary-500"
onchange="document.getElementById('trello-fields').style.display = this.value === 'trello' ? 'flex' : 'none'">
<option value="todoist">Todoist</option>
<option value="trello">Trello</option>
</select>
</div>
<button type="submit"
- class="bg-primary-600 hover:bg-primary-700 text-white px-4 py-2 rounded-lg transition-colors font-medium">
+ class="bg-primary-600 hover:bg-primary-700 text-white px-3 py-2 rounded-lg transition-colors font-medium text-sm">
Add
</button>
</div>
@@ -42,7 +49,7 @@
<div id="trello-fields" class="flex flex-wrap gap-2 mt-3" style="display: none;">
<div>
<select name="board_id"
- class="border border-gray-300 rounded-lg px-3 py-2 text-sm"
+ class="border border-gray-300 rounded-lg px-2 py-2 text-sm"
hx-get="/partials/lists"
hx-target="#list-select"
hx-trigger="change"
@@ -54,7 +61,7 @@
</select>
</div>
<div>
- <select id="list-select" name="list_id" class="border border-gray-300 rounded-lg px-3 py-2 text-sm">
+ <select id="list-select" name="list_id" class="border border-gray-300 rounded-lg px-2 py-2 text-sm">
<option value="">Select List...</option>
</select>
</div>
@@ -64,71 +71,40 @@
<!-- Unified Tasks Section -->
<section>
- <h2 class="section-header mb-6">
- <span class="section-accent bg-gradient-to-r from-red-500 to-blue-500"></span>
+ <h2 class="text-base sm:text-lg font-semibold text-gray-900 mb-3 sm:mb-4">
Upcoming Tasks
</h2>
{{if .Atoms}}
- <div class="space-y-4">
+ <div class="space-y-2 sm:space-y-3">
{{range .Atoms}}
- <div class="task-item bg-white rounded-lg p-6 shadow-sm hover:shadow-md transition-shadow border-l-4 {{.ColorClass}}">
- <div class="flex items-start gap-4">
-
- <!-- Checkbox -->
- <div class="pt-1">
- <input type="checkbox"
- class="w-5 h-5 text-blue-600 rounded border-gray-300 focus:ring-blue-500 cursor-pointer"
- hx-post="/complete-atom"
- hx-trigger="change"
- hx-vals='{"id": "{{.ID}}", "source": "{{.Source}}"}'
- hx-target="closest .task-item"
- hx-swap="outerHTML">
- </div>
-
- <div class="flex-1">
- <div class="flex items-center justify-between mb-2">
- <div class="flex items-center gap-3">
- <span class="text-2xl">{{.SourceIcon}}</span>
- <h3 class="text-lg font-semibold text-gray-900">{{.Title}}</h3>
- </div>
+ <div class="task-item bg-white rounded-lg p-3 sm:p-4 shadow-sm hover:shadow-md transition-shadow border-l-4 {{.ColorClass}}"
+ 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">
+ <span class="text-lg sm:text-xl 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 sm:text-base font-medium text-gray-900 break-words">{{.Title}}</h3>
{{if .URL}}
- <a href="{{.URL}}" target="_blank" class="text-primary-600 hover:text-primary-800 transition-colors">
- <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
+ <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">
<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-sm text-gray-600 mb-3">{{.Description}}</p>
- {{end}}
-
- <div class="flex items-center gap-4 text-sm text-gray-500">
+ <div class="flex flex-wrap items-center gap-2 sm:gap-3 mt-1 text-xs sm:text-sm text-gray-500">
{{if .DueDate}}
- <div class="flex items-center gap-1">
- <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="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"></path>
- </svg>
- <span>{{.DueDate.Format "Jan 2, 3:04 PM"}}</span>
- </div>
+ <span>{{.DueDate.Format "Jan 2"}}</span>
{{end}}
-
- <div class="flex items-center gap-1">
- <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="M7 7h.01M7 3h5c.512 0 1.024.195 1.414.586l7 7a2 2 0 010 2.828l-7 7a2 2 0 01-2.828 0l-7-7A1.994 1.994 0 013 12V7a4 4 0 014-4z"></path>
- </svg>
- <span>{{if eq .Source "trello"}}Trello{{else if eq .Source "todoist"}}Todoist{{else}}{{.Source}}{{end}}</span>
- </div>
-
{{if gt .Priority 2}}
- <div class="flex items-center gap-1 text-red-600 font-medium">
- <svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20">
- <path d="M10 2a8 8 0 100 16 8 8 0 000-16zm1 11H9v-2h2v2zm0-4H9V5h2v4z"></path>
- </svg>
- <span>Priority {{.Priority}}</span>
- </div>
+ <span class="text-red-600 font-medium">P{{.Priority}}</span>
{{end}}
</div>
</div>