function colorHeadingTable() { const headers = document.querySelectorAll('th'); headers.forEach(header => { const text = header.textContent; const match = text.match(/\((\d+)\s*\/\s*(\d+)\)/); if (match) { const [_, completed, total] = match; const ratio = completed / total; const alpha = ratio.toFixed(2); header.style.backgroundColor = `rgba(154, 205, 50, ${alpha})`; } }); } function check_validity(e) { list_inputs_good_to_fill = [ 'input[name="commerce_tag_value__contact:email"]', 'input[name="commerce_tag_value__contact:phone"]', 'input[name="commerce_tag_value__contact:website"]', 'input[name="commerce_tag_value__contact:mastodon"]', 'input[name="commerce_tag_value__address"]', 'input[name="custom_opening_hours"]', 'input[name="commerce_tag_value__contact:street"]', 'input[name="commerce_tag_value__contact:housenumber"]', 'input[name="custom__cuisine"]', ] list_inputs_good_to_fill.forEach(selector => { const input = document.querySelector(selector); if (input) { if (input.value.trim() !== '') { input.classList.add('good_filled'); } else { input.classList.remove('good_filled'); } } }); let errors = []; document.querySelectorAll('.is-invalid').forEach(input => { input.classList.remove('is-invalid'); }); const nameInput = document.querySelector('input[name="commerce_tag_value__name"]'); if (!nameInput.value.trim()) { errors.push("Le nom de l'établissement est obligatoire"); nameInput.classList.add('is-invalid'); } const emailInput = document.querySelector('input[name="commerce_tag_value__contact:email"]'); if (emailInput && emailInput.value) { const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; if (!emailRegex.test(emailInput.value)) { errors.push("L'adresse email n'est pas valide"); emailInput.classList.add('is-invalid'); } } const phoneInput = document.querySelector('input[name="commerce_tag_value__contact:phone"]'); if (phoneInput && phoneInput.value) { const phoneRegex = /^(\+33|0)[1-9](\d{2}){4}$/; if (!phoneRegex.test(phoneInput.value.replace(/\s/g, ''))) { errors.push("Le numéro de téléphone n'est pas valide"); phoneInput.classList.add('is-invalid'); } } if (errors.length > 0) { e.preventDefault(); document.querySelector('#validation_messages').innerHTML = errors.join('
'); document.querySelector('#validation_messages').classList.add('is-invalid'); } } export const genererCouleurPastel = () => { const r = Math.floor(Math.random() * 75 + 180); const g = Math.floor(Math.random() * 75 + 180); const b = Math.floor(Math.random() * 75 + 180); return `rgb(${r}, ${g}, ${b})`; }; async function searchInseeCode(query) { try { document.querySelector('#loading_search_insee').classList.remove('d-none'); const response = await fetch(`https://geo.api.gouv.fr/communes?nom=${query}&fields=nom,code,codesPostaux&limit=10`); const data = await response.json(); document.querySelector('#loading_search_insee').classList.add('d-none'); return data.map(commune => ({ label: `${commune.nom} (${commune.codesPostaux.join(', ')}, code insee ${commune.code})`, insee: commune.code, postcodes: commune.codesPostaux })); } catch (error) { console.error('Erreur lors de la recherche du code INSEE:', error); return []; } } export function updateMapHeightForLargeScreens() { const mapFound = document.querySelector('#map'); if (mapFound && window.innerHeight > 800 && window.innerWidth > 800) { mapFound.style.height = window.innerWidth * 0.8 + 'px'; } else { console.log('window.innerHeight', window.innerHeight); } } async function listChangesets() { const options = { headers: { 'Accept': 'application/json' } }; const changesets = await fetch('https://api.openstreetmap.org/api/0.6/changesets?display_name=osm-commerce-fr', options); const data = await changesets.json(); console.log(data.changesets.length); const now = new Date(); const last24h = new Date(now - 24 * 60 * 60 * 1000); const last7days = new Date(now - 7 * 24 * 60 * 60 * 1000); const last30days = new Date(now - 30 * 24 * 60 * 60 * 1000); const stats = { last24h: 0, last7days: 0, last30days: 0 }; data.changesets.forEach(changeset => { const changesetDate = new Date(changeset.closed_at); if (changesetDate >= last24h) { stats.last24h++; } if (changesetDate >= last7days) { stats.last7days++; } if (changesetDate >= last30days) { stats.last30days++; } }); const historyDiv = document.getElementById('userChangesHistory'); if (historyDiv) { historyDiv.innerHTML = `

Changesets créés :

Dernières 24h :
${stats.last24h}
7 derniers jours :
${stats.last7days}
30 derniers jours :
${stats.last30days}
`; } } function openInPanoramax() { const center = map.getCenter(); const zoom = map.getZoom(); const panoramaxUrl = `https://api.panoramax.xyz/?focus=map&map=${zoom}/${center.lat}/${center.lng}`; window.open(panoramaxUrl); } export function enableLabourageForm() { const citySearchInput = document.getElementById('citySearch'); const citySuggestionsList = document.getElementById('citySuggestions'); if (citySearchInput && citySuggestionsList) { const form = citySearchInput.closest('form'); setupCitySearch('citySearch', 'citySuggestions', function (result_search) { if (form) { const labourageBtn = form.querySelector('button[type="submit"]'); if (labourageBtn) { // Remplir le champ caché avec le code INSEE const inseeInput = form.querySelector('#selectedZipCode'); if (inseeInput) { inseeInput.value = result_search.insee; } // Changer l'action du formulaire pour pointer vers la bonne URL form.action = getLabourerUrl(result_search); // Changer le texte du bouton et le désactiver labourageBtn.innerHTML = ' Labourage de ' + result_search.name + '...'; labourageBtn.disabled = true; // Soumettre le formulaire form.submit(); } } }); } } export function setupCitySearch(inputId, suggestionListId, onSelect) { const searchInput = document.getElementById(inputId); const suggestionList = document.getElementById(suggestionListId); if (!searchInput || !suggestionList) return; let timeoutId = null; let searchOngoing = false; searchInput.addEventListener('keyup', function () { clearTimeout(timeoutId); const query = this.value.trim(); if (query.length < 3) { clearSuggestions(); return; } timeoutId = setTimeout(() => { if (!searchOngoing) { searchOngoing = true; performSearch(query).then(() => { searchOngoing = false; }); } }, 300); }); async function performSearch(query) { try { const response = await fetch(`https://geo.api.gouv.fr/communes?nom=${encodeURIComponent(query)}&fields=nom,code,codesPostaux&limit=5`); const data = await response.json(); const citySuggestions = data.map(city => ({ name: city.nom, postcode: city.codesPostaux[0], insee: city.code, display_name: `${city.nom} (${city.codesPostaux[0]})` })); displaySuggestions(citySuggestions); } catch (error) { console.error("Erreur de recherche:", error); } } function displaySuggestions(suggestions) { clearSuggestions(); suggestions.forEach(suggestion => { const item = document.createElement('div'); item.classList.add('suggestion-item'); item.textContent = suggestion.display_name; item.addEventListener('click', () => { searchInput.value = suggestion.display_name; clearSuggestions(); if (onSelect) { onSelect(suggestion); } }); suggestionList.appendChild(item); }); suggestionList.style.display = 'block'; } function clearSuggestions() { suggestionList.innerHTML = ''; suggestionList.style.display = 'none'; } document.addEventListener('click', (e) => { if (!searchInput.contains(e.target) && !suggestionList.contains(e.target)) { clearSuggestions(); } }); } export function getLabourerUrl(obj) { if (obj && obj.insee) { return `/admin/labourer/${obj.insee}`; } return '#'; } export function handleAddCityFormSubmit(event) { event.preventDefault(); const zipCode = document.getElementById('selectedZipCode').value; if (zipCode && zipCode.match(/^\d{5}$/)) { window.location.href = `/admin/labourer/${zipCode}`; } else { alert('Veuillez sélectionner une ville valide avec un code postal.'); } } export function colorizePercentageCells(selector, color = '154, 205, 50') { document.querySelectorAll(selector).forEach(cell => { const percentage = parseInt(cell.textContent.replace('%', ''), 10); if (!isNaN(percentage)) { const alpha = percentage / 100; cell.style.backgroundColor = `rgba(${color}, ${alpha})`; } }); } export function colorizePercentageCellsRelative(selector, color = '154, 205, 50') { let min = Infinity; let max = -Infinity; const cells = document.querySelectorAll(selector); cells.forEach(cell => { const value = parseInt(cell.textContent.replace('%', ''), 10); if (!isNaN(value)) { min = Math.min(min, value); max = Math.max(max, value); } }); if (max > min) { cells.forEach(cell => { const value = parseInt(cell.textContent.replace('%', ''), 10); if (!isNaN(value)) { const ratio = (value - min) / (max - min); cell.style.backgroundColor = `rgba(${color}, ${ratio.toFixed(2)})`; } }); } } export function adjustListGroupFontSize(selector, minFont = 0.8, maxFont = 1.2) { const listItems = document.querySelectorAll(selector); if (listItems.length === 0) return; let fontSize = maxFont; const count = listItems.length; if (count > 0) { fontSize = Math.max(minFont, maxFont - (count - 5) * 0.05); } listItems.forEach(item => { item.style.fontSize = fontSize + 'rem'; }); } export function calculateCompletion(properties) { let completed = 0; const total = 7; // Nombre de critères if (properties.name) completed++; if (properties['addr:housenumber'] && properties['addr:street']) completed++; if (properties.opening_hours) completed++; if (properties.website || properties['contact:website']) completed++; if (properties.phone || properties['contact:phone']) completed++; if (properties.wheelchair) completed++; return { percentage: total > 0 ? (completed / total) * 100 : 0, completed: completed, total: total }; } export function toggleCompletionInfo() { const content = document.getElementById('completionInfoContent'); const icon = document.getElementById('completionInfoIcon'); if (content) { const isVisible = content.style.display === 'block'; content.style.display = isVisible ? 'none' : 'block'; if (icon) { icon.classList.toggle('bi-chevron-down', isVisible); icon.classList.toggle('bi-chevron-up', !isVisible); } } } window.check_validity = check_validity; window.colorHeadingTable = colorHeadingTable; window.openInPanoramax = openInPanoramax; window.listChangesets = listChangesets; window.adjustListGroupFontSize = adjustListGroupFontSize; window.calculateCompletion = calculateCompletion; window.toggleCompletionInfo = toggleCompletionInfo;