arrow_back

Marketplace

Utilidades verified Verificada 🟢 Aberto Agora

LVP Embalagens

Avaliação
star 5.0
(100 avaliações)
Satisfação 100% Satisfação Média geral
two_wheeler
🛵 Entrega / Delivery Ativo

⏱️ 30-50 minTaxa padrão: R$ 5,00

Produtos de Piscina

Produtos de Piscina

Coleção oficial

Sob consulta
Garrafões Térmicos

Garrafões Térmicos

Coleção oficial

Sob consulta
Caixas Térmicas

Caixas Térmicas

Coleção oficial

Sob consulta
Produtos de Pesca

Produtos de Pesca

Coleção oficial

Sob consulta
Produtos de Pesca

Produtos de Pesca

Coleção oficial

Sob consulta
async function aplicarCupomDesconto() { const input = document.getElementById('input-cupom-codigo'); const msg = document.getElementById('cupom-status-msg'); if (!input || !msg) return; const codigo = input.value.trim(); if (!codigo) return; const formData = new FormData(); formData.append('loja_id', '9'); formData.append('codigo', codigo); try { const resp = await fetch('loja.php?action=validate_coupon', { method: 'POST', body: formData }); const data = await resp.json(); if (data.success) { appliedCoupon = data.coupon; msg.className = "text-[11px] font-bold mt-1 text-emerald-600 block"; msg.textContent = `✅ Cupom ${data.coupon.codigo} aplicado com sucesso!`; } else { appliedCoupon = null; msg.className = "text-[11px] font-bold mt-1 text-red-500 block"; msg.textContent = `❌ ${data.message}`; } } catch (e) { msg.className = "text-[11px] font-bold mt-1 text-red-500 block"; msg.textContent = '❌ Erro ao validar cupom.'; } } // Advanced Booking Module JS Helpers let professionalsLoaded = false; function renderizarDatePills(dataSelecionada) { const container = document.getElementById('booking-date-pills'); if (!container) return; const diasSemana = ['Dom', 'Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sáb']; const hoje = new Date(); let html = ''; for (let i = 0; i < 12; i++) { const d = new Date(hoje); d.setDate(hoje.getDate() + i); const yyyy = d.getFullYear(); const mm = String(d.getMonth() + 1).padStart(2, '0'); const dd = String(d.getDate()).padStart(2, '0'); const dateStr = `${yyyy}-${mm}-${dd}`; let labelDia = diasSemana[d.getDay()]; let labelNum = `${dd}/${mm}`; if (i === 0) labelDia = 'Hoje'; if (i === 1) labelDia = 'Amanhã'; const isSelected = (dateStr === dataSelecionada); const activeClasses = isSelected ? 'bg-purple-800 text-white border-purple-800 shadow-sm' : 'bg-slate-100 text-slate-700 border-slate-200 hover:bg-slate-200'; html += ` `; } container.innerHTML = html; } function aoSelecionarPillData(dateStr) { const dateInput = document.getElementById('booking-date'); if (dateInput) { dateInput.value = dateStr; renderizarDatePills(dateStr); carregarHorariosDisponiveis(); } } function aoMudarDataManual(dateStr) { renderizarDatePills(dateStr); carregarHorariosDisponiveis(); } async function carregarProfissionais() { const wrapper = document.getElementById('booking-prof-wrapper'); const select = document.getElementById('booking-professional'); if (!wrapper || !select || professionalsLoaded) return; try { const resp = await fetch('loja.php?action=fetch_professionals&loja_id=9'); const data = await resp.json(); if (data.success && data.professionals && data.professionals.length > 0) { let options = ''; data.professionals.forEach(p => { options += ``; }); select.innerHTML = options; wrapper.classList.remove('hidden'); professionalsLoaded = true; } else { wrapper.classList.add('hidden'); } } catch (e) {} } const isAgendamentoPermitido = false; function abrirModalAgendamento(servicoId, servicoNome, precoFormatted, duracaoMinutos) { if (!isAgendamentoPermitido) { if (window.showToast) window.showToast('Agendamentos indisponíveis nesta loja.', 'warning'); return; } document.getElementById('booking-service-id').value = servicoId || ''; document.getElementById('booking-service-title').textContent = servicoNome || 'Serviço'; document.getElementById('booking-service-price').value = precoFormatted || '0.00'; document.getElementById('booking-total-display').textContent = precoFormatted ? (typeof precoFormatted === 'number' ? 'R$ ' + precoFormatted.toFixed(2).replace('.', ',') : precoFormatted) : 'R$ 0,00'; const durBadge = document.getElementById('booking-service-duration'); if (durBadge) { const dur = duracaoMinutos || (activeProductData ? activeProductData.duracao_minutos : 30); if (dur) { durBadge.textContent = `⏱️ ${dur} min`; durBadge.classList.remove('hidden'); } else { durBadge.classList.add('hidden'); } } // Reset views document.getElementById('booking-step-form').classList.remove('hidden'); document.getElementById('booking-step-success').classList.add('hidden'); const dateInput = document.getElementById('booking-date'); const hojeStr = new Date().toISOString().split('T')[0]; if (dateInput) dateInput.value = hojeStr; renderizarDatePills(hojeStr); carregarProfissionais(); const modal = document.getElementById('booking-modal'); const content = document.getElementById('booking-modal-content'); modal.classList.remove('hidden'); modal.classList.add('flex'); setTimeout(() => { modal.classList.add('modal-responsive-open'); content.classList.remove('scale-95', 'opacity-0'); content.classList.add('scale-100', 'opacity-100'); }, 15); carregarHorariosDisponiveis(); } function fecharModalAgendamento() { const modal = document.getElementById('booking-modal'); const content = document.getElementById('booking-modal-content'); if (modal) modal.classList.remove('modal-responsive-open'); content.classList.remove('scale-100', 'opacity-100'); content.classList.add('scale-95', 'opacity-0'); setTimeout(() => { modal.classList.remove('flex'); modal.classList.add('hidden'); }, 250); } async function carregarHorariosDisponiveis() { const dateInput = document.getElementById('booking-date'); const profSelect = document.getElementById('booking-professional'); const servicoId = document.getElementById('booking-service-id').value; const container = document.getElementById('booking-slots-container'); document.getElementById('booking-selected-time').value = ''; if (!dateInput || !container) return; const dateVal = dateInput.value; const profVal = profSelect ? profSelect.value : ''; container.innerHTML = 'sync Buscando horários livres...'; try { const url = `loja.php?action=fetch_available_slots&loja_id=9&data=${dateVal}&profissional_id=${profVal}&produto_id=${servicoId}`; const resp = await fetch(url); const data = await resp.json(); if (data.success) { if (data.folga) { container.innerHTML = `😴 ${data.message}`; return; } if (!data.slots || data.slots.length === 0) { container.innerHTML = 'Nenhum horário disponível nesta data.'; return; } // Group slots into Shifts (Turnos): Manhã (< 12:00), Tarde (12:00 - 17:59), Noite (>= 18:00) const manha = data.slots.filter(s => s < '12:00'); const tarde = data.slots.filter(s => s >= '12:00' && s < '18:00'); const noite = data.slots.filter(s => s >= '18:00'); let html = ''; const renderShiftBlock = (titulo, icone, arraySlots) => { if (arraySlots.length === 0) return ''; let blockHtml = `
${icone} ${titulo}
`; arraySlots.forEach(slot => { blockHtml += ``; }); blockHtml += `
`; return blockHtml; }; html += renderShiftBlock('Manhã', '☀️', manha); html += renderShiftBlock('Tarde', '⛅', tarde); html += renderShiftBlock('Noite', '🌙', noite); container.innerHTML = html; } else { container.innerHTML = `${data.error || 'Erro ao buscar horários.'}`; } } catch (e) { container.innerHTML = 'Falha de conexão.'; } } function selecionarHorarioSlot(btn, timeStr) { document.querySelectorAll('.slot-btn').forEach(b => { b.classList.remove('bg-purple-800', 'text-white', 'border-purple-800', 'shadow-xs'); b.classList.add('border-slate-200', 'text-slate-700'); }); btn.classList.remove('border-slate-200', 'text-slate-700'); btn.classList.add('bg-purple-800', 'text-white', 'border-purple-800', 'shadow-xs'); document.getElementById('booking-selected-time').value = timeStr; } async function confirmarAgendamento(e) { if (e) e.preventDefault(); const servicoId = document.getElementById('booking-service-id').value; const servicoNome = document.getElementById('booking-service-title').textContent; const dateVal = document.getElementById('booking-date').value; const timeVal = document.getElementById('booking-selected-time').value; const profSelect = document.getElementById('booking-professional'); const profVal = profSelect ? profSelect.value : ''; const nameVal = document.getElementById('booking-customer-name').value.trim(); const wspVal = document.getElementById('booking-customer-wsp').value.trim(); const obsVal = document.getElementById('booking-customer-obs').value.trim(); if (!dateVal) { if (window.showToast) window.showToast('Escolha a data do agendamento.', 'warning'); return; } if (!timeVal) { if (window.showToast) window.showToast('Selecione um horário disponível.', 'warning'); return; } if (!nameVal) { if (window.showToast) window.showToast('Informe seu nome completo.', 'warning'); return; } if (!wspVal) { if (window.showToast) window.showToast('Informe seu número de WhatsApp.', 'warning'); return; } const payload = { loja_id: 9, produto_id: servicoId, profissional_id: profVal, servico_nome: servicoNome, cliente_nome: nameVal, cliente_whatsapp: wspVal, data_agendamento: dateVal, horario_agendamento: timeVal, observacoes: obsVal }; try { const resp = await fetch('loja.php?action=create_booking', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }); const data = await resp.json(); if (data.success) { const partsDate = dateVal.split('-'); const dateFmt = partsDate[2] + '/' + partsDate[1] + '/' + partsDate[0]; // Render Success View document.getElementById('booking-step-form').classList.add('hidden'); document.getElementById('booking-step-success').classList.remove('hidden'); document.getElementById('succ-service').textContent = servicoNome; document.getElementById('succ-datetime').textContent = `${dateFmt} às ${timeVal}`; // Setup Google Calendar & .ICS Links const startG = dateVal.replace(/-/g, '') + 'T' + timeVal.replace(':', '') + '00'; const endG = dateVal.replace(/-/g, '') + 'T' + String(parseInt(timeVal.split(':')[0]) + 1).padStart(2, '0') + timeVal.split(':')[1] + '00'; const gCalUrl = data.gcal_link || `https://calendar.google.com/calendar/render?action=TEMPLATE&text=${encodeURIComponent(servicoNome + ' - LVP Embalagens')}&dates=${startG}/${endG}&details=${encodeURIComponent('Agendamento confirmado no portal. Cliente: ' + nameVal)}&location=${encodeURIComponent('')}`; const btnGCal = document.getElementById('btn-google-calendar'); if (btnGCal) btnGCal.href = gCalUrl; const btnIcs = document.getElementById('btn-download-ics'); if (btnIcs) btnIcs.href = data.ics_link || `loja.php?action=download_ics&booking_id=${data.booking_id}`; // Setup WhatsApp Link with consultation link const storePhone = ''; let wspLink = '#'; const consultUrl = `${window.location.origin}${window.location.pathname}?slug=lvp-embalagens&agendamento=${data.booking_id}`; if (storePhone) { const cleanPhone = storePhone.replace(/[^0-9]/g, ''); const fullPhone = (cleanPhone.length === 10 || cleanPhone.length === 11) ? '55' + cleanPhone : cleanPhone; const msg = encodeURIComponent(`Olá! Fiz um agendamento no portal:\n\n✂️ *Serviço:* ${servicoNome}\n📅 *Data:* ${dateFmt}\n⏰ *Horário:* ${timeVal}\n👤 *Nome:* ${nameVal}\n📱 *Contato:* ${wspVal}\n🔢 *Código:* #${data.booking_id}\n\n🔗 *Ver/Reagendar:* ${consultUrl}`); wspLink = `https://wa.me/${fullPhone}?text=${msg}`; } const btnWsp = document.getElementById('btn-booking-whatsapp'); if (btnWsp) btnWsp.href = wspLink; if (window.showToast) { window.showToast('Agendamento pré-reservado com sucesso!', 'success'); } } else { if (window.showToast) window.showToast(data.error || 'Erro ao realizar agendamento.', 'error'); } } catch (err) { if (window.showToast) window.showToast('Falha na comunicação com o servidor.', 'error'); } } // ------------------------------------------------------------- // Customer Booking Consultation & Rescheduling Controllers // ------------------------------------------------------------- let currentConsultBooking = null; function abrirModalConsultaAgendamento(bookingId = null) { const modal = document.getElementById('modal-consultar-agendamento'); const content = document.getElementById('modal-consultar-content'); if (!modal) return; document.getElementById('consult-step-search').classList.remove('hidden'); document.getElementById('consult-step-details').classList.add('hidden'); document.getElementById('consult-reschedule-form').classList.add('hidden'); modal.classList.remove('hidden'); modal.classList.add('flex'); setTimeout(() => { content.classList.remove('scale-95', 'opacity-0'); content.classList.add('scale-100', 'opacity-100'); }, 10); if (bookingId) { document.getElementById('consult-input-code').value = bookingId; buscarAgendamentoCliente(); } } function fecharModalConsultaAgendamento() { const modal = document.getElementById('modal-consultar-agendamento'); const content = document.getElementById('modal-consultar-content'); if (!modal) return; content.classList.remove('scale-100', 'opacity-100'); content.classList.add('scale-95', 'opacity-0'); setTimeout(() => { modal.classList.remove('flex'); modal.classList.add('hidden'); }, 250); } async function buscarAgendamentoCliente() { const codeInput = document.getElementById('consult-input-code'); const code = codeInput ? codeInput.value.trim() : ''; if (!code) { if (window.showToast) window.showToast('Digite o código do seu agendamento.', 'warning'); return; } try { const resp = await fetch(`loja.php?action=get_booking_info&booking_id=${code}`); const data = await resp.json(); if (data.success && data.booking) { currentConsultBooking = data.booking; const bk = data.booking; document.getElementById('consult-servico').textContent = `#${bk.id} - ${bk.servico_nome}`; document.getElementById('consult-loja').textContent = bk.loja_nome; document.getElementById('consult-cliente').textContent = bk.cliente_nome; document.getElementById('consult-data').textContent = `${bk.data_formatada} às ${bk.horario_agendamento}`; document.getElementById('consult-total').textContent = bk.total_formatado; const badge = document.getElementById('consult-status-badge'); badge.textContent = bk.status; if (bk.status === 'cancelado') { badge.className = 'px-2 py-0.5 rounded-full text-[10px] font-black uppercase bg-red-100 text-red-800'; } else if (bk.status === 'confirmado' || bk.status === 'concluido') { badge.className = 'px-2 py-0.5 rounded-full text-[10px] font-black uppercase bg-emerald-100 text-emerald-800'; } else { badge.className = 'px-2 py-0.5 rounded-full text-[10px] font-black uppercase bg-amber-100 text-amber-800'; } document.getElementById('consult-btn-gcal').href = bk.gcal_link; document.getElementById('consult-btn-ics').href = bk.ics_link; document.getElementById('consult-step-search').classList.add('hidden'); document.getElementById('consult-step-details').classList.remove('hidden'); document.getElementById('consult-reschedule-form').classList.add('hidden'); } else { if (window.showToast) window.showToast(data.error || 'Agendamento não encontrado.', 'error'); } } catch (e) { if (window.showToast) window.showToast('Erro ao buscar informações do agendamento.', 'error'); } } function mostrarFormularioReagendamento() { const form = document.getElementById('consult-reschedule-form'); if (!form) return; form.classList.toggle('hidden'); if (!form.classList.contains('hidden')) { const dateInput = document.getElementById('reschedule-new-date'); if (dateInput) { const hojeStr = new Date().toISOString().split('T')[0]; dateInput.value = hojeStr; carregarHorariosReagendamento(hojeStr); } } } async function carregarHorariosReagendamento(dateStr) { if (!currentConsultBooking) return; const select = document.getElementById('reschedule-new-time'); if (!select) return; select.innerHTML = ''; try { const url = `loja.php?action=fetch_available_slots&loja_id=${currentConsultBooking.loja_id}&data=${dateStr}&produto_id=${currentConsultBooking.produto_id || ''}`; const resp = await fetch(url); const data = await resp.json(); if (data.success && data.slots && data.slots.length > 0) { let options = ''; data.slots.forEach(s => { options += ``; }); select.innerHTML = options; } else { select.innerHTML = ''; } } catch (e) { select.innerHTML = ''; } } async function confirmarReagendamentoCliente() { if (!currentConsultBooking) return; const dateVal = document.getElementById('reschedule-new-date').value; const timeVal = document.getElementById('reschedule-new-time').value; if (!dateVal || !timeVal) { if (window.showToast) window.showToast('Escolha a nova data e horário.', 'warning'); return; } try { const resp = await fetch('loja.php?action=reschedule_booking', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ booking_id: currentConsultBooking.id, nova_data: dateVal, novo_horario: timeVal }) }); const data = await resp.json(); if (data.success) { if (window.showToast) window.showToast(data.message, 'success'); buscarAgendamentoCliente(); } else { if (window.showToast) window.showToast(data.error || 'Erro ao reagendar.', 'error'); } } catch (e) { if (window.showToast) window.showToast('Falha de conexão com o servidor.', 'error'); } } async function cancelarAgendamentoCliente() { if (!currentConsultBooking) return; if (!confirm('Deseja realmente cancelar este agendamento?')) return; try { const resp = await fetch('loja.php?action=cancel_booking', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ booking_id: currentConsultBooking.id }) }); const data = await resp.json(); if (data.success) { if (window.showToast) window.showToast(data.message, 'info'); buscarAgendamentoCliente(); } else { if (window.showToast) window.showToast(data.error || 'Erro ao cancelar.', 'error'); } } catch (e) { if (window.showToast) window.showToast('Falha ao cancelar agendamento.', 'error'); } } // Auto open consultation modal if URL parameter agendamento=ID exists document.addEventListener('DOMContentLoaded', () => { const urlParams = new URLSearchParams(window.location.search); const bookingCode = urlParams.get('agendamento') || urlParams.get('booking_id'); if (bookingCode) { setTimeout(() => { abrirModalConsultaAgendamento(bookingCode); }, 300); } }); // LGPD Cookie Consent Handler function verificarConsentimentoLGPD() { if (!localStorage.getItem('liquidamix_lgpd_accepted')) { setTimeout(() => { const banner = document.getElementById('lgpd-cookie-banner'); if (banner) { banner.classList.remove('hidden'); setTimeout(() => { banner.classList.remove('opacity-0', 'translate-y-4'); banner.classList.add('opacity-100', 'translate-y-0'); }, 50); } }, 1200); } } function aceitarConsentimentoLGPD() { localStorage.setItem('liquidamix_lgpd_accepted', '1'); const banner = document.getElementById('lgpd-cookie-banner'); if (banner) { banner.classList.remove('opacity-100', 'translate-y-0'); banner.classList.add('opacity-0', 'translate-y-4'); setTimeout(() => banner.classList.add('hidden'), 300); } } document.addEventListener('DOMContentLoaded', verificarConsentimentoLGPD); // Register Service Worker for PWA if ('serviceWorker' in navigator) { window.addEventListener('load', () => { navigator.serviceWorker.register('sw.js') .then(reg => console.log('PWA Service Worker ativo na vitrine:', reg.scope)) .catch(err => console.error('Erro ao registrar Service Worker PWA:', err)); }); }