diff options
| author | Peter Stone <thepeterstone@gmail.com> | 2026-02-01 14:47:50 -1000 |
|---|---|---|
| committer | Peter Stone <thepeterstone@gmail.com> | 2026-02-01 14:47:50 -1000 |
| commit | f10044eac1997537bcdf7699f5b4284aac16f8e2 (patch) | |
| tree | 12d9ec802eb1fd4e615ab2bbcbb1f3b7f30d0d86 /web/templates/shopping-mode.html | |
| parent | d310d7d2135b3203ccb55489fe335b855c745630 (diff) | |
Improve shopping mode and flatten nav bar
Shopping mode:
- Click to complete items (deletes user items, hides external items)
- Add print button with compact two-column print layout
- Fix CSRF token for HTMX requests
- Fix input clearing with proper htmx:afterRequest handler
- Remove "Quick Add" store option, require valid store
Navigation:
- Replace dropdown menu with flat nav showing all tabs
- Remove unused dropdown JS
Tests:
- Add TestHandleShoppingModeComplete for user and external items
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Diffstat (limited to 'web/templates/shopping-mode.html')
| -rw-r--r-- | web/templates/shopping-mode.html | 100 |
1 files changed, 78 insertions, 22 deletions
diff --git a/web/templates/shopping-mode.html b/web/templates/shopping-mode.html index 88d8561..b2f129a 100644 --- a/web/templates/shopping-mode.html +++ b/web/templates/shopping-mode.html @@ -14,20 +14,6 @@ margin: 0; padding: 0; } - .item-row { - transition: all 0.2s ease; - } - .item-row:active { - transform: scale(0.98); - background: rgba(255,255,255,0.15); - } - .item-checked { - opacity: 0.5; - } - .item-checked .item-name { - text-decoration: line-through; - color: rgba(255,255,255,0.4); - } .store-switcher { scrollbar-width: none; -ms-overflow-style: none; @@ -35,11 +21,62 @@ .store-switcher::-webkit-scrollbar { display: none; } + .flash-success { + background: rgba(34, 197, 94, 0.2); + border-radius: 8px; + } + @media print { + * { + text-shadow: none !important; + } + body { + background: white !important; + color: black !important; + font-size: 10px !important; + line-height: 1.2 !important; + } + .no-print { + display: none !important; + } + main { + padding: 0 !important; + } + #shopping-items > div { + display: grid !important; + grid-template-columns: 1fr 1fr !important; + gap: 0 12px !important; + } + #shopping-items > div > div { + background: none !important; + border: none !important; + border-radius: 0 !important; + padding: 1px 0 !important; + color: black !important; + gap: 3px !important; + } + #shopping-items span { + color: black !important; + font-size: 10px !important; + } + #shopping-items .item-qty { + font-size: 8px !important; + color: #666 !important; + } + #shopping-items .rounded-full { + width: 8px !important; + height: 8px !important; + border-width: 1px !important; + border-color: #888 !important; + } + #shopping-items .text-xs { + display: none !important; + } + } </style> </head> -<body class="text-white"> +<body class="text-white" hx-headers='{"X-CSRF-Token": "{{.CSRFToken}}"}'> <!-- Header --> - <header class="sticky top-0 z-50 bg-black/40 backdrop-blur-lg border-b border-white/10"> + <header class="sticky top-0 z-50 bg-black/40 backdrop-blur-lg border-b border-white/10 no-print"> <div class="flex items-center justify-between px-4 py-3"> <a href="/?tab=shopping" class="text-white/70 hover:text-white p-2 -ml-2"> <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"> @@ -47,7 +84,11 @@ </svg> </a> <h1 class="text-lg font-semibold">{{.StoreName}}</h1> - <div class="w-10"></div> + <button onclick="window.print()" class="text-white/70 hover:text-white p-2 -mr-2"> + <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"> + <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 17h2a2 2 0 002-2v-4a2 2 0 00-2-2H5a2 2 0 00-2 2v4a2 2 0 002 2h2m2 4h6a2 2 0 002-2v-4a2 2 0 00-2-2H9a2 2 0 00-2 2v4a2 2 0 002 2zm8-12V5a2 2 0 00-2-2H9a2 2 0 00-2 2v4h10z"></path> + </svg> + </button> </div> <!-- Store Switcher --> @@ -64,18 +105,22 @@ {{end}} </header> + <!-- Print Header --> + <div class="hidden print:block mb-1"> + <h1 class="text-sm font-semibold text-black">{{.StoreName}}</h1> + </div> + <!-- Items List --> <main class="p-4" id="shopping-items"> {{template "shopping-mode-items" .}} </main> <!-- Quick Add Form (Fixed at Bottom) --> - <div class="fixed bottom-0 left-0 right-0 bg-black/60 backdrop-blur-lg border-t border-white/10 p-4"> - <form hx-post="/shopping/add" + <div class="fixed bottom-0 left-0 right-0 bg-black/60 backdrop-blur-lg border-t border-white/10 p-4 no-print"> + <form id="quick-add-form" hx-post="/shopping/add" hx-target="#shopping-items" hx-swap="innerHTML" - hx-on::after-request="if(event.detail.successful) this.reset();" - class="flex gap-2"> + class="flex gap-2 transition-all"> <input type="hidden" name="store" value="{{.StoreName}}"> <input type="hidden" name="mode" value="shopping-mode"> <input type="text" name="name" placeholder="Add item..." @@ -88,6 +133,17 @@ </div> <!-- Spacer for fixed bottom form --> - <div class="h-24"></div> + <div class="h-24 no-print"></div> + + <script> + document.body.addEventListener('htmx:afterRequest', function(evt) { + if (evt.detail.elt.id === 'quick-add-form' && evt.detail.successful) { + evt.detail.elt.reset(); + evt.detail.elt.querySelector('input[name=name]').focus(); + evt.detail.elt.classList.add('flash-success'); + setTimeout(function() { evt.detail.elt.classList.remove('flash-success'); }, 300); + } + }); + </script> </body> </html> |
