Files
dtf-system/web/site-cart.js
Cauê Faleiros 20982a945f
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 2m50s
Build and deploy / Secret scan and release gate (push) Successful in 6s
Build and deploy / Publish images (push) Successful in 1m18s
feat: icons in the header and on the Montagem controls
The header's search, account and cart get icons, with the item count on the
cart instead of "Carrinho (N)"; on phones only the icons show. The upload
zone, remove, rotate and mirror buttons used Unicode symbols that look
different, or are missing, depending on the system's fonts; they are now
Lucide icons (ISC licence) drawn inline, so nothing new is loaded and the
CSP is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 12:56:01 -03:00

144 lines
7.1 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* Site DTF — Cart totals and the order summary.
Extracted verbatim from the single inline script in web/index.html.
Loaded as classic scripts in the order listed there: they share one global
scope and run top to bottom, exactly as the original did. */
// ── carrinho
let itemAtual=null;
function invalidaItemAtual(){
if(!itemAtual) return;
itemAtual=null;
$('atual').style.display='none';
$('carrLin').innerHTML='';
pintaPedido();
}
function itemPodeEnviar(item){
return item.qualityStatus==='ok' || item.qualityStatus==='unverified' ||
(item.qualityStatus==='warning' && item.qualityAcknowledged===true);
}
function cartPodeEnviar(){
const items=[...pedido,...(itemAtual?[itemAtual]:[])];
return items.length>0 && items.every(itemPodeEnviar);
}
function limpaPaineis(){
invalidaItemAtual();
['qual','prev'].forEach(id=>$(id).classList.remove('on'));
if(!pedido.length){ $('carr').classList.remove('on'); }
}
// O carrinho junta itens de produtos diferentes e cobra uma vez só.
function pintaPedido(){
$('itens').innerHTML = pedido.map((it,i)=>
'<div class="item"><div class="nm2"><b>'+escapeHTML(it.tit)+'</b><span>'+escapeHTML(it.desc)+'</span></div>'+
'<div class="vl2">'+rs(it.total)+'</div>'+
'<button type="button" class="x" data-rmi="'+i+'" aria-label="Remover '+escapeHTML(it.tit)+'">Remover</button></div>').join('');
$('itens').querySelectorAll('[data-rmi]').forEach(b=>b.addEventListener('click',()=>{
const i=+b.dataset.rmi, [item]=pedido.splice(i,1);
pintaPedido();
avisaDesfazer(item.tit+' saiu do carrinho.',()=>{
pedido.splice(Math.min(i,pedido.length),0,item); pintaPedido();
});
}));
$('bEsvaziar').hidden = pedido.length+(itemAtual?1:0) < 2;
const itens = pedido.reduce((t,it)=>t+it.total,0) + (itemAtual? itemAtual.total : 0);
const frete = entrega.tipo==='frete' && entrega.cotado ? entrega.valor : 0;
const soma = itens + frete;
const n = pedido.length + (itemAtual?1:0);
const eco = [...pedido, ...(itemAtual?[itemAtual]:[])]
.reduce((t,it)=>t+(TABELA[it.modo]-it.unit)*it.cob, 0);
$('resLin').innerHTML =
'<div class="l"><span>'+n+(n===1?' item':' itens')+'</span><b>'+rs(itens+eco)+'</b></div>'+
(eco>0.01? '<div class="l" style="color:var(--verde-ml)"><span>Desconto pela nota</span>'+
'<b style="color:var(--verde-ml)">− '+rs(eco)+'</b></div>' : '')+
'<div class="l"><span>Frete'+(entrega.tipo==='frete' && entrega.cotado && entrega.dias
? ' · até '+entrega.dias+' dias úteis' : '')+'</span><b>'+
(entrega.tipo==='retira' ? '<span style="color:var(--verde-ml)">Grátis</span>'
: entrega.cotado ? rs(frete) : 'a cotar')+'</b></div>'+
'<div class="l"><span>Revisão e reencaixe</span>'+
'<b><span style="color:var(--verde-ml)">Grátis</span></b></div>';
$('carrTot').textContent=rs(soma);
$('bPagar').textContent = (pedido.length + (itemAtual?1:0))>1
? 'Pagar os '+(pedido.length+(itemAtual?1:0))+' itens de uma vez'
: 'Ir para o pagamento';
$('bPagar').disabled = !cartPodeEnviar() || !entrega.cotado || !clienteOk() || !enderecoOk();
if(pedido.length || itemAtual) $('carr').classList.add('on');
if($('cartN')){ $('cartN').textContent=n>99?'99+':n; $('cartN').hidden=!n;
$('cartLink').setAttribute('aria-label','Carrinho, '+n+(n===1?' item':' itens')); }
window.dispatchEvent(new Event('dtf-cart-changed'));
}
function carrinho(){
const base=precoBase(nota), cob=cobrar(metros);
const unit=base, tot=cob*unit, sobra=+(cob-metros).toFixed(2);
$('carr').classList.add('on');
let l='<div class="l"><span>'+MODOS[modo].tit+'</span><b>'+rs(base)+'/m</b></div>';
{
const teto=TABELA[modo], eco=(teto-base)*cob;
l = '<div class="l"><span>'+MODOS[modo].tit+' · tabela</span><b>'+rs(teto)+'/m</b></div>';
l += eco>0.01
? '<div class="l" style="color:#7FD4A0"><span>Desconto pela nota '+nota+'</span><b>−'+rs(eco)+'</b></div>'
: '<div class="l" style="color:#8D9AB0"><span>Nota '+nota+' · sem desconto</span><b>—</b></div>';
}
if(!ehFolha()) l += '<div class="l" style="color:#8D9AB0"><span>Montagem da folha</span>'+
'<b>inclusa · '+rs(MONTAGEM[modo])+'/m</b></div>';
l += '<div class="l"><span>Metragem'+(sobra>0.001?' · arredondada para 10 cm':'')+
'</span><b>'+fmtM(cob)+' m</b></div>';
l += '<div class="l"><span>Preço final do metro</span><b>'+rs(unit)+'</b></div>'+
'<div class="l" style="color:var(--laranja2)"><span>Revisão e reencaixe</span><b>grátis</b></div>';
$('carrLin').innerHTML=l;
$('atual').style.display='';
const sources=(ehFolha()?folhas:artes).map(x=>ehFolha()
? {kind:'sheet',width_cm:x.med?.larg||larguraFilme(),length_cm:+(x.m*100).toFixed(4),
copies:x.rep||1,rotation_degrees:0,mirrored:false,
measurement:x.med?'file':'customer'}
: {kind:'artwork',width_cm:x.cm,length_cm:+(x.cm*propDe(x)).toFixed(4),
copies:x.q,rotation_degrees:x.giro||0,mirrored:!!x.esp,
measurement:(x.src||x.semPrevia)?'file':'customer'});
let layout;
if(ehFolha()){
let y=0;
const placements=[];
sources.forEach((source,source_index)=>{
for(let copy_index=0;copy_index<source.copies;copy_index++){
placements.push({source_index,copy_index,x_cm:0,y_cm:+y.toFixed(4),
width_cm:source.width_cm,length_cm:source.length_cm,
rotation_degrees:0,mirrored:false});
y+=source.length_cm;
}
});
layout={height_cm:+y.toFixed(4),placements};
}else{
if(!montagemLayout) return;
layout=montagemLayout;
}
itemAtual={modo, tit:MODOS[modo].tit, nota, metros, cob, unit, total:tot,
localFiles:(ehFolha()?folhas:artes).map(x=>x.f),
production:{version:2,film_width_cm:larguraFilme(),sources,...layout},
qualityStatus:$('ciente').classList.contains('recusa')?'rejected':
$('ciente').classList.contains('on')?'warning':nota===0?'unverified':'ok',
qualityAcknowledged:false,
desc:fmtM(cob)+' m · '+rs(unit)+'/m · nota '+nota};
pintaPedido();
previa();
if(nota<90){
const piso=pisoEscada(), ganho=(base-piso)*cob;
if(ganho>0.5) qm('<b>Dá para pagar menos.</b> Com a arte em 300 DPI, '+
'o metro cai para '+rs(piso)+' — são '+rs(ganho)+' a menos neste pedido.','var(--verde)');
}
}
// Removing is one click, and a wrong click is undone from the notice that follows.
let desfazerAcao=null, desfazerTimer=null;
function avisaDesfazer(texto,acao){
desfazerAcao=acao; clearTimeout(desfazerTimer);
$('desfazerTxt').textContent=texto; $('desfazer').hidden=false;
desfazerTimer=setTimeout(fechaDesfazer,8000);
}
function fechaDesfazer(){ clearTimeout(desfazerTimer); desfazerAcao=null; $('desfazer').hidden=true; }
addEventListener('dtf-page-changed',fechaDesfazer);
$('desfazerBtn').addEventListener('click',()=>{ const acao=desfazerAcao; fechaDesfazer(); if(acao) acao(); });
$('bEsvaziar').addEventListener('click',()=>{
const antes=pedido.slice();
pedido=[]; invalidaItemAtual(); pintaPedido();
avisaDesfazer('Carrinho esvaziado.',()=>{ pedido=antes; pintaPedido(); });
});
function qm(t,c){ const m=$('qmsg'); m.style.display='block'; m.style.color=c||'var(--verde)'; m.innerHTML=t; }