ajout partenaires et équipe

This commit is contained in:
Valentin 2024-11-15 13:33:36 +01:00
parent 9370996c03
commit 77817ab74c
8 changed files with 386 additions and 226 deletions

View File

@ -25,14 +25,14 @@ export const useContentStore = defineStore('content', {
actions: { actions: {
async fetchContentData(path) { async fetchContentData(path) {
this.resetStore(false); this.resetStore(false);
const contentTypes = [ 'etape', 'static' ]; const contentTypes = [ 'etape', 'static', 'equipe', 'partenaires' ];
try { try {
let rawContent, let rawContent,
contentType, contentType,
response; response;
contentTypesLoop: contentTypesLoop:
for (let type of contentTypes) { for (let type of contentTypes) {
if (type !== 'partenaires') {
response = await REST.get(`/jsonapi/node/${type}/`); response = await REST.get(`/jsonapi/node/${type}/`);
for (let content of response.data.data) { for (let content of response.data.data) {
for (let tag of content.attributes.metatag) { for (let tag of content.attributes.metatag) {
@ -43,8 +43,31 @@ export const useContentStore = defineStore('content', {
break contentTypesLoop; break contentTypesLoop;
} }
} }
// pour les pages équipes
if (!rawContent) {
const baseUrl = window.location.protocol + "//" + window.location.host;
if (path.startsWith(baseUrl)) {
const shortenPath = path.slice(baseUrl.length + 1);
if (content.attributes.title.toLowerCase() === shortenPath) {
this.contentType = type;
rawContent = content;
contentType = type;
break contentTypesLoop;
} }
} }
}
}
} else {
console.log("partenaires");
// pour les pages partenaires
rawContent = await REST.get('/rest/partenaires/');
contentType = type;
this.contentType = type;
}
}
if (this.contentType !== 'equipe' && this.contentType !== 'partenaires') {
// pageTitle // pageTitle
for (let tag of rawContent.attributes.metatag) { for (let tag of rawContent.attributes.metatag) {
if (tag.tag === "meta") { if (tag.tag === "meta") {
@ -56,7 +79,7 @@ export const useContentStore = defineStore('content', {
this.content.contentTitle = rawContent.attributes.title; this.content.contentTitle = rawContent.attributes.title;
// vignette // vignette
const vignetteFetch = await this.fetchDeeperContent('field_vignette', rawContent.relationships); const vignetteFetch = await this.fetchFromRelationships('field_vignette', rawContent.relationships);
if (vignetteFetch) { if (vignetteFetch) {
this.content.vignette = { this.content.vignette = {
url: vignetteFetch.attributes.uri.url, url: vignetteFetch.attributes.uri.url,
@ -88,7 +111,7 @@ export const useContentStore = defineStore('content', {
// parties // parties
const fieldParties = contentType === 'etape' ? 'field_parties' : 'field_parties_static'; const fieldParties = contentType === 'etape' ? 'field_parties' : 'field_parties_static';
const partiesFetch = await this.fetchDeeperContent(fieldParties, rawContent.relationships); const partiesFetch = await this.fetchFromRelationships(fieldParties, rawContent.relationships);
if (partiesFetch) { if (partiesFetch) {
this.content.parties = []; this.content.parties = [];
@ -100,7 +123,7 @@ export const useContentStore = defineStore('content', {
switch (partieType) { switch (partieType) {
case 'carte_sensible': case 'carte_sensible':
const carteSensibleFetch = await this.fetchDeeperContent('field_image_carte', partie.relationships); const carteSensibleFetch = await this.fetchFromRelationships('field_image_carte', partie.relationships);
if (carteSensibleFetch) { if (carteSensibleFetch) {
partieContent.carteSensible = { partieContent.carteSensible = {
url: carteSensibleFetch.attributes.uri.url, url: carteSensibleFetch.attributes.uri.url,
@ -113,7 +136,7 @@ export const useContentStore = defineStore('content', {
partieContent.texte = partie.attributes.field_texte.value; partieContent.texte = partie.attributes.field_texte.value;
break; break;
case 'chiffres_cles': case 'chiffres_cles':
const chiffresClesFetch = await this.fetchDeeperContent('field_chiffres_clefs', partie.relationships); const chiffresClesFetch = await this.fetchFromRelationships('field_chiffres_clefs', partie.relationships);
if (chiffresClesFetch) { if (chiffresClesFetch) {
partieContent.chiffresCles = []; partieContent.chiffresCles = [];
for (let chiffre of chiffresClesFetch) { for (let chiffre of chiffresClesFetch) {
@ -125,7 +148,7 @@ export const useContentStore = defineStore('content', {
} }
break; break;
case 'diaporama': case 'diaporama':
const diaporamaFetch = await this.fetchDeeperContent('field_diaporama', partie.relationships); const diaporamaFetch = await this.fetchFromRelationships('field_diaporama', partie.relationships);
if (diaporamaFetch) { if (diaporamaFetch) {
partieContent.diaporama = []; partieContent.diaporama = [];
for (let [index, image] of diaporamaFetch.entries()) { for (let [index, image] of diaporamaFetch.entries()) {
@ -138,12 +161,12 @@ export const useContentStore = defineStore('content', {
break; break;
case 'entretien': case 'entretien':
partieContent.entretien = {}; partieContent.entretien = {};
const personnesFetch = await this.fetchDeeperContent('field_personne_s', partie.relationships); const personnesFetch = await this.fetchFromRelationships('field_personne_s', partie.relationships);
const questionsReponsesFetch = await this.fetchDeeperContent('field_questions_reponses', partie.relationships); const questionsReponsesFetch = await this.fetchFromRelationships('field_questions_reponses', partie.relationships);
if (personnesFetch && questionsReponsesFetch) { if (personnesFetch && questionsReponsesFetch) {
partieContent.entretien.personnes = []; partieContent.entretien.personnes = [];
for (let personne of personnesFetch) { for (let personne of personnesFetch) {
const portraitFetch = await this.fetchDeeperContent('field_portrait', personne.relationships); const portraitFetch = await this.fetchFromRelationships('field_portrait', personne.relationships);
if (portraitFetch) { if (portraitFetch) {
partieContent.entretien.personnes.push({ partieContent.entretien.personnes.push({
portrait: portraitFetch.attributes.uri.url, portrait: portraitFetch.attributes.uri.url,
@ -176,6 +199,53 @@ export const useContentStore = defineStore('content', {
this.content.parties.push(partieContent); this.content.parties.push(partieContent);
} }
} }
} else if (this.contentType === 'equipe') {
// pour les pages équipe
for (let tag of rawContent.attributes.metatag) {
if (tag.tag === "meta") {
this.pageTitle = tag.attributes.content;
break;
}
}
this.content.contentTitle = rawContent.attributes.title;
this.content.textIntro = rawContent.attributes.body.value;
const personnesArray = [];
const personnes = await this.fetchFromRelationships('field_personne_s', rawContent.relationships);
for (let personne of personnes) {
const fetchPortrait = await this.fetchFromRelationships('field_portrait', personne.relationships);
personnesArray.push({
nom: personne.attributes.field_nom,
prenom: personne.attributes.field_prenom,
description: personne.attributes.field_description,
portrait_alt: personne.relationships.field_portrait.data.meta.alt,
portrait_url: fetchPortrait.attributes.uri.url,
});
}
this.content.personnes = personnesArray;
// await this.fetchFromId(bundle, id);
// est peut-être plus lisible que fetchFromRelationships
} else if (this.contentType === 'partenaires') {
console.log(rawContent);
this.content.contentTitle = "Partenaires";
const partenairesArray = [];
for (let partenaire of rawContent.data) {
partenairesArray.push({
title: partenaire.title[0].value,
description: partenaire.body[0].value,
link_url: partenaire.field_lien[0].uri,
link_text: partenaire.field_lien[0].title,
logo_url: partenaire.field_logo[0].url,
logo_alt: partenaire.field_logo[0].alt,
weight: partenaire.field_poid[0].value,
})
}
this.content.partenaires = partenairesArray;
}
} catch (error) { } catch (error) {
this.error = 'Failed to fetch data'; this.error = 'Failed to fetch data';
console.error('Issue with getNodeData', error); console.error('Issue with getNodeData', error);
@ -236,7 +306,7 @@ export const useContentStore = defineStore('content', {
} }
} }
}, },
async fetchDeeperContent(field, relationships) { async fetchFromRelationships(field, relationships) {
if (relationships[field].data) { if (relationships[field].data) {
try { try {
const contentLink = relationships[field].links.related.href; const contentLink = relationships[field].links.related.href;

View File

@ -35,7 +35,7 @@ export async function handleBrowserNavigation(store, baseUrl, siteName, mapStore
pageChange(href, store, siteName, mapStore, baseUrl) pageChange(href, store, siteName, mapStore, baseUrl)
} }
async function pageChange(href, store, siteName, mapStore, baseUrl) { export async function pageChange(href, store, siteName, mapStore, baseUrl) {
if (href === '/') { if (href === '/') {
store.resetStore(true); store.resetStore(true);
document.title = siteName; document.title = siteName;

View File

@ -3,7 +3,12 @@
:enter-active-class="animationsAreEnabled ? 'v-enter-active' : 'no-transition'" :enter-active-class="animationsAreEnabled ? 'v-enter-active' : 'no-transition'"
:leave-active-class="animationsAreEnabled ? 'v-leave-active' : 'no-transition'" :leave-active-class="animationsAreEnabled ? 'v-leave-active' : 'no-transition'"
> >
<div v-if="!loading && (contentType === 'etape' || contentType === 'static')"> <div v-if="!loading && (
contentType === 'etape'
|| contentType === 'static'
|| contentType === 'equipe'
|| contentType === 'partenaires'
)">
<div class="content-wrapper"> <div class="content-wrapper">
<ModaleHeader <ModaleHeader
:contentType="contentType" :contentType="contentType"
@ -38,6 +43,12 @@
v-if="partie.type === 'video'" v-if="partie.type === 'video'"
:partie="partie" /> :partie="partie" />
</div> </div>
<EquipeContent
v-if="contentType === 'equipe'"
:content="content" />
<PartenairesContent
v-if="contentType === 'partenaires'"
:content="content" />
</main> </main>
<ModaleFooter <ModaleFooter
:contentType="contentType" :contentType="contentType"
@ -50,15 +61,16 @@
</template> </template>
<script setup> <script setup>
import { computed, watch, onMounted } from 'vue'; import { watch, onMounted } from 'vue';
import { storeToRefs } from 'pinia'; import { storeToRefs } from 'pinia';
import { useContentStore } from '../stores/content'; import { useContentStore } from '../stores/content';
import { useMapStore } from '../stores/map'; import { useMapStore } from '../stores/map';
import { useLayoutStore } from '../stores/layout';
import ModaleHeader from './components/ModaleHeader.vue'; import ModaleHeader from './components/ModaleHeader.vue';
import ModaleFooter from './components/ModaleFooter.vue'; import ModaleFooter from './components/ModaleFooter.vue';
import EquipeContent from './components/EquipeContent.vue';
import PartenairesContent from './components/PartenairesContent.vue';
import ModaleCarteSensible from './components/parties/ModaleCarteSensible.vue'; import ModaleCarteSensible from './components/parties/ModaleCarteSensible.vue';
import ModaleTitreTexte from './components/parties/ModaleTitreTexte.vue'; import ModaleTitreTexte from './components/parties/ModaleTitreTexte.vue';
@ -70,12 +82,6 @@ import ModaleVideos from './components/parties/ModaleVideos.vue';
const store = useContentStore(); const store = useContentStore();
const mapState = useMapStore(); const mapState = useMapStore();
const layoutStore = useLayoutStore();
// pour importer le breakpoint
// const { minDesktopWidth } = storeToRefs(layoutStore);
// console.log(minDesktopWidth);
const { const {
contentType, contentType,
@ -134,9 +140,7 @@ const handleMapMovement = () => {
} else { } else {
console.log('détail -> détail'); console.log('détail -> détail');
setModaleTransition(animationDuration.value); setModaleTransition(animationDuration.value);
//mapState.resetMap();
zoomToContentPlace(); zoomToContentPlace();
//setTimeout(zoomToContentPlace, animationDuration.value * 1000);
} }
} else { } else {
if (wasModaleEtape) { if (wasModaleEtape) {

View File

@ -0,0 +1,18 @@
<template>
<div id="equipe">
<div v-html="content.textIntro"></div>
<div v-for="personne in content.personnes" class="personne">
<figure>
<img :src="personne.portrait_url" :alt="personne.portrait_alt">
</figure>
<div class="name"><p v-html="personne.prenom + ' ' + personne.nom"></p></div>
<div class="description"><p v-html="personne.description"></p></div>
</div>
</div>
</template>
<script setup>
const props = defineProps({
content: Object,
});
</script>

View File

@ -5,7 +5,7 @@
</div> </div>
<div v-if="contentType === 'etape' && (content.previous || content.next)" class="related-etape-links"> <div v-if="contentType === 'etape' && (content.previous || content.next)" class="related-etape-links">
<div v-if="content.previous" class="card previous" @click="clickRelatedElement(content.previous.url)"> <div v-if="content.previous" class="card previous" @click="goToRelatedElement(content.previous.url)">
<div class="icon"> <div class="icon">
<div :style="{ backgroundColor: content.previous.couleur }"></div> <div :style="{ backgroundColor: content.previous.couleur }"></div>
<div :style="{ backgroundColor: content.previous.couleur }"></div> <div :style="{ backgroundColor: content.previous.couleur }"></div>
@ -21,7 +21,7 @@
</div> </div>
</div> </div>
</div> </div>
<div v-if="content.next" class="card next" @click="clickRelatedElement(content.next.url)"> <div v-if="content.next" class="card next" @click="goToRelatedElement(content.next.url)">
<div class="icon"> <div class="icon">
<div :style="{ backgroundColor: content.next.couleur }"></div> <div :style="{ backgroundColor: content.next.couleur }"></div>
<div :style="{ backgroundColor: content.next.couleur }"></div> <div :style="{ backgroundColor: content.next.couleur }"></div>
@ -42,12 +42,16 @@
</template> </template>
<script setup> <script setup>
import router from '../../router/router.js';
import { useContentStore } from '../../stores/content'; import { useContentStore } from '../../stores/content';
import { pageChange } from '../../utils/handle-navigation.js';
const brandColor = "#80c8bf"; const brandColor = "#80c8bf";
const store = useContentStore(); const store = useContentStore();
const mapStore = useContentStore();
const siteName = document.querySelector('#site_name').innerText;
const props = defineProps({ const props = defineProps({
contentType: String, contentType: String,
content: Object, content: Object,
@ -55,21 +59,10 @@ const props = defineProps({
map: Object, map: Object,
}); });
async function displayRelatedElement(href) { async function goToRelatedElement(href) {
const baseUrl = window.location.protocol + "//" + window.location.host; const baseUrl = window.location.protocol + "//" + window.location.host;
if (href.startsWith(baseUrl)) href = href.replace(baseUrl, ''); if (href.startsWith(baseUrl)) href = href.replace(baseUrl, '');
pageChange(href, store, siteName, mapStore, baseUrl)
router.push(href);
await store.fetchContentData(baseUrl + href);
document.title = store.pageTitle;
} }
import { setActiveNavItem } from '../../utils/set-active-nav-item.js';
function clickRelatedElement(href) {
const baseUrl = window.location.protocol + "//" + window.location.host;
if (href.startsWith(baseUrl)) href = href.replace(baseUrl, '');
setActiveNavItem('etape', href);
displayRelatedElement(href);
}
</script> </script>

View File

@ -14,7 +14,7 @@
<div class="locality"> <div class="locality">
<div class="top-triangle"></div> <div class="top-triangle"></div>
<div class="locality-title"> <div class="locality-title">
<h1>{{content.contentTitle}} <em v-if="content.adresse">({{ content.adresse.postal_code.slice(0, 2) }})</em></h1> <h1>{{content.contentTitle}}<em v-if="content.adresse">({{ content.adresse.postal_code.slice(0, 2) }})</em></h1>
</div> </div>
</div> </div>
</div> </div>

View File

@ -0,0 +1,17 @@
<template>
<div id="partenaires">
<div v-for="partenaire in content.partenaires" class="partenaire">
<figure>
<img :src="partenaire.logo_url" :alt="partenaire.logo_alt">
</figure>
<div class="title"><p v-html="partenaire.title"></p></div>
<div class="description"><p v-html="partenaire.description"></p></div>
</div>
</div>
</template>
<script setup>
const props = defineProps({
content: Object,
});
</script>

View File

@ -129,7 +129,7 @@ body{
padding-left: $menu-margin; padding-left: $menu-margin;
margin: 10px 0; margin: 10px 0;
color: white; color: white;
font-size: $l-font-size-mobile; font-size: 2rem;
font-family: 'Joost', sans-serif; font-family: 'Joost', sans-serif;
font-weight: bold; font-weight: bold;
@media screen and (min-width: $desktop-min-width) { @media screen and (min-width: $desktop-min-width) {
@ -229,7 +229,6 @@ body{
z-index: 1; z-index: 1;
font-size: $m-font-size-mobile; font-size: $m-font-size-mobile;
@media screen and (min-width: $desktop-min-width) { @media screen and (min-width: $desktop-min-width) {
font-size: $m-font-size-desktop;
width: $menu-desktop-width; width: $menu-desktop-width;
} }
> li { > li {
@ -746,6 +745,10 @@ body{
} }
} }
> #content-modale { > #content-modale {
padding-bottom: 20vh;
@media screen and (min-width: $desktop-min-width) {
z-index: 6;
}
> div:not(.image-viewer-wrapper, .image-modale) { > div:not(.image-viewer-wrapper, .image-modale) {
padding-bottom: 5vh; padding-bottom: 5vh;
> .content-wrapper { > .content-wrapper {
@ -888,6 +891,7 @@ body{
> main { > main {
width: 100%; width: 100%;
padding: 0 $modale-x-padding; padding: 0 $modale-x-padding;
padding-bottom: 5vh;
box-sizing: border-box; box-sizing: border-box;
> .partie { > .partie {
width: 100%; width: 100%;
@ -1060,6 +1064,55 @@ body{
font-size: $sm-font-size-desktop; font-size: $sm-font-size-desktop;
} }
} }
> #equipe,
> #partenaires {
margin-top: 5vh;
> div:not(.personne) {
@media screen and (min-width: $desktop-min-width) {
margin: 10vh 0;
}
}
> div.personne,
> div.partenaire {
display: grid;
grid-template-columns: 0.4fr 1fr;
column-gap: 3rem;
grid-template-rows: 1fr 1fr;
justify-items: start;
margin: 5vh 0;
> figure {
grid-column: 1;
grid-row: 1 / span 2;
width: 100%;
margin: 0;
> img {
border-radius: 50%;
}
}
> .name,
> .title {
align-self: flex-end;
margin-bottom: 1.3rem;
font-size: $m-font-size-mobile;
@media screen and (min-width: $desktop-min-width) {
font-size: $m-font-size-desktop;
}
> p {
margin: 0;
}
}
> .description {
> p {
margin: 0;
}
}
}
}
#partenaires {
@media screen and (min-width: $desktop-min-width) {
margin-top: 10vh;
}
}
} }
> footer { > footer {
.pattern-bottom { .pattern-bottom {
@ -1179,7 +1232,11 @@ body{
} }
} }
} }
> #animation-toggle > div { > #animation-toggle {
@media screen and (min-width: $desktop-min-width) {
z-index: 5;
}
> div {
cursor: pointer; cursor: pointer;
position: fixed; position: fixed;
bottom: $body-margin-bottom; bottom: $body-margin-bottom;
@ -1249,6 +1306,7 @@ body{
} }
} }
} }
}
> .user-login-form { > .user-login-form {
height: 90vh; height: 90vh;
display: flex; display: flex;