feat: icons on the buttons, delivery, payment, status and Kanban
All checks were successful
Build and deploy / Validate source (push) Successful in 5s
Build and deploy / Integration suite on a real stack (push) Successful in 2m40s
Build and deploy / Secret scan and release gate (push) Successful in 5s
Build and deploy / Publish images (push) Successful in 53s
All checks were successful
Build and deploy / Validate source (push) Successful in 5s
Build and deploy / Integration suite on a real stack (push) Successful in 2m40s
Build and deploy / Secret scan and release gate (push) Successful in 5s
Build and deploy / Publish images (push) Successful in 53s
- Buttons: add to cart (bag with plus), go to payment (lock), remove from the cart (bin). - Delivery: a pin for pickup in Franca, a truck for home delivery. - Payment: card and QR code on the methods, copy on the PIX code, a clock on its countdown, a check on the confirmation. - Status: a check when the files are sent, check, alert, redo and cross in the quality list instead of Unicode symbols, and a check on finished steps. - Kanban: a truck or pin for where an order goes, a speech bubble on the WhatsApp link, a download arrow on the file buttons. All Lucide shapes drawn inline, as in the header. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -54,7 +54,7 @@ function contato(customer){
|
||||
const d=String(customer.zap).replace(/\D/g,'').replace(/^55(?=\d{10,11}$)/,'');
|
||||
const shown=d.length===11?'('+d.slice(0,2)+') '+d.slice(2,7)+'-'+d.slice(7):d.length===10?'('+d.slice(0,2)+') '+d.slice(2,6)+'-'+d.slice(6):customer.zap;
|
||||
const a=node('a',shown,'zap');a.href=href;a.target='_blank';a.rel='noopener noreferrer';
|
||||
a.title='Abrir conversa no WhatsApp';
|
||||
a.title='Abrir conversa no WhatsApp';a.prepend(icon(ICON_CHAT));
|
||||
line.append(a);return line;
|
||||
}
|
||||
function node(tag,text,className){const e=document.createElement(tag);if(text!==undefined&&text!==null)e.textContent=text;if(className)e.className=className;return e;}
|
||||
@@ -80,6 +80,14 @@ function icon(path){
|
||||
return svg;
|
||||
}
|
||||
const ICON_OK=['M5 12l4 4 10-10'], ICON_WARN=['M12 8v5M12 17h.01','circle 12 12 9'];
|
||||
// Lucide shapes (ISC licence), in the same stroke as the two above.
|
||||
const ICON_TRUCK=['M14 18V6a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v11a1 1 0 0 0 1 1h2','M15 18H9',
|
||||
'M19 18h2a1 1 0 0 0 1-1v-3.65a1 1 0 0 0-.22-.62l-3.48-4.35A1 1 0 0 0 17.52 8H14','circle 17 18 2','circle 7 18 2'];
|
||||
const ICON_PIN=['M20 10c0 4.99-5.54 10.19-7.4 11.8a1 1 0 0 1-1.2 0C9.54 20.19 4 14.99 4 10a8 8 0 0 1 16 0','circle 12 10 3'];
|
||||
const ICON_DOWNLOAD=['M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4','m7 10 5 5 5-5','M12 15V3'];
|
||||
const ICON_CHAT=['M7.9 20A9 9 0 1 0 4 16.1L2 22Z'];
|
||||
// A download button: the arrow, then its label.
|
||||
function downloadButton(text,fn,className){const b=button(text,fn,className);b.prepend(icon(ICON_DOWNLOAD));b.classList.add('with-icon');return b;}
|
||||
async function api(path,body){
|
||||
const r=await fetch('/api/operator'+path,{headers:{'Content-Type':'application/json'},...(body===undefined?{}:{method:'POST',body:JSON.stringify(body)})});
|
||||
const d=await r.json();if(!r.ok){const error=new Error(typeof d.detail==='string'?d.detail:'Confira os campos ('+r.status+').');error.status=r.status;throw error;}return d;
|
||||
@@ -200,7 +208,8 @@ function card(order){
|
||||
const status=node('span',p.text,p.tone);status.style.display='flex';status.style.alignItems='center';status.style.gap='5px';
|
||||
if(p.tone==='ok')status.prepend(icon(ICON_OK));if(p.tone==='warn')status.prepend(icon(ICON_WARN));
|
||||
const dest=order.snapshot.destination;
|
||||
foot.append(status,node('span',dest?'Entrega · '+dest.state:'Retirada','where'));
|
||||
const where=node('span',dest?'Entrega · '+dest.state:'Retirada','where');where.prepend(icon(dest?ICON_TRUCK:ICON_PIN));
|
||||
foot.append(status,where);
|
||||
c.append(top,node('div',order.snapshot.customer.mail,'cust'),tags,foot);
|
||||
if(['rec','tra','fil','imp'].includes(order.state)&&Date.now()-new Date(order.updated_at)>LATE_HOURS*3600000)
|
||||
c.append(node('div','Parado há mais de '+LATE_HOURS+' h','late'));
|
||||
@@ -336,8 +345,8 @@ function itemCard(order,item,index){
|
||||
else body.append(file);
|
||||
}else body.append(node('div','Arquivo de impressão ainda não gerado','line'));
|
||||
const buttons=node('div',undefined,'buttons');
|
||||
if(row?.status==='ready'&&row.detail?.source!=='original')buttons.append(button('Baixar PDF',download(row.upload_id)));
|
||||
item.uploads.forEach((uid,i)=>buttons.append(button(item.uploads.length>1?'Original '+(i+1):'Baixar original',download(uid),'btn ghost')));
|
||||
if(row?.status==='ready'&&row.detail?.source!=='original')buttons.append(downloadButton('Baixar PDF',download(row.upload_id)));
|
||||
item.uploads.forEach((uid,i)=>buttons.append(downloadButton(item.uploads.length>1?'Original '+(i+1):'Baixar original',download(uid),'btn ghost')));
|
||||
if(spec?.placements)buttons.append(button('Manifesto',()=>manifest(spec),'btn ghost'));
|
||||
if(['rec','tra'].includes(order.state)&&(!row||row.status==='manual'||row.status==='failed'))
|
||||
buttons.append(button('Gerar novamente',async()=>{await api('/orders/'+order.id+'/print-files',{});await load();},'btn ghost'));
|
||||
@@ -350,7 +359,7 @@ function finalsSection(order,revisions,section){
|
||||
const rev=node('div',undefined,'rev');
|
||||
rev.append(node('b',(file.kind==='final'?'Final':'Correção do cliente')+' · item '+(file.item_index+1)+' · '+file.name),
|
||||
node('span',(file.expired?'expirado':file.active?'atual':'substituído')+' · '+when(file.created_at)+' · '+file.note,'faint'));
|
||||
if(!file.expired){const b=button('Baixar',download(file.upload_id),'btn ghost');b.style.alignSelf='flex-start';rev.append(b);}
|
||||
if(!file.expired){const b=downloadButton('Baixar',download(file.upload_id),'btn ghost');b.style.alignSelf='flex-start';rev.append(b);}
|
||||
section.append(rev);
|
||||
}
|
||||
if(!['rec','tra','cor'].includes(order.state)){if(!revisions.length)section.append(node('p','Nenhum arquivo final registrado.','faint'));return;}
|
||||
@@ -504,7 +513,7 @@ function quoteItem(item,fields){
|
||||
grid.append(asked,m,g);body.append(grid);
|
||||
}
|
||||
const buttons=node('div',undefined,'buttons');
|
||||
item.uploads.forEach((uid,i)=>buttons.append(button(item.uploads.length>1?'Original '+(i+1):'Baixar original',download(uid),'btn ghost')));
|
||||
item.uploads.forEach((uid,i)=>buttons.append(downloadButton(item.uploads.length>1?'Original '+(i+1):'Baixar original',download(uid),'btn ghost')));
|
||||
if(item.production?.placements)buttons.append(button('Manifesto',()=>manifest(item.production),'btn ghost'));
|
||||
body.append(buttons);box.append(preview,body);return box;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user