// ========================================= // app.js - UI Global - Sisprime // ========================================= 'use strict'; // ---- Global Toast ---- window.showToast = function(msg, type, duration) { var container = document.getElementById('toast-container'); if (!container) return; var icons = { success:'fa-circle-check', danger:'fa-circle-xmark', warning:'fa-triangle-exclamation', info:'fa-circle-info' }; var div = document.createElement('div'); div.className = 'toast toast--' + (type || 'info'); var icon = document.createElement('i'); icon.className = 'fa-solid ' + (icons[type] || icons.info); var span = document.createElement('span'); span.textContent = msg; div.appendChild(icon); div.appendChild(span); container.appendChild(div); setTimeout(function() { div.remove(); }, duration || 3000); }; document.addEventListener('DOMContentLoaded', function () { // ---- Sidebar Toggle ---- var sidebar = document.getElementById('app-sidebar'); var overlay = document.getElementById('sidebar-overlay'); var hamburgerBtns = document.querySelectorAll('.hamburger-btn'); function closeSidebar() { sidebar && sidebar.classList.remove('sidebar-open'); overlay && overlay.classList.remove('active'); } hamburgerBtns.forEach(function(btn) { btn.addEventListener('click', function () { sidebar && sidebar.classList.toggle('sidebar-open'); overlay && overlay.classList.toggle('active'); }); }); overlay && overlay.addEventListener('click', closeSidebar); // ---- Dropdown: Filial ---- var filialBtn = document.getElementById('filial-btn'); var filialMenu = document.getElementById('filial-menu'); filialBtn && filialBtn.addEventListener('click', function (e) { e.stopPropagation(); filialMenu && filialMenu.classList.toggle('open'); userMenu && userMenu.classList.remove('open'); }); // ---- Dropdown: Usuário ---- var userBtn = document.getElementById('user-btn'); var userMenu = document.getElementById('user-menu'); userBtn && userBtn.addEventListener('click', function (e) { e.stopPropagation(); userMenu && userMenu.classList.toggle('open'); filialMenu && filialMenu.classList.remove('open'); }); // ---- Fechar dropdowns ao clicar fora ---- document.addEventListener('click', function () { filialMenu && filialMenu.classList.remove('open'); userMenu && userMenu.classList.remove('open'); }); // ---- Logout: interceptar todos os links "Salir" no header ---- document.addEventListener('click', function(e) { var link = e.target.closest('a.user-menu-item'); if (!link) return; var span = link.querySelector('span'); if (!span || span.textContent.trim() !== 'Salir') return; e.preventDefault(); if (window.SisprimeDB) SisprimeDB.logout(); window.location.href = 'login.html'; }); // ---- Aplicar config do usuário no header ---- if (window.SisprimeDB) { var cfg = SisprimeDB.getConfig(); var nome = cfg.usuario_nome || 'U'; var inicial = nome.charAt(0).toUpperCase(); var avatarEl = document.getElementById('hdr-avatar'); var usernameEl = document.getElementById('hdr-username'); var filialEl = document.getElementById('hdr-filial'); if (avatarEl) avatarEl.textContent = inicial; if (usernameEl) usernameEl.textContent = nome; if (filialEl) filialEl.textContent = cfg.filial || '37452975'; } // ---- Upload: exibir nome do arquivo ---- var uploads = [ { input: 'input-fotos-pecas', label: 'nome-fotos-pecas' }, { input: 'input-comp-pagamento', label: 'nome-comp-pagamento' }, { input: 'input-comp-entrega', label: 'nome-comp-entrega' }, ]; uploads.forEach(function(u) { var inp = document.getElementById(u.input); var lbl = document.getElementById(u.label); if (inp && lbl) { inp.addEventListener('change', function () { lbl.textContent = inp.files.length === 0 ? 'Ningún archivo seleccionado' : inp.files.length === 1 ? inp.files[0].name : inp.files.length + ' archivos seleccionados'; }); } }); // ---- Fechar modal com Escape ---- document.addEventListener('keydown', function(e) { if (e.key === 'Escape') { document.querySelectorAll('.modal-backdrop.open').forEach(function(m) { m.classList.remove('open'); m.setAttribute('aria-hidden', 'true'); document.body.style.overflow = ''; }); } }); // ============================================= // MODAL — ADICIONAR PEÇA COTIZADA (cotacao.html) // ============================================= var modalBackdrop = document.getElementById('modal-peca-backdrop'); var btnAbrirModal = document.getElementById('btn-adicionar-peca'); var btnFecharModal = document.getElementById('modal-peca-close'); var btnCancelar = document.getElementById('modal-peca-cancelar'); var btnAdicionar = document.getElementById('modal-peca-adicionar'); var btnAdicionar = document.getElementById('modal-peca-adicionar'); var mpTarifa = document.getElementById('mp-tarifa'); var mpEnvioTotal = document.getElementById('mp-envio-total'); var mpPrecoVenda = document.getElementById('mp-preco-venda'); var mpCustoUnit = document.getElementById('mp-custo-unit'); var mpComissao = document.getElementById('mp-comissao'); var mpComissaoBadge = document.getElementById('mp-comissao-display'); var mpBeneficio = document.getElementById('mp-beneficio'); function openModal() { if (!modalBackdrop) return; modalBackdrop.classList.add('open'); modalBackdrop.setAttribute('aria-hidden', 'false'); document.body.style.overflow = 'hidden'; var fi = document.getElementById('mp-nome-peca'); fi && setTimeout(function() { fi.focus(); }, 80); } function closeModal() { if (!modalBackdrop) return; modalBackdrop.classList.remove('open'); modalBackdrop.setAttribute('aria-hidden', 'true'); document.body.style.overflow = ''; } btnAbrirModal && btnAbrirModal.addEventListener('click', openModal); btnFecharModal && btnFecharModal.addEventListener('click', closeModal); btnCancelar && btnCancelar.addEventListener('click', closeModal); modalBackdrop && modalBackdrop.addEventListener('click', function(e) { if (e.target === modalBackdrop) closeModal(); }); function calcEnvio() { if (!mpTarifa || !mpEnvioTotal) return; var peso = parseFloat(document.getElementById('mp-peso-est') ? document.getElementById('mp-peso-est').value : 0); var v = peso * (parseFloat(mpTarifa.value)||0); mpEnvioTotal.value = v.toFixed(2); var display = document.getElementById('mp-envio-total-display'); if (display && window.fmtCurrency) display.textContent = window.fmtCurrency(v); calcBeneficio(); } function calcBeneficio() { if (!mpPrecoVenda || !mpCustoUnit || !mpEnvioTotal || !mpBeneficio) return; var v = (parseFloat(mpPrecoVenda.value)||0) - (parseFloat(mpCustoUnit.value)||0) - (parseFloat(mpEnvioTotal.value)||0); mpBeneficio.textContent = window.fmtCurrency ? window.fmtCurrency(v) : v.toFixed(2); mpBeneficio.dataset.value = v; // save raw value } function updateComissao() { if (mpComissao && mpComissaoBadge && mpPrecoVenda) { var perc = parseFloat(mpComissao.value) || 0; var pv = parseFloat(mpPrecoVenda.value) || 0; var val = pv * (perc/100); mpComissaoBadge.textContent = window.fmtCurrency ? window.fmtCurrency(val) : val.toFixed(2); } } var mpPesoEst = document.getElementById('mp-peso-est'); mpPesoEst && mpPesoEst.addEventListener('input', calcEnvio); mpTarifa && mpTarifa.addEventListener('input', calcEnvio); mpPrecoVenda && mpPrecoVenda.addEventListener('input', calcBeneficio); mpPrecoVenda && mpPrecoVenda.addEventListener('input', updateComissao); mpCustoUnit && mpCustoUnit.addEventListener('input', calcBeneficio); mpComissao && mpComissao.addEventListener('input', updateComissao); // Toggle Peça não encontrada var mpNaoEncontrada = document.getElementById('mp-nao-encontrada'); var mpCamposCotizacao = document.getElementById('mp-campos-cotizacao'); mpNaoEncontrada && mpNaoEncontrada.addEventListener('change', function() { if (mpCamposCotizacao) { mpCamposCotizacao.style.display = this.checked ? 'none' : 'block'; } }); // Formatar campos para exibir decimais ao sair deles (blur) function applyDecimals(e) { var m = (document.getElementById('campo-moeda') || {}).value || 'USD'; var decimals = (m === 'PYG') ? 0 : 2; var val = parseFloat(e.target.value); if (!isNaN(val)) { e.target.value = val.toFixed(decimals); } } var currencyFields = [mpPrecoVenda, mpCustoUnit, mpTarifa, mpPesoEst]; currencyFields.forEach(function(f) { if(f) f.addEventListener('blur', applyDecimals); }); // "Añadir Pieza" → adiciona à tabela e ao array global de itens btnAdicionar && btnAdicionar.addEventListener('click', function() { var nomeEl = document.getElementById('mp-nome-peca'); if (!nomeEl || !nomeEl.value.trim()) { nomeEl && (nomeEl.style.borderColor = 'red'); showToast('El nombre de la pieza es obligatorio', 'warning'); return; } nomeEl.style.borderColor = ''; var naoEncontrada = document.getElementById('mp-nao-encontrada') ? document.getElementById('mp-nao-encontrada').checked : false; var item = { nome: nomeEl.value.trim(), tipo: (document.getElementById('mp-tipo') || {}).value || '', quantidade: parseInt((document.getElementById('mp-quantidade') || {}).value) || 1, preco_venda: parseFloat((document.getElementById('mp-preco-venda') || {}).value) || 0, custo: parseFloat((document.getElementById('mp-custo-unit') || {}).value) || 0, comissao: parseFloat((document.getElementById('mp-comissao') || {}).value) || 0, fornecedor: (document.getElementById('mp-proveedor') || {}).value || '', prazo_dias: parseInt((document.getElementById('mp-prazo') || {}).value) || 0, peso: parseFloat((document.getElementById('mp-peso-est') || {}).value) || 0, tarifa: parseFloat((document.getElementById('mp-tarifa') || {}).value) || 0, envio_total: parseFloat((document.getElementById('mp-envio-total') || {}).value) || 0, beneficio: parseFloat(mpBeneficio ? mpBeneficio.dataset.value : 0) || 0, nao_encontrada: naoEncontrada }; if (window.addItemToCotacao) window.addItemToCotacao(item); closeModal(); showToast('Pieza añadida a la cotización', 'success'); }); }); // end DOMContentLoaded