Skip to content

souzaravinho/Roni

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 

Repository files navigation

<title>Relatório de Cobranças PIX</title> <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/jspdf-autotable/3.5.28/jspdf.plugin.autotable.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/qrcode-generator/1.4.4/qrcode.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script> <style> :root { --bg: #f4f7fb; --text: #333; --card-bg: #fff; --header-bg: #0069d9; --header-text: #fff; --summary-bg: #f8f9fa; --summary-border: #ddd; --button-bg: #28a745; --button-hover: #1e7e34; }
body.dark {
  --bg: #121212;
  --text: #f1f1f1;
  --card-bg: #1e1e1e;
  --header-bg: #222;
  --header-text: #00d1ff;
  --summary-bg: #2a2a2a;
  --summary-border: #444;
  --button-bg: #007BFF;
  --button-hover: #0056b3;
}

body {
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
  margin: 0; padding: 0;
  background: var(--bg);
  color: var(--text);
  transition: background 0.3s, color 0.3s;
}
header {
  background: var(--header-bg);
  color: var(--header-text);
  padding: 15px 20px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
header h1 {
  margin: 0;
  font-size: 1.5rem;
}
.container {
  max-width: 900px;
  margin: 20px auto;
  background: var(--card-bg);
  padding: 20px;
  border-radius: 8px;
  box-shadow: 0 4px 8px rgba(0,0,0,0.1);
  transition: background 0.3s;
}
select, input, button {
  margin: 8px 0;
  padding: 10px;
  border-radius: 6px;
  font-size: 1rem;
}
select, input {
  width: 100%;
  border: 1px solid #ccc;
  background: var(--card-bg);
  color: var(--text);
}
button {
  cursor: pointer;
  border: none;
  transition: 0.3s;
}
.export-btn {
  background: var(--button-bg);
  color: white;
  width: 100%;
  font-weight: bold;
}
.export-btn:hover { background: var(--button-hover); }
.date-range { display: none; margin-top: 10px; }
label { font-weight: bold; }
.summary-box {
  background: var(--summary-bg);
  border: 1px solid var(--summary-border);
  border-radius: 6px;
  padding: 15px;
  margin-top: 15px;
}
.summary-box h3 { margin: 0 0 10px 0; font-size: 1.2rem; }
canvas { margin-top: 15px; max-width: 100%; }
ul { list-style: none; padding: 0; margin: 10px 0 0 0; }
ul li { padding: 6px 0; border-bottom: 1px solid #eee; }
.dark-toggle {
  background: transparent;
  border: 2px solid var(--header-text);
  color: var(--header-text);
  padding: 6px 12px;
  border-radius: 20px;
  cursor: pointer;
  font-size: 0.9rem;
  transition: 0.3s;
}
.dark-toggle:hover { background: var(--header-text); color: var(--header-bg); }
</style>

📊 Relatório de Cobranças PIX

🌙 Modo Escuro
📅 Escolha o período: Todo histórico Última semana Último mês Intervalo personalizado
<div class="date-range" id="dateRange">
  <label for="startDate">Data inicial:</label>
  <input type="date" id="startDate" onchange="updateSummary()">
  <label for="endDate">Data final:</label>
  <input type="date" id="endDate" onchange="updateSummary()">
</div>

<div class="summary-box" id="summaryBox">
  <h3>📌 Resumo do período</h3>
  <p id="summaryText">Selecione um período para ver o resumo.</p>
</div>

<canvas id="chartResumo"></canvas>

<button class="export-btn" onclick="exportPDF()">📄 Exportar PDF Completo</button>
<ul id="historyList"></ul>
<script> const { jsPDF } = window.jspdf; let history = JSON.parse(localStorage.getItem("pixHistory")) || []; if (history.length === 0) { history = [ { valor: "50.00", data: "30/08/2025 14:35", pix: "000201|valor=50.00" }, { valor: "120.75", data: "25/08/2025 19:12", pix: "000201|valor=120.75" }, { valor: "10.00", data: "15/08/2025 09:50", pix: "000201|valor=10.00" }, { valor: "75.00", data: "05/07/2025 16:40", pix: "000201|valor=75.00" } ]; localStorage.setItem("pixHistory", JSON.stringify(history)); } const historyList = document.getElementById("historyList"); history.forEach(item => { const li = document.createElement("li"); li.textContent = `R$ ${item.valor} - ${item.data}`; historyList.appendChild(li); }); function toggleDateRange() { const filter = document.getElementById("filterPeriod").value; document.getElementById("dateRange").style.display = (filter === "custom") ? "block" : "none"; } function parseDate(dateStr) { const [d, m, yAndTime] = dateStr.split("/"); const [y, time] = yAndTime.split(" "); const [year, month, day] = [parseInt(y), parseInt(m) - 1, parseInt(d)]; const [hh, mm] = time.split(":").map(Number); return new Date(year, month, day, hh, mm); } function generateQRCode(data) { return new Promise((resolve) => { const qr = qrcode(0, "L"); qr.addData(data); qr.make(); resolve(qr.createDataURL(4, 0)); }); } function filterHistory() { const filter = document.getElementById("filterPeriod").value; const now = new Date(); let filtered = history; if (filter === "week") { const lastWeek = new Date(); lastWeek.setDate(now.getDate() - 7); filtered = history.filter(item => parseDate(item.data) >= lastWeek); } else if (filter === "month") { const lastMonth = new Date(); lastMonth.setMonth(now.getMonth() - 1); filtered = history.filter(item => parseDate(item.data) >= lastMonth); } else if (filter === "custom") { const startDate = new Date(document.getElementById("startDate").value); const endDate = new Date(document.getElementById("endDate").value); if (!isNaN(startDate) && !isNaN(endDate)) { filtered = history.filter(item => { const itemDate = parseDate(item.data); return itemDate >= startDate && itemDate <= endDate; }); } else { filtered = []; } } return filtered; } let chart; function updateSummary() { const filtered = filterHistory(); const summaryText = document.getElementById("summaryText"); if (filtered.length === 0) { summaryText.textContent = "Nenhuma cobrança encontrada neste período ❗"; if (chart) chart.destroy(); return; } const totalCobrancas = filtered.length; const somaValores = filtered.reduce((sum, item) => sum + parseFloat(item.valor), 0).toFixed(2); summaryText.textContent = `Total de cobranças: ${totalCobrancas} | Valor total: R$ ${somaValores}`; const labels = filtered.map(item => item.data.split(" ")[0]); const valores = filtered.map(item => parseFloat(item.valor)); if (chart) chart.destroy(); const ctx = document.getElementById("chartResumo").getContext("2d"); chart = new Chart(ctx, { type: "bar", data: { labels: labels, datasets: [{ label: "Valores (R$)", data: valores, backgroundColor: getComputedStyle(document.body).getPropertyValue("--button-bg") }] }, options: { responsive: true, plugins: { legend: { display: false } } } }); } async function exportPDF() { const filteredHistory = filterHistory(); if (filteredHistory.length === 0) { alert("Nenhuma cobrança encontrada ❗"); return; } const totalCobrancas = filteredHistory.length; const somaValores = filteredHistory.reduce((sum, item) => sum + parseFloat(item.valor), 0).toFixed(2); const doc = new jsPDF(); doc.setFillColor(30, 30, 30); doc.rect(0, 0, 210, 25, "F"); doc.setTextColor(0, 209, 255); doc.setFontSize(16); doc.text("Relatório de Cobranças PIX", 14, 17); doc.setTextColor(0, 0, 0); doc.setFontSize(12); doc.text("📌 Resumo do período", 14, 35); doc.text(`- Total de cobranças: ${totalCobrancas}`, 14, 43); doc.text(`- Valor total: R$ ${somaValores}`, 14, 51); const chartCanvas = document.getElementById("chartResumo"); const chartImg = await html2canvas(chartCanvas).then(canvas => canvas.toDataURL("image/png")); doc.addImage(chartImg, "PNG", 14, 60, 180, 80); const body = []; const qrImages = []; for (let item of filteredHistory) { const qrImg = await generateQRCode(item.pix); body.push([`R$ ${item.valor}`, item.data, ""]); qrImages.push(qrImg); } doc.autoTable({ startY: 150, head: [["Valor", "Data", "QR Code"]], body: body, theme: "grid", styles: { valign: "middle", halign: "center" }, columnStyles: { 0: { cellWidth: 40 }, 1: { cellWidth: 70 }, 2: { cellWidth: 60 } }, didDrawCell: function (data) { if (data.column.index === 2 && data.cell.section === "body") { const qrImg = qrImages[data.row.index]; if (qrImg) { doc.addImage(qrImg, "PNG", data.cell.x + 15, data.cell.y + 2, 30, 30); } } } }); doc.save("relatorio_pix.pdf"); } function toggleDarkMode() { document.body.classList.toggle("dark"); updateSummary(); } updateSummary(); </script>

About

a7f54be2-7de7-481f-963d-31e32987a4f9

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published