Compare commits

..

No commits in common. "9370996c0383730f669697939d8064ef5aa4bc09" and "c82fc633aafc001e500a127a356e141d5ccdb8fc" have entirely different histories.

15 changed files with 163 additions and 356 deletions

View File

@ -269,7 +269,7 @@ display:
popupAnchor: popupAnchor:
x: '' x: ''
'y': '' 'y': ''
html: "<div></div>\r\n<div></div>\r\n<div></div>\r\n<div class=\"url\">[node:url]</div>\r\n<div class=\"couleur\">[node:field_couleur]</div>" html: "<div></div>\r\n<div></div>\r\n<div></div>\r\n<div class=\"nid\">{{ nid }}</div>\r\n<div class=\"couleur\">{{ field_couleur }}</div>"
html_class: 'leaflet-map-divicon ' html_class: 'leaflet-map-divicon '
circle_marker_options: '{"radius":100,"color":"red","fillColor":"#f03","fillOpacity":0.5}' circle_marker_options: '{"radius":100,"color":"red","fillColor":"#f03","fillOpacity":0.5}'
leaflet_markercluster: leaflet_markercluster:

View File

@ -1,7 +1,7 @@
import { initVueContentModale } from './utils/vue-setup'; import { initVueContentModale } from './utils/vue-setup';
import { processClickableElements } from './utils/process-clickable-elements'; import { processClickableElements } from './utils/process-clickable-elements';
import { handleReactiveness, setMenuToggle, setHamburgerWhenLogged } from './utils/layout-setup'; import { handleReactiveness, setMenuToggle, setHamburgerWhenLogged } from './utils/layout-setup';
import { initFirstLoadRouting, handleClickableElements, handleBrowserNavigation } from './utils/handle-navigation'; import { initFirstLoadRouting, handleClickableElements } from './utils/handle-navigation';
import { setupMapStore } from './utils/map-setup'; import { setupMapStore } from './utils/map-setup';
import '../scss/main.scss' import '../scss/main.scss'
@ -11,11 +11,11 @@ import '../scss/main.scss'
(function ($, Drupal, drupalSettings) { (function ($, Drupal, drupalSettings) {
const CaravaneTheme = function () { const CaravaneTheme = function () {
function init () { function init () {
console.log('DrupalSettings', drupalSettings); console.log('DrupalSettings', drupalSettings);
const baseUrl = window.location.protocol + "//" + window.location.host; const baseUrl = window.location.protocol + "//" + window.location.host;
const siteName = document.querySelector('#site_name').innerText; const siteName = document.querySelector('#site_name').innerText;
const { store, mapStore, router, route } = initVueContentModale(); const { store, mapStore, router, route } = initVueContentModale();
handleReactiveness(); handleReactiveness();
setMenuToggle(); setMenuToggle();
@ -25,8 +25,8 @@ import '../scss/main.scss'
Drupal.behaviors.customLeafletInteraction = { Drupal.behaviors.customLeafletInteraction = {
attach: function(context, settings) { attach: function(context, settings) {
$(context).on('leafletMapInit', function (e, settings, map, mapid, markers) { $(context).on('leafletMapInit', function (e, settings, map, mapid, markers) {
const { const {
etapeListLinks, etapeListLinks,
generalListLinks, generalListLinks,
logoLink, logoLink,
@ -39,10 +39,6 @@ import '../scss/main.scss'
initFirstLoadRouting(store, router, baseUrl, siteName); initFirstLoadRouting(store, router, baseUrl, siteName);
handleClickableElements(clickableElements, store, router, baseUrl, siteName, mapStore); handleClickableElements(clickableElements, store, router, baseUrl, siteName, mapStore);
window.addEventListener("popstate", () => {
handleBrowserNavigation(store, baseUrl, siteName, mapStore);
});
}); });
} }
} }
@ -51,4 +47,4 @@ import '../scss/main.scss'
init() init()
} }
CaravaneTheme() CaravaneTheme()
})(jQuery, Drupal, drupalSettings) })(jQuery, Drupal, drupalSettings)

View File

@ -2,13 +2,13 @@ import { createRouter, createWebHistory } from 'vue-router';
import ModaleView from '../vuejs/Modale.vue'; import ModaleView from '../vuejs/Modale.vue';
const routes = [ const routes = [
/* { /* {
name: 'etape', name: 'etape',
path: '/etapes/:title?', path: '/etapes/:title?',
component: ModaleView, component: ModaleView,
props: {id: null}, props: {id: null},
}, },
{ {
name: 'home', name: 'home',
path: '/', path: '/',
component: ModaleView, component: ModaleView,
@ -20,10 +20,10 @@ const routes = [
component: ModaleView, component: ModaleView,
} }
]; ];
const router = createRouter({ const router = createRouter({
history: createWebHistory(), history: createWebHistory(),
routes, routes,
}); });
export default router; export default router;

View File

@ -27,7 +27,7 @@ export const useContentStore = defineStore('content', {
this.resetStore(false); this.resetStore(false);
const contentTypes = [ 'etape', 'static' ]; const contentTypes = [ 'etape', 'static' ];
try { try {
let rawContent, let rawContent,
contentType, contentType,
response; response;
@ -58,11 +58,11 @@ export const useContentStore = defineStore('content', {
// vignette // vignette
const vignetteFetch = await this.fetchDeeperContent('field_vignette', rawContent.relationships); const vignetteFetch = await this.fetchDeeperContent('field_vignette', rawContent.relationships);
if (vignetteFetch) { if (vignetteFetch) {
this.content.vignette = { this.content.vignette = {
url: vignetteFetch.attributes.uri.url, url: vignetteFetch.attributes.uri.url,
alt: rawContent.relationships.field_vignette.data.meta.alt alt: rawContent.relationships.field_vignette.data.meta.alt
}; };
} }
if (contentType === 'etape') { if (contentType === 'etape') {
// coordinates // coordinates
@ -84,12 +84,12 @@ export const useContentStore = defineStore('content', {
// previous / next // previous / next
await this.getRelatedEtape('previous', response.data.data, path); await this.getRelatedEtape('previous', response.data.data, path);
await this.getRelatedEtape('next', response.data.data, path); await this.getRelatedEtape('next', response.data.data, path);
} }
// 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.fetchDeeperContent(fieldParties, rawContent.relationships);
if (partiesFetch) { if (partiesFetch) {
this.content.parties = []; this.content.parties = [];
for (let partie of partiesFetch) { for (let partie of partiesFetch) {
@ -100,7 +100,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.fetchDeeperContent('field_image_carte', partie.relationships);
if (carteSensibleFetch) { if (carteSensibleFetch) {
partieContent.carteSensible = { partieContent.carteSensible = {
url: carteSensibleFetch.attributes.uri.url, url: carteSensibleFetch.attributes.uri.url,
@ -110,7 +110,7 @@ export const useContentStore = defineStore('content', {
break; break;
case 'titre_texte': case 'titre_texte':
partieContent.titre = partie.attributes.field_titre; partieContent.titre = partie.attributes.field_titre;
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.fetchDeeperContent('field_chiffres_clefs', partie.relationships);
@ -144,7 +144,7 @@ export const useContentStore = defineStore('content', {
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.fetchDeeperContent('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,
alt: personne.relationships.field_portrait.data.meta.alt, alt: personne.relationships.field_portrait.data.meta.alt,
@ -158,7 +158,7 @@ export const useContentStore = defineStore('content', {
question: qr.attributes.field_question, question: qr.attributes.field_question,
reponse: qr.attributes.field_reponse.value, reponse: qr.attributes.field_reponse.value,
}); });
} }
} }
break; break;
case 'exergue': case 'exergue':
@ -169,7 +169,7 @@ export const useContentStore = defineStore('content', {
for (let video of partie.attributes.field_videos) { for (let video of partie.attributes.field_videos) {
const videoId = video.split('?v=')[1]; const videoId = video.split('?v=')[1];
const videoUrl = `https://www.youtube.com/embed/${videoId}`; const videoUrl = `https://www.youtube.com/embed/${videoId}`;
partieContent.videos.push(videoUrl); partieContent.videos.push(videoUrl);
} }
break; break;
} }
@ -179,8 +179,8 @@ export const useContentStore = defineStore('content', {
} 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);
} finally { } finally {
this.loading = false; this.loading = false;
} }
}, },
getCleanDate(date) { getCleanDate(date) {
@ -195,7 +195,7 @@ export const useContentStore = defineStore('content', {
const baseUrl = window.location.protocol + "//" + window.location.host; const baseUrl = window.location.protocol + "//" + window.location.host;
for (let etape of allEtapesData) { for (let etape of allEtapesData) {
for (let tag of etape.attributes.metatag) { for (let tag of etape.attributes.metatag) {
if (tag.tag === "link" && tag.attributes.href === baseUrl + relatedPath) { if (tag.tag === "link" && tag.attributes.href === baseUrl + relatedPath) {
const vignetteFetch = await REST.get(etape.relationships.field_vignette.links.related.href); const vignetteFetch = await REST.get(etape.relationships.field_vignette.links.related.href);
this.content[direction] = { this.content[direction] = {
url: tag.attributes.href, url: tag.attributes.href,
@ -223,7 +223,7 @@ export const useContentStore = defineStore('content', {
if (path.endsWith(liHref)) { if (path.endsWith(liHref)) {
const previousEtapeItemPath = li.previousElementSibling?.querySelector('a').getAttribute('href'); const previousEtapeItemPath = li.previousElementSibling?.querySelector('a').getAttribute('href');
const nextEtapeItemPath = li.nextElementSibling?.querySelector('a').getAttribute('href'); const nextEtapeItemPath = li.nextElementSibling?.querySelector('a').getAttribute('href');
if (previousEtapeItemPath && direction === 'previous') { if (previousEtapeItemPath && direction === 'previous') {
let prevContent = await getRelatedEtapeContent(previousEtapeItemPath, allEtapesData); let prevContent = await getRelatedEtapeContent(previousEtapeItemPath, allEtapesData);
return prevContent; return prevContent;
@ -256,4 +256,4 @@ export const useContentStore = defineStore('content', {
this.error = null; this.error = null;
} }
}, },
}); });

View File

@ -34,48 +34,38 @@ export const useLayoutStore = defineStore('layout', {
this.isEtapeListRetracted = false; this.isEtapeListRetracted = false;
}, },
setUpHamburgerToggle(menuBurger, menuContainer) { setUpHamburgerToggle(menuBurger, menuContainer) {
const menuTitle = document.querySelector('#menu-title'); const menuTitle = document.querySelector('#menu-title');
const menuH2 = document.querySelector('#menu > h2'); const menuH2 = document.querySelector('#menu > h2');
menuBurger.addEventListener('click', (e) => { menuBurger.addEventListener('click', (e) => {
this.toggleHamburgerMenu(menuBurger, menuContainer, menuTitle, menuH2);
});
document.addEventListener('click', (e) => {
if (
(!menuContainer.contains(e.target) && !menuBurger.contains(e.target))
|| e.target.tagName === 'A'
) {
menuContainer.classList.remove('open');
menuTitle.classList.remove('open');
menuBurger.classList.remove('open');
menuH2.classList.remove('open');
setTimeout(() => { setTimeout(() => {
if (this.isHamburgerMenuOpen) { if (!this.isHamburgerMenuOpen) menuContainer.style.display = 'block';
menuContainer.style.display = 'none'; menuContainer.classList.toggle('open');
menuTitle.classList.toggle('open');
menuBurger.classList.toggle('open');
menuH2.classList.toggle('open');
if (this.isHamburgerMenuOpen) {
setTimeout(() => {
menuContainer.style.display = 'none';
this.isHamburgerMenuOpen = !this.isHamburgerMenuOpen;
}, 300);
}
}, 50);
document.addEventListener('click', (e) => {
if (!menuContainer.contains(e.target) && !menuBurger.contains(e.target)) {
menuContainer.classList.remove('open');
menuTitle.classList.remove('open');
menuBurger.classList.remove('open');
menuH2.classList.remove('open');
setTimeout(() => {
if (this.isHamburgerMenuOpen) {
menuContainer.style.display = 'none';
}
this.isHamburgerMenuOpen = false;
}, 300);
} }
}, 300); });
this.isHamburgerMenuOpen = false; });
}
});
},
toggleHamburgerMenu(menuBurger, menuContainer, menuTitle, menuH2) {
setTimeout(() => {
if (!this.isHamburgerMenuOpen) menuContainer.style.display = 'block';
menuContainer.classList.toggle('open');
menuTitle.classList.toggle('open');
menuBurger.classList.toggle('open');
menuH2.classList.toggle('open');
// console.log('isHamburgerMenuOpen', this.isHamburgerMenuOpen);
console.log(this.isHamburgerMenuOpen);
if (this.isHamburgerMenuOpen) {
setTimeout(() => {
menuContainer.style.display = 'none';
}, 300);
}
console.log('TOGGLE', this.isHamburgerMenuOpen);
console.log('isHamburgerMenuOpen', this.isHamburgerMenuOpen);
this.isHamburgerMenuOpen = !this.isHamburgerMenuOpen;
}, 50);
} }
}, },
}) })

View File

@ -10,30 +10,23 @@ export const useMapStore = defineStore('mapState', {
currentPlace: Object, currentPlace: Object,
maxZoom: Number, maxZoom: Number,
currentZoom: Number, currentZoom: Number,
animationsAreEnabled: true, duration: 3,
animationDuration: 3,
}), }),
actions: { actions: {
zoomToPlace(lat, long) { zoomToPlace(lat, long) {
if (useLayoutStore().isDesktop) long = long - 0.03; if (useLayoutStore().isDesktop) long = long - 0.03;
this.map.flyTo( this.map.flyTo([lat, long], this.maxZoom, { duration: this.duration });
[lat, long], this.currentZoom = this.maxZoom;
this.maxZoom,
{ animate: this.animationsAreEnabled, animationDuration: this.animationDuration });
this.currentZoom = this.maxZoom;
}, },
resetMap() { resetMap() {
this.map.flyTo( this.map.flyTo(this.defaultMapCenter, useLayoutStore().isDesktop ? this.defaultZoomDesktop : this.defaultZoomMobile, { duration: this.duration });
this.defaultMapCenter,
useLayoutStore().isDesktop ? this.defaultZoomDesktop : this.defaultZoomMobile,
{ animate: this.animationsAreEnabled, animationDuration: this.animationDuration });
this.currentZoom = useLayoutStore().isDesktop ? this.defaultZoomDesktop : this.defaultZoomMobile; this.currentZoom = useLayoutStore().isDesktop ? this.defaultZoomDesktop : this.defaultZoomMobile;
}, },
lockMap() { lockMap() {
setTimeout(() => { setTimeout(() => {
this.map.options.minZoom = this.currentZoom; this.map.options.minZoom = this.currentZoom;
this.map.options.maxZoom = this.currentZoom; this.map.options.maxZoom = this.currentZoom;
}, this.animationDuration * 1000 + 100); }, this.duration * 1000 + 100);
this.map.dragging.disable(); this.map.dragging.disable();
this.map.touchZoom.disable(); this.map.touchZoom.disable();
this.map.doubleClickZoom.disable(); this.map.doubleClickZoom.disable();
@ -41,28 +34,17 @@ export const useMapStore = defineStore('mapState', {
this.map.boxZoom.disable(); this.map.boxZoom.disable();
this.map.keyboard.disable(); this.map.keyboard.disable();
// map.tap.disable(); // map.tap.disable();
}, },
unlockMap() { unlockMap() {
this.map.options.minZoom = useLayoutStore().isDesktop ? this.defaultZoomDesktop : this.defaultZoomMobile; this.map.options.minZoom = useLayoutStore().isDesktop ? this.defaultZoomDesktop : this.defaultZoomMobile;
this.map.options.maxZoom = this.maxZoom; this.map.options.maxZoom = this.maxZoom;
this.map.dragging.enable(); this.map.dragging.enable();
this.map.touchZoom.enable(); this.map.touchZoom.enable();
this.map.doubleClickZoom.enable(); this.map.doubleClickZoom.enable();
this.map.scrollWheelZoom.enable(); this.map.scrollWheelZoom.enable();
this.map.boxZoom.enable(); this.map.boxZoom.enable();
this.map.keyboard.enable(); this.map.keyboard.enable();
// map.tap.enable(); // map.tap.enable();
}, },
toggleAnimation() {
this.animationsAreEnabled = !this.animationsAreEnabled;
},
checkReducedMotion() {
const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)');
this.animationsAreEnabled = !mediaQuery.matches;
mediaQuery.addEventListener('change', (event) => {
this.animationsAreEnabled = !event.matches;
});
},
}, },
}); });

View File

@ -4,11 +4,11 @@ import { useLayoutStore } from '../stores/layout';
export async function initFirstLoadRouting(store, router, baseUrl, siteName) { export async function initFirstLoadRouting(store, router, baseUrl, siteName) {
const decoupled_origin = JSON.parse(window.localStorage.getItem('decoupled_origin')); const decoupled_origin = JSON.parse(window.localStorage.getItem('decoupled_origin'));
if(decoupled_origin) { if(decoupled_origin) {
await store.fetchContentData(baseUrl + decoupled_origin.url); await store.fetchContentData(baseUrl + decoupled_origin.url);
router.push(decoupled_origin.url); router.push(decoupled_origin.url);
window.localStorage.removeItem("decoupled_origin"); window.localStorage.removeItem("decoupled_origin");
document.title = store.pageTitle; document.title = store.pageTitle;
setActiveNavItem(store.contentType, decoupled_origin.url); setActiveNavItem(store.contentType, decoupled_origin.url);
} else { } else {
document.title = siteName; document.title = siteName;
@ -23,29 +23,19 @@ export function handleClickableElements(clickableElements, store, router, baseUr
link.onclick = async function (e) { link.onclick = async function (e) {
router.push(href); router.push(href);
if (href !== window.location.pathname) { if (href !== window.location.pathname) {
pageChange(href, store, siteName, mapStore, baseUrl); if (href === '/') {
store.resetStore(true);
document.title = siteName;
mapStore.resetMap();
} else {
await store.fetchContentData(baseUrl + href);
document.title = store.pageTitle;
}
setActiveNavItem(store.contentType, href);
const listeEtape = document.querySelector('#etapes-liste');
if (!useLayoutStore().isDesktop) useLayoutStore().collapseEtapeListe(listeEtape);
} }
} }
} }
} }
export async function handleBrowserNavigation(store, baseUrl, siteName, mapStore) {
let href = window.location.pathname;
if (href.startsWith(baseUrl)) href = href.replace(baseUrl, '');
pageChange(href, store, siteName, mapStore, baseUrl)
}
async function pageChange(href, store, siteName, mapStore, baseUrl) {
if (href === '/') {
store.resetStore(true);
document.title = siteName;
mapStore.resetMap();
} else {
await store.fetchContentData(baseUrl + href);
document.title = store.pageTitle;
}
setActiveNavItem(store.contentType, href);
const listeEtape = document.querySelector('#etapes-liste');
if (!useLayoutStore().isDesktop) useLayoutStore().collapseEtapeListe(listeEtape);
}

View File

@ -1,5 +1,5 @@
export function processClickableElements() { export function processClickableElements() {
return { return {
etapeListLinks: processEtapeLinks(), etapeListLinks: processEtapeLinks(),
generalListLinks: processStaticLinks(), generalListLinks: processStaticLinks(),
logoLink: processLogoLink(), logoLink: processLogoLink(),
@ -26,7 +26,15 @@ function processEtapeLinks() {
function processStaticLinks() { function processStaticLinks() {
const general_link_fields = document.querySelectorAll('#menu > ul > li > a'); const general_link_fields = document.querySelectorAll('#menu > ul > li > a');
for (let i = 0; i < general_link_fields.length; i ++) { for (let i = 0; i < general_link_fields.length; i ++) {
general_link_fields[i].addEventListener('click', (e) => e.preventDefault()); let general_link_path = general_link_fields[i].getAttribute('data-drupal-link-system-path');
if (general_link_path && general_link_path !== '<front>') {
const match = [...general_link_path.match(/^node\/(\d+)$/)];
if (match) {
const nid = match[1];
general_link_fields[i].setAttribute('data-nid', parseInt(nid));
}
}
general_link_fields[i].addEventListener('click', (e) => e.preventDefault());
} }
return general_link_fields; return general_link_fields;
@ -62,11 +70,11 @@ function processMapIcons() {
const popup = document.querySelector('.leaflet-tooltip-center > div'); const popup = document.querySelector('.leaflet-tooltip-center > div');
popup.style.opacity = "1"; popup.style.opacity = "1";
}); });
icon.addEventListener('mouseleave', () => { icon.addEventListener('mouseleave', () => {
icon.style.transform = icon.style.transform.split(' ')[0] + icon.style.transform.split(' ')[1] + icon.style.transform.split(' ')[2]; icon.style.transform = icon.style.transform.split(' ')[0] + icon.style.transform.split(' ')[1] + icon.style.transform.split(' ')[2];
}); });
} }
return icons; return icons;
} }

View File

@ -1,7 +1,7 @@
export function setActiveNavItem(contentType, href) { export function setActiveNavItem(contentType, href) {
const staticNavItems = document.querySelectorAll('#menu > ul > li > a'); const staticNavItems = document.querySelectorAll('#menu > ul > li > a');
const etapeNavItems = document.querySelectorAll('#etapes-liste li a'); const etapeNavItems = document.querySelectorAll('#etapes-liste li a');
for (let item of staticNavItems) { for (let item of staticNavItems) {
item.classList.remove('is-active'); item.classList.remove('is-active');
} }
@ -15,7 +15,7 @@ export function setActiveNavItem(contentType, href) {
for (let item of etapeNavItems) { for (let item of etapeNavItems) {
item.closest('li').classList.remove('inactive'); item.closest('li').classList.remove('inactive');
} }
} else { } else {
if (contentType === 'static') { if (contentType === 'static') {
for (let item of staticNavItems) { for (let item of staticNavItems) {
@ -32,4 +32,4 @@ export function setActiveNavItem(contentType, href) {
} }
} }
} }

View File

@ -2,7 +2,6 @@ import { createApp } from 'vue';
import { createPinia } from 'pinia'; import { createPinia } from 'pinia';
import router from '../router/router'; import router from '../router/router';
import Modale from '../vuejs/Modale.vue'; import Modale from '../vuejs/Modale.vue';
import AnimationToggle from '../vuejs/AnimationToggle.vue';
import VueImageZoomer from 'vue-image-zoomer'; import VueImageZoomer from 'vue-image-zoomer';
import 'vue-image-zoomer/dist/style.css'; import 'vue-image-zoomer/dist/style.css';
@ -10,20 +9,14 @@ import { useContentStore } from '../stores/content';
import { useMapStore } from '../stores/map'; import { useMapStore } from '../stores/map';
export function initVueContentModale() { export function initVueContentModale() {
const pinia = createPinia();
const app = createApp(Modale) const app = createApp(Modale)
.use(pinia) .use(createPinia())
.use(router) .use(router)
.use(VueImageZoomer); .use(VueImageZoomer);
const store = useContentStore(); const store = useContentStore();
const mapStore = useMapStore(); const mapStore = useMapStore();
app.mount('#content-modale'); app.mount('#content-modale');
const animationToggle = createApp(AnimationToggle)
.use(pinia)
.mount('#animation-toggle');
return { store, mapStore, router }; return { store, mapStore, router };
} }

View File

@ -1,37 +0,0 @@
<template>
<div @click="handleClick" class="animation-toggle-container">
<div><p>Activer les animations</p></div>
<label class="switch">
<input type="checkbox" v-model="animationsAreEnabled" @click.stop @change="toggleAnimation" />
<span class="slider round"></span>
</label>
</div>
</template>
<script>
import { useMapStore } from '../stores/map';
import { storeToRefs } from 'pinia';
export default {
setup() {
const mapStore = useMapStore();
const { animationsAreEnabled } = storeToRefs(mapStore);
const toggleAnimation = () => {
mapStore.toggleAnimation();
};
const handleClick = () => {
toggleAnimation();
};
return {
handleClick,
toggleAnimation,
animationsAreEnabled,
};
},
};
</script>

View File

@ -1,8 +1,5 @@
<template> <template>
<Transition <Transition>
:enter-active-class="animationsAreEnabled ? 'v-enter-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')">
<div class="content-wrapper"> <div class="content-wrapper">
<ModaleHeader <ModaleHeader
@ -11,8 +8,8 @@
:couleur="content.couleur || brandColor" /> :couleur="content.couleur || brandColor" />
<main> <main>
<div v-for="partie in content.parties" class="partie"> <div v-for="partie in content.parties" class="partie">
<ModaleCarteSensible <ModaleCarteSensible
v-if="partie.type === 'carte_sensible'" v-if="partie.type === 'carte_sensible'"
:partie="partie" /> :partie="partie" />
<ModaleTitreTexte <ModaleTitreTexte
v-if="partie.type === 'titre_texte'" v-if="partie.type === 'titre_texte'"
@ -81,10 +78,10 @@ const {
contentType, contentType,
content, content,
loading, loading,
error, error,
} = storeToRefs(store); } = storeToRefs(store);
const { defaultMapCenter, animationDuration, animationsAreEnabled } = storeToRefs(mapState); const { map, duration } = storeToRefs(mapState);
let isModaleEtape, wasModaleEtape; let isModaleEtape, wasModaleEtape;
@ -93,10 +90,10 @@ const brandColor = "#80c8bf";
const handleColorChange = () => { const handleColorChange = () => {
watch( watch(
() => content.value.couleur, () => content.value.couleur,
() => { () => {
if (contentType.value === 'etape' && content.value.couleur) { if (contentType.value === 'etape' && content.value.couleur) {
document.documentElement.style.setProperty('--etape-couleur', content.value.couleur || brandColor); document.documentElement.style.setProperty('--etape-couleur', content.value.couleur || brandColor);
} }
} }
); );
}; };
@ -106,59 +103,33 @@ const handleMapMovement = () => {
() => loading.value, () => loading.value,
() => { () => {
if (!loading.value) { if (!loading.value) {
isModaleEtape = contentType.value === 'etape'; isModaleEtape = contentType.value === 'etape';
// Define helper functions in variables if (!wasModaleEtape && isModaleEtape) {
const disableModaleTransition = () => { // national -> détail
document.documentElement.style.setProperty('margin-top', '0'); document.documentElement.style.setProperty('--modale-enter-delay', `${duration.value}s`);
document.documentElement.style.setProperty('transition', 'none'); mapState.zoomToPlace(content.value.coordinates.lat, content.value.coordinates.lon);
} } else if (wasModaleEtape && isModaleEtape) {
const setModaleTransition = (enterDelay) => { // détail -> détail
document.documentElement.style.setProperty('--modale-enter-delay', `${enterDelay}s`); document.documentElement.style.setProperty('--modale-leave-delay', 0);
}; document.documentElement.style.setProperty('--modale-enter-delay', `${duration.value * 2}s`);
mapState.resetMap(map.value);
const zoomToContentPlace = () => { setTimeout(() => {
mapState.zoomToPlace( mapState.zoomToPlace(content.value.coordinates.lat, content.value.coordinates.lon);
content.value.coordinates.lat ? content.value.coordinates.lat : defaultMapCenter.value.lat, }, duration.value * 1000);
content.value.coordinates.lon ? content.value.coordinates.lon : defaultMapCenter.value.lng
); } else if (wasModaleEtape && !isModaleEtape) {
}; // détail -> national
document.documentElement.style.setProperty('--modale-leave-delay', 0);
if (animationsAreEnabled.value) { document.documentElement.style.setProperty('--modale-enter-delay', `${duration.value}s`);
if (isModaleEtape) {
if (!wasModaleEtape) {
console.log('national -> détail');
setModaleTransition(animationDuration.value);
zoomToContentPlace();
} else {
console.log('détail -> détail');
setModaleTransition(animationDuration.value);
//mapState.resetMap();
zoomToContentPlace();
//setTimeout(zoomToContentPlace, animationDuration.value * 1000);
}
} else {
if (wasModaleEtape) {
console.log('détail -> national');
setModaleTransition(animationDuration.value);
mapState.resetMap();
} else {
console.log('national -> national');
setModaleTransition(0);
}
}
} else {
if (isModaleEtape) {
zoomToContentPlace();
} else {
mapState.resetMap(); mapState.resetMap();
} } else if (!wasModaleEtape && !isModaleEtape) {
disableModaleTransition(); // national -> national
console.log('national -> national');
document.documentElement.style.setProperty('--modale-leave-delay', 0);
document.documentElement.style.setProperty('--modale-enter-delay', '0.5s');
} }
scrollTo(0, 0);
wasModaleEtape = isModaleEtape; wasModaleEtape = isModaleEtape;
} }
}, },
@ -167,7 +138,7 @@ const handleMapMovement = () => {
onMounted(() => { onMounted(() => {
isModaleEtape = contentType.value === 'etape'; isModaleEtape = contentType.value === 'etape';
wasModaleEtape = isModaleEtape; wasModaleEtape = isModaleEtape;
handleColorChange(); handleColorChange();
handleMapMovement(); handleMapMovement();
}); });
@ -179,7 +150,7 @@ onMounted(() => {
} }
.v-leave-active { .v-leave-active {
transition: margin-top 0.5s ease-in; transition: margin-top 0.5s ease-in var(--modale-leave-delay);
} }
.v-enter-from, .v-enter-from,
@ -189,12 +160,6 @@ onMounted(() => {
.v-enter-to, .v-enter-to,
.v-leave-from { .v-leave-from {
margin-top: 0vh; margin-top: 0vh;
} }
</style>
/* This class will disable transitions */
.no-transition {
margin-top: 0 !important;
transition: none !important;
}
</style>

View File

@ -3,9 +3,9 @@
<div class="brand-pattern pattern-bottom" :style="{ backgroundColor: couleur }"> <div class="brand-pattern pattern-bottom" :style="{ backgroundColor: couleur }">
<div class="pattern"></div> <div class="pattern"></div>
</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="displayRelatedElement(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="displayRelatedElement(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>
@ -57,19 +57,10 @@ const props = defineProps({
async function displayRelatedElement(href) { async function displayRelatedElement(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, '');
router.push(href); router.push(href);
await store.fetchContentData(baseUrl + href); await store.fetchContentData(baseUrl + href);
document.title = store.pageTitle; document.title = store.pageTitle;
} }
</script>
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>

View File

@ -63,7 +63,7 @@ body{
display: flex; display: flex;
align-items: center; align-items: center;
@media screen and (min-width: $desktop-min-width) { @media screen and (min-width: $desktop-min-width) {
grid-column: 1 / span 1; grid-column: 1 / span 1;
} }
> div > div > a > img { > div > div > a > img {
width: 100%; width: 100%;
@ -76,7 +76,7 @@ body{
align-items: center; align-items: center;
padding-right: 2.5rem; padding-right: 2.5rem;
@media screen and (min-width: $desktop-min-width) { @media screen and (min-width: $desktop-min-width) {
grid-column: 2 / span 2; grid-column: 2 / span 2;
} }
> div > div > a > img { > div > div > a > img {
width: 100%; width: 100%;
@ -90,7 +90,7 @@ body{
display: flex; display: flex;
align-items: center; align-items: center;
@media screen and (min-width: $desktop-min-width) { @media screen and (min-width: $desktop-min-width) {
grid-column: 8 / span 2; grid-column: 8 / span 2;
} }
> div > div > a > img { > div > div > a > img {
width: 100%; width: 100%;
@ -296,7 +296,7 @@ body{
> div { > div {
pointer-events: auto; pointer-events: auto;
} }
} }
> .layout__region--second { > .layout__region--second {
position: fixed; position: fixed;
z-index: 1; z-index: 1;
@ -404,7 +404,7 @@ body{
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
*/ */
padding-top: 10px; padding-top: 10px;
padding-left: 20px; padding-left: 20px;
padding-right: 20px; padding-right: 20px;
@ -597,7 +597,6 @@ body{
margin: 30px 0; margin: 30px 0;
transform: scale(1); transform: scale(1);
opacity: 1; opacity: 1;
padding-right: 0.5rem;
transition: transform 0.3s ease-out, opacity 0.3s ease-out; transition: transform 0.3s ease-out, opacity 0.3s ease-out;
cursor: pointer; cursor: pointer;
> .infos-arret { > .infos-arret {
@ -626,7 +625,7 @@ body{
text-align: right; text-align: right;
@media screen and (min-width: $desktop-min-width) { @media screen and (min-width: $desktop-min-width) {
font-size: $m-font-size-desktop; font-size: $m-font-size-desktop;
} }
} }
} }
> .views-field-field-adresse-postal-code { > .views-field-field-adresse-postal-code {
@ -648,7 +647,7 @@ body{
content: ')'; content: ')';
} }
} }
} }
> .views-field-field-dates { > .views-field-field-dates {
grid-column: 1 / span 2; grid-column: 1 / span 2;
@ -822,7 +821,7 @@ body{
@media screen and (min-width: $tablet-min-width) { @media screen and (min-width: $tablet-min-width) {
width: calc($modale-width-mobile - $modale-x-padding * 6); width: calc($modale-width-mobile - $modale-x-padding * 6);
margin-left: $modale-x-padding * 3; margin-left: $modale-x-padding * 3;
} }
@media screen and (min-width: $desktop-min-width) { @media screen and (min-width: $desktop-min-width) {
width: calc($modale-width-desktop - $modale-x-padding * 4); width: calc($modale-width-desktop - $modale-x-padding * 4);
@ -961,7 +960,7 @@ body{
> .description { > .description {
width: 100%; width: 100%;
margin-top: 1rem; margin-top: 1rem;
@media screen and (min-width: $desktop-min-width) { @media screen and (min-width: $desktop-min-width) {
width: calc(100% - 6rem); width: calc(100% - 6rem);
margin-top: 0; margin-top: 0;
} }
@ -1179,75 +1178,6 @@ body{
} }
} }
} }
> #animation-toggle > div {
cursor: pointer;
position: fixed;
bottom: $body-margin-bottom;
right: $body-margin-x;
z-index: 999;
display: flex;
align-items: center;
padding: 0.4rem 1.2rem;
border-radius: 10rem;
background-color: white;
transition: background-color 0.3s ease-out;
> div {
margin-right: 1rem;
> p {
font-size: $sm-font-size-mobile;
@media screen and (min-width: $desktop-min-width) {
font-size: $sm-font-size-desktop;
}
}
}
> .switch {
position: relative;
display: inline-block;
width: 2.2rem;
height: 1.2rem;
> input {
opacity: 0;
width: 0;
height: 0;
&:checked + .slider {
background-color: $brand-color;
}
&:focus + .slider {
box-shadow: 0 0 1px $brand-color;
}
&:checked + .slider::before {
-webkit-transform: translateX(1rem);
-ms-transform: translateX(1rem);
transform: translateX(1rem);
}
}
> .slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
border-radius: 34px;
background-color: $main-color-light;
-webkit-transition: .4s;
transition: .4s;
&::before {
position: absolute;
content: "";
height: 1rem;
width: 1rem;
border-radius: 50%;
left: 0.1rem;
bottom: 0.1rem;
background-color: $light-color;
-webkit-transition: .4s;
transition: .4s;
}
}
}
}
} }
> .user-login-form { > .user-login-form {
height: 90vh; height: 90vh;
@ -1262,5 +1192,5 @@ body{
} }
} }
} }
} }
} }

View File

@ -52,6 +52,5 @@
</div> </div>
{% endif %} {% endif %}
<div id="content-modale"></div> <div id="content-modale"></div>
<div id="animation-toggle"></div>
</div> </div>
{% endif %} {% endif %}