diff --git a/web/themes/custom/caravane/assets/js/stores/content.js b/web/themes/custom/caravane/assets/js/stores/content.js index 54e6d24..a0fc2f4 100644 --- a/web/themes/custom/caravane/assets/js/stores/content.js +++ b/web/themes/custom/caravane/assets/js/stores/content.js @@ -6,7 +6,7 @@ import REST from '../api/rest-axios'; import { useLayoutStore } from './layout'; import { findContentByPath } from '../utils/content/findContentByPath'; -import { getCleanDate, fetchFromRelationships, getRelatedEtape } from '../utils/content/contentFetchUtils'; +import { getCleanDate, fetchFromRelationships, getRelatedEtape, getRelatedRessources } from '../utils/content/contentFetchUtils'; import { getCarteSensible, getTitreTexte, getChiffresCles, getDiaporama, getEntretien, getVideos, getDocument, getGallerie } from '../utils/content/cleanParties'; import { getPartenaires, getGouvernance, getRessources } from '../utils/content/multiItemPages'; @@ -52,13 +52,22 @@ export const useContentStore = defineStore('content', { start: getCleanDate(rawContent.attributes.field_dates.value), end: getCleanDate(rawContent.attributes.field_dates.end_value), } + this.content.relatedRessources = await getRelatedRessources(rawContent.id); } if (this.contentType === 'ressourceItem') { + console.log(rawContent); + this.content.ressourceType = rawContent.attributes.field_type_de_ressource; this.content.auteurice = rawContent.attributes.field_autheurice; this.content.date = getCleanDate(rawContent.attributes.field_date_ressource); - this.content.introduction = rawContent.attributes.field_introduction?.processed; + this.content.introduction = rawContent.attributes.field_introduction?.processed; + if (rawContent.relationships.field_etape.data) { + const relatedEtapeFetch = fetchFromRelationships('field_etape', rawContent.relationships); + const relatedEtape = await Promise.resolve(relatedEtapeFetch); + const relatedEtapeUrl = relatedEtape.attributes.metatag.find(tag => tag.tag === "link")?.attributes.href; + this.content.relatedEtape = await getRelatedEtape('', relatedEtapeUrl); + } useLayoutStore().hideEtapeList(true); } @@ -169,7 +178,7 @@ export const useContentStore = defineStore('content', { switch (this.contentType) { case 'ressource': - multiItemPageArray = await getRessources(rawContent); + multiItemPageArray = await getRessources(rawContent); this.content.ressourceTypes = new Set(multiItemPageArray.map(item => item.ressourceType)); useLayoutStore().hideEtapeList(true); break; diff --git a/web/themes/custom/caravane/assets/js/stores/layout.js b/web/themes/custom/caravane/assets/js/stores/layout.js index 23d9999..823985d 100644 --- a/web/themes/custom/caravane/assets/js/stores/layout.js +++ b/web/themes/custom/caravane/assets/js/stores/layout.js @@ -47,7 +47,8 @@ export const useLayoutStore = defineStore('layout', { this.toggleEtapeListScroll(isIntersecting, listeEtape, column, headerRect.height, animationToggleRect.top); }, hideEtapeList(souldListHide) { - const etapeList = document.querySelector('#etapes-liste'); + const etapeList = document.querySelector(window.innerWidth >= this.minDesktopWidth ? '#etapes-liste' : '.layout__region--third'); + const animationButton = document.querySelector('#animation-toggle'); const listContainer = etapeList.parentNode; if (souldListHide) { listContainer.style.minWidth = '30vw'; @@ -55,12 +56,18 @@ export const useLayoutStore = defineStore('layout', { setTimeout(() => { etapeList.style.display = 'none'; }, 300); + if (window.innerWidth >= this.minDesktopWidth) { + animationButton.style.display = 'none'; + } } else { listContainer.style.minWidth = 'unset'; etapeList.style.display = 'block'; setTimeout(() => { etapeList.style.opacity = '1'; }, 10); + if (window.innerWidth >= this.minDesktopWidth) { + animationButton.style.display = 'block'; + } } }, toggleEtapeListScroll(isIntersecting, listeEtape, column, headerHeight, animationToggleTop) { diff --git a/web/themes/custom/caravane/assets/js/utils/content/contentFetchUtils.js b/web/themes/custom/caravane/assets/js/utils/content/contentFetchUtils.js index fcf5629..a6933ee 100644 --- a/web/themes/custom/caravane/assets/js/utils/content/contentFetchUtils.js +++ b/web/themes/custom/caravane/assets/js/utils/content/contentFetchUtils.js @@ -60,9 +60,85 @@ export async function getRelatedEtape(direction, path) { if (etape.attributes.metatag.some(tag => tag.tag === "link" && tag.attributes.href === path )) { - const relatedEtapeIndex = direction === 'next' ? index + 1 : index - 1; + const relatedEtapeIndex = direction ? (direction === 'next' ? index + 1 : index - 1) : index; return getRelatedEtapeContent(allEtapesData.data.data[relatedEtapeIndex]); } } }); +} + +export async function getRessourceItemCard(item) { + try { + const ressourceFetch = await REST.get(item.links.self.href); + + const partiesFetch = await REST.get(item.relationships.field_parties_ressource.links.related.href); + const parties = partiesFetch.data.data; + + const vignettePartie = parties.find(partie => partie.type !== "paragraph--titre_texte"); + + let vignette = null; + if (vignettePartie) { + let alt; + switch (vignettePartie.type) { + case 'paragraph--diaporama': + alt = vignettePartie.relationships.field_diaporama.data[0].meta.alt; + const diaporamaFetch = await REST.get(vignettePartie.relationships.field_diaporama.links.related.href); + vignette = { + url: diaporamaFetch.data.data[0].attributes.image_style_uri.content_small, + alt + }; + break; + + case 'paragraph--video': + const videoId = vignettePartie.attributes.field_videos[0].split('?v=')[1]; + vignette = { + url: `https://img.youtube.com/vi/${videoId}/0.jpg`, + alt: item.attributes.title + }; + break; + + case 'paragraph--galleries': + const gallerieFetch = await REST.get(vignettePartie.relationships.field_gallerie.links.related.href); + const galleryAlt = gallerieFetch.data.data.relationships.field_images.data[0].meta.alt; + const gallerieImageFetch = await REST.get(gallerieFetch.data.data.relationships.field_images.links.related.href); + vignette = { + url: gallerieImageFetch.data.data[0].attributes.image_style_uri.content_small, + alt: galleryAlt + }; + break; + + case 'paragraph--document': + alt = vignettePartie.relationships.field_vignette.data.meta.alt; + const documentFetch = await REST.get(vignettePartie.relationships.field_vignette.links.related.href); + vignette = { + url: documentFetch.data.data.attributes.image_style_uri.content_small, + alt + }; + break; + + default: + vignette = null; + } + } + + return { + ressourceType: item.attributes.field_type_de_ressource, + title: item.attributes.title, + auteurice: item.attributes.field_autheurice, + date: getCleanDate(item.attributes.field_date_ressource), + url: ressourceFetch.data.data.attributes.metatag.find(tag => tag.tag === "link")?.attributes.href, + vignette + }; + } catch (error) { + console.error('Error fetching resource:', error); + return null; + } +} + +export async function getRelatedRessources(etapeId) { + const ressources = await REST.get(`/jsonapi/node/ressource/`); + const ressourcesRelatedToEtape = ressources.data.data.filter(ressource => ressource.relationships.field_etape.data?.id === etapeId); + const ressourcesRelatedPromises = ressourcesRelatedToEtape.map(ressource => getRessourceItemCard(ressource)); + + return await Promise.all(ressourcesRelatedPromises); } \ No newline at end of file diff --git a/web/themes/custom/caravane/assets/js/utils/content/multiItemPages.js b/web/themes/custom/caravane/assets/js/utils/content/multiItemPages.js index 352275c..f9f267c 100644 --- a/web/themes/custom/caravane/assets/js/utils/content/multiItemPages.js +++ b/web/themes/custom/caravane/assets/js/utils/content/multiItemPages.js @@ -1,5 +1,5 @@ import REST from '../../api/rest-axios'; -import { getCleanDate } from './contentFetchUtils'; +import { getCleanDate, getRessourceItemCard } from './contentFetchUtils'; export async function getPartenaires(rawContent) { const logoPromises = rawContent.map(item => @@ -55,76 +55,7 @@ export async function getGouvernance(rawContent) { } export async function getRessources(rawContent) { - const ressourcesPromises = rawContent.map(item => - REST.get(item.links.self.href) - .then(async ressourceFetch => { - const partiesPromises = REST.get(item.relationships.field_parties_ressource.links.related.href) - .then(async partiesFetch => { - const parties = partiesFetch.data.data; - const vignettePartie = parties.find(parties => parties.type !== "paragraph--titre_texte"); - if (vignettePartie) { - let vignettePromise; - let alt; - switch (vignettePartie.type) { - case 'paragraph--diaporama': - alt = vignettePartie.relationships.field_diaporama.data[0].meta.alt; - vignettePromise = REST.get(vignettePartie.relationships.field_diaporama.links.related.href) - .then(diaporamaFetch => { - return { - url: diaporamaFetch.data.data[0].attributes.image_style_uri.content_small, - alt - } - }); - break; - case 'paragraph--video': - const videoId = vignettePartie.attributes.field_videos[0].split('?v=')[1]; - vignettePromise = { - url: `https://img.youtube.com/vi/${videoId}/0.jpg`, - alt: item.attributes.title - } - break; - case 'paragraph--galleries': - vignettePromise = REST.get(vignettePartie.relationships.field_gallerie.links.related.href) - .then(gallerieFetch => { - alt = gallerieFetch.data.data.relationships.field_images.data[0].meta.alt; - const galleriePromise = REST.get(gallerieFetch.data.data.relationships.field_images.links.related.href) - .then(gallerieImageFetch => { - return { - url: gallerieImageFetch.data.data[0].attributes.image_style_uri.content_small, - alt - } - }); - return galleriePromise; - }); - break; - case 'paragraph--document': - alt = vignettePartie.relationships.field_vignette.data.meta.alt; - vignettePromise = REST.get(vignettePartie.relationships.field_vignette.links.related.href) - .then(documentFetch => { - return { - url: documentFetch.data.data.attributes.image_style_uri.content_small, - alt - } - }); - break; - default: - vignettePromise = Promise.resolve(null); - } - - return vignettePromise; - } - }); - - return partiesPromises.then(vignette => ({ - ressourceType: item.attributes.field_type_de_ressource, - title: item.attributes.title, - auteurice: item.attributes.field_autheurice, - date: getCleanDate(item.attributes.field_date_ressource), - url: ressourceFetch.data.data.attributes.metatag.find(tag => tag.tag === "link")?.attributes.href, - vignette - })); - }) - ); + const ressourcesPromises = rawContent.map(item => getRessourceItemCard(item)); return await Promise.all(ressourcesPromises); } \ No newline at end of file diff --git a/web/themes/custom/caravane/assets/js/vuejs/Modale.vue b/web/themes/custom/caravane/assets/js/vuejs/Modale.vue index d6ff4b1..781aa2d 100644 --- a/web/themes/custom/caravane/assets/js/vuejs/Modale.vue +++ b/web/themes/custom/caravane/assets/js/vuejs/Modale.vue @@ -51,18 +51,23 @@ :couleur="content.couleur || brandColor" /> + v-if="contentType === 'gouvernance'" + :content="content" + :couleur="brandColor" /> + v-if="contentType === 'partenaire'" + :content="content" /> + v-if="contentType === 'ressource'" + :content="content" + :couleur="brandColor" /> + -
-
- -
+
- diff --git a/web/themes/custom/caravane/assets/js/vuejs/components/RelatedRessources.vue b/web/themes/custom/caravane/assets/js/vuejs/components/RelatedRessources.vue new file mode 100644 index 0000000..9ed83d7 --- /dev/null +++ b/web/themes/custom/caravane/assets/js/vuejs/components/RelatedRessources.vue @@ -0,0 +1,23 @@ + + + \ No newline at end of file diff --git a/web/themes/custom/caravane/assets/js/vuejs/components/RessourceCard.vue b/web/themes/custom/caravane/assets/js/vuejs/components/RessourceCard.vue new file mode 100644 index 0000000..1b20666 --- /dev/null +++ b/web/themes/custom/caravane/assets/js/vuejs/components/RessourceCard.vue @@ -0,0 +1,49 @@ + + + \ No newline at end of file diff --git a/web/themes/custom/caravane/assets/js/vuejs/components/RessourceItemHeader.vue b/web/themes/custom/caravane/assets/js/vuejs/components/RessourceItemHeader.vue index abec93b..634f754 100644 --- a/web/themes/custom/caravane/assets/js/vuejs/components/RessourceItemHeader.vue +++ b/web/themes/custom/caravane/assets/js/vuejs/components/RessourceItemHeader.vue @@ -47,6 +47,9 @@ function setDisplayedType() { case 'videos': props.content.displayedType = 'Vidéo'; break; + case 'reportages': + props.content.displayedType = 'Reportage'; + break; } } diff --git a/web/themes/custom/caravane/assets/js/vuejs/components/parties/ModaleGallerie.vue b/web/themes/custom/caravane/assets/js/vuejs/components/parties/ModaleGallerie.vue index 417823a..58d44a3 100644 --- a/web/themes/custom/caravane/assets/js/vuejs/components/parties/ModaleGallerie.vue +++ b/web/themes/custom/caravane/assets/js/vuejs/components/parties/ModaleGallerie.vue @@ -21,6 +21,10 @@ import { onMounted } from 'vue'; import { useImageModal } from '../../composables/useImageModale'; import ImageModale from '../ImageModale.vue'; +// WebComponent +// https://swiperjs.com/element +import { register } from 'swiper/element/bundle'; +register(); const props = defineProps({ partie: Object, @@ -36,10 +40,10 @@ const { } = useImageModal(); const handleImageClick = (event) => { - const img = event.target; - if (img.tagName === 'IMG') { + const clickedImg = event.target; + if (clickedImg.tagName === 'IMG') { let swiperMedia = []; - const imgGrid = img.closest('.images-grid'); + const imgGrid = clickedImg.closest('.images-grid'); imgGrid.querySelectorAll('figure').forEach((figure) => { const img = figure.querySelector('img'); @@ -50,15 +54,13 @@ const handleImageClick = (event) => { } }); }); - console.log(swiperMedia); - - - openImageModale(img.src, img.alt, swiperMedia); + openImageModale(clickedImg.src, clickedImg.alt, swiperMedia); } } onMounted(() => { setVerticalImages(); + document.documentElement.style.setProperty('--etape-couleur', props.couleur); }); function setVerticalImages() { @@ -70,4 +72,13 @@ function setVerticalImages() { } }); } - \ No newline at end of file + + + \ No newline at end of file diff --git a/web/themes/custom/caravane/assets/scss/main.scss b/web/themes/custom/caravane/assets/scss/main.scss index fb0b1ed..a6d7c0a 100644 --- a/web/themes/custom/caravane/assets/scss/main.scss +++ b/web/themes/custom/caravane/assets/scss/main.scss @@ -959,7 +959,8 @@ body{ .partie-title, > .chiffres-cles, > .entretien, - > .gallerie { + > .gallerie, + &.related-ressources { > h3 { position: relative; display: inline-block; @@ -1228,7 +1229,12 @@ body{ } #centre-de-ressource { > .intro { - + font-size: $sm-font-size-mobile; + width: 66%; + margin-bottom: 4rem; + @media screen and (min-width: $desktop-min-width) { + font-size: $sm-font-size-desktop; + } } > .type-section { > h3 { @@ -1245,46 +1251,6 @@ body{ font-size: $l-font-size-desktop; } } - > .ressource-list > div { - display: grid; - grid-template-columns: repeat(4, 1fr); - align-items: start; - gap: 2rem; - margin-bottom: 2.5rem; - > .ressource-item { - display: flex; - gap: 1.5rem; - cursor: pointer; - transform: scale(1); - transition: transform 0.2s ease-in-out; - &:hover { - transform: scale(1.05); - } - > figure { - width: 40%; - margin: 0; - } - > div { - width: 50%; - > h4 { - font-size: $m-font-size-mobile; - font-family: 'Joost', sans-serif; - margin: 0; - margin-bottom: 0.5rem; - @media screen and (min-width: $desktop-min-width) { - font-size: $m-font-size-desktop; - } - } - > p { - margin: 0; - font-size: $sm-font-size-mobile; - @media screen and (min-width: $desktop-min-width) { - font-size: $sm-font-size-desktop; - } - } - } - } - } > .button-container { display: flex; justify-content: center; @@ -1410,15 +1376,27 @@ body{ background-size: 300px; background-size: repeat; } + .related-etape-label { + display: inline-block; + padding: 0.5rem 1rem; + padding-left: calc($modale-x-padding / 2); + font-size: $sm-font-size-mobile; + @media screen and (min-width: $desktop-min-width) { + font-size: $sm-font-size-desktop; + } + } .related-etape-links { - position: absolute; //bottom: calc(($modale-bottom-padding / 2) * -1); - width: 100%; box-sizing: border-box; padding: 0 calc($modale-x-padding / 2); display: grid; - grid-template-rows: 1fr 1fr; grid-template-columns: 1fr; + width: 75%; + &:not(:has(.solo)) { + width: 100%; + position: absolute; + grid-template-rows: 1fr 1fr; + } @media screen and (min-width: $desktop-min-width) { grid-template-columns: 1fr 1fr; margin-top: 2.5rem; @@ -1508,6 +1486,60 @@ body{ } } } + .ressource-list > div:not(.ressource-item), + .ressource-list.sm-ressource-list { + display: grid; + grid-template-columns: repeat(4, 1fr); + align-items: start; + gap: 2rem; + margin-bottom: 2.5rem; + &.sm-ressource-list { + margin-top: 2rem; + grid-template-columns: repeat(2, 1fr); + } + > .ressource-item > div { + display: flex; + gap: 1.5rem; + cursor: pointer; + transform: scale(1); + transition: transform 0.2s ease-in-out; + &:hover { + transform: scale(1.05); + } + > figure { + width: 40%; + margin: 0; + } + > div { + width: 50%; + > h4 { + font-size: $m-font-size-mobile; + font-family: 'Joost', sans-serif; + margin: 0; + margin-bottom: 0.5rem; + @media screen and (min-width: $desktop-min-width) { + font-size: $m-font-size-desktop; + } + } + > p { + margin: 0; + font-size: $sm-font-size-mobile; + @media screen and (min-width: $desktop-min-width) { + font-size: $sm-font-size-desktop; + } + } + } + } + } + + + + + + + + + } > #animation-toggle { transition: opacity 0.3s ease-out;