avancées centre de ressources
This commit is contained in:
@@ -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>
|
Reference in New Issue
Block a user