Booking form fixes
This commit is contained in:
@@ -0,0 +1,11 @@
|
|||||||
|
TODO
|
||||||
|
|
||||||
|
Implement mark's 'tick off the PPRs' in the old admin screen
|
||||||
|
|
||||||
|
Define schema for 'movements' table. We generate movement records as they happen so as not to reply on maths
|
||||||
|
|
||||||
|
Flow to create an arrival and maybe departure from a PPR. Perhaps we need a correlation column somewhere
|
||||||
|
|
||||||
|
Ability to add a position report to a strip
|
||||||
|
|
||||||
|
Improve journaling
|
||||||
+2
-2
@@ -76,11 +76,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.aircraft-item.departure {
|
.aircraft-item.departure {
|
||||||
background-color: #ffffcc; /* light yellow */
|
background-color: #ccccff; /* light blue */
|
||||||
}
|
}
|
||||||
|
|
||||||
.aircraft-item.inbound {
|
.aircraft-item.inbound {
|
||||||
background-color: #ccccff; /* light blue */
|
background-color: #ffffcc; /* light yellow */
|
||||||
}
|
}
|
||||||
|
|
||||||
.aircraft-item.overflight {
|
.aircraft-item.overflight {
|
||||||
|
|||||||
+207
-67
@@ -102,11 +102,8 @@
|
|||||||
font-family: inherit;
|
font-family: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type="time"],
|
|
||||||
input[type="number"] {
|
input[type="number"] {
|
||||||
padding: 12px 8px;
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
min-width: 80px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
input:focus, select:focus, textarea:focus {
|
input:focus, select:focus, textarea:focus {
|
||||||
@@ -198,6 +195,65 @@
|
|||||||
padding: 20px;
|
padding: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.modal-overlay {
|
||||||
|
display: none;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
z-index: 1000;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-overlay.active {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal {
|
||||||
|
background: white;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 30px;
|
||||||
|
max-width: 400px;
|
||||||
|
text-align: center;
|
||||||
|
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-icon {
|
||||||
|
font-size: 48px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal h2 {
|
||||||
|
color: #27ae60;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal p {
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-button {
|
||||||
|
background: #27ae60;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 12px 30px;
|
||||||
|
border-radius: 6px;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-button:hover {
|
||||||
|
background: #229954;
|
||||||
|
}
|
||||||
|
|
||||||
.spinner {
|
.spinner {
|
||||||
border: 4px solid #f3f3f3;
|
border: 4px solid #f3f3f3;
|
||||||
border-top: 4px solid #3498db;
|
border-top: 4px solid #3498db;
|
||||||
@@ -372,6 +428,15 @@
|
|||||||
<div id="successMessage" class="success-message"></div>
|
<div id="successMessage" class="success-message"></div>
|
||||||
<div id="errorMessage" class="error-message"></div>
|
<div id="errorMessage" class="error-message"></div>
|
||||||
|
|
||||||
|
<div id="successModal" class="modal-overlay">
|
||||||
|
<div class="modal">
|
||||||
|
<div class="modal-icon">✅</div>
|
||||||
|
<h2>Booking Submitted!</h2>
|
||||||
|
<p id="modalMessage"></p>
|
||||||
|
<button class="modal-button" onclick="closeSuccessModal()">Done</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="info-box">
|
<div class="info-box">
|
||||||
Booking out really helps our volunteers in the tower, thank you!
|
Booking out really helps our volunteers in the tower, thank you!
|
||||||
</div>
|
</div>
|
||||||
@@ -390,35 +455,37 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form id="localFlightForm" onsubmit="handleSubmit(event, 'local')">
|
<form id="localFlightForm" onsubmit="handleSubmit(event, 'local')">
|
||||||
|
<div class="form-row">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="localReg">Aircraft Registration <span class="required">*</span></label>
|
<label for="localReg">Aircraft Registration <span class="required">*</span></label>
|
||||||
<input type="text" id="localReg" name="registration" placeholder="e.g gbamc" required oninput="handleAircraftLookup(this.value, 'local')">
|
<input type="text" id="localReg" name="registration" placeholder="e.g gbamc" required oninput="handleAircraftLookup(this.value, 'local')">
|
||||||
<div id="localReg-lookup-results" class="aircraft-lookup-results"></div>
|
<div id="localReg-lookup-results" class="aircraft-lookup-results"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-row">
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="localType">Aircraft Type</label>
|
<label for="localType">Aircraft Type</label>
|
||||||
<input type="text" id="localType" name="type" placeholder="e.g., Cessna 172">
|
<input type="text" id="localType" name="type" placeholder="e.g., Cessna 172">
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-row">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="localPOB">POB <span class="required">*</span></label>
|
||||||
|
<input type="number" id="localPOB" name="pob" value="1" min="1" required>
|
||||||
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="localCallsign">Callsign</label>
|
<label for="localCallsign">Callsign</label>
|
||||||
<input type="text" id="localCallsign" name="callsign" placeholder="Optional">
|
<input type="text" id="localCallsign" name="callsign" placeholder="Optional">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-row-3col">
|
<div class="form-row">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="localPOB">POB <span class="required">*</span></label>
|
<label for="localETD">ETD</label>
|
||||||
<input type="number" id="localPOB" name="pob" value="1" min="1" required>
|
<input type="text" id="localETD" name="etd" placeholder="HH:MM" pattern="([0-9]{2}:[0-9]{2}|[0-9]{4})" inputmode="decimal" oninput="formatTimeInput(this)">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="localDuration">Duration</label>
|
<label for="localDuration">Duration</label>
|
||||||
<input type="number" id="localDuration" name="duration" value="45" min="5">
|
<input type="number" id="localDuration" name="duration" value="45" min="5" inputmode="numeric">
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="localETD">ETD</label>
|
|
||||||
<input type="time" id="localETD" name="etd">
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -439,35 +506,37 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form id="circuitForm" onsubmit="handleSubmit(event, 'circuits')">
|
<form id="circuitForm" onsubmit="handleSubmit(event, 'circuits')">
|
||||||
|
<div class="form-row">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="circuitReg">Aircraft Registration <span class="required">*</span></label>
|
<label for="circuitReg">Aircraft Registration <span class="required">*</span></label>
|
||||||
<input type="text" id="circuitReg" name="registration" placeholder="e.g., G-BAMC" required oninput="handleAircraftLookup(this.value, 'circuits')">
|
<input type="text" id="circuitReg" name="registration" placeholder="e.g., G-BAMC" required oninput="handleAircraftLookup(this.value, 'circuits')">
|
||||||
<div id="circuitReg-lookup-results" class="aircraft-lookup-results"></div>
|
<div id="circuitReg-lookup-results" class="aircraft-lookup-results"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-row">
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="circuitType">Aircraft Type</label>
|
<label for="circuitType">Aircraft Type</label>
|
||||||
<input type="text" id="circuitType" name="type" placeholder="e.g., Cessna 172">
|
<input type="text" id="circuitType" name="type" placeholder="e.g., Cessna 172">
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-row">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="circuitPOB">POB <span class="required">*</span></label>
|
||||||
|
<input type="number" id="circuitPOB" name="pob" value="1" min="1" required>
|
||||||
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="circuitCallsign">Callsign</label>
|
<label for="circuitCallsign">Callsign</label>
|
||||||
<input type="text" id="circuitCallsign" name="callsign" placeholder="Optional">
|
<input type="text" id="circuitCallsign" name="callsign" placeholder="Optional">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-row-3col">
|
<div class="form-row">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="circuitPOB">POB <span class="required">*</span></label>
|
<label for="circuitETD">ETD</label>
|
||||||
<input type="number" id="circuitPOB" name="pob" value="1" min="1" required>
|
<input type="text" id="circuitETD" name="etd" placeholder="HH:MM" pattern="([0-9]{2}:[0-9]{2}|[0-9]{4})" inputmode="decimal" oninput="formatTimeInput(this)">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="circuitDuration">Duration</label>
|
<label for="circuitDuration">Duration</label>
|
||||||
<input type="number" id="circuitDuration" name="duration" value="30" min="5">
|
<input type="number" id="circuitDuration" name="duration" value="30" min="5" inputmode="numeric">
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="circuitETD">ETD</label>
|
|
||||||
<input type="time" id="circuitETD" name="etd">
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -488,35 +557,37 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form id="departureForm" onsubmit="handleSubmit(event, 'departure')">
|
<form id="departureForm" onsubmit="handleSubmit(event, 'departure')">
|
||||||
|
<div class="form-row">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="depReg">Aircraft Registration <span class="required">*</span></label>
|
<label for="depReg">Aircraft Registration <span class="required">*</span></label>
|
||||||
<input type="text" id="depReg" name="registration" placeholder="e.g., N12345" required oninput="handleAircraftLookup(this.value, 'departure')">
|
<input type="text" id="depReg" name="registration" placeholder="e.g., N12345" required oninput="handleAircraftLookup(this.value, 'departure')">
|
||||||
<div id="depReg-lookup-results" class="aircraft-lookup-results"></div>
|
<div id="depReg-lookup-results" class="aircraft-lookup-results"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-row">
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="depType">Aircraft Type</label>
|
<label for="depType">Aircraft Type</label>
|
||||||
<input type="text" id="depType" name="type" placeholder="e.g., Cessna 172">
|
<input type="text" id="depType" name="type" placeholder="e.g., Cessna 172">
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-row">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="depPOB">Persons on Board <span class="required">*</span></label>
|
||||||
|
<input type="number" id="depPOB" name="pob" value="1" min="1" required>
|
||||||
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="depCallsign">Callsign</label>
|
<label for="depCallsign">Callsign</label>
|
||||||
<input type="text" id="depCallsign" name="callsign" placeholder="Optional">
|
<input type="text" id="depCallsign" name="callsign" placeholder="Optional">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-row-3col">
|
<div class="form-row">
|
||||||
<div class="form-group">
|
|
||||||
<label for="depPOB">Persons on Board <span class="required">*</span></label>
|
|
||||||
<input type="number" id="depPOB" name="pob" value="1" min="1" required>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="depTo">Destination (ICAO) <span class="required">*</span></label>
|
<label for="depTo">Destination (ICAO) <span class="required">*</span></label>
|
||||||
<input type="text" id="depTo" name="out_to" placeholder="e.g., KJFK" required oninput="handleAirportLookup(this.value, 'depTo')">
|
<input type="text" id="depTo" name="out_to" placeholder="e.g., KJFK" required oninput="handleAirportLookup(this.value, 'depTo')">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="depETD">Takeoff Time</label>
|
<label for="depETD">Takeoff Time</label>
|
||||||
<input type="time" id="depETD" name="etd">
|
<input type="text" id="depETD" name="etd" placeholder="HH:MM" pattern="([0-9]{2}:[0-9]{2}|[0-9]{4})" inputmode="decimal" oninput="formatTimeInput(this)">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="depTo-lookup-results" class="airport-lookup-results"></div>
|
<div id="depTo-lookup-results" class="airport-lookup-results"></div>
|
||||||
@@ -540,35 +611,37 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form id="arrivalForm" onsubmit="handleSubmit(event, 'arrival')">
|
<form id="arrivalForm" onsubmit="handleSubmit(event, 'arrival')">
|
||||||
|
<div class="form-row">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="arrReg">Aircraft Registration <span class="required">*</span></label>
|
<label for="arrReg">Aircraft Registration <span class="required">*</span></label>
|
||||||
<input type="text" id="arrReg" name="registration" placeholder="e.g., N12345" required oninput="handleAircraftLookup(this.value, 'arrival')">
|
<input type="text" id="arrReg" name="registration" placeholder="e.g., N12345" required oninput="handleAircraftLookup(this.value, 'arrival')">
|
||||||
<div id="arrReg-lookup-results" class="aircraft-lookup-results"></div>
|
<div id="arrReg-lookup-results" class="aircraft-lookup-results"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-row">
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="arrType">Aircraft Type</label>
|
<label for="arrType">Aircraft Type</label>
|
||||||
<input type="text" id="arrType" name="type" placeholder="e.g., Cessna 172">
|
<input type="text" id="arrType" name="type" placeholder="e.g., Cessna 172">
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-row">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="arrPOB">Persons on Board <span class="required">*</span></label>
|
||||||
|
<input type="number" id="arrPOB" name="pob" value="1" min="1" required>
|
||||||
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="arrCallsign">Callsign</label>
|
<label for="arrCallsign">Callsign</label>
|
||||||
<input type="text" id="arrCallsign" name="callsign" placeholder="Optional">
|
<input type="text" id="arrCallsign" name="callsign" placeholder="Optional">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-row-3col">
|
<div class="form-row">
|
||||||
<div class="form-group">
|
|
||||||
<label for="arrPOB">Persons on Board <span class="required">*</span></label>
|
|
||||||
<input type="number" id="arrPOB" name="pob" value="1" min="1" required>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="arrFrom">Origin (ICAO) <span class="required">*</span></label>
|
<label for="arrFrom">Origin (ICAO) <span class="required">*</span></label>
|
||||||
<input type="text" id="arrFrom" name="in_from" placeholder="e.g., KJFK" required oninput="handleAirportLookup(this.value, 'arrFrom')">
|
<input type="text" id="arrFrom" name="in_from" placeholder="e.g., KJFK" required oninput="handleAirportLookup(this.value, 'arrFrom')">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="arrETA">Arrival Time</label>
|
<label for="arrETA">Arrival Time</label>
|
||||||
<input type="time" id="arrETA" name="eta">
|
<input type="text" id="arrETA" name="eta" placeholder="HH:MM" pattern="([0-9]{2}:[0-9]{2}|[0-9]{4})" inputmode="decimal" oninput="formatTimeInput(this)">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="arrFrom-lookup-results" class="airport-lookup-results"></div>
|
<div id="arrFrom-lookup-results" class="airport-lookup-results"></div>
|
||||||
@@ -608,6 +681,7 @@
|
|||||||
const API_BASE = window.location.origin + '/api/v1';
|
const API_BASE = window.location.origin + '/api/v1';
|
||||||
const STORAGE_RECENT_REGS_KEY = 'bookingPage_recentRegs';
|
const STORAGE_RECENT_REGS_KEY = 'bookingPage_recentRegs';
|
||||||
const STORAGE_AIRCRAFT_TYPES_KEY = 'bookingPage_aircraftTypes';
|
const STORAGE_AIRCRAFT_TYPES_KEY = 'bookingPage_aircraftTypes';
|
||||||
|
const STORAGE_CALLSIGNS_KEY = 'bookingPage_callsigns';
|
||||||
const MAX_RECENT = 5;
|
const MAX_RECENT = 5;
|
||||||
|
|
||||||
// ==================== localStorage Management ====================
|
// ==================== localStorage Management ====================
|
||||||
@@ -690,6 +764,43 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function cacheCallsign(registration, callsign) {
|
||||||
|
try {
|
||||||
|
if (!registration || !callsign || callsign.trim() === '') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const reg = registration.toUpperCase().trim();
|
||||||
|
const cs = callsign.toUpperCase().trim();
|
||||||
|
const stored = localStorage.getItem(STORAGE_CALLSIGNS_KEY);
|
||||||
|
let callsigns = stored ? JSON.parse(stored) : {};
|
||||||
|
|
||||||
|
callsigns[reg] = cs;
|
||||||
|
localStorage.setItem(STORAGE_CALLSIGNS_KEY, JSON.stringify(callsigns));
|
||||||
|
console.log('✅ Cached callsign:', reg, '=', cs);
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Error caching callsign:', e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCachedCallsign(registration) {
|
||||||
|
try {
|
||||||
|
const reg = registration.toUpperCase().trim();
|
||||||
|
const stored = localStorage.getItem(STORAGE_CALLSIGNS_KEY);
|
||||||
|
if (!stored) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const callsigns = JSON.parse(stored);
|
||||||
|
const callsign = callsigns[reg] || null;
|
||||||
|
console.log('🔍 Retrieved cached callsign for', reg, '=', callsign);
|
||||||
|
return callsign;
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Error retrieving cached callsign:', e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function applyRecentReg(registration, formType) {
|
function applyRecentReg(registration, formType) {
|
||||||
const registerIdMap = {
|
const registerIdMap = {
|
||||||
'local': 'localReg',
|
'local': 'localReg',
|
||||||
@@ -705,8 +816,16 @@
|
|||||||
'arrival': 'arrType'
|
'arrival': 'arrType'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const callsignIdMap = {
|
||||||
|
'local': 'localCallsign',
|
||||||
|
'circuits': 'circuitCallsign',
|
||||||
|
'departure': 'depCallsign',
|
||||||
|
'arrival': 'arrCallsign'
|
||||||
|
};
|
||||||
|
|
||||||
const regId = registerIdMap[formType];
|
const regId = registerIdMap[formType];
|
||||||
const typeId = typeIdMap[formType];
|
const typeId = typeIdMap[formType];
|
||||||
|
const callsignId = callsignIdMap[formType];
|
||||||
|
|
||||||
console.log('📍 applyRecentReg called - reg:', registration, 'form:', formType);
|
console.log('📍 applyRecentReg called - reg:', registration, 'form:', formType);
|
||||||
document.getElementById(regId).value = registration;
|
document.getElementById(regId).value = registration;
|
||||||
@@ -720,6 +839,13 @@
|
|||||||
console.log('ℹ️ No cached type found');
|
console.log('ℹ️ No cached type found');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Restore cached callsign if available
|
||||||
|
const cachedCallsign = getCachedCallsign(registration);
|
||||||
|
if (cachedCallsign) {
|
||||||
|
console.log('✔️ Applying cached callsign:', cachedCallsign);
|
||||||
|
document.getElementById(callsignId).value = cachedCallsign;
|
||||||
|
}
|
||||||
|
|
||||||
document.getElementById(regId).focus();
|
document.getElementById(regId).focus();
|
||||||
// Trigger the lookup
|
// Trigger the lookup
|
||||||
handleAircraftLookup(registration, formType);
|
handleAircraftLookup(registration, formType);
|
||||||
@@ -780,24 +906,24 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function showMessage(message, isError = false) {
|
function showMessage(message, isError = false) {
|
||||||
const successEl = document.getElementById('successMessage');
|
|
||||||
const errorEl = document.getElementById('errorMessage');
|
|
||||||
|
|
||||||
if (isError) {
|
if (isError) {
|
||||||
|
const errorEl = document.getElementById('errorMessage');
|
||||||
errorEl.textContent = message;
|
errorEl.textContent = message;
|
||||||
errorEl.style.display = 'block';
|
errorEl.style.display = 'block';
|
||||||
successEl.style.display = 'none';
|
// Auto-hide error after 5 seconds
|
||||||
} else {
|
|
||||||
successEl.textContent = message;
|
|
||||||
successEl.style.display = 'block';
|
|
||||||
errorEl.style.display = 'none';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Auto-hide after 5 seconds
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
successEl.style.display = 'none';
|
|
||||||
errorEl.style.display = 'none';
|
errorEl.style.display = 'none';
|
||||||
}, 5000);
|
}, 5000);
|
||||||
|
} else {
|
||||||
|
// Show success modal instead
|
||||||
|
const modalMessage = document.getElementById('modalMessage');
|
||||||
|
modalMessage.textContent = message;
|
||||||
|
document.getElementById('successModal').classList.add('active');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeSuccessModal() {
|
||||||
|
document.getElementById('successModal').classList.remove('active');
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleSubmit(event, formType) {
|
async function handleSubmit(event, formType) {
|
||||||
@@ -816,6 +942,11 @@
|
|||||||
console.log('💾 Caching type on submit - reg:', data.registration, 'type:', data.type);
|
console.log('💾 Caching type on submit - reg:', data.registration, 'type:', data.type);
|
||||||
cacheAircraftType(data.registration, data.type);
|
cacheAircraftType(data.registration, data.type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cache the callsign if provided
|
||||||
|
if (data.callsign) {
|
||||||
|
cacheCallsign(data.registration, data.callsign);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set flight_type based on form type
|
// Set flight_type based on form type
|
||||||
@@ -830,8 +961,12 @@
|
|||||||
const timeFields = ['etd', 'circuit_timestamp', 'eta'];
|
const timeFields = ['etd', 'circuit_timestamp', 'eta'];
|
||||||
timeFields.forEach(field => {
|
timeFields.forEach(field => {
|
||||||
if (data[field]) {
|
if (data[field]) {
|
||||||
// data[field] is in HH:MM format (time input)
|
let timeValue = data[field];
|
||||||
const datetime = new Date(`${today}T${data[field]}:00`);
|
// Normalize 4-digit format (HHMM) to HH:MM
|
||||||
|
if (/^[0-9]{4}$/.test(timeValue)) {
|
||||||
|
timeValue = timeValue.slice(0, 2) + ':' + timeValue.slice(2);
|
||||||
|
}
|
||||||
|
const datetime = new Date(`${today}T${timeValue}:00`);
|
||||||
data[field] = datetime.toISOString();
|
data[field] = datetime.toISOString();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -869,7 +1004,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
const result = await response.json();
|
const result = await response.json();
|
||||||
showMessage(`✅ Success! Your booking has been submitted. Booking ID: ${result.id}`);
|
showMessage(`Thanks - Your booking has been submitted. Have a great flight!`);
|
||||||
form.reset();
|
form.reset();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error:', error);
|
console.error('Error:', error);
|
||||||
@@ -880,27 +1015,32 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set current time as default for time inputs
|
// Set current time as default for time inputs
|
||||||
|
function formatTimeInput(input) {
|
||||||
|
let value = input.value.replace(/[^0-9]/g, '');
|
||||||
|
|
||||||
|
// Auto-format: if user types 1430, it becomes 14:30
|
||||||
|
if (value.length === 4) {
|
||||||
|
input.value = value.slice(0, 2) + ':' + value.slice(2);
|
||||||
|
} else if (value.length <= 2) {
|
||||||
|
input.value = value;
|
||||||
|
} else if (value.length === 3) {
|
||||||
|
input.value = value.slice(0, 2) + ':' + value.slice(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function setDefaultTimes() {
|
function setDefaultTimes() {
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
const hours = String(now.getHours()).padStart(2, '0');
|
const futureTime = new Date(now.getTime() + 10 * 60000); // 10 minutes from now
|
||||||
const minutes = String(now.getMinutes()).padStart(2, '0');
|
|
||||||
const timeValue = `${hours}:${minutes}`;
|
|
||||||
|
|
||||||
// ETD fields should default to 15 minutes from now
|
|
||||||
const futureTime = new Date(now.getTime() + 15 * 60000);
|
|
||||||
const futureHours = String(futureTime.getHours()).padStart(2, '0');
|
const futureHours = String(futureTime.getHours()).padStart(2, '0');
|
||||||
const futureMinutes = String(futureTime.getMinutes()).padStart(2, '0');
|
const futureMinutes = String(futureTime.getMinutes()).padStart(2, '0');
|
||||||
const futureTimeValue = `${futureHours}:${futureMinutes}`;
|
const futureTimeValue = `${futureHours}:${futureMinutes}`;
|
||||||
|
|
||||||
const etdFieldIds = ['localETD', 'circuitETD', 'depETD'];
|
const etdFieldIds = ['localETD', 'circuitETD', 'depETD', 'arrETA'];
|
||||||
|
|
||||||
document.querySelectorAll('input[type="time"]').forEach(input => {
|
etdFieldIds.forEach(id => {
|
||||||
if (!input.value) {
|
const input = document.getElementById(id);
|
||||||
if (etdFieldIds.includes(input.id)) {
|
if (input && !input.value) {
|
||||||
input.value = futureTimeValue;
|
input.value = futureTimeValue;
|
||||||
} else {
|
|
||||||
input.value = timeValue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user