Gerador de Voucher AR7
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">
<div class="header">
<img alt="AR7-logo" class="header-logo-img" src="https://i.ibb.co/tPQMxycG/instalador-de-ar-goiania-ar7-servicos.png">
<h1>🧾 Gerador de Voucher</h1>
<div class="header-subtitle">AR7 - Ar Condicionado & Serviços</div>
</div>
<div class="form-section">
<div class="form-group">
<label for="clientName">Nome do Cliente *</label>
<input type="text" id="clientName" placeholder="Digite o nome completo do cliente" required>
</div>
<div class="form-group">
<label for="voucherValue">Valor do Voucher (1.230,00) *</label>
<input type="text" id="voucherValue" class="currency-input" placeholder="1.230,00" maxlength="15" required>
</div>
<div class="form-group">
<label for="validityType">Validade do Voucher *</label>
<select id="validityType" onchange="toggleValidityField()">
<option value="date">Data específica</option>
<option value="indefinite">Indeterminado</option>
</select>
</div>
<div class="form-group" id="validityDateGroup">
<label for="validity">Data de Validade</label>
<input type="date" id="validity">
</div>
<div class="form-group">
<label for="reference">Referência do Voucher</label>
<input type="text" id="reference" placeholder="Opcional - Referência/Nota">
</div>
<button class="generate-btn" onclick="generateVoucher()">
📄 Gerar Voucher
</button>
<div class="voucher-preview" id="voucherPreview">
<div id="canvasWrapper"...
CSS
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: Arial, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh; padding: 20px;
}
.container {
max-width: 850px; margin: 0 auto;
background: white; border-radius: 15px;
box-shadow: 0 20px 40px rgba(0,0,0,0.1); overflow: hidden;
}
.header {
background: linear-gradient(135deg, #2c3e50 0%, #3498db 50%, #2980b9 100%);
color: white; padding: 25px; text-align: center; position: relative;
}
.header-logo-img { max-width: 180px; float: right; }
.header h1 { font-size: 2.2em; text-shadow: 2px 2px 4px rgba(0,0,0,0.5); }
.header-subtitle { font-size: 1.1em; opacity: 0.9; }
.form-section { padding: 30px; }
.form-group { margin-bottom: 20px; }
label { display: block; font-weight: bold; color: #2c3e50; margin-bottom: 8px; }
input, select {
width: 100%; padding: 12px; border: 2px solid #ddd;
border-radius: 8px; font-size: 1em; outline: none;
}
input:focus { border-color: #3498db; }
.currency-input { font-family: monospace; text-align: right; font-size: 1.2em; }
.generate-btn {
width: 100%; padding: 15px;
background: linear-gradient(135deg, #27ae60, #2ecc71);
color: white; border: none; border-radius: 10px;
font-size: 1.2em; font-weight: bold; cursor: pointer;
transition: 0.3s;
}
.generate-btn:hover { transform: scale(1.02); box-shadow: 0 5px 15px rgba(0,0,0,0.2); }
.voucher-preview {
margin-top: 30px; padding: 20px;
background: #f1f1f1; border-radius: 15px;
border: 2px dashed #3498db; display: none;
}
/* ESTILO DO VOUCHER INTERNO */
.voucher {
background: white; padding: 35px; border-radius: 5px;
width: 100%; max-width: 580px; /* Largura ideal...
JavaScript
document.addEventListener('DOMContentLoaded', function() {
// Define data padrão para 30 dias à frente
const today = new Date();
today.setDate(today.getDate() + 30);
document.getElementById('validity').value = today.toISOString().split('T')[0];
// Listener para formatar moeda em tempo real
const currencyInput = document.getElementById('voucherValue');
currencyInput.addEventListener('input', formatCurrencyInput);
});
// Formata 123000 em 1.230,00
function formatCurrencyInput(e) {
let value = e.target.value.replace(/\D/g, '');
if (!value) { e.target.value = ''; return; }
value = (parseFloat(value) / 100).toFixed(2);
e.target.value = new Intl.NumberFormat('pt-BR', {
minimumFractionDigits: 2,
maximumFractionDigits: 2
}).format(value);
}
function parseCurrency(value) {
if (!value) return 0;
return parseFloat(value.replace(/\./g, '').replace(',', '.')) || 0;
}
function formatCurrency(value) {
return new Intl.NumberFormat('pt-BR', {
style: 'currency',
currency: 'BRL'
}).format(value);
}
function toggleValidityField() {
const validityType = document.getElementById('validityType').value;
const validityDateGroup = document.getElementById('validityDateGroup');
validityDateGroup.style.display = (validityType === 'indefinite') ? 'none' : 'block';
}
function generateVoucher() {
const clientName = document.getElementById('clientName').value.trim();
const rawValue = document.getElementById('voucherValue').value.trim();
const validityType = document.getElementById('validityType').value;
const validityDate = document.getElementById('validity').value;
const reference = document.getElementById('reference').value.trim();
const voucherValue = parseCurrency(rawValue);
if (!clientName || voucherValue <= 0) {
alert('❌ Preencha os campos obrigatórios');
return;
}
...