`).join('');
return `
Tracked IPOs
${ipoListHtml}
`;
};
// --- DATA & EVENT HANDLERS ---
window.updateIPOStatus = (id, newStatus) => {
const ipo = ipos.find(i => i.id === id);
if (ipo) ipo.status = newStatus;
renderChart(); // Just update chart, no need to re-render whole tab
};
window.startEditIPO = (id) => {
editingIPOId = id;
renderCurrentTab();
document.getElementById('ipo-form').scrollIntoView({ behavior: 'smooth' });
};
window.cancelEdit = () => {
editingIPOId = null;
renderCurrentTab();
};
window.deleteIPO = (id) => {
ipos = ipos.filter(i => i.id !== id);
if (editingIPOId === id) editingIPOId = null; // If deleting the one being edited
renderCurrentTab();
};
const handleFormSubmit = (event) => {
event.preventDefault();
const formData = new FormData(event.target);
const ipoData = Object.fromEntries(formData.entries());
// Convert numbers
ipoData.priceRangeLow = parseFloat(ipoData.priceRangeLow);
ipoData.priceRangeHigh = parseFloat(ipoData.priceRangeHigh);
if (editingIPOId) {
// Update existing IPO
const index = ipos.findIndex(i => i.id === editingIPOId);
ipos[index] = { ...ipos[index], ...ipoData };
} else {
// Add new IPO
ipoData.id = Date.now();
ipoData.status = 'Watching'; // Default status
ipos.push(ipoData);
}
editingIPOId = null;
renderCurrentTab();
};
// --- CHART & PDF ---
const renderChart = () => {
if (ipoChart) ipoChart.destroy();
const ctx = document.getElementById('ipoChart')?.getContext('2d');
if (!ctx) return;
const statusCounts = ipos.reduce((acc, ipo) => {
acc[ipo.status] = (acc[ipo.status] || 0) + 1;
return acc;
}, {});
ipoChart = new Chart(ctx, {
type: 'doughnut',
data: {
labels: Object.keys(statusCounts),
datasets: [{
data: Object.values(statusCounts),
backgroundColor: ['#6366f1', '#10b981', '#f59e0b'], // Indigo, Green, Amber
}]
},
options: { responsive: true, maintainAspectRatio: false, plugins: { title: { display: true, text: 'IPO Status Distribution' } } }
});
};
window.downloadPDF = () => {
const { jsPDF } = window.jspdf;
const doc = new jsPDF();
doc.setFontSize(20);
doc.text("IPO Tracker Report", doc.internal.pageSize.getWidth() / 2, 20, { align: 'center' });
const head = [['Company', 'Ticker', 'Exchange', 'IPO Date', 'Price Range ($)', 'Status']];
const body = ipos.map(ipo => [
ipo.companyName,
ipo.ticker,
ipo.exchange,
ipo.ipoDate,
`${ipo.priceRangeLow.toFixed(2)} - ${ipo.priceRangeHigh.toFixed(2)}`,
ipo.status
]);
doc.autoTable({ startY: 30, head: head, body: body, theme: 'striped', headStyles: { fillColor: [79, 70, 229] } });
doc.save('IPO-Tracker-Report.pdf');
};
// --- INITIALIZATION ---
DOM.nextBtn.addEventListener('click', () => switchTab(currentTab + 1));
DOM.prevBtn.addEventListener('click', () => switchTab(currentTab - 1));
DOM.tabButtons.forEach((btn, i) => btn.addEventListener('click', () => switchTab(i)));
renderCurrentTab();
updateNavButtons();
});