Estoque Pro - Exportação Completa
by thvinic
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
<div class="container" id="areaCaptura">
<h2>📦 Controle de Materiais</h2>
<div id="alerta" class="aviso-falta"></div>
<div class="input-group">
<input type="text" id="itemInput" placeholder="Material...">
<input type="number" id="qtdInput" value="1">
<button class="btn-add" onclick="addItem()">ADD</button>
</div>
<div class="export-group">
<button class="btn-pdf" onclick="exportarPDF()">📄 PDF COLORIDO</button>
<button class="btn-img" onclick="exportarImagem()">🖼️ SALVAR IMAGEM</button>
</div>
<ul id="listaEstoque"></ul>
</div>
CSS
:root {
--primary: #2c3e50;
--success: #27ae60;
--danger: #e74c3c;
--warning: #f39c12;
--info: #3498db;
}
body { font-family: 'Segoe UI', sans-serif; background-color: #f0f2f5; padding: 15px; }
.container { max-width: 700px; margin: auto; background: white; padding: 25px; border-radius: 12px; box-shadow: 0 4px 15px rgba(0,0,0,0.1); }
h2 { text-align: center; color: var(--primary); }
.input-group { display: flex; gap: 8px; margin-bottom: 20px; }
input[type="text"], input[type="number"] { padding: 12px; border: 2px solid #ddd; border-radius: 8px; outline: none; }
input[type="text"] { flex: 2; }
input[type="number"] { width: 80px; }
button { padding: 12px; border: none; border-radius: 8px; cursor: pointer; font-weight: bold; color: white; transition: 0.2s; }
.btn-add { background-color: var(--success); }
.export-group { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 20px; }
.btn-pdf { background-color: var(--primary); }
.btn-img { background-color: var(--info); }
.btn-remove { background-color: #eee; color: #666; padding: 5px 10px; font-size: 12px; }
.aviso-falta {
background-color: #fff3cd; color: #856404; padding: 10px;
border-radius: 8px; margin-bottom: 15px; border-left: 5px solid var(--warning);
display: none;
}
ul { list-style: none; padding: 0; margin: 0; background: white; border-radius: 8px; }
li {
display: flex; align-items: center; justify-content: space-between;
padding: 12px; border-bottom: 1px solid #eee;
}
.item-missing { background-color: #fff5f5; }
.item-info { display: flex; align-items: center; gap: 10px; flex: 1; }
.qtd-edit {
...
JavaScript
let estoque = JSON.parse(localStorage.getItem('dadosEstoqueV5')) || [];
function salvar() {
localStorage.setItem('dadosEstoqueV5', JSON.stringify(estoque));
renderizar();
}
function addItem() {
const nome = document.getElementById('itemInput').value.trim();
const qtd = document.getElementById('qtdInput').value;
if (!nome) return;
estoque.push({ id: Date.now(), nome, qtd: parseInt(qtd), tem: true });
document.getElementById('itemInput').value = "";
salvar();
}
function toggleStatus(id) {
estoque = estoque.map(item => {
if (item.id === id) {
item.tem = !item.tem;
if (!item.tem) item.qtd = 0;
}
return item;
});
salvar();
}
function editarQtd(id, novaQtd) {
estoque = estoque.map(item => {
if (item.id === id) {
item.qtd = parseInt(novaQtd) || 0;
item.tem = item.qtd > 0;
}
return item;
});
salvar();
}
function removeItem(id) {
estoque = estoque.filter(item => item.id !== id);
salvar();
}
function renderizar() {
const lista = document.getElementById('listaEstoque');
const alerta = document.getElementById('alerta');
lista.innerHTML = "";
let faltantes = 0;
estoque.forEach(item => {
if (!item.tem) faltantes++;
const li = document.createElement('li');
if (!item.tem) li.className = 'item-missing';
li.innerHTML = `
<div class="item-info">
<input type="checkbox" ${item.tem ? 'checked' : ''} onchange="toggleStatus(${item.id})">
<input type="number" class="qtd-edit" value="${item.qtd}" onchange="editarQtd(${item.id}, this.value)">
<span...