feat: Kanban shows each order's artwork, filters quotes and searches orders and quotes
All checks were successful
Build and deploy / Validate source (push) Successful in 1m25s
Build and deploy / Integration suite on a real stack (push) Successful in 3m16s
Build and deploy / Secret scan and release gate (push) Successful in 13s
Build and deploy / Publish images (push) Successful in 1m29s

The customer's browser sends the small picture it already makes of each file
(at most 300 KB, WebP/JPEG/PNG read from the bytes, own uploads only); it goes
when the file's bytes go. Board cards, quote rows, the order panel and the
quote detail show it, with the layout drawing as a second view and as the
fallback for files without a picture.

Cotações gets a customer filter (e-mail, CNPJ, WhatsApp) and product, layout
and resolution-warning chips, with the page bar always shown. The board adds
Entrega, Retirada and stalled-order chips. The top search now covers orders in
any stage and unpaid quotes; CNPJ and phone match by digits only when nothing
but digits and punctuation was typed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Cauê Faleiros
2026-10-01 11:46:33 -03:00
parent b54c635cfc
commit 352590e63a
15 changed files with 547 additions and 52 deletions

View File

@@ -51,8 +51,25 @@ input[type=file]{font-size:14px;color:var(--muted);max-width:100%}
.tabs button{display:flex;align-items:center;gap:8px;padding:0 14px;border:0;border-bottom:2px solid transparent;background:none;color:var(--muted);font-weight:600;font-size:14.5px}
.tabs button[aria-selected=true]{color:var(--tx);font-weight:700;border-bottom-color:var(--accent)}
.tabs .count{font-family:var(--mono);font-size:13.5px;color:var(--muted)}
.search{display:flex;align-items:center;gap:8px;width:300px;height:38px;padding:0 12px;border:1px solid var(--line2);border-radius:9px;background:var(--card);color:var(--faint);margin-left:auto}
.searchbox{position:relative;margin-left:auto}
.search{display:flex;align-items:center;gap:8px;width:380px;height:38px;padding:0 12px;border:1px solid var(--line2);border-radius:9px;background:var(--card);color:var(--faint)}
.search:focus-within{border-color:var(--accent);box-shadow:0 0 0 3px rgba(255,139,43,.18)}
.search input{flex:1;min-width:0;border:0;background:transparent;height:auto;padding:0;outline:none}
.search kbd{font:inherit;font-size:12px;padding:0 6px;border:1px solid var(--line3);border-radius:5px;color:var(--faint)}
.search:focus-within kbd{display:none}
/* The search results: orders and unpaid quotes, grouped. */
.results{position:absolute;top:calc(100% + 8px);right:0;width:580px;max-height:min(70vh,580px);overflow:auto;z-index:8;padding:6px 0;border:1px solid var(--line3);border-radius:12px;background:var(--card);box-shadow:0 18px 48px rgba(0,0,0,.5)}
.rgroup{padding:8px 14px 4px;font-size:12.5px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--faint)}
.rhit{display:flex;align-items:center;gap:12px;width:100%;padding:8px 14px;border:0;background:transparent;text-align:left}
.rhit:hover,.rhit[aria-selected=true]{background:rgba(255,139,43,.08)}
.rtext{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.rtext div{display:flex;gap:8px;align-items:baseline;min-width:0}
.rtext b{font-size:14px;flex-shrink:0}
.rtext div span{font-size:13.5px;color:var(--faint);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.rmeta{font-size:13px;color:var(--muted)}
.rbadge{flex-shrink:0;font-size:12.5px;font-weight:700;padding:2px 9px;border-radius:999px;background:color-mix(in srgb,var(--c,#8B929A) 18%,transparent);color:var(--c,var(--tx2))}
.rempty{margin:0;padding:14px;font-size:14px;color:var(--muted)}
.rhelp{margin-top:6px;padding:8px 14px 4px;border-top:1px solid var(--line);font-size:12.5px;color:var(--faint)}
.tinydot{display:flex;align-items:center;gap:8px;font-size:14px;color:var(--muted);white-space:nowrap}
.tinydot::before{content:"";width:8px;height:8px;border-radius:999px;background:var(--dot,#5B6168)}
.tinydot:empty{display:none}
@@ -137,7 +154,14 @@ main{padding:0 24px 24px}
#tab-quotes{padding-top:18px}
.split{display:flex;gap:0;border:1px solid var(--line);border-radius:12px;overflow:hidden;min-height:calc(100vh - 140px)}
.split .list{width:460px;flex-shrink:0;border-right:1px solid var(--line);padding:16px;display:flex;flex-direction:column;gap:12px;background:#111316}
.qitem{text-align:left;display:flex;justify-content:space-between;gap:12px;padding:14px;border-radius:10px;border:1px solid var(--line2);background:var(--card);width:100%}
.qitem{text-align:left;display:flex;align-items:center;gap:12px;padding:12px;border-radius:10px;border:1px solid var(--line2);background:var(--card);width:100%}
.qitem .qmain{flex:1;min-width:0}
.qitem .qmain>span{display:block}
.qsearch{display:flex;align-items:center;gap:8px;height:38px;padding:0 12px;border:1px solid var(--line2);border-radius:9px;background:var(--card);color:var(--faint)}
.qsearch:focus-within{border-color:var(--accent)}
.qsearch input{flex:1;min-width:0;border:0;background:transparent;height:auto;padding:0;outline:none}
.chips.small{gap:6px}
.chips.small .chip{height:30px;padding:0 10px;font-size:13px}
.qitem[aria-current=true]{border-color:var(--accent);background:#1F1A15}
.qitem b{display:block;font-size:14.5px;overflow-wrap:anywhere}
.qitem span{font-size:13.5px;color:var(--muted)}
@@ -196,7 +220,9 @@ table.log td{padding:10px 12px;border-bottom:1px solid #1E2226;vertical-align:to
@media (max-width:900px){
.top{flex-wrap:wrap;height:auto;padding:10px 16px;gap:10px}
.search{order:5;width:100%;margin-left:0}
.searchbox{order:5;width:100%;margin-left:0}
.search{width:100%}
.results{width:100%}
main{padding:0 16px 16px}
.split{flex-direction:column}
.split .list{width:auto;border-right:0;border-bottom:1px solid var(--line)}
@@ -207,3 +233,28 @@ table.log td{padding:10px 12px;border-bottom:1px solid #1E2226;vertical-align:to
.btn.with-icon{display:inline-flex;align-items:center;gap:6px}
.card .foot .where{display:inline-flex;align-items:center;gap:4px}
a.zap{display:inline-flex;align-items:center;gap:4px;vertical-align:bottom}
/* Artwork pictures, made by the customer's browser. The checkerboard shows
what is transparent; without a picture, the layout drawing stands in. */
.art{position:relative;overflow:hidden;display:flex;align-items:center;justify-content:center;flex-shrink:0;border-radius:8px;border:1px solid var(--line2);
background-color:#2A2F35;background-image:conic-gradient(#323840 25%,transparent 0 50%,#323840 0 75%,transparent 0);background-size:12px 12px}
.art img{display:block;max-width:100%;max-height:100%;object-fit:contain}
.art.layout{background:var(--card2);padding:4px}
.art.layout svg{display:block;height:100%;width:auto;max-width:100%}
.art.none{background:var(--card2)}
.art .noart{font-size:12px;font-weight:700;color:var(--faint)}
.card .card-art{width:100%;height:96px}
.qart{width:56px;height:56px}
.rart{width:44px;height:44px;background-size:8px 8px}
.item .preview.with-art{width:220px;padding:8px;flex-direction:column;align-items:stretch;gap:8px}
.pane .item .preview.with-art{width:320px}
.ptabs{display:flex;gap:4px}
.ptabs button{height:28px;padding:0 10px;border-radius:7px;border:0;background:transparent;color:var(--muted);font-size:12.5px;font-weight:600}
.ptabs button[aria-pressed=true]{background:var(--card);color:var(--tx);font-weight:700}
.preview .view{height:220px;border-radius:8px;display:flex;gap:6px;align-items:center;justify-content:center;overflow:hidden}
.pane .preview .view{height:300px}
.preview .view.art{padding:6px;border:1px solid var(--line2);
background-color:#2A2F35;background-image:conic-gradient(#323840 25%,transparent 0 50%,#323840 0 75%,transparent 0);background-size:14px 14px}
.preview .view.art img{flex:1;min-width:0;max-height:100%;object-fit:contain}
.preview .view.layout{padding:6px;background:var(--bg)}
.item .preview .view.layout svg{height:100%;width:auto;max-width:100%}