drupal-caravane/web/themes/custom/caravane/assets/js/vuejs/Modale.vue

148 lines
3.8 KiB
Vue

<template>
<Transition>
<div v-if="isEtapeValid">
<header>
<div class="cover">
<img :src="etape.vignette.url" :alt="etape.vignette.alt">
</div>
<div class="cartouche" :style="{ backgroundColor: etape.couleur }">
<p>Étape n°{{etape.etape_number}}</p>
<p>Du {{etape.dates.start.d}} {{etape.dates.start.m}} au {{ etape.dates.end.d }} {{ etape.dates.end.m }} {{ etape.dates.end.y }}</p>
</div>
<div class="brand-pattern" :style="{ backgroundColor: etape.couleur }">
<div class="pattern"></div>
</div>
<div class="locality">
<div class="top-triangle"></div>
<div class="locality-title">
<h1>{{etape.title}} <em>({{ etape.adresse.postal_code }})</em></h1>
</div>
</div>
</header>
<main>
<div v-for="partie in etape.parties" class="partie">
<div class="partie-title">
<h3>
<div class="underline" :style="{ backgroundColor: etape.couleur }"></div>
<p v-html="partie.title"></p>
</h3>
</div>
<p v-html="partie.text"></p>
</div>
</main>
<!--
<div v-if="loading">Loading...</div>
<div v-if="error">{{ error }}</div>
{{etape.adresse.locality}}
-->
<div><pre>{{href}}</pre></div>
<div><pre><b>GEOFIELD</b>{{etape.geofield}}</pre></div>
<div><pre><b>VIGNETTE</b>{{etape.vignette}}</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>
</Transition>
<Transition>
<div v-if="isPageValid">
<header>
<h1>{{ page.title }}</h1>
</header>
<main>
<div v-html="page.text"></div>
</main>
</div>
</Transition>
</template>
<script setup>
import { ref, computed, watch } from 'vue';
import { storeToRefs } from 'pinia';
import { useContentStore } from '../stores/content';
import { useRoute, useRouter } from 'vue-router';
const router = useRouter();
const store = useContentStore();
const route = useRoute();
const { loading, error, href, etape, page } = storeToRefs(store);
watch(() => route.params.id, (newId) => {
if (!newId) {
store.emptyAll();
} else {
store.fetchEtapeData(newId);
if (!etape.value.data) {
store.fetchStaticData(newId);
}
window.scrollTo({top: 0, behavior: 'smooth'});
}
});
watch(() => href.value, (newHref) => {
const relativePath = newHref.split('.fr')[1];
if (relativePath && (relativePath !== '' || relativePath !== '/')) {
router.push(relativePath);
}
});
const isEtapeValid = computed(() => {
return etape.value && !isObjectEmpty(etape.value);
});
const isPageValid = computed(() => {
return page.value && !isObjectEmpty(page.value);
});
// Utility function to check if an object and its children are empty
function isObjectEmpty(obj) {
if (obj === null || obj === undefined || typeof obj !== 'object') {
return true;
}
for (const key in obj) {
if (Object.hasOwnProperty.call(obj, key)) {
const value = obj[key];
if (Array.isArray(value)) {
if (value.length > 0) {
return false;
}
} else if (typeof value === 'object') {
if (!isObjectEmpty(value)) {
return false;
}
} else if (value !== null && value !== undefined && value !== '') {
return false;
}
}
}
return true;
}
</script>
<style>
.v-enter-active,
.v-leave-active {
transition: all 0.3s ease;
}
.v-enter-from,
.v-leave-to {
transform: translateY(100%);
opacity: 0;
}
.v-leave-from {
transform: translateY(0%);
opacity: 1;
}
</style>