diff options
| author | Peter Stone <thepeterstone@gmail.com> | 2026-01-20 20:32:22 -1000 |
|---|---|---|
| committer | Peter Stone <thepeterstone@gmail.com> | 2026-01-20 20:32:22 -1000 |
| commit | b412b2a7e6b475d77d215374eafbabc086ba1534 (patch) | |
| tree | 13e2210cb4fb62426af6b94b81b62a277352e838 | |
| parent | 6cdfc55e5712075fef24a559138c054ef58e1ac1 (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>
| -rw-r--r-- | web/static/css/input.css | 4 | ||||
| -rw-r--r-- | web/templates/index.html | 19 | ||||
| -rw-r--r-- | web/templates/partials/tasks-tab.html | 98 |
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> |
