From 3ec22cbe3b7ce4ad0a9944912e8463310906384b Mon Sep 17 00:00:00 2001 From: Tykayn Date: Sat, 27 Sep 2025 01:31:36 +0200 Subject: [PATCH] up traffic --- oedb/resources/demo.py | 34 +++-- oedb/resources/demo/static/edit.js | 157 +++++++++++++++++++++--- oedb/resources/demo/static/traffic.js | 89 ++++++++++++-- oedb/resources/demo/templates/edit.html | 99 +++++++++++---- 4 files changed, 321 insertions(+), 58 deletions(-) diff --git a/oedb/resources/demo.py b/oedb/resources/demo.py index c67ac72..bce150a 100644 --- a/oedb/resources/demo.py +++ b/oedb/resources/demo.py @@ -52,27 +52,47 @@ class DemoResource: # Set content type to HTML resp.content_type = 'text/html' - # Fetch the event data from the API + # Fetch the event data from the OEDB API + logger.info(f"Fetching event data from API for event ID: {id}") response = requests.get(f'https://api.openeventdatabase.org/event/{id}') - + if response.status_code != 200: + logger.error(f"API returned status {response.status_code} for event {id}") resp.status = falcon.HTTP_404 - resp.text = f"Event with ID {id} not found" + resp.text = f"Event with ID {id} not found on API" return - + event_data = response.json() - + logger.info(f"Successfully retrieved event data for {id}: {type(event_data)}") + + # Validate event data structure + if not isinstance(event_data, dict): + logger.error(f"Invalid event data type: {type(event_data)}") + resp.status = falcon.HTTP_500 + resp.text = "Invalid event data format received from API" + return + + if 'properties' not in event_data: + logger.error(f"Event data missing 'properties': {event_data}") + resp.status = falcon.HTTP_500 + resp.text = "Invalid event data structure - missing properties" + return + # Render the template with the event data template = self.jinja_env.get_template('edit.html') html = template.render( id=id, - event_data=event_data + event_data=event_data # Pass Python object directly, let Jinja2 handle JSON conversion ) - + # Set the response body and status resp.text = html resp.status = falcon.HTTP_200 logger.success(f"Successfully processed GET request to /demo/edit for event ID: {id}") + except requests.RequestException as e: + logger.error(f"Error fetching event data from API: {e}") + resp.status = falcon.HTTP_500 + resp.text = f"Error fetching event data: {str(e)}" except Exception as e: logger.error(f"Error processing GET request to /demo/edit: {e}") resp.status = falcon.HTTP_500 diff --git a/oedb/resources/demo/static/edit.js b/oedb/resources/demo/static/edit.js index 22d04fa..25d314e 100644 --- a/oedb/resources/demo/static/edit.js +++ b/oedb/resources/demo/static/edit.js @@ -57,61 +57,127 @@ function populateForm() { console.log('✅ Données événement validées, remplissage du formulaire...'); + // Remplir le tableau des propriétés + populatePropertiesTable(eventData.properties); + const properties = eventData.properties; - + // Set form values document.getElementById('label').value = properties.label || ''; document.getElementById('type').value = properties.type || 'scheduled'; document.getElementById('what').value = properties.what || ''; - + // Handle optional fields if (properties['what:series']) { document.getElementById('what_series').value = properties['what:series']; } - + if (properties.where) { document.getElementById('where').value = properties.where; } - + // Format dates for datetime-local input if (properties.start) { const startDate = new Date(properties.start); document.getElementById('start').value = startDate.toISOString().slice(0, 16); } - + if (properties.stop) { const stopDate = new Date(properties.stop); document.getElementById('stop').value = stopDate.toISOString().slice(0, 16); } - + // Set marker on map if (eventData.geometry && eventData.geometry.coordinates) { const coords = eventData.geometry.coordinates; marker.setLngLat(coords).addTo(map); - + // Center map on event location map.flyTo({ center: coords, zoom: 10 }); } + + // Initialiser l'autocomplétion pour le champ "what" + const whatInput = document.getElementById('what'); + if (whatInput && window.initializeEventTypeAutocomplete) { + initializeEventTypeAutocomplete(whatInput); + } +} + +// Function to populate the properties table +function populatePropertiesTable(properties) { + const tableBody = document.getElementById('propertiesTableBody'); + if (!tableBody) return; + + // Clear existing rows + tableBody.innerHTML = ''; + + // Sort properties alphabetically + const sortedProperties = Object.keys(properties).sort(); + + sortedProperties.forEach(key => { + const value = properties[key]; + const row = document.createElement('tr'); + + // Determine value type and format + let displayValue; + let valueType; + + if (value === null) { + displayValue = 'null'; + valueType = 'null'; + } else if (typeof value === 'object') { + displayValue = `
${JSON.stringify(value, null, 2)}
`; + valueType = 'object'; + } else if (typeof value === 'string' && value.match(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}/)) { + displayValue = value + ` (${new Date(value).toLocaleString()})`; + valueType = 'datetime'; + } else if (typeof value === 'string' && value.startsWith('http')) { + displayValue = `${value}`; + valueType = 'url'; + } else { + displayValue = String(value); + valueType = typeof value; + } + + row.innerHTML = ` + ${key} + ${displayValue} + ${valueType} + `; + + // Add alternating row colors + if (tableBody.children.length % 2 === 0) { + row.style.backgroundColor = '#f9f9f9'; + } + + tableBody.appendChild(row); + }); } // Attendre que les données soient disponibles avant de peupler le formulaire -function initializeForm() { - if (typeof window.eventDataJson !== 'undefined') { +function initializeForm(retryCount = 0) { + console.log(`🔄 Tentative d'initialisation ${retryCount + 1}/10`); + + if (typeof window.eventData !== 'undefined' && window.eventData !== null) { console.log('📄 Données disponibles, initialisation du formulaire...'); populateForm(); + } else if (retryCount < 10) { + console.log('⏳ En attente des données, nouvelle tentative dans 200ms...'); + setTimeout(() => initializeForm(retryCount + 1), 200); } else { - console.log('⏳ En attente des données, nouvelle tentative dans 100ms...'); - setTimeout(initializeForm, 100); + console.error('❌ Timeout: Impossible de récupérer les données après 10 tentatives'); + showResult('Impossible de charger les données de l\'événement après plusieurs tentatives', 'error'); } } // Démarrer l'initialisation document.addEventListener('DOMContentLoaded', function() { console.log('🚀 DOM chargé, démarrage de l\'initialisation...'); - initializeForm(); + // Attendre un peu pour laisser le temps au script du template de s'exécuter + setTimeout(() => initializeForm(), 100); }); // Add marker on map click @@ -119,6 +185,36 @@ map.on('click', function(e) { marker.setLngLat(e.lngLat).addTo(map); }); +// Add functionality for swapping coordinates button +document.addEventListener('DOMContentLoaded', function() { + const swapButton = document.getElementById('swapCoordinatesButton'); + if (swapButton) { + swapButton.addEventListener('click', function() { + if (!marker || !marker.getLngLat()) { + showResult('Veuillez d\'abord placer un marqueur sur la carte', 'error'); + return; + } + + const currentLngLat = marker.getLngLat(); + const swappedLngLat = [currentLngLat.lat, currentLngLat.lng]; + + // Update marker position + marker.setLngLat(swappedLngLat); + + // Show confirmation message + showResult(`Coordonnées inversées: ${currentLngLat.lng.toFixed(6)}, ${currentLngLat.lat.toFixed(6)} → ${swappedLngLat[0].toFixed(6)}, ${swappedLngLat[1].toFixed(6)}`, 'success'); + + // Auto-hide success message after 3 seconds + setTimeout(() => { + const resultElement = document.getElementById('result'); + if (resultElement && resultElement.className === 'success') { + resultElement.style.display = 'none'; + } + }, 3000); + }); + } +}); + // Function to show result message function showResult(message, type) { const resultElement = document.getElementById('result'); @@ -180,8 +276,8 @@ document.getElementById('eventForm').addEventListener('submit', function(e) { event.properties.where = where; } - // Submit event to API - fetch(`/event/${eventId}`, { + // Submit event to OEDB API + fetch(`https://api.openeventdatabase.org/event/${eventId}`, { method: 'PUT', headers: { 'Content-Type': 'application/json' @@ -198,14 +294,39 @@ document.getElementById('eventForm').addEventListener('submit', function(e) { } }) .then(data => { - showResult(`Event updated successfully with ID: ${data.id}`, 'success'); - + console.log('📅 Réponse API de modification:', data); + + // Extract event ID from response (handle different response structures) + let eventId = null; + if (data.properties && data.properties.id) { + eventId = data.properties.id; + } else if (data.id) { + eventId = data.id; + } else if (typeof data === 'string') { + eventId = data; + } else { + // Fallback: use the eventId from the form + eventId = document.getElementById('eventId').value; + } + + console.log('🆔 ID événement pour les liens:', eventId); + + showResult(`✅ Événement mis à jour avec succès !${eventId ? ` ID: ${eventId}` : ''}`, 'success'); + // Add link to view the event const resultElement = document.getElementById('result'); - resultElement.innerHTML += `

