2
if(inColor) inColor.value = e.target.value;
if(preview) preview.style.background = e.target.value;
mudarCor(cssVar, e.target.value); salvarLocalStorage();
});
}
montarPaleta('palBg', '--bg-color', 'corBg', 'hexBg');
montarPaleta('palCard', '--bg-card', 'corCard', 'hexCard');
montarPaleta('palPrim', '--primary-color', 'corPrim', 'hexPrim');
montarPaleta('palTexto', '--text-color', 'corTexto', 'hexTexto');
montarPaleta('palBtnTexto', '--btn-text-color', 'corBtnTexto', 'hexBtnTexto');
} else {
atualizarBannerUI();
}
// Lista e paginação (com busca/ordem)
const termo = (document.getElementById('searchInput')?.value || '')
.toLowerCase()
.normalize('NFD')
.replace(/[\u0300-\u036f]/g,'');
let listaFiltrada = produtos.filter(p=>{
const texto = (String(p.nome) + ' ' + String(p.categoria))
.toLowerCase()
.normalize('NFD')
.replace(/[\u0300-\u036f]/g,'');
return texto.includes(termo);
});
const criterio = document.getElementById('sortSelect')?.value || '';
if (criterio === "nome") {
listaFiltrada.sort((a,b)=>a.nome.localeCompare(b.nome));
} else if (criterio === "preco") {
listaFiltrada.sort((a,b)=>parseFloat(a.preco)-parseFloat(b.preco));
} else if (criterio === "categoria") {
listaFiltrada.sort((a,b)=>a.categoria.localeCompare(b.categoria));
}
const totalPaginas = Math.max(1, Math.ceil(listaFiltrada.length/produtosPorPagina));
if (paginaAtual > totalPaginas) paginaAtual = totalPaginas;
if (paginaAtual < 1) paginaAtual = 1;
const start=(paginaAtual-1)*produtosPorPagina;
const end=Math.min(start+produtosPorPagina,listaFiltrada.length);
const produtosPagina = listaFiltrada.slice(start,end);
const container = document.createElement('div');
container.className='produtos';
produtosPagina.forEach((p)=>{
// garante campo estoque
if(typeof p.estoque === 'undefined' || p.estoque === null) p.estoque = 0;
const div=document.createElement('div');
div.className='produto';
div.dataset.id = p.id;
// botão de adicionar fica desativado se estoque for 0
const botaoCompra = (p.estoque > 0)
? ``
: ``;
div.innerHTML=`
`;
if(modoAdmin){ div.classList.add('admin'); }
container.appendChild(div);
if(modoAdmin){
// Edição inline (nome, preço, categoria, imagem)
const img = div.querySelector('img');
const h3 = div.querySelector('h3');
const ps = div.querySelectorAll('p');
const pCat = ps[0];
const pPreco = ps[1];
h3.style.cursor='pointer'; h3.title='(Admin) Clique para editar o nome';
h3.addEventListener('click', ()=>{
const idx = produtos.findIndex(x=>x.id===p.id);
const novo = prompt('Editar nome do produto:', produtos[idx].nome);
if(novo!==null){
produtos[idx].nome = novo.trim() || produtos[idx].nome;
salvarLocalStorage(); renderProdutos();
}
});
pPreco.style.cursor='pointer'; pPreco.title='(Admin) Clique para editar o preço';
pPreco.addEventListener('click', ()=>{
const idx = produtos.findIndex(x=>x.id===p.id);
const atual = produtos[idx].preco;
const val = prompt('Editar preço (use ponto para decimais):', atual);
if(val!==null){
const n = parseFloat(val.replace(',','.'));
if(!isNaN(n)){ produtos[idx].preco = n.toFixed(2); salvarLocalStorage(); renderProdutos(); }
else alert('Preço inválido.');
}
});
pCat.style.cursor='pointer'; pCat.title='(Admin) Clique para editar a classificação';
pCat.addEventListener('click', ()=>{
const idx = produtos.findIndex(x=>x.id===p.id);
const atualIdx = Math.max(0, CLASSIFICACOES.indexOf(produtos[idx].categoria));
const menu = CLASSIFICACOES.map((c,i)=>`${i+1} - ${c}`).join('\n');
const escolha = prompt(`Escolha a classificação:\n${menu}\n\nDigite o número da opção:`, (atualIdx+1).toString());
if(escolha!==null){
const num = parseInt(escolha,10);
if(num>=1 && num<=CLASSIFICACOES.length){
produtos[idx].categoria = CLASSIFICACOES[num-1];
salvarLocalStorage(); renderProdutos();
} else {
alert('Opção inválida.');
}
}
});
img.style.cursor='pointer'; img.title='(Admin) Clique para trocar a imagem';
img.addEventListener('click', ()=>{
const idx = produtos.findIndex(x=>x.id===p.id);
const escolha = confirm("OK = enviar imagem do dispositivo\nCancelar = colar uma URL");
if(escolha){
const input = document.createElement('input');
input.type = 'file';
input.accept = 'image/*';
input.style.display = 'none';
document.body.appendChild(input);
input.addEventListener('change', ()=>{
const file = input.files && input.files[0];
if(file){
const reader = new FileReader();
reader.onload = e=>{
produtos[idx].imagem = e.target.result;
salvarLocalStorage(); renderProdutos();
document.body.removeChild(input);
};
reader.readAsDataURL(file);
} else {
document.body.removeChild(input);
}
}, { once:true });
input.click();
} else {
const url = prompt("Cole a URL da imagem:", produtos[idx].imagem || '');
if(url){
produtos[idx].imagem = url;
salvarLocalStorage(); renderProdutos();
}
}
});
}
});
main.appendChild(container);
const pagDiv = document.createElement('div');
pagDiv.className='pagination';
pagDiv.innerHTML = `
`;
main.appendChild(pagDiv);
if(!modoAdmin){
const footer = document.createElement('div');
footer.className='cliente-footer';
footer.innerHTML = `
`;
main.appendChild(footer);
}
if(modoAdmin){
atualizarBannerUI();
} else {
atualizarBannerUI();
}
}
function colarURLBanner(){
const url = prompt('Cole a URL da imagem do banner:');
if(url){
bannerSrc = url.trim();
const bannerEl = document.getElementById('topBanner');
if(bannerEl) bannerEl.src = bannerSrc;
salvarLocalStorage();
}
}
/* ========================
CARRINHO COM QUANTIDADE + BOTÕES ➕/➖
======================== */
function getProdutoById(id){ return produtos.find(p=>p.id===id); }
function adicionarAoCarrinho(index){
// Mantido para compatibilidade antiga (index numérico, não usado no fluxo novo)
const p = produtos[index];
if(p) adicionarAoCarrinhoPorId(p.id);
}
function adicionarAoCarrinhoPorId(prodId){
const p = getProdutoById(prodId);
if(!p){ alert('Produto não encontrado.'); return; }
if((p.estoque||0) <= 0){ alert('Produto esgotado.'); return; }
const precoNum = parseFloat(p.preco);
let item = carrinho.find(i => i.nome === p.nome);
const currentQty = item ? parseInt(item.quantidade||1,10) : 0;
if(currentQty + 1 > (p.estoque||0)){
alert('Não há estoque suficiente para adicionar mais unidades.');
return;
}
if(item){
item.quantidade = currentQty + 1;
} else {
carrinho.push({ nome: p.nome, preco: isNaN(precoNum) ? 0 : precoNum, quantidade: 1 });
}
atualizarCarrinho(); salvarLocalStorage();
atualizarBadgeCarrinho();
alert(`${p.nome} adicionado ao carrinho`);
}
function atualizarCarrinho(){
const ul=document.getElementById('itensCarrinho'); if(!ul) return;
ul.innerHTML='';
let total=0;
carrinho.forEach((item,i)=>{
const li=document.createElement('li');
const unit = isNaN(parseFloat(item.preco)) ? 0 : parseFloat(item.preco);
const qtd = parseInt(item.quantidade||1,10);
const subtotal = unit * qtd;
// botão ➖, input quantidade e botão ➕
li.innerHTML = `
${item.nome}
x R$ ${unit.toFixed(2)} = R$ ${subtotal.toFixed(2)}
`;
ul.appendChild(li);
total+=subtotal;
});
const totalEl = document.getElementById('totalCarrinho');
if(totalEl) totalEl.textContent=total.toFixed(2);
const chkEl = document.getElementById('checkoutTotal');
if(chkEl) chkEl.textContent = total.toFixed(2);
atualizarBadgeCarrinho();
}
function alterarQuantidade(index, valor){
let qtd = parseInt(valor,10);
if(isNaN(qtd) || qtd < 1) qtd = 1;
if(!carrinho[index]) return;
const item = carrinho[index];
const prod = produtos.find(p=>p.nome === item.nome);
const estoqueDisp = prod ? (prod.estoque||0) : Infinity;
if(qtd > estoqueDisp){
alert('Quantidade maior que o estoque disponível.');
qtd = estoqueDisp;
}
item.quantidade = qtd;
atualizarCarrinho(); salvarLocalStorage();
}
function removerItem(i){
const qtd = parseInt(carrinho[i].quantidade||1,10);
if(qtd > 1){
carrinho[i].quantidade = qtd - 1;
} else {
carrinho.splice(i,1);
}
atualizarCarrinho(); salvarLocalStorage();
}
function calcularTotalCarrinho(){
return carrinho.reduce((soma, item)=>{
const unit = isNaN(parseFloat(item.preco))?0:parseFloat(item.preco);
const qtd = parseInt(item.quantidade||1,10);
return soma + unit*qtd;
}, 0);
}
function desistirCompra(){
if(confirm("Deseja realmente desistir da compra e voltar ao início?")){
carrinho = [];
atualizarCarrinho();
salvarLocalStorage();
paginaAtual = 1;
renderProdutos();
fecharCarrinho();
}
}
/* 🆕 SUBSTITUI: abrirPagamento antigo -> agora abre o modal */
function abrirPagamento(){
if(carrinho.length === 0){
alert("Seu carrinho está vazio!");
return;
}
let total = calcularTotalCarrinho().toFixed(2);
const checkoutTotalEl = document.getElementById('checkoutTotal');
if(checkoutTotalEl) checkoutTotalEl.textContent = total;
const modal = document.getElementById('checkoutModal');
if(modal){ modal.style.display = 'flex'; document.body.style.overflow = 'hidden'; }
}
function closeCheckout(){
const modal = document.getElementById('checkoutModal');
if(modal){ modal.style.display = 'none'; document.body.style.overflow = ''; }
}
function fecharCheckout(event){ if(!event || event.target.id==='checkoutModal'){ closeCheckout(); } }
function gerarComprovante(){
let comprovante = "🧾 Comprovante de Pedido\n\n";
let total=0;
carrinho.forEach(item=>{
const unit = isNaN(parseFloat(item.preco))?0:parseFloat(item.preco);
const qtd = parseInt(item.quantidade||1,10);
const sub = unit*qtd;
comprovante += `${item.nome} (${qtd}x) - R$ ${sub.toFixed(2)}\n`;
total+=sub;
});
comprovante += `\nTotal: R$ ${total.toFixed(2)}\n`;
const pixKey = localStorage.getItem('pixKey');
if(pixKey){
comprovante += `\n💳 Chave Pix para pagamento: ${pixKey}\n`;
} else {
comprovante += `\n⚠️ Nenhuma chave Pix cadastrada.\n`;
}
comprovante += `\nAcompanhe seu pedido: https://www.appcreator24.com/app3699570-ip7ogd`;
alert(comprovante);
try { navigator.clipboard.writeText(comprovante); } catch(e){}
}
function finalizarPedido(){
if(carrinho.length===0){ alert("Carrinho vazio!"); return; }
// valida estoque antes de finalizar
for(const item of carrinho){
const prod = produtos.find(p=>p.nome === item.nome);
const qtd = parseInt(item.quantidade||1,10);
if(prod && (prod.estoque||0) < qtd){
alert(`Estoque insuficiente para: ${prod.nome}. Ajuste a quantidade antes de finalizar.`);
return;
}
}
let texto="🛒 Pedido:\n";
let total=0;
carrinho.forEach(item=>{
const unit = isNaN(parseFloat(item.preco))?0:parseFloat(item.preco);
const qtd = parseInt(item.quantidade||1,10);
const sub = unit*qtd;
texto+=`${item.nome} (${qtd}x) - R$ ${sub.toFixed(2)}\n`;
total+=sub;
// reduz estoque
const idx = produtos.findIndex(p=>p.nome === item.nome);
if(idx>=0){
produtos[idx].estoque = Math.max(0,(produtos[idx].estoque||0) - qtd);
}
});
texto+=`\nTotal: R$ ${total.toFixed(2)}`;
const pixKey = localStorage.getItem('pixKey');
if(pixKey){ texto+=`\n\n💳 Pague via Pix: ${pixKey}`; }
const msg = encodeURIComponent(texto);
window.open(`https://wa.me/?text=${msg}`,"_blank");
gerarComprovante();
carrinho = [];
salvarLocalStorage();
renderProdutos();
fecharCarrinho();
}
/* 🆕 Opções de pagamento no modal */
function finalizarPedidoPix(){
let total = calcularTotalCarrinho().toFixed(2);
const pixKey = localStorage.getItem('pixKey');
if(pixKey){
alert("🔐 Pagamento via Pix\n\nChave Pix: " + pixKey + "\nValor total: R$ " + total);
} else {
alert("⚠️ Nenhuma chave Pix cadastrada!\nCadastre no modo administrador.");
}
closeCheckout();
}
function finalizarPedidoEntrega(){
alert("✅ Pedido confirmado! Pague em Dinheiro ou Cartão na entrega.");
closeCheckout();
}
function finalizarPedidoCartao(){
alert("Você será redirecionado para o pagamento com cartão.");
// 🔗 Substitua pelo seu link real de checkout do Mercado Pago
window.open("https://www.mercadopago.com.br/checkout/v1/redirect?pref_id=SEU_ID_AQUI", "_blank");
closeCheckout();
}
function abrirCarrinho(){ document.getElementById('carrinhoModal').style.display='flex'; atualizarCarrinho(); }
function fecharCarrinho(event){ if(!event || event.target.id==='carrinhoModal'){ document.getElementById('carrinhoModal').style.display='none'; } }
/* 🔇 alternarTema removido */
function mudarCor(varName,value){
try {
document.documentElement.style.setProperty(varName,value);
document.body.style.setProperty(varName,value);
} catch(e){}
}
/* ✅ alternarModo agora também controla a classe .admin-mode no */
function alternarModo() {
const modoTop = document.getElementById('modoBtn');
const modoFoot = document.getElementById('modoBtnFooter');
if (!modoAdmin) {
const senha = prompt("Digite a senha para entrar no modo administrador:");
if (senha === "2010") {
modoAdmin = true;
if(modoTop) modoTop.textContent = 'Versão Cliente';
if(modoFoot) modoFoot.textContent = 'Versão Cliente';
document.body.classList.add('admin-mode'); // <<<<<< ADICIONA CLASSE
atualizarBannerUI();
renderProdutos();
} else {
alert("Senha incorreta!");
}
} else {
modoAdmin = false;
if(modoTop) modoTop.textContent = 'Versão Administrador';
if(modoFoot) modoFoot.textContent = 'Versão Administrador';
document.body.classList.remove('admin-mode'); // <<<<<< REMOVE CLASSE
atualizarBannerUI();
renderProdutos();
}
}
function enviarLink(){
const linkCliente = "https://www.appcreator24.com/app3699570-ip7ogd";
try { navigator.clipboard.writeText(linkCliente); } catch(e){}
alert('Link do modo cliente copiado!');
}
function enviarWhatsappEmail(){
const linkCliente = "https://www.appcreator24.com/app3699570-ip7ogd";
const texto = encodeURIComponent(`Confira nosso app de mercado: ${linkCliente}`);
window.open(`https://wa.me/?text=${texto}`, '_blank');
}
/* atualiza o texto dos botões de carrinho no footer (e no topo se existir) */
function atualizarBadgeCarrinho(){
const btnTop = document.getElementById("btnCarrinho");
const btnFoot = document.getElementById("btnCarrinhoFooter");
const qtd = carrinho.reduce((soma, i)=> soma + parseInt(i.quantidade||1,10), 0);
const text = qtd > 0 ? `Carrinho 🛒 (${qtd})` : "Carrinho 🛒";
if(btnTop) btnTop.textContent = text;
if(btnFoot) btnFoot.textContent = text;
}
function salvarPix(){
const pixKeyInput = document.getElementById('pixKey');
if(!pixKeyInput) return;
const pixKey = pixKeyInput.value.trim();
if(pixKey === ""){
alert("Digite uma chave Pix válida!");
return;
}
localStorage.setItem('pixKey', pixKey);
alert("✅ Chave Pix salva com sucesso!");
}
// 🔎 eventos de busca e ordenação
const searchEl = document.getElementById('searchInput');
if (searchEl) {
searchEl.addEventListener('input', ()=>{
paginaAtual = 1;
renderProdutos();
});
}
const sortEl = document.getElementById('sortSelect');
if (sortEl) {
sortEl.addEventListener('change', ()=>{
paginaAtual = 1;
renderProdutos();
});
}
/* 🎯 ZOOM — lógica (funciona só no modo cliente) */
const imgZoom = document.getElementById('imgZoom');
const imgZoomSrc = document.getElementById('imgZoomSrc');
const imgZoomClose = document.getElementById('imgZoomClose');
function abrirZoomImagem(src){
if(!imgZoom || !imgZoomSrc) return;
imgZoomSrc.src = src;
imgZoom.style.display = 'flex';
document.body.style.overflow = 'hidden'; /* evita rolar por trás */
}
function fecharZoomImagem(){
if(!imgZoom) return;
imgZoom.style.display = 'none';
if(imgZoomSrc) imgZoomSrc.src = '';
document.body.style.overflow = '';
}
/* Fecha clicando fora da imagem */
if(imgZoom){
imgZoom.addEventListener('click', (e)=>{
if(e.target === imgZoom) fecharZoomImagem();
});
}
/* Fecha no botão X */
if(imgZoomClose) imgZoomClose.addEventListener('click', fecharZoomImagem);
/* Fecha com ESC */
document.addEventListener('keydown', (e)=>{
if(e.key === 'Escape'){
if(imgZoom && imgZoom.style.display === 'flex'){ fecharZoomImagem(); }
const cm = document.getElementById('checkoutModal');
if(cm && cm.style.display === 'flex'){ closeCheckout(); }
}
});
/* Delegação de evento: captura cliques nas imagens dos produtos renderizadas dinamicamente */
document.addEventListener('click', (e)=>{
if(!modoAdmin && e.target && e.target.matches('.produto img')){
abrirZoomImagem(e.target.src);
}
});
/* 🆕 EDITAR ESTOQUE (ADMIN) */
function editarEstoque(prodId){
const idx = produtos.findIndex(p=>p.id===prodId);
if(idx<0) return;
const atual = produtos[idx].estoque || 0;
const novo = prompt("Digite o novo estoque:", atual);
if(novo!==null){
const n = parseInt(novo,10);
if(!isNaN(n) && n>=0){ produtos[idx].estoque = n; salvarLocalStorage(); renderProdutos(); }
}
}
/* Boot */
carregarLocalStorage();
renderProdutos();
atualizarBadgeCarrinho();
${p.nome}
${p.categoria}
R$ ${p.preco}
Estoque: ${p.estoque}
${botaoCompra}