`;
}
function createConfigTableRow(item, type) {
let cells = '';
if (type === 'flight') {
cells = `
|
|
|
|
|
`;
} else if (type === 'fleet') {
cells = `
|
|
|
|
|
`;
}
return `${cells}
| `;
}
function addTableRow(tableId) {
const tableBody = document.querySelector(`#${tableId} tbody`);
const newRow = tableBody.insertRow();
const type = tableId.includes('flight') ? 'flight' : 'fleet';
const emptyItem = type === 'flight' ? {id:'', origin:'', destination:'', aircraft:'', status:'On Time'} : {tail:'', type:'', hours:'', location:'', status:'Active'};
newRow.innerHTML = createConfigTableRow(emptyItem, type);
newRow.querySelector('.delete-row-btn').addEventListener('click', (e) => e.target.closest('tr').remove());
}
function renderCharts() {
// ... (Chart rendering logic remains the same, but uses dashboardData.analytics) ...
const { analytics } = dashboardData;
const chartOptions = {
scales: { y: { beginAtZero: true, ticks: { color: '#94a3b8' }, grid: { color: '#475569' } }, x: { ticks: { color: '#94a3b8' }, grid: { color: '#334155' } } },
plugins: { legend: { labels: { color: '#cbd5e1' } } }
};
if (window.otpChartInstance) window.otpChartInstance.destroy();
if (window.delayChartInstance) window.delayChartInstance.destroy();
const otpCtx = document.getElementById('otpChart')?.getContext('2d');
if(otpCtx) window.otpChartInstance = new Chart(otpCtx, { type: 'line', data: { labels: analytics.otpByMonth.labels, datasets: [{ label: 'OTP %', data: analytics.otpByMonth.data, backgroundColor: 'rgba(59, 130, 246, 0.2)', borderColor: 'rgba(59, 130, 246, 1)', borderWidth: 2, tension: 0.3, fill: true }] }, options: chartOptions });
const delayCtx = document.getElementById('delayChart')?.getContext('2d');
if(delayCtx) window.delayChartInstance = new Chart(delayCtx, { type: 'doughnut', data: { labels: analytics.delayCauses.labels, datasets: [{ label: 'Delay Causes', data: analytics.delayCauses.data, backgroundColor: ['#f59e0b', '#ef4444', '#3b82f6', '#10b981', '#6366f1'], borderColor: '#1e293b', borderWidth: 3 }] }, options: { plugins: { legend: { position: 'bottom', labels: { color: '#cbd5e1' } } } } });
}
function filterFlights() {
const filter = document.getElementById('flight-search').value.toUpperCase();
const rows = document.querySelectorAll('#flight-table-body .flight-row');
rows.forEach(row => {
row.style.display = row.textContent.toUpperCase().includes(filter) ? "" : "none";
});
}
function navigateTabs(direction) {
const newIndex = currentTabIndex + direction;
if (newIndex >= 0 && newIndex < tabs.length) showTab(newIndex);
}
function updateNavButtons() {
prevTabBtn.disabled = currentTabIndex === 0;
nextTabBtn.disabled = currentTabIndex === tabs.length - 1;
}
function generatePDF() {
const { jsPDF } = window.jspdf;
const doc = new jsPDF();
const activeTab = tabs[currentTabIndex];
doc.setFontSize(18); doc.text('Airline Operations Dashboard Report', 14, 22);
doc.setFontSize(12); doc.text(activeTab.name, 14, 30);
let tableId, tableTitle;
if (activeTab.id === 'flight-status') {
tableId = '#flight-table-body';
tableTitle = 'Flight Status List';
} else if (activeTab.id === 'fleet-management') {
tableId = '#fleet-table';
tableTitle = 'Fleet Management List';
}
if (tableId) {
doc.autoTable({ html: tableId, startY: 40, theme: 'grid', headStyles: { fillColor: [51, 65, 85] } });
} else if (activeTab.id === 'global-overview') {
doc.autoTable({
startY: 40, theme: 'grid', headStyles: { fillColor: [51, 65, 85] },
body: Object.entries(dashboardData.kpis).map(([key, value]) => [key, value.toLocaleString()])
});
}
// PDF generation for other tabs can be expanded here.
doc.save(`Airline_Dashboard_${activeTab.name.replace(/\s/g, '_')}.pdf`);
}
// --- LET'S GO ---
init();
});