From 6e760a3e96406b0bdcdf8b99cb4fd2bc9d629070 Mon Sep 17 00:00:00 2001 From: James Pattinson Date: Sat, 25 Oct 2025 13:57:19 +0000 Subject: [PATCH] New date picker --- backend/app/templates/ppr_submitted.html | 2 +- web/edit.html | 178 ++++++++++++++++++++--- web/ppr.html | 143 +++++++++++++++--- 3 files changed, 285 insertions(+), 38 deletions(-) diff --git a/backend/app/templates/ppr_submitted.html b/backend/app/templates/ppr_submitted.html index 946ec84..c807256 100644 --- a/backend/app/templates/ppr_submitted.html +++ b/backend/app/templates/ppr_submitted.html @@ -14,7 +14,7 @@
  • Departure: {{ departure_time }}
  • Purpose: {{ purpose }}
  • -

    You can edit or cancel your PPR using this secure link.

    +

    You can edit or cancel your PPR using this secure link.

    You will receive further updates via email.

    Best regards,
    Swansea Airport Team

    diff --git a/web/edit.html b/web/edit.html index d45a9b2..9f714bf 100644 --- a/web/edit.html +++ b/web/edit.html @@ -289,7 +289,12 @@
    - +
    + + +
    @@ -311,7 +316,12 @@
    - +
    + + +
    @@ -370,6 +380,28 @@ window.location.href = '/'; } + // Initialize time dropdowns + function initializeTimeDropdowns() { + const timeSelects = ['eta-time', 'etd-time']; + + timeSelects.forEach(selectId => { + const select = document.getElementById(selectId); + // Clear existing options except the first one + select.innerHTML = ''; + + // Add time options in 15-minute intervals + for (let hour = 0; hour < 24; hour++) { + for (let minute = 0; minute < 60; minute += 15) { + const timeString = `${hour.toString().padStart(2, '0')}:${minute.toString().padStart(2, '0')}`; + const option = document.createElement('option'); + option.value = timeString; + option.textContent = timeString; + select.appendChild(option); + } + } + }); + } + // Notification system function showNotification(message, isError = false) { const notification = document.getElementById('notification'); @@ -398,11 +430,43 @@ document.getElementById('ac_call').value = ppr.ac_call || ''; document.getElementById('captain').value = ppr.captain || ''; document.getElementById('in_from').value = ppr.in_from || ''; - document.getElementById('eta').value = ppr.eta ? new Date(ppr.eta).toISOString().slice(0, 16) : ''; + + // Handle ETA date/time separately + if (ppr.eta) { + let utcDateStr = ppr.eta; + if (!utcDateStr.includes('T')) { + utcDateStr = utcDateStr.replace(' ', 'T'); + } + if (!utcDateStr.includes('Z')) { + utcDateStr += 'Z'; + } + const etaDate = new Date(utcDateStr); + const etaDateStr = etaDate.toISOString().split('T')[0]; + const etaTimeStr = etaDate.toISOString().slice(11, 16); + document.getElementById('eta-date').value = etaDateStr; + document.getElementById('eta-time').value = etaTimeStr; + } + document.getElementById('pob_in').value = ppr.pob_in || ''; document.getElementById('fuel').value = ppr.fuel || ''; document.getElementById('out_to').value = ppr.out_to || ''; - document.getElementById('etd').value = ppr.etd ? new Date(ppr.etd).toISOString().slice(0, 16) : ''; + + // Handle ETD date/time separately + if (ppr.etd) { + let utcDateStr = ppr.etd; + if (!utcDateStr.includes('T')) { + utcDateStr = utcDateStr.replace(' ', 'T'); + } + if (!utcDateStr.includes('Z')) { + utcDateStr += 'Z'; + } + const etdDate = new Date(utcDateStr); + const etdDateStr = etdDate.toISOString().split('T')[0]; + const etdTimeStr = etdDate.toISOString().slice(11, 16); + document.getElementById('etd-date').value = etdDateStr; + document.getElementById('etd-time').value = etdTimeStr; + } + document.getElementById('pob_out').value = ppr.pob_out || ''; document.getElementById('email').value = ppr.email || ''; document.getElementById('phone').value = ppr.phone || ''; @@ -492,6 +556,7 @@ async function handleArrivalAirportLookup(query) { clearTimeout(arrivalAirportLookupTimeout); const resultsDiv = document.getElementById('arrival-airport-lookup-results'); + const inputField = document.getElementById('in_from'); if (!query || query.length < 2) { resultsDiv.innerHTML = ''; @@ -506,12 +571,31 @@ if (response.ok) { const data = await response.json(); if (data && data.length > 0) { - const airport = data[0]; - resultsDiv.innerHTML = ` -
    - ${airport.icao}/${airport.iata || ''} - ${airport.name}, ${airport.country} -
    - `; + if (data.length === 1) { + // Single match - auto-populate the input field with ICAO code + const airport = data[0]; + inputField.value = airport.icao; + resultsDiv.innerHTML = ` +
    + ${airport.icao}/${airport.iata || ''} - ${airport.name}, ${airport.country} +
    + `; + } else if (data.length <= 10) { + // Multiple matches - show as clickable list + resultsDiv.innerHTML = ` +
    + ${data.map(airport => ` +
    +
    ${airport.icao}/${airport.iata || ''}
    +
    ${airport.name}, ${airport.country}
    +
    + `).join('')} +
    + `; + } else { + // Too many matches + resultsDiv.innerHTML = 'Too many matches, please be more specific'; + } } else { resultsDiv.innerHTML = 'No airport found'; } @@ -529,6 +613,7 @@ async function handleDepartureAirportLookup(query) { clearTimeout(departureAirportLookupTimeout); const resultsDiv = document.getElementById('departure-airport-lookup-results'); + const inputField = document.getElementById('out_to'); if (!query || query.length < 2) { resultsDiv.innerHTML = ''; @@ -543,12 +628,31 @@ if (response.ok) { const data = await response.json(); if (data && data.length > 0) { - const airport = data[0]; - resultsDiv.innerHTML = ` -
    - ${airport.icao}/${airport.iata || ''} - ${airport.name}, ${airport.country} -
    - `; + if (data.length === 1) { + // Single match - auto-populate the input field with ICAO code + const airport = data[0]; + inputField.value = airport.icao; + resultsDiv.innerHTML = ` +
    + ${airport.icao}/${airport.iata || ''} - ${airport.name}, ${airport.country} +
    + `; + } else if (data.length <= 10) { + // Multiple matches - show as clickable list + resultsDiv.innerHTML = ` +
    + ${data.map(airport => ` +
    +
    ${airport.icao}/${airport.iata || ''}
    +
    ${airport.name}, ${airport.country}
    +
    + `).join('')} +
    + `; + } else { + // Too many matches + resultsDiv.innerHTML = 'Too many matches, please be more specific'; + } } else { resultsDiv.innerHTML = 'No airport found'; } @@ -562,6 +666,28 @@ }, 500); } + function selectAirport(fieldId, icaoCode) { + document.getElementById(fieldId).value = icaoCode; + // Clear the results + const resultsDivId = fieldId === 'in_from' ? 'arrival-airport-lookup-results' : 'departure-airport-lookup-results'; + document.getElementById(resultsDivId).innerHTML = ''; + // Remove focus from the field to hide the dropdown + document.getElementById(fieldId).blur(); + } + + // Clear airport lookup results when input loses focus + document.getElementById('in_from').addEventListener('blur', function() { + setTimeout(() => { + document.getElementById('arrival-airport-lookup-results').innerHTML = ''; + }, 150); + }); + + document.getElementById('out_to').addEventListener('blur', function() { + setTimeout(() => { + document.getElementById('departure-airport-lookup-results').innerHTML = ''; + }, 150); + }); + // Form submission (update) document.getElementById('ppr-form').addEventListener('submit', async function(e) { e.preventDefault(); @@ -573,9 +699,18 @@ if (value.trim() !== '') { if (key === 'pob_in' || key === 'pob_out') { pprData[key] = parseInt(value); - } else if (key === 'eta' || key === 'etd') { - pprData[key] = new Date(value).toISOString(); - } else { + } else if (key === 'eta-date' && formData.get('eta-time')) { + // Combine date and time for ETA + const dateStr = formData.get('eta-date'); + const timeStr = formData.get('eta-time'); + pprData.eta = new Date(`${dateStr}T${timeStr}`).toISOString(); + } else if (key === 'etd-date' && formData.get('etd-time')) { + // Combine date and time for ETD + const dateStr = formData.get('etd-date'); + const timeStr = formData.get('etd-time'); + pprData.etd = new Date(`${dateStr}T${timeStr}`).toISOString(); + } else if (key !== 'eta-time' && key !== 'etd-time') { + // Skip the time fields as they're handled above pprData[key] = value; } } @@ -647,6 +782,11 @@ // Load data on page load loadPPRData(); + + // Initialize the page when DOM is loaded + document.addEventListener('DOMContentLoaded', function() { + initializeTimeDropdowns(); + }); \ No newline at end of file diff --git a/web/ppr.html b/web/ppr.html index acfd308..3f88b21 100644 --- a/web/ppr.html +++ b/web/ppr.html @@ -289,7 +289,12 @@
    - +
    + + +
    @@ -311,7 +316,12 @@
    - +
    + + +
    @@ -354,6 +364,28 @@
    \ No newline at end of file