`;
attachDashboardListeners();
updatePaymentDetails();
};
const renderConfig = () => {
const configContent = document.getElementById('content-gateway-configuration');
if (!configContent) return;
const cryptoRows = appData.cryptos.map((crypto, index) => `
`).join('');
configContent.innerHTML = `
`;
document.getElementById('save-config-btn').addEventListener('click', handleConfigUpdate);
};
const renderLog = () => {
const logContent = document.getElementById('content-transaction-log');
if (!logContent) return;
let logRows = 'No transactions yet. ';
if (appData.transactions.length > 0) {
logRows = [...appData.transactions].reverse().map(tx => `
${tx.id}
${tx.date.toLocaleString()}
${formatCurrency(tx.usdAmount)}
${tx.cryptoSymbol}
${formatCrypto(tx.cryptoTotal)}
${tx.status}
`).join('');
}
logContent.innerHTML = `
`;
document.getElementById('download-pdf-btn').addEventListener('click', generatePdf);
};
const attachDashboardListeners = () => {
document.getElementById('usd-amount').addEventListener('input', updatePaymentDetails);
document.getElementById('crypto-select').addEventListener('change', updatePaymentDetails);
document.getElementById('copy-address-btn').addEventListener('click', copyWalletAddress);
document.getElementById('simulate-payment-btn').addEventListener('click', simulatePayment);
document.getElementById('new-payment-btn').addEventListener('click', () => {
document.getElementById('payment-widget').classList.remove('hidden');
document.getElementById('success-modal').classList.add('hidden');
document.getElementById('usd-amount').value = "100.00";
updatePaymentDetails();
});
};
const handleConfigUpdate = () => {
appData.transactionFeePercent = parseFloat(document.getElementById('transaction-fee').value) || 0;
const newCryptos = [];
document.querySelectorAll('#config-form .grid.grid-cols-12').forEach(row => {
const index = row.querySelector('input').dataset.index;
if (index) {
newCryptos.push({
...appData.cryptos[index],
enabled: row.querySelector(`[data-index="${index}"][data-field="enabled"]`).checked,
name: row.querySelector(`[data-index="${index}"][data-field="name"]`).value,
symbol: row.querySelector(`[data-index="${index}"][data-field="symbol"]`).value,
walletAddress: row.querySelector(`[data-index="${index}"][data-field="walletAddress"]`).value,
});
}
});
appData.cryptos = newCryptos;
alert('Configuration saved!');
renderDashboard();
};
const updatePaymentDetails = () => {
const usdAmount = parseFloat(document.getElementById('usd-amount').value) || 0;
const selectedSymbol = document.getElementById('crypto-select').value;
const crypto = appData.cryptos.find(c => c.symbol === selectedSymbol);
if (!crypto || !crypto.rate) return;
const cryptoAmount = usdAmount / crypto.rate;
const fee = cryptoAmount * (appData.transactionFeePercent / 100);
const total = cryptoAmount + fee;
document.getElementById('crypto-amount-display').textContent = `${formatCrypto(cryptoAmount)} ${crypto.symbol}`;
document.getElementById('crypto-fee-display').textContent = `${formatCrypto(fee)} ${crypto.symbol}`;
document.getElementById('crypto-total-display').textContent = `${formatCrypto(total)} ${crypto.symbol}`;
document.getElementById('wallet-address-display').value = crypto.walletAddress;
generateQrCode(crypto.walletAddress, total, crypto.name.toLowerCase());
};
const generateQrCode = (address, amount, cryptoName) => {
const container = document.getElementById('qrcode-container');
container.innerHTML = '';
if (!address) {
container.innerHTML = 'Wallet address not configured.';
return;
}
const uri = `${cryptoName}:${address}?amount=${amount.toFixed(8)}`;
qrCodeInstance = new QRCode(container, {
text: uri,
width: 200,
height: 200,
colorDark: "#000000",
colorLight: "#ffffff",
correctLevel: QRCode.CorrectLevel.H
});
};
const copyWalletAddress = () => {
const addressInput = document.getElementById('wallet-address-display');
addressInput.select();
document.execCommand('copy');
alert('Address copied to clipboard!');
};
const simulatePayment = () => {
const usdAmount = parseFloat(document.getElementById('usd-amount').value) || 0;
const selectedSymbol = document.getElementById('crypto-select').value;
const crypto = appData.cryptos.find(c => c.symbol === selectedSymbol);
if (!crypto || !crypto.rate || usdAmount <= 0) {
alert("Invalid payment details.");
return;
}
const cryptoAmount = usdAmount / crypto.rate;
const fee = cryptoAmount * (appData.transactionFeePercent / 100);
const total = cryptoAmount + fee;
appData.transactions.push({
id: 'TX' + Date.now().toString().slice(-8),
date: new Date(),
usdAmount: usdAmount,
cryptoSymbol: selectedSymbol,
cryptoTotal: total,
status: 'Completed'
});
document.getElementById('payment-widget').classList.add('hidden');
document.getElementById('success-modal').classList.remove('hidden');
renderLog(); // Re-render log in the background
};
const generatePdf = () => {
loadingOverlay.style.display = 'flex';
const { jsPDF } = window.jspdf;
const pdfContent = document.getElementById('pdf-content-area');
const pdfHeader = document.getElementById('pdf-header');
document.getElementById('pdf-generated-date').textContent = new Date().toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' });
pdfHeader.classList.remove('hidden');
html2canvas(pdfContent, { scale: 2, useCORS: true, logging: false })
.then(canvas => {
pdfHeader.classList.add('hidden');
const imgData = canvas.toDataURL('image/jpeg', 0.95);
const pdf = new jsPDF({ orientation: 'landscape', unit: 'px', format: 'a4' });
const pdfWidth = pdf.internal.pageSize.getWidth();
const imgProps = pdf.getImageProperties(imgData);
const imgHeight = (imgProps.height * pdfWidth) / imgProps.width;
pdf.addImage(imgData, 'JPEG', 0, 0, pdfWidth, imgHeight);
pdf.save('Crypto-Transaction-Report.pdf');
loadingOverlay.style.display = 'none';
}).catch(err => {
console.error("PDF generation failed:", err);
pdfHeader.classList.add('hidden');
loadingOverlay.style.display = 'none';
alert('An error occurred generating the PDF.');
});
};
// --- TAB NAVIGATION & INITIALIZATION ---
const switchTab = (tabIndex) => {
activeTabIndex = tabIndex;
document.querySelectorAll('.tab-btn').forEach((btn, i) => btn.classList.toggle('active', i === tabIndex));
document.querySelectorAll('.tab-content').forEach((content, i) => content.classList.toggle('hidden', i !== tabIndex));
updateNavButtons();
};
const updateNavButtons = () => {
prevTabBtn.disabled = activeTabIndex === 0;
nextTabBtn.disabled = activeTabIndex === tabIdentifiers.length - 1;
};
const initializeUI = () => {
const tabs = [
{ name: 'Payment Dashboard', id: 'payment-dashboard' },
{ name: 'Gateway Configuration', id: 'gateway-configuration' },
{ name: 'Transaction Log', id: 'transaction-log' }
];
tabIdentifiers = tabs.map(t => t.id);
tabsContainer.innerHTML = tabs.map(tab => ``).join('');
mainContent.innerHTML = tabs.map(tab => ``).join('');
tabs.forEach((tab, index) => {
document.getElementById(`tab-${tab.id}`).addEventListener('click', () => switchTab(index));
});
renderDashboard();
renderConfig();
renderLog();
switchTab(0);
lucide.createIcons();
};
initializeUI();
prevTabBtn.addEventListener('click', () => { if (activeTabIndex > 0) switchTab(activeTabIndex - 1); });
nextTabBtn.addEventListener('click', () => { if (activeTabIndex < tabIdentifiers.length - 1) switchTab(activeTabIndex + 1); });
});
Transaction Summary Report
Generated on:
Transaction History
| TX ID | Date | Amount | Crypto | Crypto Total | Status |
|---|
