From 756107c174e8f89777b601ab106377db2b923786 Mon Sep 17 00:00:00 2001 From: NguyenND Date: Mon, 4 May 2026 15:35:41 -0400 Subject: [PATCH] 05/04 Update form creation page --- app/templates/inspections/execute.html | 112 ++++++++++++++++++++----- 1 file changed, 90 insertions(+), 22 deletions(-) diff --git a/app/templates/inspections/execute.html b/app/templates/inspections/execute.html index d2db6bc..93349db 100644 --- a/app/templates/inspections/execute.html +++ b/app/templates/inspections/execute.html @@ -36,28 +36,45 @@ width: max-content; } - /* ── iPad / touch-device fluid grid override ── */ + /* ── iPad / touch-device fluid grid override ── + --fg-w is set by ResizeObserver in JS (see bottom of file), + which measures the actual .insp-body clientWidth — no vw/scrollbar ambiguity. + Falls back to a safe 100% - padding calculation if JS hasn't run yet. */ @media (max-width: 1194px) { .form-grid { - /* Tighter column gap (4px) so empty intermediate columns between fields - don't create a large visual gap — e.g. between rating stars and upload */ - --_gap: 4px; - --_cell: calc((min(calc(100vw - 2rem), 900px) - 11 * 4px) / 12); - grid-template-columns: repeat(12, var(--_cell)); - grid-auto-rows: minmax(calc(var(--_cell) * 0.72), auto); - gap: 4px var(--_gap); + --fg-gap: 4px; + --fg-w: calc(100% - 2rem); /* JS overrides this with measured px value */ + --fg-cell: calc((var(--fg-w) - 11 * var(--fg-gap)) / 12); + grid-template-columns: repeat(12, var(--fg-cell)); + grid-auto-rows: minmax(calc(var(--fg-cell) * 0.72), auto); + gap: var(--fg-gap); width: 100%; } .insp-body { padding: 1rem; } /* Rating stars: scale down to fit compressed grid cells on iPad */ - .rating-stars button { font-size: .85rem; } + .rating-stars button { font-size: .9rem; min-height: 36px; min-width: 28px; } + + /* Pass/fail pills: allow wrapping on narrow cells */ + .pf-group { flex-wrap: wrap !important; gap: .4rem !important; } + .pf-btn { flex-shrink: 0; } /* Image upload cells: don't clip the chosen-file row */ .upload-zone { overflow: visible; } + + /* Touch: larger tap targets for checkboxes and radios */ + .form-check-input { width: 1.1em; height: 1.1em; margin-top: .15rem; } } .fg-cell { - overflow:hidden; display:flex; flex-direction:column; padding:.18rem .45rem; + /* overflow:visible so content (dropdowns, tall labels) is never silently clipped. + align-content:start keeps items pinned to the top of the cell. */ + overflow: visible; + display: flex; + flex-direction: column; + align-content: start; + padding: .18rem .45rem; + /* Min height ensures touch targets are reachable even on very short row spans */ + min-height: 36px; } .fg-cell .field-lbl { font-size:.74rem; font-weight:500; color:#64748b; @@ -119,7 +136,27 @@ } .upload-clear:hover { background:#fecaca; } - .signature-pad-wrap { + /* ── Pass / Fail pills ── */ + .pf-group { display:flex; gap:.5rem; flex-wrap:wrap; } + .pf-btn { + display: flex; align-items: center; gap: .35rem; + cursor: pointer; + padding: .4rem .85rem; border-radius: 20px; + font-size: .84rem; font-weight: 600; + border: 2px solid transparent; + transition: background .15s, color .15s, border-color .15s; + user-select: none; + min-height: 36px; /* 44px touch target via padding — no layout shift */ + } + .pf-btn input[type=radio] { display: none; } + /* Pass variants */ + .pf-btn.pf-pass { border-color: #16a34a; color: #16a34a; background: transparent; } + .pf-btn.pf-pass.pf-on, + .pf-btn.pf-pass:has(input:checked) { background: #16a34a; color: #fff; } + /* Fail variants */ + .pf-btn.pf-fail { border-color: #dc2626; color: #dc2626; background: transparent; } + .pf-btn.pf-fail.pf-on, + .pf-btn.pf-fail:has(input:checked) { background: #dc2626; color: #fff; } flex:1; min-height:0; border-radius:6px; border:1px solid #e2e8f0; background:#f8fafc; position:relative; overflow:hidden; } @@ -334,20 +371,14 @@ {% elif field.type == 'pass_fail' %} {% set pf_options = field.options if field.options else ['Pass', 'Fail'] %} -
+
{% for opt in pf_options %} - {% set is_pass = opt.lower() in ('pass','yes','ok','good') %} -