${isSend ? '-' : '+'} ${formatCurrency(tx.amount * (walletData.assets.find(a=>a.name===tx.asset)?.price || 0))}
Fee: ${formatCurrency(tx.gasFee)}
`;
elements.lists.transactions.appendChild(el);
});
};
const updateDataFromForm = () => {
const newAssets = [];
document.querySelectorAll('#asset-inputs-container tr').forEach(row => {
newAssets.push({
id: parseInt(row.dataset.id),
name: row.querySelector('.asset-name-input').value.toUpperCase() || 'N/A',
quantity: parseFloat(row.querySelector('.asset-quantity-input').value) || 0,
price: parseFloat(row.querySelector('.asset-price-input').value) || 0,
change24h: parseFloat(row.querySelector('.asset-change-input').value) || 0,
});
});
walletData.assets = newAssets;
const newTransactions = [];
document.querySelectorAll('#transaction-inputs-container tr').forEach(row => {
newTransactions.push({
id: parseInt(row.dataset.id),
type: row.querySelector('.tx-type-select').value,
asset: row.querySelector('.tx-asset-input').value.toUpperCase() || 'N/A',
amount: parseFloat(row.querySelector('.tx-amount-input').value) || 0,
gasFee: parseFloat(row.querySelector('.tx-gas-input').value) || 0,
});
});
walletData.transactions = newTransactions;
updateKpiCards();
renderAllCharts();
};
const createDynamicRow = (container, item, type) => {
const row = document.createElement('tr');
row.dataset.id = item.id;
if (type === 'asset') {
row.innerHTML = `
|
|
|
|
| `;
} else { // transaction
row.innerHTML = `
|
|
|
|
| `;
}
container.appendChild(row);
row.querySelector('.remove-btn').addEventListener('click', () => { row.remove(); updateDataFromForm(); });
row.querySelectorAll('input, select').forEach(input => input.addEventListener('change', updateDataFromForm));
};
const populateConfigForm = () => {
elements.config.assetContainer.innerHTML = '';
walletData.assets.forEach(a => createDynamicRow(elements.config.assetContainer, a, 'asset'));
elements.config.transactionContainer.innerHTML = '';
walletData.transactions.forEach(t => createDynamicRow(elements.config.transactionContainer, t, 'transaction'));
};
const downloadPdf = async () => {
const { jsPDF } = window.jspdf;
const printableArea = elements.pdf.printableArea;
const buttonContainer = document.getElementById('pdf-button-container');
buttonContainer.classList.add('pdf-hide');
const canvas = await html2canvas(printableArea, { scale: 2, useCORS: true, logging: false });
buttonContainer.classList.remove('pdf-hide');
const imgData = canvas.toDataURL('image/png');
const pdf = new jsPDF({ orientation: 'portrait', unit: 'px', format: [canvas.width, canvas.height] });
pdf.addImage(imgData, 'PNG', 0, 0, canvas.width, canvas.height);
pdf.save('Crypto-Wallet-Dashboard.pdf');
};
// --- 4. EVENT LISTENERS ---
elements.tabs.dashboardBtn.addEventListener('click', () => switchTab('dashboard'));
elements.tabs.configBtn.addEventListener('click', () => switchTab('config'));
elements.nav.nextBtn.addEventListener('click', () => switchTab('config'));
elements.nav.prevBtn.addEventListener('click', () => switchTab('dashboard'));
elements.pdf.downloadBtn.addEventListener('click', downloadPdf);
elements.config.addAssetBtn.addEventListener('click', () => {
const newId = (walletData.assets.reduce((max, a) => Math.max(a.id, max), 0) || 0) + 1;
const newItem = { id: newId, name: 'NEW', quantity: 0, price: 0, change24h: 0 };
walletData.assets.push(newItem);
createDynamicRow(elements.config.assetContainer, newItem, 'asset');
});
elements.config.addTransactionBtn.addEventListener('click', () => {
const newId = (walletData.transactions.reduce((max, t) => Math.max(t.id, max), 0) || 0) + 1;
const newItem = { id: newId, type: 'Send', asset: 'NEW', amount: 0, gasFee: 0 };
walletData.transactions.push(newItem);
createDynamicRow(elements.config.transactionContainer, newItem, 'transaction');
});
// --- 5. INITIALIZATION ---
updateKpiCards();
renderAllCharts();
populateConfigForm();
});