Train Ticket Price Tracker

Train Ticket Price Tracker

Find and track train ticket prices for your next journey.

${train.name}

${train.departure} → ${train.arrival} (${train.duration})

$${train.price.toFixed(2)}

`; trainList.appendChild(trainEl); createSparkline(train); }); } function createSparkline(train) { const ctx = document.getElementById(`sparkline-${train.id}`).getContext('2d'); new Chart(ctx, { type: 'line', data: { labels: Array(30).fill(''), datasets: [{ data: train.history, borderColor: train.history[29] > train.history[0] ? '#ef4444' : '#22c55e', borderWidth: 2, pointRadius: 0, }] }, options: { plugins: { legend: { display: false } }, scales: { x: { display: false }, y: { display: false } } } }); } trainList.addEventListener('click', (e) => { if (e.target.classList.contains('track-btn')) { const trainId = parseInt(e.target.dataset.id); openTrackerModal(trainId); } }); function openTrackerModal(trainId) { const train = trainData.find(t => t.id === trainId); modalContent.innerHTML = `

${train.name}

Price History & Alerts

Set Price Alert

Get notified if the price drops below your target.

`; trackerModal.classList.remove('hidden'); createPriceHistoryChart(train); document.getElementById('close-modal-btn').addEventListener('click', () => trackerModal.classList.add('hidden')); document.getElementById('set-alert-btn').addEventListener('click', setPriceAlert); document.getElementById('pdf-download-btn').addEventListener('click', generatePdf); } function createPriceHistoryChart(train) { const ctx = document.getElementById('price-history-chart').getContext('2d'); if(priceHistoryChart) priceHistoryChart.destroy(); priceHistoryChart = new Chart(ctx, { type: 'line', data: { labels: Array.from({length: 30}, (_, i) => `Day ${i + 1}`), datasets: [{ label: 'Price ($)', data: train.history, borderColor: '#4f46e5', backgroundColor: 'rgba(79, 70, 229, 0.1)', fill: true, tension: 0.3 }] }, options: { responsive: true, maintainAspectRatio: false } }); } function setPriceAlert(e) { const trainId = parseInt(e.target.dataset.id); const targetPrice = parseFloat(document.getElementById('alert-price').value); if (targetPrice > 0) { priceAlerts[trainId] = { target: targetPrice, name: trainData.find(t=>t.id===trainId).name }; alert('Price alert set for ' + priceAlerts[trainId].name); } } function simulatePriceChanges() { trainData = trainData.map(train => { const change = (Math.random() - 0.5) * 5; train.price = Math.max(50, train.price + change); train.history.shift(); train.history.push(train.price); return train; }); if (!resultsContainer.classList.contains('hidden')) { displayTrains(); } checkAlerts(); } function checkAlerts() { for (const id in priceAlerts) { const train = trainData.find(t => t.id == id); if (train && train.price <= priceAlerts[id].target) { document.getElementById('alert-text').textContent = `Price for ${priceAlerts[id].name} dropped to $${train.price.toFixed(2)}!`; alertNotification.classList.add('show'); delete priceAlerts[id]; // One-time alert setTimeout(() => alertNotification.classList.remove('show'), 5000); } } } function generatePdf() { const { jsPDF } = jspdf; const pdf = new jsPDF(); const content = document.getElementById('pdf-content'); html2canvas(content, {scale: 2}).then(canvas => { const imgData = canvas.toDataURL('image/png'); const { width, height } = pdf.internal.pageSize; const imgHeight = canvas.height * width / canvas.width; pdf.addImage(imgData, 'PNG', 0, 0, width, imgHeight); pdf.save('train-price-report.pdf'); }); } setInterval(simulatePriceChanges, 5000); // Simulate price changes every 5 seconds });
Scroll to Top