diff --git a/config/sync/core.extension.yml b/config/sync/core.extension.yml
index ec9d810..a4cebfa 100644
--- a/config/sync/core.extension.yml
+++ b/config/sync/core.extension.yml
@@ -48,6 +48,7 @@ module:
entity_browser: 0
entity_browser_enhanced: 0
entity_reference_revisions: 0
+ erable_mod: 0
faq: 0
field: 0
field_group: 0
diff --git a/config/sync/page_manager.page_variant.home-panels_variant-0.yml b/config/sync/page_manager.page_variant.home-panels_variant-0.yml
index 854900e..1536265 100644
--- a/config/sync/page_manager.page_variant.home-panels_variant-0.yml
+++ b/config/sync/page_manager.page_variant.home-panels_variant-0.yml
@@ -7,6 +7,7 @@ dependencies:
- views.view.actus
- views.view.home_blocks
module:
+ - erable_mod
- panels
- views
id: home-panels_variant-0
@@ -55,6 +56,15 @@ variant_settings:
region: content
weight: 1
uuid: 0e39f25a-d433-49bd-84d4-3e6c11c16c47
+ 41595e31-d8d6-4940-a1e5-8687c04af5a5:
+ id: sitesmap_block
+ label: 'Sites map Block'
+ label_display: '0'
+ provider: erable_mod
+ context_mapping: { }
+ region: content
+ weight: 0
+ uuid: 41595e31-d8d6-4940-a1e5-8687c04af5a5
page_title: ''
layout: layout_onecol
layout_settings:
diff --git a/web/modules/custom/erable_mod/assets/css/carte-interactive.css b/web/modules/custom/erable_mod/assets/css/carte-interactive.css
new file mode 100644
index 0000000..09af117
--- /dev/null
+++ b/web/modules/custom/erable_mod/assets/css/carte-interactive.css
@@ -0,0 +1,98 @@
+@font-face {
+ font-family: 'gilroy-semibold';
+ src: url('../css/fonts/Gilroy/gilroy-semibold-webfont.woff') format('woff');
+}
+#sites-map-container {
+ background-color: transparent;
+ text-align: center;
+ position: relative;
+ width: 100%; /* Prend toute la largeur du conteneur parent */
+ max-width: 800px; /* Optionnel : Limiter la largeur maximale */
+ margin: 0 auto; /* Centrer le conteneur */
+ height: auto; /* Permet à la hauteur de s'ajuster automatiquement */
+ @media (max-width: 810px) {
+ width: 80%; /* Prend toute la largeur du conteneur parent */
+ }
+ @media (max-width: 530px) {
+ width: 100%; /* Prend toute la largeur du conteneur parent */
+ height: 485px;
+ }
+ @media (max-width: 400px) {
+ width: 100%; /* Prend toute la largeur du conteneur parent */
+ height: 430px;
+ }
+}
+
+
+
+/* Changer la couleur au survol (hover) */
+#sites-map-container .site-link:hover{
+ cursor: pointer;
+}
+
+
+/* Styles du popup (caché par défaut) */
+#sites-map-container #popup {
+ font-family: 'gilroy-light';
+ display: none;
+ position: absolute;
+ z-index: 1000;
+ text-align: left;
+ padding-left: 1rem;
+ pointer-events: none;
+ @media (max-width: 1090px) {
+ bottom: 20px;
+ }
+
+}
+
+/* Position du popup à droite lorsque l'écran est plus grand que 1090px */
+@media (min-width: 1090px) {
+ #sites-map-container #popup {
+ top: 50%; /* Centrer verticalement */
+ left: 80%; /* Placer le popup à droite de la carte */
+ transform: translateY(-50%); /* Ajuster pour centrer verticalement */
+ width: 300px;
+ }
+}
+
+
+#sites-map-container strong{
+ color: #f7002b;
+ font-family: 'gilroy-bold';
+}
+#sites-map-container a{
+ display: none;
+ align-items: center;
+ color: white;
+ background: black;
+ text-transform: uppercase;
+ font-size: 0.8rem;
+ padding-left: 0.5rem;
+ text-decoration: none;
+ margin-top: 0.7rem;
+ height: 1.3rem;
+}
+#sites-map-container a:after{
+ display: inline-flex;
+ content: url("../img/noun-arrow-to-right.svg");
+ padding-right: 0.2rem;
+ padding-left: 0.2rem;
+
+}
+
+#popup-content{
+ width: 300px;
+ padding-right: 30px;
+
+ p{
+ font-size: 0.7rem;
+ }
+ @media (max-width : 810px) {
+ width: 300px;
+ background-color: white;
+ border-radius: 5px;
+ padding: 0.5rem;
+ padding-left: 1rem;
+ }
+}
diff --git a/web/modules/custom/erable_mod/assets/css/fonts/Gilroy/gilroy-semibold-webfont.woff b/web/modules/custom/erable_mod/assets/css/fonts/Gilroy/gilroy-semibold-webfont.woff
new file mode 100644
index 0000000..8abd458
Binary files /dev/null and b/web/modules/custom/erable_mod/assets/css/fonts/Gilroy/gilroy-semibold-webfont.woff differ
diff --git a/web/modules/custom/erable_mod/assets/js/carte-interactive.js b/web/modules/custom/erable_mod/assets/js/carte-interactive.js
new file mode 100644
index 0000000..30abdbc
--- /dev/null
+++ b/web/modules/custom/erable_mod/assets/js/carte-interactive.js
@@ -0,0 +1,116 @@
+// // Sélection des éléments principaux
+const svgElement = document.querySelector('#sites-map-container svg');
+const popup = document.querySelector('#sites-map-container #popup');
+const popupContent = document.querySelector('#sites-map-container #popup-content');
+const modalBackground = document.querySelector('#sites-map-container #modal-background');
+
+// Vérifiez si la page contient la classe '.node-type-site'
+const isSitePage = document.body.classList.contains('node-type-site');
+
+
+// Fonction pour afficher le popup
+function showPopup(content, x, y, isLeftHalf) {
+ // Si on est sur une page avec la classe 'node-type-site', ne pas afficher le popup
+ if (isSitePage) return;
+
+ popupContent.innerHTML = content;
+
+
+ // Afficher le popup et le fond de modal
+ popup.style.display = 'block';
+ modalBackground.style.display = 'block';
+
+}
+
+// Fonction pour fermer le popup
+function closePopup() {
+ popup.style.display = 'none';
+ modalBackground.style.display = 'none'; // Désactiver le fond modal
+}
+
+// Gérer le survol des cercles (au lieu du clic)
+svgElement.addEventListener('mouseover', function(event) {
+ if (event.target.classList.contains('site-link')) {
+ const content = event.target.getAttribute('data-content');
+
+ // Afficher le popup avec la position et l'alignement adaptés
+ showPopup(content);
+ }
+
+ // Gestion du changement de couleur sur le cercle
+ if (event.target.tagName === 'circle') {
+ event.target.setAttribute('fill', 'red');
+ }
+});
+
+// Fermer le popup lorsque la souris quitte le cercle
+svgElement.addEventListener('mouseout', function(event) {
+ if (event.target.classList.contains('site-link')) {
+ closePopup();
+ }
+
+ // Réinitialiser la couleur du cercle au survol de la souris
+ if (event.target.tagName === 'circle') {
+ event.target.setAttribute('fill', 'black'); // Remettre en noir
+ }
+});
+
+
+// Mettre à jour la logique de calcul des positions
+function recalculateSitePositions() {
+ const allSites = document.querySelectorAll('.site-link');
+
+ allSites.forEach((site, index) => {
+ const geofield = site.getAttribute('data-geofield'); // Assurez-vous que ces attributs sont bien définis
+ const lon = parseFloat(geofield.split(',')[0]);
+ const lat = parseFloat(geofield.split(',')[1]);
+
+ const x = round((lon - lonLeft) / (lonRight - lonLeft) * vp_w);
+ const y = round((latTop - lat) / (latTop - latBottom) * vp_h);
+
+ site.setAttribute('transform', `translate(${x}, ${y})`);
+ });
+}
+
+window.addEventListener('resize', function() {
+ recalculateSitePositions();
+ if (popup.style.display === 'block') {
+ const currentPopupRect = popup.getBoundingClientRect();
+ const rect = svgElement.getBoundingClientRect();
+ showPopup(popupContent.innerHTML, currentPopupRect.left - rect.left, currentPopupRect.top - rect.top);
+ }
+});
+
+// Gérer le clic ou le toucher des cercles
+function handleCircleClick(content) {
+ showPopup(content, event.clientX, event.clientY, event.target.getAttribute('data-left-half') === 'true');
+}
+
+// Écouter les événements de clic et de toucher sur le SVG
+svgElement.addEventListener('click', function(event) {
+ if (event.target.classList.contains('site-link') || event.target.tagName === 'rect') {
+ const content = event.target.getAttribute('data-content');
+ handleCircleClick(content);
+ }
+});
+
+
+///////////////////// page site point rouge quand sur page ///////////////////////
+
+// Récupérer l'ID de la page depuis la classe du body
+const body = document.querySelector('body');
+const pageId = body.className.match(/node-id-(\d+)/)[1]; // Extraire l'ID de la page
+
+// Sélectionner le groupe SVG qui a l'ID correspondant
+const matchingGroup = document.querySelector(`#site-${pageId}`);
+
+// Si un groupe correspondant est trouvé, changer la couleur du cercle à l'intérieur
+if (matchingGroup) {
+ const circle = matchingGroup.querySelector('circle'); // Sélectionner le cercle à l'intérieur du groupe
+ if (circle) {
+ circle.setAttribute('fill', 'red'); // Changer la couleur du cercle
+ }
+}
+
+
+
diff --git a/web/modules/custom/erable_mod/erable_mod.info.yml b/web/modules/custom/erable_mod/erable_mod.info.yml
new file mode 100644
index 0000000..a73f431
--- /dev/null
+++ b/web/modules/custom/erable_mod/erable_mod.info.yml
@@ -0,0 +1,7 @@
+name: erable_mod
+type: module
+description: Provides additional functionality for the site.
+package: Custom
+core_version_requirement: ^9 || ^10
+dependencies:
+ - drupal:block
\ No newline at end of file
diff --git a/web/modules/custom/erable_mod/erable_mod.libraries.yml b/web/modules/custom/erable_mod/erable_mod.libraries.yml
new file mode 100644
index 0000000..50a42b1
--- /dev/null
+++ b/web/modules/custom/erable_mod/erable_mod.libraries.yml
@@ -0,0 +1,7 @@
+sites_map_block:
+ css:
+ theme:
+ assets/css/fontface.scss: {}
+ assets/css/carte-interactive.css: {}
+ js:
+ assets/js/carte-interactive.js: {}
\ No newline at end of file
diff --git a/web/modules/custom/erable_mod/erable_mod.module b/web/modules/custom/erable_mod/erable_mod.module
new file mode 100644
index 0000000..ee58c18
--- /dev/null
+++ b/web/modules/custom/erable_mod/erable_mod.module
@@ -0,0 +1,17 @@
+ array(
+ 'variables' => array('vpw' => null, 'vph' => null, 'sites' => []),
+ ),
+ );
+}
\ No newline at end of file
diff --git a/web/modules/custom/erable_mod/src/Plugin/Block/SitesMap.php b/web/modules/custom/erable_mod/src/Plugin/Block/SitesMap.php
new file mode 100644
index 0000000..9533366
--- /dev/null
+++ b/web/modules/custom/erable_mod/src/Plugin/Block/SitesMap.php
@@ -0,0 +1,115 @@
+getStorage('node')
+ ->loadByProperties(['type' => 'projet', 'status' => 1]);
+
+ $sites_paths = "";
+
+ $vp_w = 600;
+ $vp_h = 600;
+
+ // Coordonnées géographiques des coins de la carte (France)
+ $latTop = 52.0; // Nord-Ouest (coin supérieur gauche)
+ $lonLeft = -6.0;
+ $latBottom = 40.0; // Sud-Est (coin inférieur droit)
+ $lonRight = 11.0;
+
+
+ foreach($allSites as $index => $site){
+ $title = $site->get('title')->getString();
+ $subtitle = $site->get('field_sous_titre')->getString();
+
+ $link_options = ['absolute' => FALSE, 'attributes' => ['class' => 'site-link']];
+ $site_link_object = Link::createFromRoute("voir le site", 'entity.node.canonical', ['node' => $site->id()], $link_options);
+ $link = $site_link_object->toString()->getGeneratedLink();
+
+ $datacontent = htmlspecialchars("$title
$subtitle
$link");
+
+ $geofield = $site->get('field_carte')->get(0);
+ $lon = $geofield->lon;
+ $lat = $geofield->lat;
+ $geofieldData = "$lon,$lat"; // Utiliser une chaîne pour stocker la position
+
+ $x = round(($lon - $lonLeft) / ($lonRight - $lonLeft) * $vp_w);
+ $y = round(($latTop - $lat) / ($latTop - $latBottom) * $vp_h);
+
+ $r = 10;
+ $m = -$r+4;
+ $l = $r*2-7;
+ $sites_paths .= <<
+ >
+
+
+
+
+
+
+
+ SVGSITEPATH;
+ }
+
+
+ $return = [
+ '#cache' => [
+ 'max-age' => 0,
+ ],
+ 'svg_mapsites' => [
+ '#theme' => 'svg_mapsites',
+ '#sites' => $sites_paths,
+ '#vpw' => $vp_w,
+ '#vph' => $vp_h,
+ '#attached' => [
+ 'library' => [
+ 'erable_mod/sites_map_block',
+ ],
+ ],
+ ]
+ ];
+
+ return $return;
+ // return [
+ // '#markup' => $this->t('Hello, Sites Map!'),
+ // ];
+ }
+ public function getCacheMaxAge() {
+ return 0;
+ }
+}
\ No newline at end of file
diff --git a/web/modules/custom/erable_mod/templates/svg-mapsites.html.twig b/web/modules/custom/erable_mod/templates/svg-mapsites.html.twig
new file mode 100644
index 0000000..b0e1544
--- /dev/null
+++ b/web/modules/custom/erable_mod/templates/svg-mapsites.html.twig
@@ -0,0 +1,52 @@
+
+ {#
#}
+
+
+
+
+
+
+
+
\ No newline at end of file