avancées centre de ressources
This commit is contained in:
parent
a1916e3219
commit
d805ef35b1
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
@ -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);
|
||||
}
|
@ -51,18 +51,23 @@
|
||||
:couleur="content.couleur || brandColor" />
|
||||
</div>
|
||||
<EquipeContent
|
||||
v-if="contentType === 'gouvernance'"
|
||||
:content="content"
|
||||
:couleur="brandColor" />
|
||||
v-if="contentType === 'gouvernance'"
|
||||
:content="content"
|
||||
:couleur="brandColor" />
|
||||
<PartenairesContent
|
||||
v-if="contentType === 'partenaire'"
|
||||
:content="content" />
|
||||
v-if="contentType === 'partenaire'"
|
||||
:content="content" />
|
||||
<CentreDeRessource
|
||||
v-if="contentType === 'ressource'"
|
||||
:content="content"
|
||||
:couleur="brandColor" />
|
||||
v-if="contentType === 'ressource'"
|
||||
:content="content"
|
||||
:couleur="brandColor" />
|
||||
<RelatedRessources
|
||||
v-if="contentType === 'etape' && content.relatedRessources"
|
||||
:relatedRessources="content.relatedRessources"
|
||||
:couleur="content.couleur || brandColor" />
|
||||
</main>
|
||||
<PiecesJointes
|
||||
v-if="content.pieces_jointes || content.liens"
|
||||
:content="content"
|
||||
:couleur="content.couleur || brandColor" />
|
||||
<ModaleFooter
|
||||
@ -88,6 +93,7 @@ import PartenairesContent from './components/PartenairesContent.vue';
|
||||
import CentreDeRessource from './components/CentreDeRessource.vue';
|
||||
import RessourceItemHeader from './components/RessourceItemHeader.vue';
|
||||
import PiecesJointes from './components/PiecesJointes.vue';
|
||||
import RelatedRessources from './components/RelatedRessources.vue';
|
||||
|
||||
import ModaleCarteSensible from './components/parties/ModaleCarteSensible.vue';
|
||||
import ModaleTitreTexte from './components/parties/ModaleTitreTexte.vue';
|
||||
@ -98,6 +104,7 @@ import ModaleExergue from './components/parties/ModaleExergue.vue';
|
||||
import ModaleVideos from './components/parties/ModaleVideos.vue';
|
||||
import ModaleGallerie from './components/parties/ModaleGallerie.vue';
|
||||
import ModaleDocument from './components/parties/ModaleDocument.vue';
|
||||
import { getRelatedRessources } from '../utils/content/contentFetchUtils';
|
||||
|
||||
const store = useContentStore();
|
||||
const mapState = useMapStore();
|
||||
|
@ -1,8 +1,5 @@
|
||||
<template>
|
||||
<div id="centre-de-ressource">
|
||||
<div v-if="content.intro" class="intro">
|
||||
<!-- <p v-html="content.intro"></p> -->
|
||||
</div>
|
||||
<div id="centre-de-ressource" :style="{ '--couleur': couleur }">
|
||||
<div class="filters">
|
||||
<input type="text" v-model="searchQuery" placeholder="Rechercher..." class="search-bar">
|
||||
<select v-model="selectedType">
|
||||
@ -12,24 +9,17 @@
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<template v-for="type in filteredTypes" :key="type">
|
||||
<div v-if="content.intro" v-html="content.intro" class="intro"></div>
|
||||
<template v-for="(type, typeIndex) in filteredTypes" :key="type">
|
||||
<div class="type-section" v-if="ressourcesToDisplay[type] && ressourcesToDisplay[type].length > 0">
|
||||
<h3>{{ type.replace(/_/g, ' ').replace(/^\w/, char => char.toUpperCase()) }}</h3>
|
||||
<div class="ressource-list">
|
||||
<TransitionGroup name="itemFade" tag="div" appear>
|
||||
<div class="ressource-item"
|
||||
:data-href="ressource.url"
|
||||
<div class="ressource-item"
|
||||
v-for="(ressource, ressourceIndex) in ressourcesToDisplay[type]"
|
||||
:key="`${type}-${ressourceIndex}`"
|
||||
:style="{ '--index': ressourceIndex - visibleItemsPerSection }">
|
||||
<figure>
|
||||
<img :src="ressource.vignette.url" :alt="ressource.vignette.alt" />
|
||||
</figure>
|
||||
<div>
|
||||
<h4>{{ ressource.title }}</h4>
|
||||
<p>Le {{ ressource.date.d }} {{ ressource.date.m }} {{ ressource.date.y }}</p>
|
||||
<p>Par {{ ressource.auteurice }}</p>
|
||||
</div>
|
||||
<RessourceCard :ressource="ressource" :index="`${typeIndex}-${ressourceIndex}`" />
|
||||
</div>
|
||||
</TransitionGroup>
|
||||
</div>
|
||||
@ -52,17 +42,9 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, watch, onMounted } from 'vue';
|
||||
import router from '../../router/router';
|
||||
import RessourceCard from './RessourceCard.vue';
|
||||
|
||||
import { useContentStore } from '../../stores/content';
|
||||
import { useMapStore } from '../../stores/map';
|
||||
|
||||
import { handleClickableElements } from '../../utils/handle-navigation.js';
|
||||
|
||||
const store = useContentStore();
|
||||
const mapStore = useMapStore();
|
||||
const siteName = document.querySelector('#site_name').innerText;
|
||||
import { ref, computed, watch, nextTick } from 'vue';
|
||||
|
||||
const props = defineProps({
|
||||
content: Object,
|
||||
@ -111,31 +93,28 @@ watch(searchQuery, () => {
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
let relatedItemCards, baseUrl;
|
||||
|
||||
watch(ressourcesToDisplay.value, () => {
|
||||
setClickableElements();
|
||||
watch(ressourcesToDisplay.value, async () => {
|
||||
await nextTick();
|
||||
document.querySelectorAll('.ressource-item > div').forEach(el => {
|
||||
const card = el.__vueParentComponent.exposed;
|
||||
if (card && card.setClickableElements) {
|
||||
card.setClickableElements();
|
||||
}
|
||||
});
|
||||
}, { deep: true });
|
||||
|
||||
watch(selectedType, () => {
|
||||
setClickableElements();
|
||||
watch(selectedType, async () => {
|
||||
await nextTick();
|
||||
document.querySelectorAll('.ressource-item > div').forEach(el => {
|
||||
const card = el.__vueParentComponent.exposed;
|
||||
if (card && card.setClickableElements) {
|
||||
card.setClickableElements();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
baseUrl = window.location.protocol + "//" + window.location.host;
|
||||
setClickableElements();
|
||||
});
|
||||
|
||||
function setClickableElements() {
|
||||
setTimeout(() => {
|
||||
relatedItemCards = document.querySelectorAll('.ressource-item');
|
||||
handleClickableElements(relatedItemCards, store, router, baseUrl, siteName, mapStore);
|
||||
}, 50);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
<style lang="scss" scoped>
|
||||
.itemFade-enter-active, .itemFade-leave-active {
|
||||
transition: all 0.3s ease !important;
|
||||
transition-delay: calc(0.1s * var(--index)) !important;
|
||||
@ -150,4 +129,27 @@ function setClickableElements() {
|
||||
opacity: 1;
|
||||
transform: translateY(0px);
|
||||
}
|
||||
|
||||
.filters {
|
||||
margin: 3rem 0;
|
||||
margin-top: 5rem;
|
||||
> .search-bar{
|
||||
margin-right: 2rem;
|
||||
border: solid 1px var(--couleur);
|
||||
padding: 0.5rem 1rem;
|
||||
border-radius: 1rem;
|
||||
font-family: 'Marianne', sans-serif;
|
||||
}
|
||||
> select {
|
||||
appearance: none;
|
||||
border: solid 1px var(--couleur);
|
||||
padding: 0.5rem 1rem;
|
||||
font-family: 'Marianne', sans-serif;
|
||||
border-radius: 1rem;
|
||||
background-color: white;
|
||||
background: url("data:image/svg+xml,<svg height='10px' width='10px' viewBox='0 0 16 16' fill='rgba(128, 200, 191)' xmlns='http://www.w3.org/2000/svg'><path d='M7.247 11.14 2.451 5.658C1.885 5.013 2.345 4 3.204 4h9.592a1 1 0 0 1 .753 1.659l-4.796 5.48a1 1 0 0 1-1.506 0z'/></svg>") no-repeat;
|
||||
background-position: calc(100% - 1rem) center !important;
|
||||
padding-right: 2.5rem !important;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -0,0 +1,39 @@
|
||||
<template>
|
||||
<div class="card" :class="direction ? (direction === 'previous' ? 'previous' : 'next') : 'solo'" :data-href="relatedContent.url">
|
||||
<div class="icon" :style="{ backgroundColor: relatedContent.couleur }"></div>
|
||||
<div class="card-content">
|
||||
<div class="infos">
|
||||
<div class="titre">{{ relatedContent.title }} <span>({{ relatedContent.postalCode.slice(0, 2) }})</span></div>
|
||||
<div class="date">Du {{ relatedContent.dates.start.d }} {{ relatedContent.dates.start.m }}<br>au {{ relatedContent.dates.end.d }} {{ relatedContent.dates.end.m }} {{ relatedContent.dates.end.y }}</div>
|
||||
</div>
|
||||
<div class="vignette">
|
||||
<img :src="relatedContent.vignette.url.small" :alt="relatedContent.vignette.alt">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const props = defineProps({
|
||||
relatedContent: Object,
|
||||
direction: String,
|
||||
});
|
||||
|
||||
import { onMounted } from 'vue';
|
||||
import router from '../../router/router';
|
||||
|
||||
import { useContentStore } from '../../stores/content';
|
||||
import { useMapStore } from '../../stores/map';
|
||||
|
||||
import { handleClickableElements } from '../../utils/handle-navigation.js';
|
||||
|
||||
const store = useContentStore();
|
||||
const mapStore = useMapStore();
|
||||
const siteName = document.querySelector('#site_name').innerText;
|
||||
|
||||
onMounted(() => {
|
||||
const relatedEtapesCards = document.querySelectorAll('.card');
|
||||
const baseUrl = window.location.protocol + "//" + window.location.host;
|
||||
handleClickableElements(relatedEtapesCards, store, router, baseUrl, siteName, mapStore);
|
||||
});
|
||||
</script>
|
@ -16,6 +16,7 @@
|
||||
:navigation="true"
|
||||
:pagination="true"
|
||||
:initialSlide="currentSlideIndex"
|
||||
:keyboard="{ enabled: true }"
|
||||
:injectStyles="[`
|
||||
.swiper-button-next, .swiper-button-prev {
|
||||
color: white;
|
||||
|
@ -5,49 +5,20 @@
|
||||
</div>
|
||||
|
||||
<div v-if="contentType === 'etape' && (content.previous || content.next)" class="related-etape-links">
|
||||
<div v-if="content.previous" class="card previous" :data-href="content.previous.url">
|
||||
<div class="icon" :style="{ backgroundColor: content.previous.couleur }"></div>
|
||||
<div class="card-content">
|
||||
<div class="infos">
|
||||
<div class="titre">{{ content.previous.title }} <span>({{ content.previous.postalCode.slice(0, 2) }})</span></div>
|
||||
<div class="date">Du {{ content.previous.dates.start.d }} {{ content.previous.dates.start.m }}<br>au {{ content.previous.dates.end.d }} {{ content.previous.dates.end.m }} {{ content.previous.dates.end.y }}</div>
|
||||
</div>
|
||||
<div class="vignette">
|
||||
<img :src="content.previous.vignette.url.small" :alt="content.previous.vignette.alt">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="content.next" class="card next" :data-href="content.next.url">
|
||||
<div class="icon" :style="{ backgroundColor: content.next.couleur }"></div>
|
||||
<div class="card-content">
|
||||
<div class="infos">
|
||||
<div class="titre">{{ content.next.title }} <span>({{ content.next.postalCode.slice(0, 2) }})</span></div>
|
||||
<div class="date">Du {{ content.next.dates.start.d }} {{ content.next.dates.start.m }}<br>au {{ content.next.dates.end.d }} {{ content.next.dates.end.m }} {{ content.next.dates.end.y }}</div>
|
||||
</div>
|
||||
<div class="vignette">
|
||||
<img :src="content.next.vignette.url.small" :alt="content.next.vignette.alt">
|
||||
</div>
|
||||
</div>
|
||||
<EtapeCard v-if="content.previous" :relatedContent="content.previous" :direction="'previous'"/>
|
||||
<EtapeCard v-if="content.next" :relatedContent="content.next" :direction="'next'"/>
|
||||
</div>
|
||||
<div v-if="contentType === 'ressourceItem' && content.relatedEtape" >
|
||||
<div class="related-etape-label" :style="{ backgroundColor: couleur }">Étape de la ressource</div>
|
||||
<div class="related-etape-links">
|
||||
<EtapeCard :relatedContent="content.relatedEtape" :direction="''" />
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onMounted } from 'vue';
|
||||
import router from '../../router/router';
|
||||
|
||||
import { useContentStore } from '../../stores/content';
|
||||
import { useMapStore } from '../../stores/map';
|
||||
|
||||
import { handleClickableElements } from '../../utils/handle-navigation.js';
|
||||
|
||||
const brandColor = "#80c8bf";
|
||||
|
||||
const store = useContentStore();
|
||||
const mapStore = useMapStore();
|
||||
const siteName = document.querySelector('#site_name').innerText;
|
||||
|
||||
import EtapeCard from './EtapeCard.vue';
|
||||
|
||||
const props = defineProps({
|
||||
contentType: String,
|
||||
@ -55,10 +26,4 @@ const props = defineProps({
|
||||
couleur: String,
|
||||
map: Object,
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
const relatedEtapesCards = document.querySelectorAll('.card');
|
||||
const baseUrl = window.location.protocol + "//" + window.location.host;
|
||||
handleClickableElements(relatedEtapesCards, store, router, baseUrl, siteName, mapStore);
|
||||
});
|
||||
</script>
|
||||
|
@ -0,0 +1,23 @@
|
||||
<template>
|
||||
<div class="partie related-ressources">
|
||||
<h3>
|
||||
<p :style="{ background: `linear-gradient(transparent 70%, ${couleur} 70%)` }">
|
||||
Ressources liées
|
||||
</p>
|
||||
</h3>
|
||||
<div class="ressource-list sm-ressource-list">
|
||||
<div class="ressource-item" v-for="(relatedRessource, index) in relatedRessources">
|
||||
<RessourceCard :ressource="relatedRessource" :index="index" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import RessourceCard from './RessourceCard.vue';
|
||||
|
||||
const props = defineProps({
|
||||
relatedRessources: Object,
|
||||
couleur: String,
|
||||
});
|
||||
</script>
|
@ -0,0 +1,49 @@
|
||||
<template>
|
||||
<div
|
||||
:data-href="ressource.url"
|
||||
:id="`ressource-${index}`">
|
||||
<figure>
|
||||
<img :src="ressource.vignette.url" :alt="ressource.vignette.alt" />
|
||||
</figure>
|
||||
<div>
|
||||
<h4>{{ ressource.title }}</h4>
|
||||
<p>Le {{ ressource.date.d }} {{ ressource.date.m }} {{ ressource.date.y }}</p>
|
||||
<p>Par {{ ressource.auteurice }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onMounted, defineExpose } from 'vue';
|
||||
import router from '../../router/router';
|
||||
import { handleClickableElements } from '../../utils/handle-navigation.js';
|
||||
|
||||
import { useContentStore } from '../../stores/content';
|
||||
import { useMapStore } from '../../stores/map';
|
||||
|
||||
const store = useContentStore();
|
||||
const mapStore = useMapStore();
|
||||
const siteName = document.querySelector('#site_name').innerText;
|
||||
|
||||
|
||||
let relatedItemCards, baseUrl;
|
||||
|
||||
onMounted(() => {
|
||||
baseUrl = window.location.protocol + "//" + window.location.host;
|
||||
setClickableElements();
|
||||
});
|
||||
|
||||
const setClickableElements = () => {
|
||||
relatedItemCards = document.querySelector(`#ressource-${props.index}`);
|
||||
console.log(relatedItemCards);
|
||||
handleClickableElements([relatedItemCards], store, router, baseUrl, siteName, mapStore);
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
setClickableElements,
|
||||
});
|
||||
const props = defineProps({
|
||||
ressource: Object,
|
||||
index: String,
|
||||
});
|
||||
</script>
|
@ -47,6 +47,9 @@ function setDisplayedType() {
|
||||
case 'videos':
|
||||
props.content.displayedType = 'Vidéo';
|
||||
break;
|
||||
case 'reportages':
|
||||
props.content.displayedType = 'Reportage';
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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() {
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:root {
|
||||
--swiper-navigation-color: #1a1918; /* cf main.scss */
|
||||
--swiper-pagination-color: var(--etape-couleur);
|
||||
--swiper-navigation-top-offset: calc(100% - 1.5rem);
|
||||
--swiper-navigation-sides-offset: 5vw; /* cf main.scss */
|
||||
}
|
||||
</style>
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user