diff --git a/web/themes/custom/eql/dist/assets/bundle.js b/web/themes/custom/eql/dist/assets/bundle.js index faf01a4..399ea61 100644 --- a/web/themes/custom/eql/dist/assets/bundle.js +++ b/web/themes/custom/eql/dist/assets/bundle.js @@ -36,7 +36,7 @@ eval("/**\n * @file\n * External links js file.\n */\n\n (function ($, Drupal, d \*************************/ /***/ (function() { -eval("jQuery(function ($) {\n console.log('salut');\n\n // MENU BURGER\n const burger = document.getElementById(\"block-burger\");\n const burgertitle = document.getElementById(\"block-burger-menu\");\n if (burger && burgertitle) {\n burgertitle.addEventListener(\"click\", function () {\n burger.classList.toggle('opened');\n });\n }\n\n // FAQ — réponses\n const answers = document.getElementsByClassName(\"field--name-field-reponse\");\n const fichiers = document.getElementsByClassName(\"field--name-field-fichiers\");\n const liens = document.getElementsByClassName(\"field--name-field-liens\");\n const ressources = document.getElementsByClassName(\"field--name-field-ress\");\n const questions = document.getElementsByClassName(\"field--name-field-question\");\n\n for (let i = 0; i < questions.length; i++) {\n const q = questions[i];\n q.addEventListener(\"click\", function () {\n // Réponses\n Array.from(answers).forEach(a => a.classList.remove(\"opened\"));\n const r = this.parentNode.querySelector(\".field--name-field-reponse\");\n if (r) r.classList.add(\"opened\");\n\n // Fichiers\n Array.from(fichiers).forEach(f => f.classList.remove(\"opened\"));\n const f = this.parentNode.querySelector(\".field--name-field-fichiers\");\n if (f) f.classList.add(\"opened\");\n\n // Liens\n Array.from(liens).forEach(l => l.classList.remove(\"opened\"));\n const l = this.parentNode.querySelector(\".field--name-field-liens\");\n if (l) l.classList.add(\"opened\");\n\n // Ressources\n Array.from(ressources).forEach(r => r.classList.remove(\"opened\"));\n const res = this.parentNode.querySelector(\".field--name-field-ress\");\n if (res) res.classList.add(\"opened\");\n });\n }\n\n // SLIDESHOW INIT\n $('.path-frontpage .view-actus-blocks-pages .view-content .view-type-slide .views-row-wrapper').slick({\n slidesToShow: 1,\n dots: true,\n arrows: true,\n centerMode: true,\n responsive: [{\n breakpoint: 810,\n settings: {\n slidesToShow: 1,\n adaptiveHeight: true,\n arrows: false,\n draggable: true,\n centerMode: true,\n }\n }]\n });\n\n $('.page-node-type-actualite .block-entity-fieldnodefield-images .field--type-image').slick({\n dots: true,\n arrows: true,\n adaptiveHeight: true,\n responsive: [{\n breakpoint: 800,\n settings: { adaptiveHeight: true }\n }]\n });\n\n $('.page-node-type-projet .block-entity-fieldnodefield-photo .field--type-image').slick({\n slidesToShow: 1,\n dots: true,\n arrows: false,\n draggable: true,\n adaptiveHeight: true,\n responsive: [{\n breakpoint: 800,\n settings: { adaptiveHeight: true }\n }]\n });\n \n\n \n \n ///// fusion views-type-slide de class identique ////////////\n\n const seen = new Set();\n \n $('.view-type-slide').each(function () {\n const $slide = $(this);\n const classes = $slide.attr('class').split(/\\s+/);\n const typeClass = classes.find(cls => cls.startsWith('type-'));\n \n if (typeClass) {\n if (seen.has(typeClass)) {\n // Trouver le premier slide avec cette classe\n const $target = $('.view-type-slide.' + typeClass).first();\n \n // Déplacer les rows de la slide actuelle vers la première\n $slide.find('.views-row').appendTo($target.find('.views-row-wrapper'));\n \n // Supprimer la slide en double\n $slide.remove();\n } else {\n seen.add(typeClass);\n }\n }\n });\n\n $('.path-ressources .view:not(.view-partenaires) .view-content .view-type-slide .views-row-wrapper').slick({\n slidesToShow: 3,\n dots: false,\n arrows: true,\n infinite: false,\n centerMode: false,\n draggable: true,\n\n responsive: [{\n breakpoint: 810,\n settings: {\n slidesToShow: 3,\n arrows: false,\n draggable: true,\n centerMode: true,\n }\n }]\n });\n\n // Classes media → .wrapper-ressource\n $(\".wrapper-ressource\").each(function () {\n const media = $(this).find(\".field--name-field-type-de-media\").text().trim();\n const className = media\n .toLowerCase()\n .normalize(\"NFD\").replace(/[\\u0300-\\u036f]/g, \"\")\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/(^-|-$)/g, '');\n $(this).addClass('type-media-' + className);\n });\n console.log(\"classses media\");\n\n // MASQUER TYPE DE RESSOURCE DOUBLON\n if (document.body.classList.contains(\"path-ressources\")) {\n $(\".view-type-slide\").each(function () {\n const h3Content = $(this).find(\"h3\").text().trim();\n console.log(h3Content);\n $(this).find(\".field--name-field-type-de-ressource .field__item a\").each(function () {\n if ($(this).text().trim() === h3Content) {\n $(this).hide();\n }\n });\n });\n\n }\n\n // Ouvrir les liens externes dans un nouvel onglet\n document.querySelectorAll('a[href^=\"http\"]').forEach(link => {\n if (!link.href.includes(location.hostname)) {\n link.setAttribute('target', '_blank');\n link.setAttribute('rel', 'noopener noreferrer');\n }\n });\n\n // Scroll automatique au filtre\n if (document.body.classList.contains(\"path-projets\")) {\n const form = document.querySelector(\".views-exposed-form\");\n if (form) form.setAttribute(\"action\", form.action.split(\"#\")[0] + \"#filtres\");\n\n if (window.location.hash === \"#filtres\") {\n const target = document.getElementById(\"filtres\");\n if (target) {\n const offset = 300;\n const top = target.getBoundingClientRect().top + window.pageYOffset - offset;\n window.scrollTo({ top: top, behavior: \"smooth\" });\n }\n }\n\n\n }\n});\n\n\n//# sourceURL=webpack://dev.eql.fr/./scripts/main.js?"); +eval("jQuery(function ($) {\n console.log('salut');\n\n // MENU BURGER\n const burger = document.getElementById(\"block-burger\");\n const burgertitle = document.getElementById(\"block-burger-menu\");\n if (burger && burgertitle) {\n burgertitle.addEventListener(\"click\", function () {\n burger.classList.toggle('opened');\n });\n }\n\n // FAQ — réponses\n const answers = document.getElementsByClassName(\"field--name-field-reponse\");\n const fichiers = document.getElementsByClassName(\"field--name-field-fichiers\");\n const liens = document.getElementsByClassName(\"field--name-field-liens\");\n const ressources = document.getElementsByClassName(\"field--name-field-ress\");\n const questions = document.getElementsByClassName(\"field--name-field-question\");\n\n for (let i = 0; i < questions.length; i++) {\n const q = questions[i];\n q.addEventListener(\"click\", function () {\n // Réponses\n Array.from(answers).forEach(a => a.classList.remove(\"opened\"));\n const r = this.parentNode.querySelector(\".field--name-field-reponse\");\n if (r) r.classList.add(\"opened\");\n\n // Fichiers\n Array.from(fichiers).forEach(f => f.classList.remove(\"opened\"));\n const f = this.parentNode.querySelector(\".field--name-field-fichiers\");\n if (f) f.classList.add(\"opened\");\n\n // Liens\n Array.from(liens).forEach(l => l.classList.remove(\"opened\"));\n const l = this.parentNode.querySelector(\".field--name-field-liens\");\n if (l) l.classList.add(\"opened\");\n\n // Ressources\n Array.from(ressources).forEach(r => r.classList.remove(\"opened\"));\n const res = this.parentNode.querySelector(\".field--name-field-ress\");\n if (res) res.classList.add(\"opened\");\n });\n }\n\n // SLIDESHOW INIT\n $('.path-frontpage .view-actus-blocks-pages .view-content .view-type-slide .views-row-wrapper').slick({\n slidesToShow: 1,\n dots: true,\n arrows: true,\n centerMode: true,\n responsive: [{\n breakpoint: 810,\n settings: {\n slidesToShow: 1,\n adaptiveHeight: true,\n arrows: false,\n draggable: true,\n centerMode: true,\n }\n }]\n });\n\n $('.page-node-type-actualite .block-entity-fieldnodefield-images .field--type-image').slick({\n dots: true,\n arrows: true,\n adaptiveHeight: true,\n responsive: [{\n breakpoint: 800,\n settings: { adaptiveHeight: true }\n }]\n });\n\n $('.page-node-type-projet .block-entity-fieldnodefield-photo .field--type-image').slick({\n slidesToShow: 1,\n dots: true,\n arrows: false,\n draggable: true,\n adaptiveHeight: true,\n responsive: [{\n breakpoint: 800,\n settings: { adaptiveHeight: true }\n }]\n });\n \n\n\n \n \n ///// fusion views-type-slide de class identique ////////////\n\n const seen = new Set();\n \n $('.view-type-slide').each(function () {\n const $slide = $(this);\n const classes = $slide.attr('class').split(/\\s+/);\n const typeClass = classes.find(cls => cls.startsWith('type-'));\n \n if (typeClass) {\n if (seen.has(typeClass)) {\n // Trouver le premier slide avec cette classe\n const $target = $('.view-type-slide.' + typeClass).first();\n \n // Déplacer les rows de la slide actuelle vers la première\n $slide.find('.views-row').appendTo($target.find('.views-row-wrapper'));\n \n // Supprimer la slide en double\n $slide.remove();\n } else {\n seen.add(typeClass);\n }\n }\n });\n\n $('.path-ressources .view:not(.view-partenaires) .view-content .view-type-slide .views-row-wrapper').slick({\n slidesToShow: 3,\n dots: false,\n arrows: true,\n infinite: false,\n centerMode: false,\n draggable: true,\n\n responsive: [{\n breakpoint: 810,\n settings: {\n slidesToShow: 3,\n arrows: false,\n draggable: true,\n centerMode: true,\n }\n }]\n });\n\n // Classes media → .wrapper-ressource\n $(\".wrapper-ressource\").each(function () {\n const media = $(this).find(\".field--name-field-type-de-media\").text().trim();\n const className = media\n .toLowerCase()\n .normalize(\"NFD\").replace(/[\\u0300-\\u036f]/g, \"\")\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/(^-|-$)/g, '');\n $(this).addClass('type-media-' + className);\n });\n console.log(\"classses media\");\n\n // MASQUER TYPE DE RESSOURCE DOUBLON\n if (document.body.classList.contains(\"path-ressources\")) {\n $(\".view-type-slide\").each(function () {\n const h3Content = $(this).find(\"h3\").text().trim();\n console.log(h3Content);\n $(this).find(\".field--name-field-type-de-ressource .field__item a\").each(function () {\n if ($(this).text().trim() === h3Content) {\n $(this).hide();\n }\n });\n });\n\n }\n\n // Ouvrir les liens externes dans un nouvel onglet\n document.querySelectorAll('a[href^=\"http\"]').forEach(link => {\n if (!link.href.includes(location.hostname)) {\n link.setAttribute('target', '_blank');\n link.setAttribute('rel', 'noopener noreferrer');\n }\n });\n\n // Scroll automatique au filtre\n if (document.body.classList.contains(\"path-projets\")) {\n const form = document.querySelector(\".views-exposed-form\");\n if (form) form.setAttribute(\"action\", form.action.split(\"#\")[0] + \"#filtres\");\n\n if (window.location.hash === \"#filtres\") {\n const target = document.getElementById(\"filtres\");\n if (target) {\n const offset = 300;\n const top = target.getBoundingClientRect().top + window.pageYOffset - offset;\n window.scrollTo({ top: top, behavior: \"smooth\" });\n }\n }\n\n\n }\n});\n/////////////////diaporama ressource //////////\ndocument.addEventListener('DOMContentLoaded', function () {\n // Attendre que les éléments HTML soient bien présents\n const interval = setInterval(() => {\n const mainImage = document.getElementById('mainImage');\n const prevArrow = document.getElementById('prevArrow');\n const nextArrow = document.getElementById('nextArrow');\n const caption = document.getElementById('caption');\n const thumbsContainer = document.getElementById('thumbnails');\n const imagesInDom = document.querySelectorAll('.carousel-items .carousel-item img');\n\n if (mainImage && prevArrow && nextArrow && caption && thumbsContainer && imagesInDom) {\n clearInterval(interval); // Tous les éléments sont là, on lance le carrousel\n initCarousel({ mainImage, prevArrow, nextArrow, caption, thumbsContainer });\n }\n }, 100); // vérifie toutes les 100ms\n});\nfunction initCarousel({ mainImage, prevArrow, nextArrow, caption, thumbsContainer }) {\n const images = [];\n document.querySelectorAll('.carousel-items .carousel-item img').forEach((img) => {\n images.push({\n src: img.getAttribute('src'),\n caption: img.getAttribute('alt') || 'Image sans légende'\n });\n });\n console.log('Images chargées pour le carrousel :', images);\n\n if (!images.length) return;\n\n let currentIndex = 0;\n\n function showImage(index) {\n mainImage.src = images[index].src;\n caption.textContent = images[index].caption;\n\n const thumbnails = document.querySelectorAll('.thumbnails img');\n thumbnails.forEach(img => img.classList.remove('active'));\n if (thumbnails[index]) {\n thumbnails[index].classList.add('active');\n }\n }\n\n prevArrow.addEventListener('click', () => {\n currentIndex = (currentIndex - 1 + images.length) % images.length;\n showImage(currentIndex);\n });\n\n nextArrow.addEventListener('click', () => {\n currentIndex = (currentIndex + 1) % images.length;\n showImage(currentIndex);\n });\n\n images.forEach((img, index) => {\n const thumb = document.createElement('img');\n thumb.src = img.src;\n thumb.alt = img.caption;\n thumb.onclick = () => {\n currentIndex = index;\n showImage(index);\n };\n thumbsContainer.appendChild(thumb);\n });\n\n showImage(currentIndex);\n const thumbPrev = document.getElementById('thumbPrev');\n const thumbNext = document.getElementById('thumbNext');\n\n thumbPrev.addEventListener('click', () => {\n thumbsContainer.scrollBy({ left: -150, behavior: 'smooth' });\n });\n\n thumbNext.addEventListener('click', () => {\n thumbsContainer.scrollBy({ left: 150, behavior: 'smooth' });\n });\n\n}\n\n\n//# sourceURL=webpack://dev.eql.fr/./scripts/main.js?"); /***/ }) diff --git a/web/themes/custom/eql/dist/assets/css/bundle.css b/web/themes/custom/eql/dist/assets/css/bundle.css index 5a3fb6f..ca64376 100644 --- a/web/themes/custom/eql/dist/assets/css/bundle.css +++ b/web/themes/custom/eql/dist/assets/css/bundle.css @@ -2206,11 +2206,11 @@ svg.ext { width: fit-content; padding-left: 25%; } -@media screen and (min-width: 1100px) { +@media (min-width: 1100px) { .page-node-type-ressource .layout__region--top .block-region-top .block-entity-fieldnodefield-images { grid-column: 1; - grid-row: 1/span 7; /* Prendre toutes les lignes disponibles */ - align-self: start; /* S'assurer qu'il commence en haut */ + grid-row: 1/span 7; + align-self: start; justify-self: end; margin-left: 2rem; } @@ -5585,7 +5585,7 @@ svg.ext { .path-ressources .layout-content .region-content #block-contenudelapageprincipale .layout--onecol .layout__region--content .block-region-content .block-views-blockbase-de-donnees-block-1 .view-base-de-donnees .view-content .view-type-slide:not(footer) h3.type-les-projets-en-images { width: 80%; border-top: solid 2px rgba(0, 0, 0, 0.3); - padding-top: 4rem; + padding-top: 4 rem; } .path-ressources .layout-content .region-content #block-contenudelapageprincipale .layout--onecol .layout__region--content .block-region-content .block-views-blockbase-de-donnees-block-1 .view-base-de-donnees .view-content .view-type-slide:not(footer) h3.type-les-projets-en-images:before { content: url("../images/pictos/picto-ressource-projetsimages.svg"); @@ -5634,6 +5634,114 @@ svg.ext { right: 15%; } +.page-node-type-ressource .type-les-projets-en-images .block-region-top { + display: flex !important; + flex-direction: column; + margin-left: 11%; +} +@media screen and (min-width: 1100px) { + .page-node-type-ressource .type-les-projets-en-images .block-region-top { + display: flex; + } +} +.page-node-type-ressource .type-les-projets-en-images .block-region-top .block { + margin-left: 0; +} +.page-node-type-ressource .type-les-projets-en-images .block-region-top .block-entity-fieldnodefield-images { + padding: 0; + order: 7; +} +.page-node-type-ressource .type-les-projets-en-images .block-region-top .block-entity-fieldnodefield-images .carousel { + max-width: 60vw; + margin: auto; + text-align: center; +} +.page-node-type-ressource .type-les-projets-en-images .block-region-top .block-entity-fieldnodefield-images .carousel .main-image-container { + position: relative; + height: 500px; + max-height: 500px; + overflow: hidden; + width: 100%; + object-fit: contain; +} +.page-node-type-ressource .type-les-projets-en-images .block-region-top .block-entity-fieldnodefield-images .carousel .main-image-container img { + width: 100%; + height: 100%; + object-fit: contain; + transition: transform 0.3s ease-in-out; +} +.page-node-type-ressource .type-les-projets-en-images .block-region-top .block-entity-fieldnodefield-images .carousel .main-image-container img.animate { + transform: scale(1.02); +} +.page-node-type-ressource .type-les-projets-en-images .block-region-top .block-entity-fieldnodefield-images .carousel .main-image-container .arrow { + position: absolute; + top: 50%; + transform: translateY(-50%); + background: #00aaff; + border-radius: 50%; + padding: 5px 10px; + color: white; + cursor: pointer; +} +content .page-node-type-ressource .type-les-projets-en-images .block-region-top .block-entity-fieldnodefield-images .carousel .main-image-container .arrow.left { + left: 10px; +} +.page-node-type-ressource .type-les-projets-en-images .block-region-top .block-entity-fieldnodefield-images .carousel .main-image-container .arrow.right { + right: 10px; +} +.page-node-type-ressource .type-les-projets-en-images .block-region-top .block-entity-fieldnodefield-images .carousel .caption { + margin-top: 10px; + font-family: sans-serif; +} +.page-node-type-ressource .type-les-projets-en-images .block-region-top .block-entity-fieldnodefield-images .carousel .thumbnails-wrapper { + position: relative; + max-width: 100%; + overflow: hidden; + display: flex; + align-items: center; + justify-content: center; +} +.page-node-type-ressource .type-les-projets-en-images .block-region-top .block-entity-fieldnodefield-images .carousel .thumbnails-wrapper .thumb-arrow { + cursor: pointer; + padding: 5px 10px; + background: #00aaff; + color: white; + border-radius: 50%; + user-select: none; + z-index: 2; +} +.page-node-type-ressource .type-les-projets-en-images .block-region-top .block-entity-fieldnodefield-images .carousel .thumbnails-wrapper .thumb-arrow.left { + margin-right: 10px; +} +.page-node-type-ressource .type-les-projets-en-images .block-region-top .block-entity-fieldnodefield-images .carousel .thumbnails-wrapper .thumb-arrow.right { + margin-left: 10px; +} +.page-node-type-ressource .type-les-projets-en-images .block-region-top .block-entity-fieldnodefield-images .carousel .thumbnails-wrapper .thumbnails { + display: flex; + gap: 10px; + overflow-x: auto; + scroll-behavior: smooth; + max-width: 100%; + padding: 10px 0; + scrollbar-width: none; +} +.page-node-type-ressource .type-les-projets-en-images .block-region-top .block-entity-fieldnodefield-images .carousel .thumbnails-wrapper .thumbnails::-webkit-scrollbar { + display: none; +} +.page-node-type-ressource .type-les-projets-en-images .block-region-top .block-entity-fieldnodefield-images .carousel .thumbnails-wrapper .thumbnails img { + width: 60px; + height: 60px; + object-fit: cover; + border: 2px solid transparent; + cursor: pointer; +} +.page-node-type-ressource .type-les-projets-en-images .block-region-top .block-entity-fieldnodefield-images .carousel .thumbnails-wrapper .thumbnails img.active { + border-color: #00aaff; +} +.page-node-type-ressource .type-les-projets-en-images .block-region-top .block-entity-fieldnodefield-images .field__items { + display: none; +} + /*partials*/ .layout-container { position: relative; diff --git a/web/themes/custom/eql/eql.theme b/web/themes/custom/eql/eql.theme index 3e30fdc..e446bef 100644 --- a/web/themes/custom/eql/eql.theme +++ b/web/themes/custom/eql/eql.theme @@ -14,9 +14,18 @@ use Drupal\Core\Template\Attribute; function eql_preprocess_html(&$variables) { $node = \Drupal::routeMatch()->getParameter('node'); - if ($node){ + if ($node instanceof NodeInterface) { $variables['attributes']['class'][] = 'node-type-' . $node->bundle(); $variables['attributes']['class'][] = 'node-id-' . $node->id(); + + // Pour les ressources : ajoute la classe de type de ressource + if ($node->bundle() === 'ressource' && $node->hasField('field_type_de_ressource')) { + foreach ($node->get('field_type_de_ressource')->referencedEntities() as $term) { + $label = $term->label(); + $css_class = 'type-' . Html::getClass($label); + $variables['attributes']['class'][] = $css_class; + } + } } } @@ -33,16 +42,7 @@ function eql_preprocess_node(&$variables){ $type_protagoniste = $node->get('field_type_de_protagoniste')->getString(); $variables['attributes']['class'][] = 'type-de-protagoniste-' . $type_protagoniste; } - - // if ($node->hasField('field_type_de_ressource') && !$node->get('field_type_de_ressource')->isEmpty()) { - // // Récupère la valeur de field_type_de_ressource - // $type_de_ressource_entity = $node->get('field_type_de_ressource')->entity; - // if ($type_de_ressource_entity) { - // $type_de_ressource_name = $type_de_ressource_entity->getName(); - // // Ajoute la classe CSS basée sur la valeur du type de ressource - // $variables['attributes']['class'][] = 'type-de-ressource-' . Html::cleanCssIdentifier($type_de_ressource_name); - // } - // } + if ($node->getType() === 'ressource' && $node->hasField('field_type_de_ressource') && !$node->get('field_type_de_ressource')->isEmpty()) { foreach ($node->get('field_type_de_ressource')->referencedEntities() as $term) { $label = $term->label(); // ex: "Presse" @@ -51,6 +51,26 @@ function eql_preprocess_node(&$variables){ } } } +function eql_preprocess_page(array &$variables) { + $node = \Drupal::routeMatch()->getParameter('node'); + if ($node instanceof \Drupal\node\NodeInterface && $node->bundle() === 'ressource') { + if ($node->hasField('field_type_de_ressource') && !$node->get('field_type_de_ressource')->isEmpty()) { + foreach ($node->get('field_type_de_ressource')->referencedEntities() as $term) { + $label = $term->label(); + $css_class = 'type-' . \Drupal\Component\Utility\Html::getClass($label); + + // S'assurer que les attributs existent + if (!isset($variables['page']['top']['#attributes'])) { + $variables['page']['top']['#attributes'] = ['class' => []]; + } + + $variables['page']['top']['#attributes']['class'][] = $css_class; + } + } + } +} + + function eql_preprocess_field(&$variables) { $node = \Drupal::routeMatch()->getParameter('node'); @@ -76,6 +96,7 @@ function eql_preprocess_field(&$variables) { function eql_preprocess_layout__threecol_25_50_25(&$variables) { $node = \Drupal::routeMatch()->getParameter('node'); + if($node->gettype() == "projet"){ $variables['content']['top_bottom'] = []; /////// déclare les nvx array $variables['content']['top_right'] = []; @@ -102,39 +123,27 @@ function eql_preprocess_layout__threecol_25_50_25(&$variables) { } } } + + if ($node && $node->getType() === 'ressource') { + if ($node->hasField('field_type_de_ressource') && !$node->get('field_type_de_ressource')->isEmpty()) { + $terms = $node->get('field_type_de_ressource')->referencedEntities(); + if (!empty($terms)) { + $label = $terms[0]->label(); + $css_class = 'type-' . Html::cleanCssIdentifier(strtolower($label)); + + // Appliquer cette classe à la région "top" + if (!isset($variables['region_attributes']['top'])) { + $variables['region_attributes']['top'] = new \Drupal\Core\Template\Attribute(); + } + + $variables['region_attributes']['top']->addClass($css_class); + } + } + } } - -// function eql_preprocess_views_view_unformatted(&$variables) { -// // On utilise le service de translittération de Drupal -// $transliterator = \Drupal::service('transliteration'); - -// foreach ($variables['rows'] as &$row) { -// if (isset($row['content']['#node'])) { -// $node = $row['content']['#node']; - -// if ($node->hasField('field_type_de_ressource') && !$node->get('field_type_de_ressource')->isEmpty()) { -// foreach ($node->get('field_type_de_ressource')->referencedEntities() as $term) { -// $label = $term->label(); - -// // Supprimer les accents -// $label_ascii = $transliterator->transliterate($label); - -// // Nettoyer pour que ce soit une classe CSS valide -// $class = 'type-' . Html::cleanCssIdentifier(strtolower($label_ascii)); - -// $row['attributes']->addClass($class); -// } -// } -// } -// } -// } - - - - function eql_preprocess_views_view_unformatted(array &$variables) { $view = $variables['view']; diff --git a/web/themes/custom/eql/scripts/main.js b/web/themes/custom/eql/scripts/main.js index 70ac91d..46ce5b7 100644 --- a/web/themes/custom/eql/scripts/main.js +++ b/web/themes/custom/eql/scripts/main.js @@ -83,6 +83,7 @@ jQuery(function ($) { }); + ///// fusion views-type-slide de class identique //////////// @@ -180,3 +181,79 @@ jQuery(function ($) { } }); +/////////////////diaporama ressource ////////// +document.addEventListener('DOMContentLoaded', function () { + // Attendre que les éléments HTML soient bien présents + const interval = setInterval(() => { + const mainImage = document.getElementById('mainImage'); + const prevArrow = document.getElementById('prevArrow'); + const nextArrow = document.getElementById('nextArrow'); + const caption = document.getElementById('caption'); + const thumbsContainer = document.getElementById('thumbnails'); + const imagesInDom = document.querySelectorAll('.carousel-items .carousel-item img'); + + if (mainImage && prevArrow && nextArrow && caption && thumbsContainer && imagesInDom) { + clearInterval(interval); // Tous les éléments sont là, on lance le carrousel + initCarousel({ mainImage, prevArrow, nextArrow, caption, thumbsContainer }); + } + }, 100); // vérifie toutes les 100ms +}); +function initCarousel({ mainImage, prevArrow, nextArrow, caption, thumbsContainer }) { + const images = []; + document.querySelectorAll('.carousel-items .carousel-item img').forEach((img) => { + images.push({ + src: img.getAttribute('src'), + caption: img.getAttribute('alt') || 'Image sans légende' + }); + }); + console.log('Images chargées pour le carrousel :', images); + + if (!images.length) return; + + let currentIndex = 0; + + function showImage(index) { + mainImage.src = images[index].src; + caption.textContent = images[index].caption; + + const thumbnails = document.querySelectorAll('.thumbnails img'); + thumbnails.forEach(img => img.classList.remove('active')); + if (thumbnails[index]) { + thumbnails[index].classList.add('active'); + } + } + + prevArrow.addEventListener('click', () => { + currentIndex = (currentIndex - 1 + images.length) % images.length; + showImage(currentIndex); + }); + + nextArrow.addEventListener('click', () => { + currentIndex = (currentIndex + 1) % images.length; + showImage(currentIndex); + }); + + images.forEach((img, index) => { + const thumb = document.createElement('img'); + thumb.src = img.src; + thumb.alt = img.caption; + thumb.onclick = () => { + currentIndex = index; + showImage(index); + }; + thumbsContainer.appendChild(thumb); + }); + + showImage(currentIndex); + const thumbPrev = document.getElementById('thumbPrev'); + const thumbNext = document.getElementById('thumbNext'); + + thumbPrev.addEventListener('click', () => { + thumbsContainer.scrollBy({ left: -150, behavior: 'smooth' }); + }); + + thumbNext.addEventListener('click', () => { + thumbsContainer.scrollBy({ left: 150, behavior: 'smooth' }); + }); + +} diff --git a/web/themes/custom/eql/scss/pages/_ressource-type-en-images.scss b/web/themes/custom/eql/scss/pages/_ressource-type-en-images.scss new file mode 100644 index 0000000..9988bc3 --- /dev/null +++ b/web/themes/custom/eql/scss/pages/_ressource-type-en-images.scss @@ -0,0 +1,147 @@ + +.page-node-type-ressource{ + + .type-les-projets-en-images .block-region-top{ + display: flex !important; + flex-direction: column; + margin-left: 11%; + @media screen and (min-width:1100px) { + display: flex; + } + .block { + margin-left: 0; + } + .block-entity-fieldnodefield-images{ + padding: 0; + order: 7; + + .carousel { + max-width: 60vw; + margin: auto; + text-align: center; + + .main-image-container { + position: relative; + // background: #e0f5ff; + height: 500px; + max-height: 500px; + overflow: hidden; + width: 100%; + object-fit: contain; + + img { + width: 100%; + height: 100%; + object-fit: contain; + transition: transform 0.3s ease-in-out; + // transition: opacity 0.4s ease-in-out; // à réactiver si fade souhaité + &.animate { + transform: scale(1.02); // léger effet smooth sur changement + } + } + + .arrow { + position: absolute; + top: 50%; + transform: translateY(-50%); + background: #00aaff; + border-radius: 50%; + padding: 5px 10px; + color: white; + cursor: pointer; + content + + &.left { + left: 10px; + } + + &.right { + right: 10px; + } + } + // #prevArrow{ + // &::before{ + // content:url("../images/pictos/fleche-droite-dans-rond.png"); + // display: block; + // transform: scaleX(-1); + // width: 50px; + // } + // } + // #nextArrow{ + // &::before{ + // content:url("../images/pictos/fleche-droite-dans-rond.png"); + // display: block; + // } + // } + } + + .caption { + margin-top: 10px; + font-family: sans-serif; + } + + .thumbnails-wrapper { + position: relative; + max-width: 100%; + overflow: hidden; + display: flex; + align-items: center; + justify-content: center; + + .thumb-arrow { + cursor: pointer; + padding: 5px 10px; + background: #00aaff; + color: white; + border-radius: 50%; + user-select: none; + z-index: 2; + // font-weight: bold; + + &.left { + margin-right: 10px; + } + + &.right { + margin-left: 10px; + } + } + + .thumbnails { + display: flex; + gap: 10px; + overflow-x: auto; + scroll-behavior: smooth; + max-width: 100%; + padding: 10px 0; + scrollbar-width: none; // Firefox + + &::-webkit-scrollbar { + display: none; // Chrome, Safari + } + + img { + width: 60px; + height: 60px; + object-fit: cover; + border: 2px solid transparent; + cursor: pointer; + + &.active { + border-color: #00aaff; + } + } + } + } + } + + // Masquer les images Drupal originales (facultatif) + .field__items { + display: none; + } + } + + } + + // } +} \ No newline at end of file diff --git a/web/themes/custom/eql/scss/pages/_ressource.scss b/web/themes/custom/eql/scss/pages/_ressource.scss index 8d49ad8..e87b3cb 100644 --- a/web/themes/custom/eql/scss/pages/_ressource.scss +++ b/web/themes/custom/eql/scss/pages/_ressource.scss @@ -10,6 +10,7 @@ @media (max-width: 550px) { padding-top: 0rem; } + .block-region-top{ display: flex; flex-direction: column; @@ -18,27 +19,31 @@ grid-template-columns: 1fr 2fr; /* 1/3 pour l'image, 2/3 pour le contenu */ gap: 0.5rem; } - .block-entity-fieldnodefield-images{ + + .block-entity-fieldnodefield-images { width: fit-content; - // padding-right: 2rem; padding-left: 25%; - - @media screen and (min-width:1100px) { - grid-column: 1; - grid-row: 1 /span 7; /* Prendre toutes les lignes disponibles */ - align-self: start; /* S'assurer qu'il commence en haut */ - justify-self: end; - margin-left: 2rem; + + @media (min-width: 1100px) { + grid-column: 1; + grid-row: 1 / span 7; + align-self: start; + justify-self: end; + margin-left: 2rem; } + @media (max-width: 1100px) { - padding-left: 13%; + padding-left: 13%; } + @media (max-width: 550px) { - width: 100vw; - padding: 0; + width: 100vw; + padding: 0; } - - } + + + } + .block-block-content4e5df355-e76c-4e44-bec0-e211d94f2640, .block-entity-fieldnodefield-type-de-ressource, .block-entity-fieldnodetitle, @@ -164,6 +169,8 @@ } + .block-region-top:has(.type-de-media-video) + .block-region-top:has(.type-de-media-video){ } @@ -181,6 +188,7 @@ display: none; } } + .layout__region--first{ // menu ancres a gauche margin-top: 3rem; position: relative; diff --git a/web/themes/custom/eql/scss/pages/ressources.scss b/web/themes/custom/eql/scss/pages/ressources.scss index bcabb4c..1382782 100644 --- a/web/themes/custom/eql/scss/pages/ressources.scss +++ b/web/themes/custom/eql/scss/pages/ressources.scss @@ -346,7 +346,7 @@ h3.type-les-projets-en-images { width: 80%; border-top: solid 2px rgba(0, 0, 0, 0.3); - padding-top: 4rem; + padding-top: 4 rem; &:before{ content:url("../images/pictos/picto-ressource-projetsimages.svg"); padding-right: 1rem; diff --git a/web/themes/custom/eql/scss/styles.scss b/web/themes/custom/eql/scss/styles.scss index c0ed207..6fc27c1 100644 --- a/web/themes/custom/eql/scss/styles.scss +++ b/web/themes/custom/eql/scss/styles.scss @@ -53,6 +53,7 @@ @import "pages/_incubateur"; @import "pages/_lincubateur_newpage"; @import "pages/ressources"; +@import "pages/ressource-type-en-images"; diff --git a/web/themes/custom/eql/templates/block--entity-field--node--field-images.html.twig b/web/themes/custom/eql/templates/block--entity-field--node--field-images.html.twig new file mode 100644 index 0000000..cea01f7 --- /dev/null +++ b/web/themes/custom/eql/templates/block--entity-field--node--field-images.html.twig @@ -0,0 +1,61 @@ +{# +/** + * @file + * Theme override to display a block. + * + * Available variables: + * - plugin_id: The ID of the block implementation. + * - label: The configured label of the block if visible. + * - configuration: A list of the block's configuration values. + * - label: The configured label for the block. + * - label_display: The display settings for the label. + * - provider: The module or other provider that provided this block plugin. + * - Block plugin specific settings will also be stored here. + * - content: The content of this block. + * - attributes: array of HTML attributes populated by modules, intended to + * be added to the main container tag of this template. + * - id: A valid HTML ID and guaranteed unique. + * - title_attributes: Same as attributes, except applied to the main title + * tag that appears in the template. + * - title_prefix: Additional output populated by modules, intended to be + * displayed in front of the main title tag that appears in the template. + * - title_suffix: Additional output populated by modules, intended to be + * displayed after the main title tag that appears in the template. + * + * @see template_preprocess_block() + */ +#} +{% + set classes = [ + 'block', + 'block-' ~ configuration.provider|clean_class, + 'block-' ~ plugin_id|clean_class, + ] +%} +