diff --git a/src/Controller/PublicController.php b/src/Controller/PublicController.php index 216658a7..8637fd46 100644 --- a/src/Controller/PublicController.php +++ b/src/Controller/PublicController.php @@ -547,6 +547,14 @@ class PublicController extends AbstractController foreach ($request_post as $key => $value) { if (strpos($key, 'commerce_tag_value__') === 0) { $tagKey = str_replace('commerce_tag_value__', '', $key); + // Corriger les underscores convertis par PHP en deux-points pour les tags OSM + // PHP convertit automatiquement les deux-points en underscores dans les noms de champs POST + // On restaure les deux-points pour les tags qui commencent par contact_ ou addr_ + if (strpos($tagKey, 'contact_') === 0) { + $tagKey = preg_replace('/^contact_/', 'contact:', $tagKey); + } elseif (strpos($tagKey, 'addr_') === 0) { + $tagKey = preg_replace('/^addr_/', 'addr:', $tagKey); + } // On ajoute la clé même si la valeur est vide (pour affichage suppression) $tags[$tagKey] = trim($value); } else { diff --git a/templates/admin/stats.html.twig b/templates/admin/stats.html.twig index fc1b47a0..31533d3e 100644 --- a/templates/admin/stats.html.twig +++ b/templates/admin/stats.html.twig @@ -129,6 +129,39 @@ .table-theme th { background: #f8f9fa; } + + /* En-têtes de tableau fixes */ + #table_container { + position: relative; + max-height: 70vh; + overflow-y: auto; + overflow-x: auto; + } + + #stats-table { + width: 100%; + border-collapse: separate; + border-spacing: 0; + } + + #stats-table thead { + position: sticky; + top: 0; + z-index: 10; + background: #fff; + } + + #stats-table thead th { + background: #f8f9fa; + border-bottom: 2px solid #dee2e6; + box-shadow: 0 2px 2px -1px rgba(0, 0, 0, 0.1); + padding: 0.75rem; + font-weight: 600; + } + + #stats-table tbody td { + border-top: 1px solid #dee2e6; + } {% endblock %} @@ -919,20 +952,65 @@ const coordinates = e.features[0].geometry.coordinates.slice(); const properties = e.features[0].properties; let missing_tags = []; + let missing_tags_info = []; - const tags_for_completion = ['name', 'wheelchair', 'siret', 'opening_hours']; - tags_for_completion.forEach(function (tag) { - if (!properties[tag]) { - missing_tags.push(tag); + // Vérifier les tags manquants avec leurs descriptions + const tags_info = { + 'name': {tag: 'name', desc: 'Nom du commerce'}, + 'opening_hours': {tag: 'opening_hours', desc: 'Horaires d\'ouverture'}, + 'wheelchair': {tag: 'wheelchair', desc: 'Accessibilité PMR'}, + 'ref:FR:SIRET': {tag: 'ref:FR:SIRET', desc: 'SIRET'}, + 'contact:street': {tag: 'contact:street', desc: 'Rue (ou addr:street)'}, + 'contact:housenumber': {tag: 'contact:housenumber', desc: 'Numéro (ou addr:housenumber)'}, + 'website': {tag: 'website', desc: 'Site web (ou contact:website, url, contact:url)'}, + 'contact:phone': {tag: 'contact:phone', desc: 'Téléphone (ou phone)'} + }; + + // Vérifier le nom + if (!properties['name']) { + missing_tags.push('name'); + missing_tags_info.push(tags_info['name']); + } + + // Vérifier l'adresse + const hasStreet = properties['contact:street'] || properties['addr:street']; + const hasHousenumber = properties['contact:housenumber'] || properties['addr:housenumber']; + if (!hasStreet || !hasHousenumber) { + if (!hasStreet) { + missing_tags.push('contact:street'); + missing_tags_info.push(tags_info['contact:street']); } - }) + if (!hasHousenumber) { + missing_tags.push('contact:housenumber'); + missing_tags_info.push(tags_info['contact:housenumber']); + } + } - if (!properties['phone'] && properties['contact:phone']) { - missing_tags.push('contact:phone'); + // Vérifier les horaires + if (!properties['opening_hours']) { + missing_tags.push('opening_hours'); + missing_tags_info.push(tags_info['opening_hours']); } - if (!properties['website'] && properties['contact:website']) { - missing_tags.push('contact:website'); + + // Vérifier le site web + const hasWebsite = properties['website'] || properties['contact:website'] || properties['url'] || properties['contact:url']; + if (!hasWebsite) { + missing_tags.push('website'); + missing_tags_info.push(tags_info['website']); } + + // Vérifier l'accessibilité + if (!properties['wheelchair']) { + missing_tags.push('wheelchair'); + missing_tags_info.push(tags_info['wheelchair']); + } + + // Vérifier le SIRET + if (!properties['ref:FR:SIRET'] && !properties['siret']) { + missing_tags.push('ref:FR:SIRET'); + missing_tags_info.push(tags_info['ref:FR:SIRET']); + } + properties.missing_tags = missing_tags; let popupContent = `${properties.name || 'Sans nom'}
`; @@ -940,11 +1018,16 @@ if (properties.main_tag) popupContent += `${properties.main_tag}
`; if (properties.note) popupContent += `Note: ${properties.note}
`; popupContent += `Complétion : ${properties.completion !== null ? properties.completion + '%' : '–'}`; - const missingTags = Array.isArray(properties.missing_tags) ? properties.missing_tags : []; - console.log('e.features[0]', e.features[0], missingTags, 'tags', properties) - // if (missingTags.length > 0) { - // popupContent += `
Manque : ${missingTags.map(t => `${t}`).join(', ')}
`; - // } + + // Afficher les tags manquants avec leurs descriptions + if (missing_tags_info.length > 0) { + popupContent += `
Informations manquantes :
`; + } + popupContent += `
Voir sur OSM`; while (Math.abs(e.lngLat.lng - coordinates[0]) > 180) { @@ -1293,6 +1376,12 @@