View Event | Back to Map

`; + let linksHtml = '

'; + + if (eventId) { + linksHtml += `Voir l'événement | `; + } + + linksHtml += 'Retour à la carte

'; + resultElement.innerHTML += linksHtml; }) .catch(error => { - showResult(`Error: ${error.message}`, 'error'); + console.error('❌ Erreur lors de la modification:', error); + showResult(`❌ Erreur lors de la modification: ${error.message}`, 'error'); }); }); diff --git a/oedb/resources/demo/static/traffic.js b/oedb/resources/demo/static/traffic.js index 2ec5432..4aa24d9 100644 --- a/oedb/resources/demo/static/traffic.js +++ b/oedb/resources/demo/static/traffic.js @@ -140,11 +140,11 @@ document.addEventListener('DOMContentLoaded', function () { } // Set up form submission after DOM is loaded - const reportForm = document.getElementById('trafficForm'); + const reportForm = document.getElementById('reportForm'); if (reportForm) { reportForm.addEventListener('submit', submitReport); } else { - console.warn('Traffic form not found in DOM'); + console.warn('Report form not found in DOM'); } } @@ -251,13 +251,26 @@ document.addEventListener('DOMContentLoaded', function () { } } - // Submit the event to the API - const response = await fetch('/event', { + // Submit the event to the OEDB API + const response = await fetch('https://api.openeventdatabase.org/event', { method: 'POST', headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(eventData) + body: JSON.stringify({ + type: 'Feature', + geometry: eventData.geometry, + properties: { + type: eventData.type, + what: eventData.what, + label: eventData.label, + description: eventData.description, + start: eventData.start, + stop: eventData.stop, + ...(eventData.source && { source: eventData.source }), + ...(eventData.media && { media: eventData.media }) + } + }) }); if (!response.ok) { @@ -267,8 +280,44 @@ document.addEventListener('DOMContentLoaded', function () { const data = await response.json(); - // Show success message - resultElement.textContent = `Report submitted successfully! Event ID: ${data.id}`; + // Extract event ID from response (handle different response structures) + let eventId = null; + if (data.properties && data.properties.id) { + eventId = data.properties.id; + } else if (data.id) { + eventId = data.id; + } else if (typeof data === 'string') { + eventId = data; + } + + console.log('📅 Réponse API complète:', data); + console.log('🆔 ID événement extrait:', eventId); + + // Show success message with links + let successHtml = ` +
+ + ✅ Événement créé avec succès ! + `; + + if (eventId) { + successHtml += `
ID: ${eventId}

