Overflights reporting and menu layout changes

This commit is contained in:
2025-12-19 05:28:17 -05:00
parent b46a88d471
commit 3ab9a6e04c
3 changed files with 190 additions and 42 deletions

View File

@@ -22,23 +22,32 @@
color: white;
padding: 0.5rem 2rem;
display: flex;
justify-content: space-between;
justify-content: center;
align-items: center;
gap: 2rem;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
.title {
order: 2;
flex: 1;
text-align: center;
}
.title h1 {
margin: 0;
font-size: 1.5rem;
}
.menu-buttons {
order: 1;
display: flex;
gap: 1rem;
align-items: center;
}
.top-bar .user-info {
order: 3;
font-size: 0.9rem;
opacity: 0.9;
display: flex;
@@ -352,14 +361,14 @@
</head>
<body>
<div class="top-bar">
<div class="title">
<h1>📊 PPR Reports</h1>
</div>
<div class="menu-buttons">
<button class="btn btn-secondary" onclick="window.location.href='admin'">
← Back to Admin
</button>
</div>
<div class="title">
<h1>📊 PPR Reports</h1>
</div>
<div class="user-info">
Logged in as: <span id="current-user">Loading...</span> |
<a href="#" onclick="logout()" style="color: white;">Logout</a>
@@ -431,7 +440,7 @@
<!-- Non-PPR Section -->
<div style="grid-column: 1/-1; padding-bottom: 1rem; border-bottom: 2px solid rgba(255,255,255,0.3);">
<div style="font-size: 0.95rem; font-weight: 600; margin-bottom: 0.6rem;">Non-PPR Movements</div>
<div style="display: grid; grid-template-columns: repeat(5, 1fr); gap: 1rem;">
<div style="display: grid; grid-template-columns: repeat(6, 1fr); gap: 1rem;">
<div class="summary-item" style="padding: 0.6rem;">
<div class="summary-item-label" style="font-size: 0.75rem; margin-bottom: 0.2rem;">Local Flights</div>
<div class="summary-item-value" style="font-size: 1.3rem;" id="local-flights-movements">0</div>
@@ -448,6 +457,10 @@
<div class="summary-item-label" style="font-size: 0.75rem; margin-bottom: 0.2rem;">Departures</div>
<div class="summary-item-value" style="font-size: 1.3rem;" id="non-ppr-departures">0</div>
</div>
<div class="summary-item" style="padding: 0.6rem;">
<div class="summary-item-label" style="font-size: 0.75rem; margin-bottom: 0.2rem;">Overflights</div>
<div class="summary-item-value" style="font-size: 1.3rem;" id="overflights-count">0</div>
</div>
<div class="summary-item" style="border-left-color: #ffd700; background: rgba(255,215,0,0.1); padding: 0.6rem;">
<div class="summary-item-label" style="font-weight: 600; font-size: 0.75rem; margin-bottom: 0.2rem;">Non-PPR Total</div>
<div class="summary-item-value" style="font-size: 1.3rem;" id="non-ppr-total">0</div>
@@ -551,8 +564,8 @@
<th>Callsign</th>
<th>From</th>
<th>To</th>
<th>ETA / ETD</th>
<th>Landed / Departed</th>
<th>ETA / ETD / Called</th>
<th>Landed / Departed / QSY</th>
<th>Circuits</th>
</tr>
</thead>
@@ -671,11 +684,12 @@
if (status) url += `&status=${status}`;
// Fetch all data in parallel
const [pprResponse, arrivalsResponse, departuresResponse, localFlightsResponse] = await Promise.all([
const [pprResponse, arrivalsResponse, departuresResponse, localFlightsResponse, overflightsResponse] = await Promise.all([
authenticatedFetch(url),
authenticatedFetch(`/api/v1/arrivals/?limit=10000${dateFrom ? `&date_from=${dateFrom}` : ''}${dateTo ? `&date_to=${dateTo}` : ''}`),
authenticatedFetch(`/api/v1/departures/?limit=10000${dateFrom ? `&date_from=${dateFrom}` : ''}${dateTo ? `&date_to=${dateTo}` : ''}`),
authenticatedFetch(`/api/v1/local-flights/?limit=10000${dateFrom ? `&date_from=${dateFrom}` : ''}${dateTo ? `&date_to=${dateTo}` : ''}`)
authenticatedFetch(`/api/v1/local-flights/?limit=10000${dateFrom ? `&date_from=${dateFrom}` : ''}${dateTo ? `&date_to=${dateTo}` : ''}`),
authenticatedFetch(`/api/v1/overflights/?limit=10000${dateFrom ? `&date_from=${dateFrom}` : ''}${dateTo ? `&date_to=${dateTo}` : ''}`)
]);
if (!pprResponse.ok) {
@@ -739,6 +753,20 @@
})));
}
if (overflightsResponse.ok) {
const overflights = await overflightsResponse.json();
otherFlights.push(...overflights.map(f => ({
...f,
flightType: 'OVERFLIGHT',
aircraft_type: f.type,
circuits: null,
timeField: f.call_dt,
fromField: f.departure_airfield,
toField: f.destination_airfield,
callsign: f.registration
})));
}
// Apply search filtering to other flights
if (search) {
const searchLower = search.toLowerCase();
@@ -816,6 +844,7 @@
});
// Other flights movements (excluding CANCELLED)
let overflightCount = 0;
otherFlights.filter(flight => flight.status !== 'CANCELLED').forEach(flight => {
if (flight.flightType === 'ARRIVAL') {
nonPprArrivals += 1;
@@ -828,17 +857,21 @@
// 2 movements (takeoff + landing) plus the circuit count
const circuits = flight.circuits || 0;
circuitsMovements += 2 + circuits;
} else if (flight.flightType === 'OVERFLIGHT') {
// 1 movement for each overflight (they're just talking to tower)
overflightCount += 1;
}
});
const pprTotal = pprArrivals + pprDepartures;
const nonPprTotal = localFlightsMovements + circuitsMovements + nonPprArrivals + nonPprDepartures;
const nonPprTotal = localFlightsMovements + circuitsMovements + nonPprArrivals + nonPprDepartures + overflightCount;
const grandTotal = pprTotal + nonPprTotal;
// Update the summary display
document.getElementById('ppr-arrivals').textContent = pprArrivals;
document.getElementById('ppr-departures').textContent = pprDepartures;
document.getElementById('ppr-total').textContent = pprTotal;
document.getElementById('overflights-count').textContent = overflightCount;
document.getElementById('local-flights-movements').textContent = localFlightsMovements;
document.getElementById('circuits-movements').textContent = circuitsMovements;
@@ -945,9 +978,18 @@
const from = flight.fromField || '-';
const to = flight.toField || '-';
const timeDisplay = flight.timeField ? formatDateTime(flight.timeField) : '-';
const actualDisplay = flight.flightType === 'ARRIVAL'
? (flight.landed_dt ? formatDateTime(flight.landed_dt) : '-')
: (flight.departed_dt ? formatDateTime(flight.departed_dt) : '-');
// Different display for different flight types
let actualDisplay = '-';
if (flight.flightType === 'ARRIVAL') {
actualDisplay = flight.landed_dt ? formatDateTime(flight.landed_dt) : '-';
} else if (flight.flightType === 'OVERFLIGHT') {
// For overflights, show qsy_dt (frequency change time)
actualDisplay = flight.qsy_dt ? formatDateTime(flight.qsy_dt) : '-';
} else {
actualDisplay = flight.departed_dt ? formatDateTime(flight.departed_dt) : '-';
}
const status = flight.status || (flight.flightType === 'CIRCUIT' ? 'COMPLETED' : 'PENDING');
const circuits = (flight.flightType === 'CIRCUIT' || flight.flightType === 'LOCAL') ? (flight.circuits > 0 ? flight.circuits : '-') : '-';