${alert.status.charAt(0).toUpperCase() + alert.status.slice(1)}
$${stock.price.toFixed(2)}
(${changePercent.toFixed(2)}%)
`;
this.dom.marketPrices.appendChild(priceDiv);
}
},
showNotification(message) {
const notification = document.createElement('div');
notification.className = 'notification-toast bg-green-600 text-white font-semibold py-2 px-4 rounded-lg shadow-lg';
notification.textContent = message;
this.dom.notificationContainer.appendChild(notification);
setTimeout(() => notification.remove(), 5000);
},
getConditionText(condition) {
const map = { above: 'Price >', below: 'Price <', change_above: '% Change >', change_below: '% Change <' };
return map[condition] || condition;
},
generatePdf() {
if (this.alerts.length === 0) {
alert("No alerts to report.");
return;
}
const { jsPDF } = window.jspdf;
const pdf = new jsPDF({ unit: 'pt', format: 'a4' });
pdf.setFontSize(18);
pdf.text("Stock Alerts Report", 40, 60);
pdf.setFontSize(10);
pdf.text(`Date: ${new Date().toLocaleDateString()}`, 40, 75);
const tableData = this.alerts.map(alert => {
const value = alert.condition.startsWith('change') ? `${alert.value}%` : `$${alert.value.toFixed(2)}`;
const currentPrice = this.stockData[alert.ticker].price;
return [
alert.ticker,
this.getConditionText(alert.condition) + ' ' + value,
`$${currentPrice.toFixed(2)}`,
alert.status.charAt(0).toUpperCase() + alert.status.slice(1)
];
});
pdf.autoTable({
startY: 100,
head: [['Ticker', 'Condition', 'Current Price', 'Status']],
body: tableData,
headStyles: { fillColor: [37, 99, 235] }
});
pdf.save('Stock-Alerts-Report.pdf');
}
};
app.init();
});
