From 03fede15aa593a195a6b27911294e7d9767af2ca Mon Sep 17 00:00:00 2001 From: Tykayn Date: Wed, 19 Nov 2025 23:03:58 +0100 Subject: [PATCH] add themes in main city page --- src/Controller/AdminController.php | 26 +++++++++++ src/Controller/PublicController.php | 24 +++++++++++ src/Service/FollowUpService.php | 2 +- templates/admin/stats.html.twig | 48 ++++++++++++++------- templates/public/stats_evolutions.html.twig | 9 +++- 5 files changed, 91 insertions(+), 18 deletions(-) diff --git a/src/Controller/AdminController.php b/src/Controller/AdminController.php index 389a35ac..9e5c9039 100644 --- a/src/Controller/AdminController.php +++ b/src/Controller/AdminController.php @@ -633,6 +633,31 @@ final class AdminController extends AbstractController } $progression7Days['places'] = \App\Service\FollowUpService::calculate7DayProgression($stats, 'places'); + // Construire theme_groups pour inclure tous les thèmes + $allThemes = \App\Service\FollowUpService::getFollowUpThemes(); + $theme_groups = [ + 'emergency' => ['fire_hydrant', 'defibrillator'], + 'transport' => ['bus_stop', 'charging_station', 'bicycle_parking'], + 'healthcare' => ['healthcare', 'laboratory', 'drinking_water'], + 'education' => ['school'], + 'security' => ['police', 'camera'], + 'infrastructure' => ['toilets', 'recycling', 'substation', 'power_pole', 'street_lamp', 'manhole'], + 'mobilier_urbain' => ['bench', 'waste_basket', 'tree', 'advertising_board'], + 'loisirs' => ['playground', 'little_free_library'], + 'commerces' => ['restaurant', 'places'], + 'batiments' => ['building', 'rnb'], + 'divers' => ['email'], + ]; + // Ajouter les thèmes manquants dans une catégorie "divers" + $allGroupedThemes = []; + foreach ($theme_groups as $group => $themes) { + $allGroupedThemes = array_merge($allGroupedThemes, $themes); + } + $missingThemes = array_diff(array_keys($allThemes), $allGroupedThemes); + if (!empty($missingThemes)) { + $theme_groups['divers'] = array_merge($theme_groups['divers'] ?? [], $missingThemes); + } + // --- Ajout : mesures CTC CityFollowUp pour le graphique d'évolution --- $ctc_completion_series = []; foreach ($stats->getCityFollowUps() as $fu) { @@ -673,6 +698,7 @@ final class AdminController extends AbstractController 'ctc_completion_series' => $ctc_completion_series, 'averageUpdateDate' => $averageUpdateDate, 'daysSinceUpdate' => $daysSinceUpdate, + 'theme_groups' => $theme_groups, ]); } diff --git a/src/Controller/PublicController.php b/src/Controller/PublicController.php index 13b97467..216658a7 100644 --- a/src/Controller/PublicController.php +++ b/src/Controller/PublicController.php @@ -1122,7 +1122,12 @@ class PublicController extends AbstractController $types[$type][] = $fu; } } + // Récupérer tous les thèmes connus pour afficher même ceux sans données + $allThemes = \App\Service\FollowUpService::getFollowUpThemes(); + $allIcons = \App\Service\FollowUpService::getFollowUpIcons(); + $evolutions = []; + // D'abord, traiter les types qui ont des données foreach ($types as $type => $fus) { usort($fus, fn($a, $b) => $a->getDate() <=> $b->getDate()); $latest = end($fus); @@ -1140,6 +1145,23 @@ class PublicController extends AbstractController $evolutions[$type][$label] = $past !== null && $latest ? $latest->getMeasure() - $past : null; } } + // Ensuite, ajouter les thèmes qui n'ont pas encore de données + foreach ($allThemes as $theme => $themeLabel) { + if (!isset($evolutions[$theme])) { + $evolutions[$theme] = [ + 'now' => null + ]; + foreach ($periods as $periodLabel => $date) { + $evolutions[$theme][$periodLabel] = null; + } + } + } + // Trier les évolutions par ordre alphabétique des labels + uksort($evolutions, function($a, $b) use ($allThemes) { + $labelA = $allThemes[$a] ?? $a; + $labelB = $allThemes[$b] ?? $b; + return strcasecmp($labelA, $labelB); + }); // Grouper les lieux par date de modification $places = $stats->getPlaces(); $now = new \DateTime(); @@ -1170,6 +1192,8 @@ class PublicController extends AbstractController 'places_7j' => $places_7j, 'places_30j' => $places_30j, 'places_6mois' => $places_6mois, + 'theme_labels' => $allThemes, + 'theme_icons' => $allIcons, ]); } diff --git a/src/Service/FollowUpService.php b/src/Service/FollowUpService.php index 6efd5804..fce5db81 100644 --- a/src/Service/FollowUpService.php +++ b/src/Service/FollowUpService.php @@ -511,7 +511,7 @@ class FollowUpService 'tree' => ['species', 'leaf_type', 'leaf_cycle'], 'power_pole' => ['ref', 'material'], 'places' => ['name', 'address', 'opening_hours', 'website', 'phone', 'wheelchair', 'ref:FR:SIRET', 'contact:phone', 'contact:email', 'contact:website'], - 'manhole' => ['manhole', 'location'], + 'manhole' => ['manhole'], 'little_free_library' => ['amenity', 'operator'], 'playground' => ['playground', 'operator'], 'restaurant' => ['contact:phone', 'phone', 'contact:email', 'email', 'contact:website', 'website', 'cuisine', 'ref:FR:SIRET'], diff --git a/templates/admin/stats.html.twig b/templates/admin/stats.html.twig index 03d6b9e4..fc1b47a0 100644 --- a/templates/admin/stats.html.twig +++ b/templates/admin/stats.html.twig @@ -282,14 +282,7 @@ 'healthcare': 'nwr["healthcare"](area.searchArea);nwr["amenity"="doctors"](area.searchArea);nwr["amenity"="pharmacy"](area.searchArea);nwr["amenity"="hospital"](area.searchArea);nwr["amenity"="clinic"](area.searchArea);nwr["amenity"="social_facility"](area.searchArea);' } %} - {% set theme_groups = { - 'emergency': ['fire_hydrant', 'defibrillator'], - 'transport': ['bus_stop', 'charging_station', 'bicycle_parking'], - 'healthcare': ['healthcare', 'laboratory', 'drinking_water'], - 'education': ['school'], - 'security': ['police', 'camera'], - 'infrastructure': ['toilets', 'recycling', 'substation'] - } %} + {# theme_groups est maintenant passé depuis le contrôleur pour inclure tous les thèmes #}
@@ -346,14 +339,39 @@ {% if loop.first %} + {% set group_display_names = { + 'batiments': '🏢 Bâtiments', + 'commerces': '🏪 Commerces', + 'divers': '📦 Divers', + 'education': '🎓 Éducation', + 'emergency': '🚨 Urgence', + 'healthcare': '🏥 Santé', + 'infrastructure': '🏗️ Infrastructure', + 'loisirs': '🎮 Loisirs', + 'mobilier_urbain': '🪑 Mobilier urbain', + 'security': '🛡️ Sécurité', + 'transport': '🚌 Transport' + } %} + {% set sorted_group_names = group_display_names|keys|sort %} + {% set sorted_group_display_names = {} %} + {% for g in sorted_group_names %} + {% set sorted_group_display_names = sorted_group_display_names|merge({ (g): group_display_names[g] }) %} + + + {% endfor %} {% if group_name == 'emergency' %}🚨 Urgence - {% elseif group_name == 'transport' %}🚌 Transport - {% elseif group_name == 'healthcare' %}🏥 Santé - {% elseif group_name == 'education' %}🎓 Éducation - {% elseif group_name == 'security' %}🛡️ Sécurité - {% elseif group_name == 'infrastructure' %}🏗️ Infrastructure - {% else %}{{ group_name|capitalize }} - {% endif %} + {% elseif group_name == 'transport' %}🚌 Transport + {% elseif group_name == 'healthcare' %}🏥 Santé + {% elseif group_name == 'education' %}🎓 Éducation + {% elseif group_name == 'security' %}🛡️ Sécurité + {% elseif group_name == 'infrastructure' %}🏗️ Infrastructure + {% elseif group_name == 'mobilier_urbain' %}🪑 Mobilier urbain + {% elseif group_name == 'loisirs' %}🎮 Loisirs + {% elseif group_name == 'commerces' %}🏪 Commerces + {% elseif group_name == 'batiments' %}🏢 Bâtiments + {% elseif group_name == 'divers' %}📦 Divers + {% else %}{{ group_name|capitalize }} + {% endif %} {% endif %} diff --git a/templates/public/stats_evolutions.html.twig b/templates/public/stats_evolutions.html.twig index d92ae9fb..00d08efa 100644 --- a/templates/public/stats_evolutions.html.twig +++ b/templates/public/stats_evolutions.html.twig @@ -42,9 +42,14 @@ title="Voir le graphe détaillé"> - {{ tag_emoji(type) }} {{ type }} + {% if theme_icons[type] is defined %} + + {% else %} + {{ tag_emoji(type) }} + {% endif %} + {{ theme_labels[type]|default(type) }} - {{ evo.now }} + {{ evo.now ?? '-' }} {% for p in periods %} {% if evo[p] is not null %}