Gone live

This commit is contained in:
James Pattinson
2025-12-07 15:02:51 +00:00
parent 3780b3cf2f
commit 4d71d59d90
10 changed files with 542 additions and 401 deletions

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Swansea PPR Request</title>
<title>Swansea PPR</title>
<style>
* {
margin: 0;
@@ -254,13 +254,91 @@
color: #6c757d;
font-size: 0.85rem;
}
/* Mobile responsive styles */
@media (max-width: 768px) {
.container {
margin: 1rem auto;
padding: 1rem;
}
.header h1 {
font-size: 1.3rem;
}
.header p {
font-size: 1rem;
}
.form-grid {
grid-template-columns: 1fr; /* Single column on mobile */
gap: 0.8rem;
}
.form-group input, .form-group select, .form-group textarea {
padding: 0.7rem;
font-size: 1rem; /* Prevent zoom on iOS */
}
.form-actions {
flex-direction: column;
align-items: stretch;
}
.btn {
width: 100%;
padding: 1rem;
font-size: 1rem;
}
.notification {
font-size: 0.9rem;
padding: 1rem;
}
.success-message {
padding: 1.5rem;
font-size: 0.95rem;
}
.loading {
padding: 2rem;
}
.airport-lookup-results, .aircraft-lookup-results {
max-height: 200px;
font-size: 0.9rem;
}
.aircraft-option, .airport-option {
padding: 0.8rem;
font-size: 0.9rem;
}
}
/* Extra small screens */
@media (max-width: 480px) {
.container {
margin: 0.5rem;
padding: 0.8rem;
}
.header {
margin-bottom: 1.5rem;
}
.form-grid {
gap: 0.6rem;
}
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>✈️ Swansea Airport PPR Request</h1>
<p>Please fill out the form below to submit a Prior Permission Required (PPR) request for Swansea Airport.</p>
<h1>✈️ PPR Request</h1>
<p>Please fill out the form below to submit a PPR request for Swansea Airport.</p>
<p>Note that this is a new form, and is under test. Please email james.pattinson@sasalliance.org if you have any issues with the form.</p>
</div>
<form id="ppr-form">
@@ -354,9 +432,9 @@
</div>
<div class="success-message" id="success-message">
<h3>PPR Request Submitted Successfully!</h3>
<p>Your Prior Permission Required request has been submitted and will be reviewed by airport operations. You will receive confirmation via email if provided.</p>
<p><strong>Please note:</strong> This is not confirmation of approval. Airport operations will contact you if additional information is required.</p>
<h3>PPR Request Submitted.</h3>
<p>Your PPR request has been submitted. You will receive confirmation via email if provided.</p>
<p><strong>Please note:</strong> PPR requests are accepted by default. We will contact you if additional information is required. Remember to check NOTAMs before your flight.</p>
</div>
</div>
@@ -364,6 +442,29 @@
<div id="notification" class="notification"></div>
<script>
// API base URL for iframe embedding
const API_BASE = 'https://ppr.swansea-airport.wales/api/v1';
// Iframe resizing functionality
function sendHeightToParent() {
const height = document.body.scrollHeight || document.documentElement.scrollHeight;
if (window.parent !== window) {
window.parent.postMessage({
type: 'setHeight',
height: height + 20 // Add some padding
}, '*');
}
}
// Send height on load and resize
window.addEventListener('load', function() {
sendHeightToParent();
// Also send height after any content changes
setTimeout(sendHeightToParent, 100);
});
window.addEventListener('resize', sendHeightToParent);
// Initialize time dropdowns
function initializeTimeDropdowns() {
const timeSelects = ['eta-time', 'etd-time'];
@@ -395,11 +496,15 @@
// Show notification
setTimeout(() => {
notification.classList.add('show');
// Update iframe height when notification appears
setTimeout(sendHeightToParent, 50);
}, 10);
// Hide after 5 seconds
setTimeout(() => {
notification.classList.remove('show');
// Update iframe height when notification disappears
setTimeout(sendHeightToParent, 50);
}, 5000);
}
@@ -419,7 +524,7 @@
aircraftLookupTimeout = setTimeout(async () => {
try {
const response = await fetch(`/api/v1/aircraft/public/lookup/${registration.toUpperCase()}`);
const response = await fetch(`${API_BASE}/aircraft/public/lookup/${registration.toUpperCase()}`);
if (response.ok) {
const data = await response.json();
if (data && data.length > 0) {
@@ -498,17 +603,19 @@
arrivalAirportLookupTimeout = setTimeout(async () => {
try {
const response = await fetch(`/api/v1/airport/public/lookup/${query.toUpperCase()}`);
const response = await fetch(`${API_BASE}/airport/public/lookup/${query.toUpperCase()}`);
if (response.ok) {
const data = await response.json();
if (data && data.length > 0) {
if (data.length === 1) {
// Single match - auto-populate the input field with ICAO code
// Single match - show as clickable option
const airport = data[0];
inputField.value = airport.icao;
resultsDiv.innerHTML = `
<div class="lookup-match">
${airport.icao}/${airport.iata || ''} - ${airport.name}, ${airport.country}
<div class="aircraft-list">
<div class="aircraft-option" onclick="selectAirport('in_from', '${airport.icao}')">
<div class="aircraft-code">${airport.icao}/${airport.iata || ''}</div>
<div class="aircraft-details">${airport.name}, ${airport.country}</div>
</div>
</div>
`;
} else if (data.length <= 10) {
@@ -555,17 +662,19 @@
departureAirportLookupTimeout = setTimeout(async () => {
try {
const response = await fetch(`/api/v1/airport/public/lookup/${query.toUpperCase()}`);
const response = await fetch(`${API_BASE}/airport/public/lookup/${query.toUpperCase()}`);
if (response.ok) {
const data = await response.json();
if (data && data.length > 0) {
if (data.length === 1) {
// Single match - auto-populate the input field with ICAO code
// Single match - show as clickable option
const airport = data[0];
inputField.value = airport.icao;
resultsDiv.innerHTML = `
<div class="lookup-match">
${airport.icao}/${airport.iata || ''} - ${airport.name}, ${airport.country}
<div class="aircraft-list">
<div class="aircraft-option" onclick="selectAirport('out_to', '${airport.icao}')">
<div class="aircraft-code">${airport.icao}/${airport.iata || ''}</div>
<div class="aircraft-details">${airport.name}, ${airport.country}</div>
</div>
</div>
`;
} else if (data.length <= 10) {
@@ -653,7 +762,7 @@
document.getElementById('submit-btn').textContent = 'Submitting...';
try {
const response = await fetch('/api/v1/pprs/public', {
const response = await fetch(`${API_BASE}/pprs/public`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
@@ -670,6 +779,8 @@
document.getElementById('success-message').style.display = 'block';
showNotification('PPR request submitted successfully!');
// Update iframe height after content change
setTimeout(sendHeightToParent, 100);
} else {
const errorData = await response.json().catch(() => ({}));
throw new Error(errorData.detail || `Submission failed: ${response.status}`);
@@ -677,6 +788,8 @@
} catch (error) {
console.error('Error submitting PPR:', error);
showNotification(`Error submitting PPR: ${error.message}`, true);
// Update iframe height after showing error
setTimeout(sendHeightToParent, 100);
} finally {
// Hide loading
document.getElementById('loading').style.display = 'none';