+ + Voir l'événement + + |`; + } else { + successHtml += `
ID d'événement non disponible dans la réponse

`; + } + + successHtml += ` + + Retour à la carte + +
+ `; + + resultElement.innerHTML = successHtml; resultElement.className = 'success'; // Reset the form @@ -280,11 +329,29 @@ document.addEventListener('DOMContentLoaded', function () { previewContainer.style.display = 'none'; } + // Remove marker from map + if (marker) { + marker.remove(); + marker = null; + currentPosition = null; + } + // Initialize the form again initForm(); + + // Re-validate form to disable submit button + validateForm(); } catch (error) { + console.error('❌ Erreur lors de la création d\'événement:', error); + // Show error message - resultElement.textContent = `Error: ${error.message}`; + resultElement.innerHTML = ` +
+ + ❌ Erreur lors de la création de l'événement +
${error.message} +
+ `; resultElement.className = 'error'; } } @@ -325,7 +392,7 @@ document.addEventListener('DOMContentLoaded', function () { // Setup form validation function setupFormValidation() { - const form = document.getElementById('trafficForm'); + const form = document.getElementById('reportForm'); if (!form) return; // Get all form fields that need validation @@ -359,7 +426,7 @@ document.addEventListener('DOMContentLoaded', function () { } // Initial validation - validateForm(); + // validateForm(); } @@ -376,7 +443,7 @@ function clearFieldError(element) { } // Validate the entire form function validateForm() { - const form = document.getElementById('trafficForm'); + const form = document.getElementById('reportForm'); const submitButton = document.getElementById('report_issue_button'); if (!form || !submitButton) { diff --git a/oedb/resources/demo/templates/edit.html b/oedb/resources/demo/templates/edit.html index 47bad90..5fb116b 100644 --- a/oedb/resources/demo/templates/edit.html +++ b/oedb/resources/demo/templates/edit.html @@ -115,30 +115,85 @@ {% block scripts %}