347 lines
No EOL
11 KiB
HTML
347 lines
No EOL
11 KiB
HTML
{% extends "layout.html" %}
|
|
|
|
{% block title %}Événement {{ properties.label|default(id) }} - OpenEventDatabase{% endblock %}
|
|
|
|
{% block css %}
|
|
<style>
|
|
.event-header {
|
|
background: white;
|
|
padding: 20px;
|
|
border-radius: 8px;
|
|
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.event-title {
|
|
margin: 0 0 10px 0;
|
|
color: #333;
|
|
font-size: 1.8rem;
|
|
}
|
|
|
|
.event-subtitle {
|
|
color: #666;
|
|
font-size: 1rem;
|
|
margin: 0;
|
|
}
|
|
|
|
#map {
|
|
width: 100%;
|
|
height: 400px;
|
|
border: 1px solid #ddd;
|
|
border-radius: 8px;
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.properties-table {
|
|
background: white;
|
|
border-radius: 8px;
|
|
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
|
overflow: hidden;
|
|
}
|
|
|
|
.table-header {
|
|
background: #f8f9fa;
|
|
padding: 15px 20px;
|
|
border-bottom: 1px solid #dee2e6;
|
|
}
|
|
|
|
.table-header h2 {
|
|
margin: 0;
|
|
color: #333;
|
|
font-size: 1.3rem;
|
|
}
|
|
|
|
table {
|
|
width: 100%;
|
|
border-collapse: collapse;
|
|
}
|
|
|
|
th, td {
|
|
padding: 12px 20px;
|
|
border-bottom: 1px solid #eee;
|
|
text-align: left;
|
|
vertical-align: top;
|
|
}
|
|
|
|
th {
|
|
background: #f9fafb;
|
|
font-weight: 600;
|
|
color: #495057;
|
|
width: 200px;
|
|
}
|
|
|
|
td {
|
|
word-wrap: break-word;
|
|
max-width: 0;
|
|
}
|
|
|
|
.what-link {
|
|
display: inline-block;
|
|
padding: 4px 12px;
|
|
background: #0078ff;
|
|
color: white !important;
|
|
text-decoration: none;
|
|
border-radius: 20px;
|
|
font-size: 0.9rem;
|
|
font-weight: 500;
|
|
transition: background-color 0.2s;
|
|
}
|
|
|
|
.what-link:hover {
|
|
background: #0056b3;
|
|
text-decoration: none;
|
|
}
|
|
|
|
.nav-links {
|
|
margin-top: 10px;
|
|
}
|
|
|
|
.nav-links a {
|
|
color: #0078ff;
|
|
text-decoration: none;
|
|
margin-right: 15px;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.nav-links a:hover {
|
|
text-decoration: underline;
|
|
}
|
|
|
|
.error-message {
|
|
background: #f8d7da;
|
|
color: #721c24;
|
|
padding: 12px;
|
|
border-radius: 4px;
|
|
margin-bottom: 20px;
|
|
border: 1px solid #f5c6cb;
|
|
}
|
|
|
|
.loading {
|
|
text-align: center;
|
|
padding: 20px;
|
|
color: #6c757d;
|
|
}
|
|
</style>
|
|
{% endblock %}
|
|
|
|
{% block header %}
|
|
<div class="event-header">
|
|
<h1 class="event-title">{{ properties.label|default('Événement sans titre') }}</h1>
|
|
<p class="event-subtitle">ID: {{ id }}</p>
|
|
<div class="nav-links">
|
|
<a href="/demo"><i class="fas fa-home"></i> Accueil</a>
|
|
<a href="/demo/view-events"><i class="fas fa-table"></i> Tous les événements</a>
|
|
<a href="https://api.openeventdatabase.org/event/{{ id }}" target="_blank"><i class="fas fa-code"></i> API JSON</a>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block content %}
|
|
<div id="loading-map" class="loading">
|
|
<i class="fas fa-spinner fa-spin"></i>
|
|
Chargement de la carte...
|
|
</div>
|
|
<div id="map-error" class="error-message" style="display: none;">
|
|
<i class="fas fa-exclamation-triangle"></i>
|
|
Erreur lors du chargement de la carte
|
|
</div>
|
|
<div id="map" style="display: none;"></div>
|
|
|
|
<div class="properties-table">
|
|
<div class="table-header">
|
|
<h2><i class="fas fa-info-circle"></i> Propriétés de l'événement</h2>
|
|
</div>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Propriété</th>
|
|
<th>Valeur</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for key, value in properties.items()|sort %}
|
|
<tr>
|
|
<td><strong>{{ key }}</strong></td>
|
|
<td>
|
|
{% if key == 'what' %}
|
|
<a href="/demo/map-by-what/{{ value }}" class="what-link">
|
|
<i class="fas fa-tag"></i> {{ value }}
|
|
</a>
|
|
<small style="display: block; margin-top: 5px; color: #6c757d;">
|
|
Cliquez pour voir tous les événements de ce type
|
|
</small>
|
|
{% elif key in ['start', 'stop', 'createdate', 'lastupdate'] and value %}
|
|
{{ value }}
|
|
<small style="display: block; color: #6c757d;">
|
|
{{ value }}
|
|
|
|
</small>
|
|
{% elif key == 'url' and value %}
|
|
<a href="{{ value }}" target="_blank" style="color: #0078ff;">
|
|
{{ value }}
|
|
<i class="fas fa-external-link-alt" style="font-size: 0.8em;"></i>
|
|
</a>
|
|
{% elif value is string and value.startswith('http') %}
|
|
<a href="{{ value }}" target="_blank" style="color: #0078ff;">
|
|
{{ value }}
|
|
<i class="fas fa-external-link-alt" style="font-size: 0.8em;"></i>
|
|
</a>
|
|
{% else %}
|
|
{{ value|safe if value else '-' }}
|
|
{% endif %}
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block scripts %}
|
|
<script>
|
|
// Fonction pour formater les dates
|
|
function formatDate(dateString) {
|
|
try {
|
|
const date = new Date(dateString);
|
|
return date.toLocaleDateString('fr-FR', {
|
|
weekday: 'long',
|
|
year: 'numeric',
|
|
month: 'long',
|
|
day: 'numeric',
|
|
hour: '2-digit',
|
|
minute: '2-digit'
|
|
});
|
|
} catch (e) {
|
|
return dateString;
|
|
}
|
|
}
|
|
|
|
// Formater les dates dans le tableau après le chargement de la page
|
|
function formatDatesInTable() {
|
|
const dateElements = document.querySelectorAll('.date-display[data-date]');
|
|
dateElements.forEach(element => {
|
|
const dateValue = element.getAttribute('data-date');
|
|
if (dateValue) {
|
|
const formattedDate = formatDate(dateValue);
|
|
element.textContent = formattedDate;
|
|
element.title = dateValue; // Garder la date originale en tooltip
|
|
}
|
|
});
|
|
}
|
|
|
|
// Gestion des erreurs et logging
|
|
function logError(message, error) {
|
|
console.error(message, error);
|
|
document.getElementById('loading-map').style.display = 'none';
|
|
document.getElementById('map-error').style.display = 'block';
|
|
document.getElementById('map-error').innerHTML = `
|
|
<i class="fas fa-exclamation-triangle"></i>
|
|
${message}: ${error.message || error}
|
|
`;
|
|
}
|
|
|
|
// Formater les dates dans le tableau
|
|
formatDatesInTable();
|
|
|
|
// Initialisation de la carte
|
|
try {
|
|
console.log('🗺️ Initialisation de la carte...');
|
|
|
|
// Parser les données de l'événement de manière sécurisée
|
|
let eventFeature;
|
|
try {
|
|
const featureJson = '{{ feature_json|safe }}';
|
|
console.log('📄 JSON reçu:', featureJson);
|
|
eventFeature = JSON.parse(featureJson);
|
|
console.log('✅ Données de l\'événement parsées:', eventFeature);
|
|
} catch (parseError) {
|
|
throw new Error(`Impossible de parser les données JSON: ${parseError.message}`);
|
|
}
|
|
|
|
// Vérifier la structure des données
|
|
if (!eventFeature) {
|
|
throw new Error('Aucune donnée d\'événement trouvée');
|
|
}
|
|
|
|
// Déterminer les coordonnées pour la carte
|
|
let center = [2.3522, 48.8566]; // Paris par défaut
|
|
let hasValidGeometry = false;
|
|
|
|
if (eventFeature.geometry &&
|
|
eventFeature.geometry.type === 'Point' &&
|
|
eventFeature.geometry.coordinates &&
|
|
Array.isArray(eventFeature.geometry.coordinates) &&
|
|
eventFeature.geometry.coordinates.length === 2) {
|
|
|
|
const coords = eventFeature.geometry.coordinates;
|
|
// Vérifier que les coordonnées sont des nombres valides
|
|
if (typeof coords[0] === 'number' && typeof coords[1] === 'number' &&
|
|
!isNaN(coords[0]) && !isNaN(coords[1])) {
|
|
center = coords;
|
|
hasValidGeometry = true;
|
|
console.log('📍 Coordonnées trouvées:', center);
|
|
}
|
|
}
|
|
|
|
if (!hasValidGeometry) {
|
|
console.warn('⚠️ Pas de coordonnées valides, utilisation du centre par défaut');
|
|
}
|
|
|
|
// Créer la carte
|
|
const map = new maplibregl.Map({
|
|
container: 'map',
|
|
style: 'https://tiles.openfreemap.org/styles/liberty',
|
|
center: center,
|
|
zoom: hasValidGeometry ? 14 : 6
|
|
});
|
|
|
|
// Ajouter les contrôles
|
|
map.addControl(new maplibregl.NavigationControl());
|
|
map.addControl(new maplibregl.AttributionControl({
|
|
customAttribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
|
}));
|
|
|
|
// Quand la carte est chargée
|
|
map.on('load', function() {
|
|
console.log('✅ Carte chargée avec succès');
|
|
document.getElementById('loading-map').style.display = 'none';
|
|
document.getElementById('map').style.display = 'block';
|
|
|
|
// Ajouter le marqueur si on a des coordonnées valides
|
|
if (hasValidGeometry) {
|
|
const marker = new maplibregl.Marker({
|
|
color: '#0078ff'
|
|
})
|
|
.setLngLat(center)
|
|
.addTo(map);
|
|
|
|
// Créer une popup avec les informations de l'événement
|
|
const properties = eventFeature.properties || {};
|
|
const popupContent = `
|
|
<div style="max-width: 250px;">
|
|
<h3 style="margin: 0 0 10px 0;">${properties.label || 'Événement'}</h3>
|
|
${properties.what ? `<p><strong>Type:</strong> ${properties.what}</p>` : ''}
|
|
${properties.start ? `<p><strong>Début:</strong> ${formatDate(properties.start)}</p>` : ''}
|
|
${properties.where ? `<p><strong>Lieu:</strong> ${properties.where}</p>` : ''}
|
|
</div>
|
|
`;
|
|
|
|
const popup = new maplibregl.Popup({ offset: 25 })
|
|
.setHTML(popupContent);
|
|
|
|
marker.setPopup(popup);
|
|
|
|
console.log('📍 Marqueur ajouté à la carte');
|
|
}
|
|
});
|
|
|
|
// Gestion des erreurs de carte
|
|
map.on('error', function(e) {
|
|
logError('Erreur lors du chargement de la carte', e.error || e);
|
|
});
|
|
|
|
} catch (error) {
|
|
logError('Erreur lors de l\'initialisation de la carte', error);
|
|
}
|
|
</script>
|
|
{% endblock %} |