otimizacoes de performance
Signed-off-by: Rodrigo Bertoldo de Sousa Martins <rodrigo.sousa.577@gmail.com>
This commit is contained in:
1 parent
f23b925a99
commit
685d37e3f6
2 files changed
+72
-120
No files matched your search
BIN
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
+72
-120
@@ -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);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Copia automaticamente na primeira vez
|
|
||||||
copyToClipboard(pixCode);
|
copyToClipboard(pixCode);
|
||||||
}
|
};
|
||||||
|
|
||||||
function buildPixCode(pixKey, merchantName, city, value, txid) {
|
const buildPixCode = (pixKey, merchantName, city, value, txid) => {
|
||||||
// Função auxiliar para criar campo EMV
|
const emvField = (id, value) => id + value.length.toString().padStart(2, '0') + value;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
function crc16(str) {
|
const 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>
|
||||||
|
|||||||
Reference in new issue
Block a user