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 2m23s
Build and deploy / Secret scan and release gate (push) Successful in 6s
Build and deploy / Publish images (push) Successful in 1m48s
New landing (hero with a sheet preview, four steps, product cards priced from the checkout table, price table and benefits), a progress bar that follows the order through Montagem, Dados e entrega and Pagamento, the live sheet beside the artworks, and a running total bar on phones. The cart's saved-in-browser note no longer takes a grid column, which had pushed the order into a narrow strip and the summary below it. The previous look is kept in tag ui-v1. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
73 lines
3.6 KiB
JavaScript
73 lines
3.6 KiB
JavaScript
/* Site DTF — the order progress bar, the product card prices and the phone
|
|
total bar. This file only reads the page's state (which panels are open,
|
|
the cart total, the checkout status); it never changes an order, a price or
|
|
a file, so the flow in the other site-*.js files behaves exactly as before. */
|
|
(function(){
|
|
// Card prices come from the same table the checkout uses, so they cannot drift.
|
|
document.querySelectorAll('[data-de]').forEach(el=>{ el.textContent=rs(pisoEscada(el.dataset.de)); });
|
|
document.querySelectorAll('[data-ate]').forEach(el=>{ el.textContent=rs(TABELA[el.dataset.ate]); });
|
|
|
|
const passos=$('passos'), barra=$('barraM');
|
|
// The store header is sticky; the progress bar and the side panels sit below it.
|
|
function alturas(){
|
|
const topo=document.querySelector('.topo')?.offsetHeight||0;
|
|
document.documentElement.style.setProperty('--topo',topo+'px');
|
|
document.documentElement.style.setProperty('--topo-passos',(topo+(passos.hidden?0:passos.offsetHeight)+16)+'px');
|
|
}
|
|
const foco=$('foco'), carr=$('carr'), status=$('checkoutStatus'), acoes=$('checkoutActions');
|
|
|
|
function naTela(el){
|
|
const r=el.getBoundingClientRect();
|
|
return r.top < innerHeight*0.55 && r.bottom > innerHeight*0.2;
|
|
}
|
|
function etapa(){
|
|
// Once the cart is sent, the quote, the payment and the order live in the
|
|
// checkout status: that is the payment step.
|
|
if((status.textContent||'').trim() || acoes.children.length) return 3;
|
|
if(carr.classList.contains('on') && (naTela(carr) || !foco.classList.contains('on'))) return 2;
|
|
return 1;
|
|
}
|
|
let pendente=false;
|
|
function pinta(){
|
|
pendente=false;
|
|
const ativo=foco.classList.contains('on') || carr.classList.contains('on') || (status.textContent||'').trim();
|
|
passos.hidden=!ativo; alturas();
|
|
if(ativo){
|
|
const atual=etapa();
|
|
passos.querySelectorAll('[data-passo]').forEach(a=>{
|
|
const n=Number(a.dataset.passo);
|
|
a.classList.toggle('atual',n===atual); a.classList.toggle('feito',n<atual);
|
|
if(n===atual) a.setAttribute('aria-current','step'); else a.removeAttribute('aria-current');
|
|
});
|
|
}
|
|
// Phone bar: the running total while the cart itself is off screen.
|
|
const temPedido=carr.classList.contains('on');
|
|
const mostrar=temPedido && !naTela(carr) && !(status.textContent||'').trim();
|
|
barra.hidden=!mostrar;
|
|
if(mostrar){
|
|
$('barraMTot').textContent=$('carrTot').textContent;
|
|
$('barraMSub').textContent=foco.classList.contains('on')?'Total até agora':'Seu pedido';
|
|
}
|
|
}
|
|
function agenda(){ if(!pendente){ pendente=true; requestAnimationFrame(pinta); } }
|
|
|
|
const obs=new MutationObserver(agenda);
|
|
obs.observe(foco,{attributes:true,attributeFilter:['class']});
|
|
obs.observe(carr,{attributes:true,attributeFilter:['class']});
|
|
obs.observe(status,{childList:true,characterData:true,subtree:true});
|
|
obs.observe(acoes,{childList:true});
|
|
obs.observe($('carrTot'),{childList:true,characterData:true,subtree:true});
|
|
addEventListener('scroll',agenda,{passive:true});
|
|
addEventListener('resize',agenda);
|
|
addEventListener('dtf-cart-changed',agenda);
|
|
|
|
// Steps are links; step 3 only makes sense once there is something to pay.
|
|
passos.querySelectorAll('a').forEach(a=>a.addEventListener('click',e=>{
|
|
const destino=document.querySelector(a.getAttribute('href'));
|
|
if(!destino || destino.offsetParent===null){ e.preventDefault(); return; }
|
|
e.preventDefault(); destino.scrollIntoView({behavior:'smooth',block:'start'});
|
|
}));
|
|
$('barraMBtn').addEventListener('click',e=>{ e.preventDefault(); carr.scrollIntoView({behavior:'smooth',block:'start'}); });
|
|
pinta();
|
|
})();
|