// Configuration partagée des types d'événements avec leurs emojis et descriptions window.EVENT_TYPES = { // Community / OSM 'community.osm.event': { emoji: '🗺️', label: 'Événement OpenStreetMap', category: 'Communauté', description: 'Événement lié à la communauté OpenStreetMap' }, // Culture / Arts 'culture.arts': { emoji: '🎨', label: 'Arts et culture', category: 'Culture', description: 'Événement artistique et culturel' }, 'culture.geek': { emoji: '🤓', label: 'Culture geek', category: 'Culture', description: 'Événement geek, technologie, gaming' }, 'culture.music': { emoji: '🎵', label: 'Musique', category: 'Culture', description: 'Événement musical général' }, // Music specific 'music.festival': { emoji: '🎪', label: 'Festival de musique', category: 'Musique', description: 'Festival musical' }, // Power / Energy 'power.production.unavail': { emoji: '⚡', label: 'Production électrique indisponible', category: 'Énergie', description: 'Arrêt ou réduction de production électrique' }, // Sale / Commerce 'sale': { emoji: '🛒', label: 'Vente / Commerce', category: 'Commerce', description: 'Événement commercial, vente, marché' }, // Time / Temporal 'time.daylight.summer': { emoji: '☀️', label: 'Heure d\'été', category: 'Temps', description: 'Passage à l\'heure d\'été' }, // Tourism 'tourism.exhibition': { emoji: '🖼️', label: 'Exposition', category: 'Tourisme', description: 'Exposition, salon, foire' }, // Traffic / Transportation 'traffic.accident': { emoji: '💥', label: 'Accident', category: 'Circulation', description: 'Accident de la circulation' }, 'traffic.incident': { emoji: '⚠️', label: 'Incident de circulation', category: 'Circulation', description: 'Incident sur la route' }, 'traffic.obstacle': { emoji: '🚧', label: 'Obstacle', category: 'Circulation', description: 'Obstacle sur la voie' }, 'traffic.partially_closed': { emoji: '🚦', label: 'Voie partiellement fermée', category: 'Circulation', description: 'Fermeture partielle de voie' }, 'traffic.roadwork': { emoji: '⛑️', label: 'Travaux routiers', category: 'Circulation', description: 'Travaux sur la chaussée' }, 'wildlife': { emoji: '🦌', label: 'Animal', category: 'Vie sauvage', description: 'Détection d\'animaux' }, 'traffic.mammoth': { emoji: '🦣', label: 'Mammouth laineux', category: 'Obstacle', description: 'Un mammouth laineux bloque la route' }, 'hazard.piranha': { emoji: '🐟', label: 'Piranha dans la piscine', category: 'Danger', description: 'Des pirana attaquent dans cette piscine' } }; // Fonction pour obtenir les suggestions d'autocomplétion function getEventTypeSuggestions(input) { const inputLower = input.toLowerCase(); const suggestions = []; for (const [key, config] of Object.entries(window.EVENT_TYPES)) { // Recherche dans la clé, le label et la catégorie const searchableText = `${key} ${config.label} ${config.category}`.toLowerCase(); if (searchableText.includes(inputLower)) { suggestions.push({ value: key, label: `${config.emoji} ${config.label}`, category: config.category, fullText: `${key} - ${config.label}` }); } } // Trier par pertinence (correspondance exacte en premier) suggestions.sort((a, b) => { const aExact = a.value.toLowerCase().startsWith(inputLower); const bExact = b.value.toLowerCase().startsWith(inputLower); if (aExact && !bExact) return -1; if (!aExact && bExact) return 1; return a.value.localeCompare(b.value); }); return suggestions.slice(0, 10); // Limiter à 10 suggestions } // Fonction pour initialiser l'autocomplétion sur un champ function initializeEventTypeAutocomplete(inputElement, onSelect) { if (!inputElement) return; let suggestionsContainer = null; let currentSuggestions = []; let selectedIndex = -1; let selectorButton = null; // Créer le bouton de sélection function createSelectorButton() { selectorButton = document.createElement('button'); selectorButton.type = 'button'; selectorButton.className = 'event-type-selector-btn'; selectorButton.innerHTML = '📋 Types d\'événements'; selectorButton.style.cssText = ` margin-top: 5px; padding: 6px 12px; background-color: #0078ff; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 12px; display: inline-block; `; selectorButton.addEventListener('click', function() { showAllEventTypes(); }); const parent = inputElement.parentElement; parent.appendChild(selectorButton); } // Créer le conteneur de suggestions function createSuggestionsContainer() { suggestionsContainer = document.createElement('div'); suggestionsContainer.className = 'autocomplete-suggestions'; suggestionsContainer.style.cssText = ` position: absolute; top: 100%; left: 0; right: 0; max-height: 300px; overflow-y: auto; background: white; border: 1px solid #ddd; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.15); z-index: 1000; display: none; margin-top: 2px; `; // Positionner le conteneur parent en relatif const parent = inputElement.parentElement; if (parent.style.position !== 'relative') { parent.style.position = 'relative'; } parent.appendChild(suggestionsContainer); } // Afficher tous les types d'événements dans un beau sélecteur function showAllEventTypes() { const allTypes = Object.entries(window.EVENT_TYPES).map(([key, config]) => ({ value: key, emoji: config.emoji, label: config.label, category: config.category, description: config.description || '', fullText: `${key} - ${config.label}` })); showEventTypeSelector(allTypes); } // Afficher le sélecteur de types d'événements function showEventTypeSelector(types) { if (!suggestionsContainer) return; currentSuggestions = types; selectedIndex = -1; // Grouper par catégorie const groupedTypes = {}; types.forEach(type => { if (!groupedTypes[type.category]) { groupedTypes[type.category] = []; } groupedTypes[type.category].push(type); }); let html = `