diff --git a/web/themes/custom/caravane/assets/js/stores/content.js b/web/themes/custom/caravane/assets/js/stores/content.js index e1947a6..e5dbbb5 100644 --- a/web/themes/custom/caravane/assets/js/stores/content.js +++ b/web/themes/custom/caravane/assets/js/stores/content.js @@ -3,6 +3,25 @@ import { defineStore } from 'pinia'; import REST from '../api/rest-axios'; +import { findContentByPath } from '../utils/content/findContentByPath'; +import { + getCleanDate, + fetchFromRelationships, + getRelatedEtape, +} from '../utils/content/contentFetchUtils'; +import { + getCarteSensible, + getTitreTexte, + getChiffresCles, + getDiaporama, + getEntretien, + getVideos, +} from '../utils/content/cleanParties'; +import { + getPartenaires, + getGouvernance, +} from '../utils/content/multiItemPages'; + export const useContentStore = defineStore('content', { state: () => ({ contentType: '', @@ -14,7 +33,7 @@ export const useContentStore = defineStore('content', { etape_number: '', couleur: '', dates: {}, - previous : {}, + previous: {}, next: {}, vignette: {}, parties: [], @@ -30,105 +49,23 @@ export const useContentStore = defineStore('content', { }), actions: { async fetchContentData(path) { - console.log('start fetch content'); this.resetStore(false); - const contentTypes = [ 'etape', 'static', 'gouvernance', 'partenaire' ]; + const contentTypes = ['etape', 'static', 'gouvernance', 'partenaire']; try { - const findContentByPath = async (contentTypes, path) => { - for (let type of contentTypes) { - const response = await REST.get(`/jsonapi/node/${type}/`); - - const content = response.data.data.find(content => - content.attributes.metatag.some(tag => - tag.tag === "link" && tag.attributes.href === path - ) - ); - - if (content) { - console.log('content found'); - - return { - contentType: type, - rawContent: content, - }; - } - - // Handle special case for governance/partners (multiple items per page) - const pageRequested = window.location.href.split('/').pop().replace(/s?$/, ''); - if (type === pageRequested - || (type === 'gouvernance' && pageRequested === 'contact') - ) { - return { - contentType: type, - rawContent: response.data.data, - }; - } - } - return null; - }; - const { contentType, rawContent } = await findContentByPath(contentTypes, path); this.contentType = contentType; - // console.log(`current type: ${contentType}`); + if (this.contentType !== 'gouvernance' && this.contentType !== 'partenaire') { + const vignettePromise = fetchFromRelationships('field_vignette', rawContent.relationships); + const partiesPromise = fetchFromRelationships('field_parties', rawContent.relationships); - // TO DEBUG - const cleanContentMethod = 'original'; - - if (this.contentType !== 'gouvernance' && this.contentType !== 'partenaire' - && cleanContentMethod === 'original' - ) { - console.time('etape content processing'); - // pageTitle - for (let tag of rawContent.attributes.metatag) { - if (tag.tag === "meta") { - this.pageTitle = tag.attributes.content; - break; - } - } - // contentTitle - this.content.contentTitle = rawContent.attributes.title; - - // vignette - const vignetteFetch = await this.fetchFromRelationships('field_vignette', rawContent.relationships); - if (vignetteFetch) { - this.content.vignette = { - url: { - original: vignetteFetch.attributes.uri.url, - small: vignetteFetch.attributes.image_style_uri.content_small, - medium: vignetteFetch.attributes.image_style_uri.content_medium, - large: vignetteFetch.attributes.image_style_uri.content_large, - }, - alt: rawContent.relationships.field_vignette.data.meta.alt - }; - } - - // liens - if (rawContent.attributes.field_liens.length) { - this.content.liens = []; - for (let lien of rawContent.attributes.field_liens) { - this.content.liens.push({ - title: lien.title, - url: lien.uri, - }); - } - } - // pièces jointes - if (rawContent.relationships.field_pieces_jointes.data.length) { - this.content.pieces_jointes = []; - for (let pieceJointe of rawContent.relationships.field_pieces_jointes.data) { - if (pieceJointe.meta.display) { - const uuid = pieceJointe.id; - const response = await REST.get(`/jsonapi/file/file/${uuid}`); - this.content.pieces_jointes.push({ - title: pieceJointe.meta.description, - url: response.data.data.attributes.uri.url, - }); - } - } - } + let previousEtapePromise, nextEtapePromise; if (contentType === 'etape') { + // related étapes + previousEtapePromise = getRelatedEtape('previous', path); + nextEtapePromise = getRelatedEtape('next', path); + // coordinates this.content.coordinates = { lat: rawContent.attributes.field_geofield.lat, @@ -142,185 +79,9 @@ export const useContentStore = defineStore('content', { this.content.couleur = rawContent.attributes.field_couleur; // dates this.content.dates = { - start: this.getCleanDate(rawContent.attributes.field_dates.value), - end: this.getCleanDate(rawContent.attributes.field_dates.end_value), + start: getCleanDate(rawContent.attributes.field_dates.value), + end: getCleanDate(rawContent.attributes.field_dates.end_value), } - // previous / next - await this.getRelatedEtape('previous', path); - await this.getRelatedEtape('next', path); - } - - // parties - const fieldParties = contentType === 'etape' ? 'field_parties' : 'field_parties_static'; - const partiesFetch = await this.fetchFromRelationships(fieldParties, rawContent.relationships); - console.log(this.content); - console.timeEnd('etape content processing'); - if (partiesFetch) { - this.content.parties = []; - for (let partie of partiesFetch) { - const partieType = partie.type.replace(/^paragraph--/, ""); - let partieContent = { - type: partieType, - }; - - switch (partieType) { - case 'carte_sensible': - const carteSensibleFetch = await this.fetchFromRelationships('field_image_carte', partie.relationships); - if (carteSensibleFetch) { - partieContent.carteSensible = { - url: { - original: carteSensibleFetch.attributes.uri.url, - small: carteSensibleFetch.attributes.image_style_uri.content_small, - medium: carteSensibleFetch.attributes.image_style_uri.content_medium, - large: carteSensibleFetch.attributes.image_style_uri.content_large, - xlarge: carteSensibleFetch.attributes.image_style_uri.content_x_large, - }, - alt: partie.relationships.field_image_carte.data.meta.alt, - }; - } - break; - case 'titre_texte': - console.time('get images from text original') - partieContent.titre = partie.attributes.field_titre; - partieContent.texte = partie.attributes.field_texte.value; - - // get the resized images from the text - const imgRegex = /]+>/g; - const uuidRegex = /data-entity-uuid="([^"]+)"/; - - const imgTags = partieContent.texte.match(imgRegex); - - if (imgTags) { - for (const imgTag of imgTags) { - const uuidMatch = imgTag.match(uuidRegex); - if (uuidMatch && uuidMatch[1]) { - const uuid = uuidMatch[1]; - - const response = await REST.get(`/jsonapi/file/file/${uuid}`); - const imagesFetch = response.data.data; - - const newImgTag = imgTag - .replace(/src="[^"]+"/,`src="${imagesFetch.attributes.image_style_uri.content_medium}"`) - .replace('>',' data-large-src="' + imagesFetch.attributes.image_style_uri.content_large + '">'); - partieContent.texte = partieContent.texte.replace(imgTag, newImgTag); - } - } - } - - - console.timeEnd('get images from text original') - break; - case 'chiffres_cles': - const chiffresClesFetch = await this.fetchFromRelationships('field_chiffres_clefs', partie.relationships); - if (chiffresClesFetch) { - partieContent.chiffresCles = []; - for (let chiffre of chiffresClesFetch) { - partieContent.chiffresCles.push({ - chiffre: chiffre.attributes.field_chiffre, - description: chiffre.attributes.field_description, - }); - } - } - break; - case 'diaporama': - const diaporamaFetch = await this.fetchFromRelationships('field_diaporama', partie.relationships); - - if (diaporamaFetch) { - partieContent.diaporama = []; - for (let [index, image] of diaporamaFetch.entries()) { - partieContent.diaporama.push({ - url: { - original: image.attributes.uri.url, - small: image.attributes.image_style_uri.content_small, - medium: image.attributes.image_style_uri.content_medium, - large: image.attributes.image_style_uri.content_large, - }, - alt: partie.relationships.field_diaporama.data[index].meta.alt, - }); - } - - } - break; - case 'entretien': - partieContent.entretien = {}; - partieContent.entretien.titre = partie.attributes.field_titre; - const personnesFetch = await this.fetchFromRelationships('field_personne_s', partie.relationships); - const questionsReponsesFetch = await this.fetchFromRelationships('field_questions_reponses', partie.relationships); - if (personnesFetch && questionsReponsesFetch) { - partieContent.entretien.personnes = []; - for (let personne of personnesFetch) { - const portraitFetch = await this.fetchFromRelationships('field_portrait', personne.relationships); - if (portraitFetch) { - partieContent.entretien.personnes.push({ - portrait: { - original: portraitFetch.attributes.uri.url, - small: portraitFetch.attributes.image_style_uri.content_small, - medium: portraitFetch.attributes.image_style_uri.content_medium, - large: portraitFetch.attributes.image_style_uri.content_large, - }, - alt: personne.relationships.field_portrait.data.meta.alt, - description: personne.attributes.field_description, - }); - } - } - partieContent.entretien.questionsReponses = []; - for (let qr of questionsReponsesFetch) { - partieContent.entretien.questionsReponses.push({ - question: qr.attributes.field_question, - reponse: qr.attributes.field_reponse.value, - }); - } - } - break; - case 'exergue': - partieContent.exergue = partie.attributes.field_texte_exergue.value; - break; - case 'video': - partieContent.videos = []; - for (let video of partie.attributes.field_videos) { - const videoId = video.split('?v=')[1]; - const videoUrl = `https://www.youtube.com/embed/${videoId}`; - partieContent.videos.push(videoUrl); - } - break; - } - this.content.parties.push(partieContent); - } - } - console.log('content cleaned'); - } else if (this.contentType !== 'gouvernance' && this.contentType !== 'partenaire' - && cleanContentMethod === 'promise' - ) { - - - - - console.time('etape content promise processing'); - - - const vignettePromise = this.fetchFromRelationships('field_vignette', rawContent.relationships); - const partiesPromise = this.fetchFromRelationships('field_parties', rawContent.relationships); - - const previousEtapePromise = contentType === 'etape'? this.getRelatedEtape('previous', path) : null; - const nextEtapePromise = contentType === 'etape' ? this.getRelatedEtape('next', path) : null; - - if (contentType === 'etape') { - // coordinates - this.content.coordinates = { - lat: rawContent.attributes.field_geofield.lat, - lon: rawContent.attributes.field_geofield.lon, - }; - // adresse - this.content.adresse = rawContent.attributes.field_adresse; - // étape number - this.content.etape_number = rawContent.attributes.field_arret_numero; - // couleur - this.content.couleur = rawContent.attributes.field_couleur; - // dates - this.content.dates = { - start: this.getCleanDate(rawContent.attributes.field_dates.value), - end: this.getCleanDate(rawContent.attributes.field_dates.end_value), - } } // pageTitle @@ -353,74 +114,29 @@ export const useContentStore = defineStore('content', { const partieType = partie.type.replace(/^paragraph--/, ""); let partieContent = { type: partieType }; - switch(partieType) { + switch (partieType) { case 'carte_sensible': - const carteSensiblePromise = this.fetchFromRelationships('field_image_carte', partie.relationships); - - const carteSensibleData = await carteSensiblePromise; - if (carteSensibleData) { - partieContent.carteSensible = { - url: { - original: carteSensibleData.attributes.uri.url, - small: carteSensibleData.attributes.image_style_uri.content_small, - medium: carteSensibleData.attributes.image_style_uri.content_medium, - large: carteSensibleData.attributes.image_style_uri.content_large, - xlarge: carteSensibleData.attributes.image_style_uri.content_x_large, - }, - alt: partie.relationships.field_image_carte.data.meta.alt, - }; - } - + partieContent.carteSensible = await getCarteSensible(partie); break; case 'titre_texte': - partieContent.titre = partie.attributes.field_titre; - partieContent.texte = partie.attributes.field_texte.value; - - // get the resized images from the text - const imgRegex = /]+>/g; - const uuidRegex = /data-entity-uuid="([^"]+)"/; - const imgTags = partieContent.texte.match(imgRegex); - - if (imgTags) { - const imagePromises = imgTags.map(imgTag => { - const uuidMatch = imgTag.match(uuidRegex); - if (uuidMatch && uuidMatch[1]) { - return REST.get(`/jsonapi/file/file/${uuidMatch[1]}`) - .then(response => ({ - originalTag: imgTag, - imageData: response.data.data - })); - } - }); - - const images = await Promise.all(imagePromises); - images.forEach(({originalTag, imageData}) => { - const newImgTag = originalTag - .replace(/src="[^"]+"/,`src="${imageData.attributes.image_style_uri.content_medium}"`) - .replace('>',' data-large-src="' + imageData.attributes.image_style_uri.content_large + '">'); - partieContent.texte = partieContent.texte.replace(originalTag, newImgTag); - }); - } + const { titre, texte } = await getTitreTexte(partie); + partieContent.titre = titre; + partieContent.texte = texte; break; case 'chiffres_cles': - const chiffresClesFetch = await this.fetchFromRelationships('field_chiffres_clefs', partie.relationships); - if (chiffresClesFetch) { - partieContent.chiffresCles = []; - for (let chiffre of chiffresClesFetch) { - partieContent.chiffresCles.push({ - chiffre: chiffre.attributes.field_chiffre, - description: chiffre.attributes.field_description, - }); - } - } + partieContent.chiffresCles = await getChiffresCles(partie); break; case 'diaporama': + partieContent.diaporama = await getDiaporama(partie); break; case 'entretien': + partieContent.entretien = await getEntretien(partie); break; case 'exergue': + partieContent.exergue = partie.attributes.field_texte_exergue.value; break; case 'video': + partieContent.videos = getVideos(partie); break; } return partieContent; @@ -430,72 +146,32 @@ export const useContentStore = defineStore('content', { } // related étapes - if (contentType === 'etape') await Promise.all([previousEtapePromise, nextEtapePromise]); - - console.log(this.content); - console.timeEnd('etape content promise processing'); + if (contentType === 'etape') { + const [prevContent, nextContent] = await Promise.all([previousEtapePromise, nextEtapePromise]); + this.content.previous = prevContent; + this.content.next = nextContent; + } } else { // pages gouvernance (contact) et partenaire // ont plusieurs items par pages const intro = await REST.get(`/jsonapi/config_pages/intro_${this.contentType}/`); const introContent = intro.data.data[0]; - this.pageTitle = + this.pageTitle = `${introContent.attributes.field_titre} ${introContent.attributes.metatag.find(tag => tag.tag === "meta")?.attributes.content}`; this.content.contentTitle = introContent.attributes.field_titre; this.content.intro = introContent.attributes.field_intro?.value; - const multiItemPageArray = []; + let multiItemPageArray = []; if (this.contentType === 'partenaire') { - for (let item of rawContent) { - const logoFetch = await REST.get(item.relationships.field_logo.links.related.href); - - multiItemPageArray.push({ - title: item.attributes.title, - description: item.attributes.body.value, - weight: item.attributes.field_poid, - link_url: item.attributes.field_lien.uri , - logo_alt: item.relationships.field_logo.data.meta.alt, - logo_url: { - original: logoFetch.data.data.attributes.uri.url, - small: logoFetch.data.data.attributes.image_style_uri.content_small, - medium: logoFetch.data.data.attributes.image_style_uri.content_medium, - large: logoFetch.data.data.attributes.image_style_uri.content_large, - }, - }); - } + multiItemPageArray = await getPartenaires(rawContent); } else if (this.contentType === 'gouvernance') { - for (let item of rawContent) { - const personnesFetch = await REST.get(item.relationships.field_personne_s.links.related.href); - let personnes = []; - for (let personne of personnesFetch.data.data) { - const portraitFetch = await REST.get(personne.relationships.field_portrait.links.related.href); - personnes.push({ - nom: personne.attributes.field_nom, - prenom: personne.attributes.field_prenom, - description: personne.attributes.field_description, - photo_meta: personne.relationships.field_portrait.data?.meta.alt, - photo_url: portraitFetch.data.data ? { - original: portraitFetch.data.data.attributes.uri.url, - small: portraitFetch.data.data.attributes.image_style_uri.content_small, - medium: portraitFetch.data.data.attributes.image_style_uri.content_medium, - large: portraitFetch.data.data.attributes.image_style_uri.content_large, - } : null - }); - } - multiItemPageArray.push({ - title: item.attributes.title, - weight: item.attributes.field_poid, - personnes: personnes, - }); - } + multiItemPageArray = await getGouvernance(rawContent); } this.content[`${this.contentType}s`] = multiItemPageArray; - - // console.log(this.content); } } catch (error) { this.error = 'Failed to fetch data'; @@ -504,107 +180,6 @@ export const useContentStore = defineStore('content', { this.loading = false; } }, - getCleanDate(date) { - return { - d: date.split('-')[2], - m: new Intl.DateTimeFormat('fr-FR', { month: 'long' }).format(new Date(date)), - y: date.split('-')[0], - } - }, - async getRelatedEtape(direction, path) { - const getRelatedEtapeContent = async (relatedEtapeData) => { - if (relatedEtapeData) { - const vignetteFetch = await REST.get(relatedEtapeData.relationships.field_vignette.links.related.href); - if (vignetteFetch.data.data) { - this.content[direction] = { - url: relatedEtapeData.attributes.metatag.find(tag => tag.tag === "link")?.attributes.href, - couleur: relatedEtapeData.attributes.field_couleur, - title: relatedEtapeData.attributes.title, - postalCode: relatedEtapeData.attributes.field_adresse.postal_code, - dates: { - start: this.getCleanDate(relatedEtapeData.attributes.field_dates.value), - end: this.getCleanDate(relatedEtapeData.attributes.field_dates.end_value), - }, - vignette: { - url: { - original: vignetteFetch.data.data.attributes.uri.url, - small: vignetteFetch.data.data.attributes.image_style_uri.content_small, - medium: vignetteFetch.data.data.attributes.image_style_uri.content_medium, - large: vignetteFetch.data.data.attributes.image_style_uri.content_large, - }, - alt: relatedEtapeData.relationships.field_vignette.data.meta.alt, - }, - } - } - - } - } - - const allEtapesData = await REST.get('/jsonapi/views/etapes/block_1/'); - for (let [index, etape] of allEtapesData.data.data.entries()) { - if (etape.attributes.metatag.some(tag => - tag.tag === "link" && tag.attributes.href === path - )) { - const relatedEtapeIndex = direction === 'next' ? index + 1 : index - 1; - await getRelatedEtapeContent(allEtapesData.data.data[relatedEtapeIndex]); - } - } - }, - async getRelatedEtape(direction, path) { - const getRelatedEtapeContent = (relatedEtapeData) => { - if (relatedEtapeData) { - return this.fetchFromRelationships('field_vignette', relatedEtapeData.relationships) - .then(vignetteFetch => { - if (vignetteFetch) { - this.content[direction] = { - url: relatedEtapeData.attributes.metatag.find(tag => tag.tag === "link")?.attributes.href, - couleur: relatedEtapeData.attributes.field_couleur, - title: relatedEtapeData.attributes.title, - postalCode: relatedEtapeData.attributes.field_adresse.postal_code, - dates: { - start: this.getCleanDate(relatedEtapeData.attributes.field_dates.value), - end: this.getCleanDate(relatedEtapeData.attributes.field_dates.end_value), - }, - vignette: { - url: { - original: vignetteFetch.attributes.uri.url, - small: vignetteFetch.attributes.image_style_uri.content_small, - medium: vignetteFetch.attributes.image_style_uri.content_medium, - large: vignetteFetch.attributes.image_style_uri.content_large, - }, - alt: relatedEtapeData.relationships.field_vignette.data.meta.alt, - }, - } - } - }); - } - } - - const allEtapesPromise = REST.get('/jsonapi/views/etapes/block_1/'); - - return allEtapesPromise.then(allEtapesData => { - for (let [index, etape] of allEtapesData.data.data.entries()) { - if (etape.attributes.metatag.some(tag => - tag.tag === "link" && tag.attributes.href === path - )) { - const relatedEtapeIndex = direction === 'next' ? index + 1 : index - 1; - return getRelatedEtapeContent(allEtapesData.data.data[relatedEtapeIndex]); - } - } - }); - }, - async fetchFromRelationships(field, relationships) { - if (relationships[field].links) { - const contentLink = relationships[field].links.related.href; - return REST.get(contentLink) - .then(contentFetch => contentFetch.data.data) - .catch(error => { - this.error = 'Failed to fetch data'; - console.error('Issue with getNodeData', error); - }); - } - return null; - }, resetStore(forFrontDisplay) { this.contentType = ''; this.pageTitle = ''; diff --git a/web/themes/custom/caravane/assets/js/utils/content/cleanParties.js b/web/themes/custom/caravane/assets/js/utils/content/cleanParties.js new file mode 100644 index 0000000..bb055ab --- /dev/null +++ b/web/themes/custom/caravane/assets/js/utils/content/cleanParties.js @@ -0,0 +1,134 @@ +import REST from '../../api/rest-axios'; +import { fetchFromRelationships } from './contentFetchUtils'; + + +export async function getCarteSensible(partie) { + const carteSensiblePromise = fetchFromRelationships('field_image_carte', partie.relationships); + + const carteSensibleData = await carteSensiblePromise; + if (carteSensibleData) { + return { + url: { + original: carteSensibleData.attributes.uri.url, + small: carteSensibleData.attributes.image_style_uri.content_small, + medium: carteSensibleData.attributes.image_style_uri.content_medium, + large: carteSensibleData.attributes.image_style_uri.content_large, + xlarge: carteSensibleData.attributes.image_style_uri.content_x_large, + }, + alt: partie.relationships.field_image_carte.data.meta.alt, + }; + } +} + +export async function getTitreTexte(partie) { + let titre = partie.attributes.field_titre; + let texte = partie.attributes.field_texte.value; + + // get the resized images from the text + const imgRegex = /]+>/g; + const uuidRegex = /data-entity-uuid="([^"]+)"/; + const imgTags = texte.match(imgRegex); + + if (imgTags) { + const imagePromises = imgTags.map(imgTag => { + const uuidMatch = imgTag.match(uuidRegex); + if (uuidMatch && uuidMatch[1]) { + return REST.get(`/jsonapi/file/file/${uuidMatch[1]}`) + .then(response => ({ + originalTag: imgTag, + imageData: response.data.data + })); + } + }); + + const images = await Promise.all(imagePromises); + images.forEach(({originalTag, imageData}) => { + const newImgTag = originalTag + .replace(/src="[^"]+"/,`src="${imageData.attributes.image_style_uri.content_medium}"`) + .replace('>',' data-large-src="' + imageData.attributes.image_style_uri.content_large + '">'); + texte = texte.replace(originalTag, newImgTag); + }); + } + + return { titre, texte }; +} + +export async function getChiffresCles(partie) { + const chiffresClesFetch = await fetchFromRelationships('field_chiffres_clefs', partie.relationships); + if (chiffresClesFetch) { + let chiffresCles = []; + for (let chiffre of chiffresClesFetch) { + chiffresCles.push({ + chiffre: chiffre.attributes.field_chiffre, + description: chiffre.attributes.field_description, + }); + } + return chiffresCles; + } +} + +export async function getDiaporama(partie) { + const diaporamaFetch = await fetchFromRelationships('field_diaporama', partie.relationships); + + if (diaporamaFetch) { + const diaporamaPromises = diaporamaFetch.map((image, index) => { + return { + url: { + original: image.attributes.uri.url, + small: image.attributes.image_style_uri.content_small, + medium: image.attributes.image_style_uri.content_medium, + large: image.attributes.image_style_uri.content_large, + }, + alt: partie.relationships.field_diaporama.data[index].meta.alt, + }; + }); + + return await Promise.all(diaporamaPromises); + } +} + +export async function getEntretien(partie) { + const [personnesFetch, questionsReponsesFetch] = await Promise.all([ + fetchFromRelationships('field_personne_s', partie.relationships), + fetchFromRelationships('field_questions_reponses', partie.relationships) + ]); + + if (personnesFetch && questionsReponsesFetch) { + const personnesPromises = personnesFetch.map(async (personne) => { + const portraitFetch = await fetchFromRelationships('field_portrait', personne.relationships); + if (portraitFetch) { + return { + portrait: { + original: portraitFetch.attributes.uri.url, + small: portraitFetch.attributes.image_style_uri.content_small, + medium: portraitFetch.attributes.image_style_uri.content_medium, + large: portraitFetch.attributes.image_style_uri.content_large, + }, + alt: personne.relationships.field_portrait.data.meta.alt, + description: personne.attributes.field_description, + }; + } + }); + + const questionsReponses = questionsReponsesFetch.map(qr => ({ + question: qr.attributes.field_question, + reponse: qr.attributes.field_reponse.value, + })); + + return { + titre: partie.attributes.field_titre, + personnes: await Promise.all(personnesPromises), + questionsReponses: questionsReponses + } + } +} + +export function getVideos(partie) { + let videos = []; + for (let video of partie.attributes.field_videos) { + const videoId = video.split('?v=')[1]; + const videoUrl = `https://www.youtube.com/embed/${videoId}`; + videos.push(videoUrl); + } + return videos; +} \ No newline at end of file diff --git a/web/themes/custom/caravane/assets/js/utils/content/contentFetchUtils.js b/web/themes/custom/caravane/assets/js/utils/content/contentFetchUtils.js new file mode 100644 index 0000000..8ac8452 --- /dev/null +++ b/web/themes/custom/caravane/assets/js/utils/content/contentFetchUtils.js @@ -0,0 +1,68 @@ +import REST from '../../api/rest-axios'; + +export async function fetchFromRelationships(field, relationships) { + field = relationships[field] ? field : `${field}_static`; + + if (relationships[field].links) { + const contentLink = relationships[field].links.related.href; + return REST.get(contentLink) + .then(contentFetch => contentFetch.data.data) + .catch(error => { + this.error = 'Failed to fetch data'; + console.error('Issue with getNodeData', error); + }); + } + return null; +} + +export function getCleanDate(date) { + return { + d: date.split('-')[2], + m: new Intl.DateTimeFormat('fr-FR', { month: 'long' }).format(new Date(date)), + y: date.split('-')[0], + } +} + +export async function getRelatedEtape(direction, path) { + const getRelatedEtapeContent = (relatedEtapeData) => { + if (relatedEtapeData) { + return fetchFromRelationships('field_vignette', relatedEtapeData.relationships) + .then(vignetteFetch => { + if (vignetteFetch) { + return { + url: relatedEtapeData.attributes.metatag.find(tag => tag.tag === "link")?.attributes.href, + couleur: relatedEtapeData.attributes.field_couleur, + title: relatedEtapeData.attributes.title, + postalCode: relatedEtapeData.attributes.field_adresse.postal_code, + dates: { + start: getCleanDate(relatedEtapeData.attributes.field_dates.value), + end: getCleanDate(relatedEtapeData.attributes.field_dates.end_value), + }, + vignette: { + url: { + original: vignetteFetch.attributes.uri.url, + small: vignetteFetch.attributes.image_style_uri.content_small, + medium: vignetteFetch.attributes.image_style_uri.content_medium, + large: vignetteFetch.attributes.image_style_uri.content_large, + }, + alt: relatedEtapeData.relationships.field_vignette.data.meta.alt, + }, + } + } + }); + } + } + + const allEtapesPromise = REST.get('/jsonapi/views/etapes/block_1/'); + + return allEtapesPromise.then(allEtapesData => { + for (let [index, etape] of allEtapesData.data.data.entries()) { + if (etape.attributes.metatag.some(tag => + tag.tag === "link" && tag.attributes.href === path + )) { + const relatedEtapeIndex = direction === 'next' ? index + 1 : index - 1; + return getRelatedEtapeContent(allEtapesData.data.data[relatedEtapeIndex]); + } + } + }); +} \ No newline at end of file diff --git a/web/themes/custom/caravane/assets/js/utils/content/findContentByPath.js b/web/themes/custom/caravane/assets/js/utils/content/findContentByPath.js new file mode 100644 index 0000000..85eb18f --- /dev/null +++ b/web/themes/custom/caravane/assets/js/utils/content/findContentByPath.js @@ -0,0 +1,32 @@ +import REST from '../../api/rest-axios'; + +export async function findContentByPath(contentTypes, path) { + for (let type of contentTypes) { + const response = await REST.get(`/jsonapi/node/${type}/`); + + const content = response.data.data.find(content => + content.attributes.metatag.some(tag => + tag.tag === "link" && tag.attributes.href === path + ) + ); + + if (content) { + return { + contentType: type, + rawContent: content, + }; + } + + // Handle special case for governance/partners (multiple items per page) + const pageRequested = window.location.href.split('/').pop().replace(/s?$/, ''); + if (type === pageRequested + || (type === 'gouvernance' && pageRequested === 'contact') + ) { + return { + contentType: type, + rawContent: response.data.data, + }; + } + } + return null; +} \ 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 new file mode 100644 index 0000000..6110021 --- /dev/null +++ b/web/themes/custom/caravane/assets/js/utils/content/multiItemPages.js @@ -0,0 +1,54 @@ +import REST from '../../api/rest-axios'; + +export async function getPartenaires(rawContent) { + const logoPromises = rawContent.map(item => + REST.get(item.relationships.field_logo.links.related.href) + .then(logoFetch => ({ + title: item.attributes.title, + description: item.attributes.body.value, + weight: item.attributes.field_poid, + link_url: item.attributes.field_lien.uri, + logo_alt: item.relationships.field_logo.data.meta.alt, + logo_url: { + original: logoFetch.data.data.attributes.uri.url, + small: logoFetch.data.data.attributes.image_style_uri.content_small, + medium: logoFetch.data.data.attributes.image_style_uri.content_medium, + large: logoFetch.data.data.attributes.image_style_uri.content_large, + } + })) + ); + + return await Promise.all(logoPromises); +} + +export async function getGouvernance(rawContent) { + const itemPromises = rawContent.map(item => + REST.get(item.relationships.field_personne_s.links.related.href) + .then(async personnesFetch => { + const portraitPromises = personnesFetch.data.data.map(personne => + REST.get(personne.relationships.field_portrait.links.related.href) + .then(portraitFetch => ({ + nom: personne.attributes.field_nom, + prenom: personne.attributes.field_prenom, + description: personne.attributes.field_description, + photo_meta: personne.relationships.field_portrait.data?.meta.alt, + photo_url: portraitFetch.data.data ? { + original: portraitFetch.data.data.attributes.uri.url, + small: portraitFetch.data.data.attributes.image_style_uri.content_small, + medium: portraitFetch.data.data.attributes.image_style_uri.content_medium, + large: portraitFetch.data.data.attributes.image_style_uri.content_large, + } : null + })) + ); + + return Promise.all(portraitPromises) + .then(personnes => ({ + title: item.attributes.title, + weight: item.attributes.field_poid, + personnes + })); + }) + ); + + return await Promise.all(itemPromises); +} \ No newline at end of file diff --git a/web/themes/custom/caravane/assets/js/utils/handle-navigation.js b/web/themes/custom/caravane/assets/js/utils/handle-navigation.js index 0350e2f..a0a845c 100644 --- a/web/themes/custom/caravane/assets/js/utils/handle-navigation.js +++ b/web/themes/custom/caravane/assets/js/utils/handle-navigation.js @@ -22,7 +22,7 @@ export function handleClickableElements(clickableElements, store, router, baseUr let href = link.href || link.dataset.href; if (href.startsWith(baseUrl)) href = href.replace(baseUrl, ''); - link.onclick = async function (e) { + link.onclick = async function (e) { if (href !== window.location.pathname) { router.push(href); pageChange(href, store, siteName, mapStore, baseUrl); diff --git a/web/themes/custom/caravane/assets/js/vuejs/components/ModaleFooter.vue b/web/themes/custom/caravane/assets/js/vuejs/components/ModaleFooter.vue index 7672fef..827d187 100644 --- a/web/themes/custom/caravane/assets/js/vuejs/components/ModaleFooter.vue +++ b/web/themes/custom/caravane/assets/js/vuejs/components/ModaleFooter.vue @@ -5,7 +5,7 @@