From 657de9e61a95a6bb5e667f2c6e28df0694a58285 Mon Sep 17 00:00:00 2001 From: Steve Dogiakos Date: Tue, 28 Apr 2026 08:32:07 -0600 Subject: [PATCH] fix(ui): resolve deposit panel scroll and PDF open on iOS - Switch #deposit-panel to 100dvh so iOS browser chrome doesn't clip the Save button - Move overflow-y:auto to #deposit-panel-body so the actions footer stays pinned - Replace window.open(blob:) with click to fix PDF opening in Firefox iOS (Firefox iOS blocks blob: URL navigation in new tabs) Closes #7, closes #9 --- public/css/style.css | 6 ++++-- public/js/app.js | 16 ++++++++++++++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/public/css/style.css b/public/css/style.css index fdfaf4e..df91266 100644 --- a/public/css/style.css +++ b/public/css/style.css @@ -679,7 +679,7 @@ input[type="file"] { right: 0; width: 560px; max-width: 98vw; - height: 100vh; + height: 100dvh; background: var(--surface); z-index: 101; box-shadow: -4px 0 24px rgba(0,0,0,0.15); @@ -687,7 +687,7 @@ input[type="file"] { transition: transform 0.2s ease; display: flex; flex-direction: column; - overflow-y: auto; + overflow: hidden; } #deposit-panel.open { transform: translateX(0); } @@ -697,6 +697,8 @@ input[type="file"] { flex-direction: column; gap: 14px; flex: 1; + overflow-y: auto; + min-height: 0; } .dep-summary { diff --git a/public/js/app.js b/public/js/app.js index 39128bb..510008a 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -780,6 +780,18 @@ async function deleteCheck(id) { } } +// Firefox on iOS blocks window.open(blob:) in a new tab; use a temporary instead. +function openPdfBlob(blob, filename) { + const url = URL.createObjectURL(blob); + const a = document.createElement('a'); + a.href = url; + a.download = filename; + document.body.appendChild(a); + a.click(); + document.body.removeChild(a); + setTimeout(() => URL.revokeObjectURL(url), 10000); +} + async function generatePdf() { const ids = [...state.selected]; if (ids.length === 0) return; @@ -801,7 +813,7 @@ async function generatePdf() { throw new Error(err.error || res.statusText); } const blob = await res.blob(); - window.open(URL.createObjectURL(blob), '_blank'); + openPdfBlob(blob, 'checks.pdf'); await loadChecks(); // refresh to show printed status } catch (err) { countSpan.textContent = savedCount; @@ -1595,7 +1607,7 @@ async function generateDepositPdf(type) { throw new Error(err.error || res.statusText); } const blob = await res.blob(); - window.open(URL.createObjectURL(blob), '_blank'); + openPdfBlob(blob, type === 'slip' ? 'deposit-slip.pdf' : 'deposit-report.pdf'); if (type === 'slip') await loadDeposits(); } catch (err) { alert('PDF error: ' + err.message);