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 @@