otimizacoes de performance

Signed-off-by: Rodrigo Bertoldo de Sousa Martins <rodrigo.sousa.577@gmail.com>
This commit is contained in:
rodrigo committed 2026-02-21 16:36:19 -03:00
1 parent f23b925a99
commit 685d37e3f6
2 files changed
+70 -118

No files matched your search

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

+70 -118
View File
@@ -36,6 +36,7 @@
background-size: 400% 400%; background-size: 400% 400%;
animation: gradientAnimation 15s ease infinite; animation: gradientAnimation 15s ease infinite;
z-index: -2; z-index: -2;
will-change: background-position;
} }
@keyframes gradientAnimation { @keyframes gradientAnimation {
@@ -62,14 +63,10 @@
width: 100px; width: 100px;
height: 100px; height: 100px;
margin: 0 auto 15px; margin: 0 auto 15px;
background-image: url('fotos/logo.png'); background: url('fotos/logo.png') center/80% no-repeat rgba(255, 255, 255, 0.95);
background-size: 80%;
background-position: center;
background-repeat: no-repeat;
border-radius: 50%; border-radius: 50%;
border: 3px solid rgba(255, 255, 255, 0.3); border: 3px solid rgba(255, 255, 255, 0.3);
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3); box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3);
background-color: rgba(255, 255, 255, 0.95);
} }
.header { .header {
@@ -92,19 +89,25 @@
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5); text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5);
} }
/* Botão Salvar na Agenda */ /* Botões principais */
.save-contact { .save-contact,
.pix-button {
display: inline-block; display: inline-block;
padding: 12px 30px; padding: 12px 30px;
background: linear-gradient(135deg, #20337b, #2d4a9e);
color: white; color: white;
text-decoration: none; text-decoration: none;
border-radius: 50px; border-radius: 50px;
font-size: 0.95em; font-size: 0.95em;
font-weight: bold; font-weight: bold;
margin-bottom: 25px;
transition: all 0.3s ease; transition: all 0.3s ease;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3); box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3);
cursor: pointer;
border: none;
}
.save-contact {
background: linear-gradient(135deg, #20337b, #2d4a9e);
margin-bottom: 25px;
} }
.save-contact:hover { .save-contact:hover {
@@ -113,7 +116,6 @@
background: linear-gradient(135deg, #2d4a9e, #20337b); background: linear-gradient(135deg, #2d4a9e, #20337b);
} }
/* Container de ícones */
.icons-row { .icons-row {
display: flex; display: flex;
justify-content: center; justify-content: center;
@@ -128,7 +130,7 @@
align-items: center; align-items: center;
text-decoration: none; text-decoration: none;
color: white; color: white;
transition: all 0.3s ease; transition: transform 0.3s ease;
} }
.icon-item:hover { .icon-item:hover {
@@ -214,7 +216,6 @@
transform: translateY(-1px) scale(0.98); transform: translateY(-1px) scale(0.98);
} }
/* Modal PIX */
.modal { .modal {
display: none; display: none;
position: fixed; position: fixed;
@@ -252,6 +253,7 @@
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.5); box-shadow: 0 10px 40px rgba(0, 0, 0, 0.5);
transform: translateY(30px) scale(0.9); transform: translateY(30px) scale(0.9);
opacity: 0; opacity: 0;
will-change: transform, opacity;
} }
.modal.active .modal-content { .modal.active .modal-content {
@@ -385,6 +387,7 @@
transition: all 0.2s ease; transition: all 0.2s ease;
border: 2px solid transparent; border: 2px solid transparent;
position: relative; position: relative;
will-change: transform, opacity;
} }
.pix-code-area::before { .pix-code-area::before {
@@ -453,7 +456,6 @@
} }
} }
/* Ícones pequenos */
.small-icons { .small-icons {
display: flex; display: flex;
justify-content: center; justify-content: center;
@@ -488,7 +490,6 @@
fill: white; fill: white;
} }
/* Responsividade */
@media (max-width: 600px) { @media (max-width: 600px) {
.header h1 { .header h1 {
font-size: 1.5em; font-size: 1.5em;
@@ -631,129 +632,89 @@
</div> </div>
<script> <script>
function openPixModal() { // Cache de elementos DOM para melhor performance
const modal = document.getElementById('pixModal'); const pixModal = document.getElementById('pixModal');
modal.classList.add('active'); const pixValue = document.getElementById('pixValue');
setTimeout(() => { const pixCodeArea = document.getElementById('pixCodeArea');
document.getElementById('pixValue').focus(); const copyNotification = document.getElementById('copyNotification');
}, 100); const modalContent = pixModal.querySelector('.modal-content');
}
function closePixModal() { const openPixModal = () => {
const modal = document.getElementById('pixModal'); pixModal.classList.add('active');
const modalContent = modal.querySelector('.modal-content'); setTimeout(() => pixValue.focus(), 100);
};
// Animação de saída const closePixModal = () => {
modalContent.style.animation = 'slideDownScale 0.3s ease forwards'; modalContent.style.animation = 'slideDownScale 0.3s ease forwards';
modal.style.animation = 'fadeOut 0.3s ease forwards'; pixModal.style.animation = 'fadeOut 0.3s ease forwards';
setTimeout(() => { setTimeout(() => {
modal.classList.remove('active'); pixModal.classList.remove('active');
modal.style.animation = ''; pixModal.style.animation = '';
modalContent.style.animation = ''; modalContent.style.animation = '';
document.getElementById('pixValue').value = ''; pixValue.value = '';
document.getElementById('pixCodeArea').classList.remove('active'); pixCodeArea.classList.remove('active');
document.getElementById('copyNotification').classList.remove('active'); copyNotification.classList.remove('active');
}, 300); }, 300);
} };
function generatePix() { const generatePix = () => {
const value = parseFloat(document.getElementById('pixValue').value); const value = parseFloat(pixValue.value);
if (!value || value <= 0) { if (!value || value <= 0) {
alert('Por favor, digite um valor válido'); alert('Por favor, digite um valor válido');
return; return;
} }
// Gera código PIX EMV (padrão brasileiro) const pixCode = buildPixCode(
const pixKey = 'financeiro@martinsevieira.adv.br'; 'financeiro@martinsevieira.adv.br',
const merchantName = 'MARTINS E VIEIRA'; 'MARTINS E VIEIRA',
const city = 'PALMAS'; 'PALMAS',
const txid = 'PAGAMENTO' + Date.now().toString().slice(-10); value.toFixed(2),
'PAGAMENTO' + Date.now().toString().slice(-10)
);
// Formata o valor com 2 casas decimais
const formattedValue = value.toFixed(2);
// Constrói o código PIX Copia e Cola (EMV)
const pixCode = buildPixCode(pixKey, merchantName, city, formattedValue, txid);
// Exibe o código
const pixCodeArea = document.getElementById('pixCodeArea');
pixCodeArea.textContent = pixCode; pixCodeArea.textContent = pixCode;
pixCodeArea.classList.add('active'); pixCodeArea.classList.add('active');
pixCodeArea.onclick = () => copyToClipboard(pixCode);
// Adiciona evento de clique para copiar
pixCodeArea.onclick = function() {
copyToClipboard(pixCode); copyToClipboard(pixCode);
}; };
// Copia automaticamente na primeira vez const buildPixCode = (pixKey, merchantName, city, value, txid) => {
copyToClipboard(pixCode); const emvField = (id, value) => id + value.length.toString().padStart(2, '0') + value;
}
function buildPixCode(pixKey, merchantName, city, value, txid) {
// Função auxiliar para criar campo EMV
function emvField(id, value) {
const length = value.length.toString().padStart(2, '0');
return id + length + value;
}
// Monta a chave PIX
const merchantAccountInfo = emvField('00', 'BR.GOV.BCB.PIX') + emvField('01', pixKey); const merchantAccountInfo = emvField('00', 'BR.GOV.BCB.PIX') + emvField('01', pixKey);
let emv = ''; let emv = emvField('00', '01') + emvField('26', merchantAccountInfo) +
emv += emvField('00', '01'); // Payload Format Indicator emvField('52', '0000') + emvField('53', '986') + emvField('54', value) +
emv += emvField('26', merchantAccountInfo); // Merchant Account Information emvField('58', 'BR') + emvField('59', merchantName) + emvField('60', city) +
emv += emvField('52', '0000'); // Merchant Category Code emvField('62', emvField('05', txid)) + '6304';
emv += emvField('53', '986'); // Transaction Currency (986 = BRL)
emv += emvField('54', value); // Transaction Amount
emv += emvField('58', 'BR'); // Country Code
emv += emvField('59', merchantName); // Merchant Name
emv += emvField('60', city); // Merchant City
emv += emvField('62', emvField('05', txid)); // Additional Data Field
// Calcula CRC16 return emv + crc16(emv);
emv += '6304'; };
const crc = crc16(emv);
emv += crc;
return emv; const crc16 = str => {
}
function crc16(str) {
let crc = 0xFFFF; let crc = 0xFFFF;
for (let i = 0; i < str.length; i++) { for (let i = 0; i < str.length; i++) {
crc ^= str.charCodeAt(i) << 8; crc ^= str.charCodeAt(i) << 8;
for (let j = 0; j < 8; j++) { for (let j = 0; j < 8; j++) {
if (crc & 0x8000) { crc = crc & 0x8000 ? (crc << 1) ^ 0x1021 : crc << 1;
crc = (crc << 1) ^ 0x1021;
} else {
crc = crc << 1;
}
} }
} }
return (crc & 0xFFFF).toString(16).toUpperCase().padStart(4, '0'); return (crc & 0xFFFF).toString(16).toUpperCase().padStart(4, '0');
} };
function copyToClipboard(text) { const copyToClipboard = text => {
// Usa a API moderna de clipboard if (navigator.clipboard?.writeText) {
if (navigator.clipboard && navigator.clipboard.writeText) { navigator.clipboard.writeText(text).then(showCopyNotification, () => fallbackCopy(text));
navigator.clipboard.writeText(text).then(() => {
showCopyNotification();
}).catch(err => {
// Fallback para método antigo
fallbackCopy(text);
});
} else { } else {
fallbackCopy(text); fallbackCopy(text);
} }
} };
function fallbackCopy(text) { const fallbackCopy = text => {
const textarea = document.createElement('textarea'); const textarea = document.createElement('textarea');
textarea.value = text; textarea.value = text;
textarea.style.position = 'fixed'; textarea.style.cssText = 'position:fixed;opacity:0';
textarea.style.opacity = '0';
document.body.appendChild(textarea); document.body.appendChild(textarea);
textarea.select(); textarea.select();
try { try {
@@ -763,31 +724,22 @@
alert('Erro ao copiar. Por favor, copie manualmente.'); alert('Erro ao copiar. Por favor, copie manualmente.');
} }
document.body.removeChild(textarea); document.body.removeChild(textarea);
} };
function showCopyNotification() { const showCopyNotification = () => {
const notification = document.getElementById('copyNotification'); copyNotification.classList.remove('active');
notification.classList.remove('active'); // Remove primeiro para reiniciar animação setTimeout(() => copyNotification.classList.add('active'), 10);
setTimeout(() => { setTimeout(() => copyNotification.classList.remove('active'), 3000);
notification.classList.add('active'); };
}, 10);
setTimeout(() => {
notification.classList.remove('active');
}, 3000);
}
// Fecha modal ao clicar fora // Fecha modal ao clicar fora
document.getElementById('pixModal').addEventListener('click', function(e) { pixModal.addEventListener('click', e => {
if (e.target === this) { if (e.target === pixModal) closePixModal();
closePixModal();
}
}); });
// Permite gerar PIX ao pressionar Enter // Permite gerar PIX ao pressionar Enter
document.getElementById('pixValue').addEventListener('keypress', function(e) { pixValue.addEventListener('keypress', e => {
if (e.key === 'Enter') { if (e.key === 'Enter') generatePix();
generatePix();
}
}); });
</script> </script>
</body> </body>