maj config : création view pages static, modale réactive contenu soit static soit etape
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
import { createApp } from 'vue'
|
||||
import { createPinia } from 'pinia'
|
||||
import '../scss/main.scss'
|
||||
import Etape from './vuejs/Etape.vue'
|
||||
import Modale from './vuejs/Modale.vue'
|
||||
|
||||
import { useEtapeStore } from './stores/etape';
|
||||
import { useContentStore } from './stores/content';
|
||||
|
||||
// Working with the history API
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/History_API/Working_with_the_History_API
|
||||
@@ -43,30 +43,45 @@ import { useEtapeStore } from './stores/etape';
|
||||
}
|
||||
|
||||
function initVues(){
|
||||
initVueEtapeModale();
|
||||
initVueContentModale();
|
||||
}
|
||||
|
||||
function initVueEtapeModale(){
|
||||
const app = createApp(Etape).use(createPinia());
|
||||
const store = useEtapeStore();
|
||||
app.mount('#etape-modale');
|
||||
function initVueContentModale(){
|
||||
const app = createApp(Modale).use(createPinia());
|
||||
const store = useContentStore();
|
||||
app.mount('#content-modale');
|
||||
|
||||
processEtapeLinks(store);
|
||||
processStaticLinks(store)
|
||||
}
|
||||
|
||||
|
||||
function onClickEtapeLink(e, store){
|
||||
function onClickContentLink(e, store, category){
|
||||
e.preventDefault();
|
||||
|
||||
let a = e.currentTarget;
|
||||
let nid = a.dataset.nodeNid;
|
||||
console.log(nid);
|
||||
|
||||
store.fetchEtapeData(nid);
|
||||
if (category === 'etape') {
|
||||
store.fetchEtapeData(nid);
|
||||
} else if (category === 'static') {
|
||||
store.fetchStaticData(nid);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function processStaticLinks(store){
|
||||
let general_link_fields = document.querySelectorAll('#menu > ul > li > a');
|
||||
for (let field of general_link_fields) {
|
||||
let general_link_href = field.getAttribute('href');
|
||||
const nid = general_link_href.charAt(general_link_href.length-1);
|
||||
field.setAttribute('data-node-nid', nid);
|
||||
field.addEventListener('click', (e) => onClickContentLink(e, store, 'static'));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function processEtapeLinks(store){
|
||||
let etape_link_fields = document.querySelectorAll('#etapes-liste div.views-field-title');
|
||||
@@ -85,7 +100,7 @@ import { useEtapeStore } from './stores/etape';
|
||||
if (nid) {
|
||||
let a = field.querySelector('a');
|
||||
a.setAttribute('data-node-nid', nid);
|
||||
a.addEventListener('click', (e) => onClickEtapeLink(e, store));
|
||||
a.addEventListener('click', (e) => onClickContentLink(e, store, 'etape'));
|
||||
}
|
||||
|
||||
|
||||
|
109
web/themes/custom/caravane/assets/js/stores/content.js
Normal file
109
web/themes/custom/caravane/assets/js/stores/content.js
Normal file
@@ -0,0 +1,109 @@
|
||||
import { defineStore } from 'pinia';
|
||||
import REST from '../api/rest-axios';
|
||||
|
||||
export const useContentStore = defineStore('content', {
|
||||
state: () => ({
|
||||
etape: {
|
||||
href: '',
|
||||
title: '',
|
||||
adresse: {},
|
||||
etape_number: '',
|
||||
dates: {},
|
||||
geofield: {},
|
||||
galeries: [],
|
||||
parties: [],
|
||||
saison: {},
|
||||
thematiques: [],
|
||||
vignette: {},
|
||||
},
|
||||
page: {
|
||||
href: '',
|
||||
title: '',
|
||||
text: '',
|
||||
},
|
||||
loading: false,
|
||||
error: null,
|
||||
}),
|
||||
actions: {
|
||||
async fetchEtapeData(nid) {
|
||||
this.loading = true;
|
||||
this.error = null;
|
||||
this.page = {};
|
||||
try {
|
||||
const response = await REST.get(`/jsonapi/node/etape/`);
|
||||
for (let etape of response.data.data) {
|
||||
if (etape.attributes.drupal_internal__nid == nid) {
|
||||
for (let metatag of etape.attributes.metatag) {
|
||||
if (metatag.tag === "link") {
|
||||
this.etape.href = metatag.attributes.href;
|
||||
}
|
||||
}
|
||||
this.etape.title = etape.attributes.title;
|
||||
this.etape.adresse = etape.attributes.field_adresse;
|
||||
this.etape.etape_number = etape.attributes.field_arret_numero;
|
||||
this.etape.dates = etape.attributes.field_dates;
|
||||
this.etape.geofield = etape.attributes.field_geofield;
|
||||
this.etape.galeries = await fetchEtapeContent('field_galleries', etape.relationships);
|
||||
const partiesFetch = await fetchEtapeContent('field_parties', etape.relationships);
|
||||
let partiesArray = []
|
||||
for (let partie of partiesFetch) {
|
||||
partiesArray.push({ title: partie.attributes.field_titre, text: partie.attributes.field_texte.value });
|
||||
}
|
||||
this.etape.parties = partiesArray;
|
||||
this.etape.saison = await fetchEtapeContent('field_saison', etape.relationships);
|
||||
this.etape.saison = await fetchEtapeContent('field_saison', etape.relationships);
|
||||
this.etape.thematiques = await fetchEtapeContent('field_thematiques', etape.relationships);
|
||||
const vignetteFetch = await fetchEtapeContent('field_vignette', etape.relationships);
|
||||
this.etape.vignette = { url: vignetteFetch.attributes.uri.url, alt: etape.attributes.field_vignette_alt };
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
this.error = 'Failed to fetch data';
|
||||
console.error('Issue with getNodeData', error);
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
async fetchStaticData(nid) {
|
||||
this.loading = true;
|
||||
this.error = null;
|
||||
this.etape = {};
|
||||
try {
|
||||
const response = await REST.get(`/jsonapi/node/static/`);
|
||||
for (let staticContent of response.data.data) {
|
||||
if (staticContent.attributes.drupal_internal__nid == nid) {
|
||||
staticContent.attributes.metatag.forEach(item => {
|
||||
if (item.tag === 'meta') {
|
||||
this.page.title = item.attributes.content;
|
||||
}
|
||||
if (item.tag === 'link') {
|
||||
this.page.href = item.attributes.href;
|
||||
}
|
||||
})
|
||||
this.page.text = staticContent.attributes.field_texte.value;
|
||||
console.log(this.page.title, this.page.href, this.page.text);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
this.error = 'Failed to fetch data';
|
||||
console.error('Issue with getNodeData', error);
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
async function fetchEtapeContent(field, relationships) {
|
||||
if (relationships[field].data) {
|
||||
try {
|
||||
const contentLink = relationships[field].links.related.href;
|
||||
const contentFetch = await REST.get(contentLink);
|
||||
return contentFetch.data.data;
|
||||
} catch (error) {
|
||||
this.error = 'Failed to fetch data';
|
||||
console.error('Issue with getNodeData', error);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,75 +0,0 @@
|
||||
import { defineStore } from 'pinia';
|
||||
import REST from '../api/rest-axios';
|
||||
|
||||
export const useEtapeStore = defineStore('etape', {
|
||||
state: () => ({
|
||||
href: '',
|
||||
title: '',
|
||||
adresse: {},
|
||||
etape_number: '',
|
||||
dates: {},
|
||||
geofield: {},
|
||||
galeries: [],
|
||||
parties: [],
|
||||
saison: {},
|
||||
thematiques: [],
|
||||
vignette: {},
|
||||
loading: false,
|
||||
error: null,
|
||||
}),
|
||||
actions: {
|
||||
async fetchEtapeData(nid) {
|
||||
this.loading = true;
|
||||
this.error = null;
|
||||
try {
|
||||
// const response = await REST.get(`/node/${nid}?_format=json`);
|
||||
const response = await REST.get(`/jsonapi/node/etape/`);
|
||||
for (let etape of response.data.data) {
|
||||
if (etape.attributes.drupal_internal__nid == nid) {
|
||||
for (let metatag of etape.attributes.metatag) {
|
||||
if (metatag.tag === "link") {
|
||||
this.href = metatag.attributes.href;
|
||||
}
|
||||
}
|
||||
this.title = etape.attributes.title;
|
||||
this.adresse = etape.attributes.field_adresse;
|
||||
this.etape_number = etape.attributes.field_arret_numero;
|
||||
this.dates = etape.attributes.field_dates;
|
||||
this.geofield = etape.attributes.field_geofield;
|
||||
this.galeries = await fetchEtapeContent('field_galleries', etape.relationships);
|
||||
const partiesFetch = await fetchEtapeContent('field_parties', etape.relationships);
|
||||
let partiesArray = []
|
||||
for (let partie of partiesFetch) {
|
||||
partiesArray.push({ title: partie.attributes.field_titre, text: partie.attributes.field_texte.value });
|
||||
}
|
||||
this.parties = partiesArray;
|
||||
this.saison = await fetchEtapeContent('field_saison', etape.relationships);
|
||||
this.saison = await fetchEtapeContent('field_saison', etape.relationships);
|
||||
this.thematiques = await fetchEtapeContent('field_thematiques', etape.relationships);
|
||||
const vignetteFetch = await fetchEtapeContent('field_vignette', etape.relationships);
|
||||
this.vignette = { url: vignetteFetch.attributes.uri.url, alt: etape.attributes.field_vignette_alt };
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
this.error = 'Failed to fetch data';
|
||||
console.error('Issue with getNodeData', error);
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
async function fetchEtapeContent(field, relationships) {
|
||||
if (relationships[field].data) {
|
||||
try {
|
||||
const contentLink = relationships[field].links.related.href;
|
||||
const contentFetch = await REST.get(contentLink);
|
||||
return contentFetch.data.data;
|
||||
} catch (error) {
|
||||
this.error = 'Failed to fetch data';
|
||||
console.error('Issue with getNodeData', error);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,72 +0,0 @@
|
||||
<template>
|
||||
<div v-if="etape_number">
|
||||
<header>
|
||||
<h1>{{adresse.locality}}, {{ adresse.postal_code }}</h1>
|
||||
<h2>{{title}}</h2>
|
||||
<div>
|
||||
<p>Étape n°{{etape_number}}</p>
|
||||
<p>Du {{dates.value}} au {{ dates.end_value }}</p>
|
||||
</div>
|
||||
<img :src="vignette.url" :alt="vignette.alt">
|
||||
</header>
|
||||
<main>
|
||||
<div v-for="partie in parties">
|
||||
<h3 v-html="partie.title"></h3>
|
||||
<p v-html="partie.text"></p>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
|
||||
|
||||
|
||||
<!--
|
||||
<div v-if="loading">Loading...</div>
|
||||
<div v-if="error">{{ error }}</div>
|
||||
-->
|
||||
|
||||
<div><pre>{{href}}</pre></div>
|
||||
|
||||
|
||||
<div><pre><b>GEOFIELD</b>{{geofield}}</pre></div>
|
||||
<div><pre><b>GALERIES</b>{{galeries}}</pre></div>
|
||||
<div><pre><b>PARTIES</b>{{parties}}</pre></div>
|
||||
<div><pre><b>SAISON</b>{{saison}}</pre></div>
|
||||
<div><pre><b>THEMATIQUES</b>{{thematiques}}</pre></div>
|
||||
|
||||
|
||||
<div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useEtapeStore } from '../stores/etape';
|
||||
|
||||
const store = useEtapeStore();
|
||||
|
||||
const {
|
||||
loading, error,
|
||||
|
||||
href,
|
||||
title,
|
||||
adresse,
|
||||
etape_number,
|
||||
dates,
|
||||
geofield,
|
||||
galeries,
|
||||
parties,
|
||||
saison,
|
||||
thematiques,
|
||||
vignette,
|
||||
|
||||
} = storeToRefs(store);
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
header {
|
||||
img {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
62
web/themes/custom/caravane/assets/js/vuejs/Modale.vue
Normal file
62
web/themes/custom/caravane/assets/js/vuejs/Modale.vue
Normal file
@@ -0,0 +1,62 @@
|
||||
<template>
|
||||
<div v-if="etape.etape_number">
|
||||
<header>
|
||||
<h1>{{etape.adresse.locality}}, {{ etape.adresse.postal_code }}</h1>
|
||||
<h2>{{etape.title}}</h2>
|
||||
<div>
|
||||
<p>Étape n°{{etape.etape_number}}</p>
|
||||
<p>Du {{etape.dates.value}} au {{ etape.dates.end_value }}</p>
|
||||
</div>
|
||||
<img :src="etape.vignette.url" :alt="etape.vignette.alt">
|
||||
</header>
|
||||
<main>
|
||||
<div v-for="partie in etape.parties">
|
||||
<h3 v-html="partie.title"></h3>
|
||||
<p v-html="partie.text"></p>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
|
||||
|
||||
|
||||
<!--
|
||||
<div v-if="loading">Loading...</div>
|
||||
<div v-if="error">{{ error }}</div>
|
||||
-->
|
||||
|
||||
<div><pre>{{etape.href}}</pre></div>
|
||||
|
||||
|
||||
<div><pre><b>GEOFIELD</b>{{etape.geofield}}</pre></div>
|
||||
<div><pre><b>GALERIES</b>{{etape.galeries}}</pre></div>
|
||||
<div><pre><b>PARTIES</b>{{etape.parties}}</pre></div>
|
||||
<div><pre><b>SAISON</b>{{etape.saison}}</pre></div>
|
||||
<div><pre><b>THEMATIQUES</b>{{etape.thematiques}}</pre></div>
|
||||
|
||||
|
||||
<div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="page.title">
|
||||
<header>
|
||||
<h1>{{ page.title }}</h1>
|
||||
</header>
|
||||
<main>
|
||||
<div v-html="page.text"></div>
|
||||
</main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useContentStore } from '../stores/content';
|
||||
|
||||
const store = useContentStore();
|
||||
|
||||
const {
|
||||
loading, error,
|
||||
etape,
|
||||
page,
|
||||
|
||||
} = storeToRefs(store);
|
||||
</script>
|
Reference in New Issue
Block a user