Public display improvements WIP
This commit is contained in:
116
web/index.html
116
web/index.html
@@ -62,6 +62,9 @@
|
||||
padding: 12px;
|
||||
text-align: left;
|
||||
border: 1px solid #ccc;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
th {
|
||||
@@ -134,7 +137,7 @@
|
||||
<body>
|
||||
<header>
|
||||
<img src="assets/logo.png" alt="EGFH Logo" class="left-image">
|
||||
<h1>Arrivals/Departures Information</h1>
|
||||
<h1>Flight Information</h1>
|
||||
<img src="assets/flightImg.png" alt="EGFH Logo" class="right-image">
|
||||
</header>
|
||||
|
||||
@@ -145,15 +148,14 @@
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Registration</th>
|
||||
<th>Aircraft Type</th>
|
||||
<th>From</th>
|
||||
<th>Due</th>
|
||||
<th style="width: 25%;">Aircraft</th>
|
||||
<th style="width: 60%;">From</th>
|
||||
<th style="width: 15%;">Due</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="arrivals-tbody">
|
||||
<tr>
|
||||
<td colspan="4" class="loading">Loading arrivals...</td>
|
||||
<td colspan="3" class="loading">Loading arrivals...</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -165,15 +167,14 @@
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Registration</th>
|
||||
<th>Aircraft Type</th>
|
||||
<th>To</th>
|
||||
<th>Due</th>
|
||||
<th style="width: 25%;">Aircraft</th>
|
||||
<th style="width: 60%;">To</th>
|
||||
<th style="width: 15%;">Due</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="departures-tbody">
|
||||
<tr>
|
||||
<td colspan="4" class="loading">Loading departures...</td>
|
||||
<td colspan="3" class="loading">Loading departures...</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -191,6 +192,27 @@
|
||||
|
||||
<script>
|
||||
let wsConnection = null;
|
||||
|
||||
// ICAO code to airport name cache
|
||||
const airportNameCache = {};
|
||||
|
||||
async function getAirportName(code) {
|
||||
if (!code || code.length !== 4 || !/^[A-Z]{4}$/.test(code)) return code;
|
||||
if (airportNameCache[code]) return airportNameCache[code];
|
||||
try {
|
||||
const resp = await fetch(`/api/v1/airport/public/lookup/${code}`);
|
||||
if (resp.ok) {
|
||||
const data = await resp.json();
|
||||
if (data && data.length && data[0].name) {
|
||||
airportNameCache[code] = data[0].name;
|
||||
return data[0].name;
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error looking up airport:', error);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
// WebSocket connection for real-time updates
|
||||
function connectWebSocket() {
|
||||
@@ -276,22 +298,38 @@
|
||||
const arrivals = await response.json();
|
||||
|
||||
if (arrivals.length === 0) {
|
||||
tbody.innerHTML = '<tr><td colspan="4">No arrivals found.</td></tr>';
|
||||
tbody.innerHTML = '<tr><td colspan="3">No arrivals found.</td></tr>';
|
||||
return;
|
||||
}
|
||||
|
||||
tbody.innerHTML = arrivals.map(arrival => `
|
||||
<tr>
|
||||
<td>${escapeHtml(arrival.ac_reg || '')}</td>
|
||||
<td>${escapeHtml(arrival.ac_type || '')}</td>
|
||||
<td>${escapeHtml(arrival.in_from || '')}</td>
|
||||
<td>${convertToLocalTime(arrival.eta)}</td>
|
||||
</tr>
|
||||
`).join('');
|
||||
// Build rows asynchronously to lookup airport names
|
||||
const rows = await Promise.all(arrivals.map(async (arrival) => {
|
||||
const aircraftDisplay = `${escapeHtml(arrival.ac_reg || '')} <span style="font-size: 0.8em; color: #666;">(${escapeHtml(arrival.ac_type || '')})</span>`;
|
||||
const fromDisplay = await getAirportName(arrival.in_from || '');
|
||||
|
||||
// Show landed time if available, otherwise ETA
|
||||
let timeDisplay;
|
||||
if (arrival.status === 'LANDED' && arrival.landed_dt) {
|
||||
const time = convertToLocalTime(arrival.landed_dt);
|
||||
timeDisplay = `<div style="display: flex; align-items: center; gap: 8px;"><span style="color: #27ae60; font-weight: bold;">${time}</span><span style="font-size: 0.7em; background: #27ae60; color: white; padding: 2px 4px; border-radius: 3px; white-space: nowrap;">LANDED</span></div>`;
|
||||
} else {
|
||||
timeDisplay = convertToLocalTime(arrival.eta);
|
||||
}
|
||||
|
||||
return `
|
||||
<tr>
|
||||
<td>${aircraftDisplay}</td>
|
||||
<td>${escapeHtml(fromDisplay)}</td>
|
||||
<td>${timeDisplay}</td>
|
||||
</tr>
|
||||
`;
|
||||
}));
|
||||
|
||||
tbody.innerHTML = rows.join('');
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error loading arrivals:', error);
|
||||
tbody.innerHTML = '<tr><td colspan="4" class="error">Error loading arrivals</td></tr>';
|
||||
tbody.innerHTML = '<tr><td colspan="3" class="error">Error loading arrivals</td></tr>';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -309,22 +347,38 @@
|
||||
const departures = await response.json();
|
||||
|
||||
if (departures.length === 0) {
|
||||
tbody.innerHTML = '<tr><td colspan="4">No departures found.</td></tr>';
|
||||
tbody.innerHTML = '<tr><td colspan="3">No departures found.</td></tr>';
|
||||
return;
|
||||
}
|
||||
|
||||
tbody.innerHTML = departures.map(departure => `
|
||||
<tr>
|
||||
<td>${escapeHtml(departure.ac_reg || '')}</td>
|
||||
<td>${escapeHtml(departure.ac_type || '')}</td>
|
||||
<td>${escapeHtml(departure.out_to || '')}</td>
|
||||
<td>${convertToLocalTime(departure.etd)}</td>
|
||||
</tr>
|
||||
`).join('');
|
||||
// Build rows asynchronously to lookup airport names
|
||||
const rows = await Promise.all(departures.map(async (departure) => {
|
||||
const aircraftDisplay = `${escapeHtml(departure.ac_reg || '')} <span style="font-size: 0.8em; color: #666;">(${escapeHtml(departure.ac_type || '')})</span>`;
|
||||
const toDisplay = await getAirportName(departure.out_to || '');
|
||||
|
||||
// Show departed time if available, otherwise ETD
|
||||
let timeDisplay;
|
||||
if (departure.status === 'DEPARTED' && departure.departed_dt) {
|
||||
const time = convertToLocalTime(departure.departed_dt);
|
||||
timeDisplay = `<div style="display: flex; align-items: center; gap: 8px;"><span style="color: #3498db; font-weight: bold;">${time}</span><span style="font-size: 0.7em; background: #3498db; color: white; padding: 2px 4px; border-radius: 3px; white-space: nowrap;">DEPARTED</span></div>`;
|
||||
} else {
|
||||
timeDisplay = convertToLocalTime(departure.etd);
|
||||
}
|
||||
|
||||
return `
|
||||
<tr>
|
||||
<td>${aircraftDisplay}</td>
|
||||
<td>${escapeHtml(toDisplay)}</td>
|
||||
<td>${timeDisplay}</td>
|
||||
</tr>
|
||||
`;
|
||||
}));
|
||||
|
||||
tbody.innerHTML = rows.join('');
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error loading departures:', error);
|
||||
tbody.innerHTML = '<tr><td colspan="4" class="error">Error loading departures</td></tr>';
|
||||
tbody.innerHTML = '<tr><td colspan="3" class="error">Error loading departures</td></tr>';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user