generated from gitea_admin/default
Concerts
This commit is contained in:
883
app/pages/concerts/[id].vue
Normal file
883
app/pages/concerts/[id].vue
Normal file
@@ -0,0 +1,883 @@
|
||||
<template>
|
||||
<div>
|
||||
<section v-if="pending" aria-busy="true" aria-live="polite">
|
||||
<p>en cours de chargement...</p>
|
||||
</section>
|
||||
|
||||
<template v-else>
|
||||
<PageSection tone="" content-size="default" class="breadcrum_wp">
|
||||
<Breadcrumb :current-label="concert?.titre_concert || ''" />
|
||||
</PageSection>
|
||||
|
||||
|
||||
<section class="fiche_header_wp">
|
||||
<div class="fiche_header_wp_gauche"></div>
|
||||
<div class="fiche_header_wp_gauche_carre"></div>
|
||||
<div class="fiche_header_inner">
|
||||
<div class="fiche_header_titres">
|
||||
<div>
|
||||
<DsHeading as="h1" tone="default" textcase="uppercase" class="concert-card__title">
|
||||
{{ concert.titre_concert }}
|
||||
</DsHeading>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<DsText as="p" size="md" tone="default" class="" v-if="concert.sous_titre_concert">
|
||||
{{ concert.sous_titre_concert }}
|
||||
</DsText>
|
||||
</div>
|
||||
</div>
|
||||
<div class="fiche_header_img">
|
||||
<DsMedia
|
||||
v-if="illustration?.url"
|
||||
:src="illustration.url"
|
||||
:alt="illustration.alternativeText || concert?.titre_concert || ''"
|
||||
ratio="3-4"
|
||||
/>
|
||||
</div>
|
||||
<div class="fiche_header_bandeau"></div>
|
||||
<div class="fiche_header_infos">
|
||||
<div>
|
||||
<DsHeading as="h2" tone="invert" textcase="uppercase" class="fiche_header_infos_genre" v-if="genreLabel">
|
||||
{{ genreLabel }}
|
||||
</DsHeading>
|
||||
</div>
|
||||
<div v-if="concert.duree_concert">
|
||||
<DsText as="p" tone="invert" weight="bold" spacing="space-0" class="">
|
||||
DURÉE {{ concert.duree_concert }}
|
||||
</DsText>
|
||||
<DsText as="p" tone="invert" class="" v-if="concert.duree_entracte">
|
||||
Entracte {{ concert.duree_entracte }}
|
||||
</DsText>
|
||||
</div>
|
||||
<div v-if="concert.production_concert">
|
||||
<DsText as="p" tone="invert" class="">
|
||||
{{ concert.production_concert }}
|
||||
</DsText>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="fiche_header_wp_droite"></div>
|
||||
</section>
|
||||
|
||||
|
||||
<PageSection tone="" content-size="default">
|
||||
<section class="fiche_details_wp">
|
||||
<section class="distribution_wp">
|
||||
<div v-if="directionsOndif.length">
|
||||
<div v-for="d in directionsOndif" :key="d.id" class="distribution_item">
|
||||
<DsText as="p" tone="default" size="lg" v-if="d.postes_artiste_ondif?.length" class="distribution_item_poste direction">
|
||||
{{ d.postes_artiste_ondif.map((p) => p.nom_poste).join(', ') }}
|
||||
</DsText>
|
||||
<DsText as="p" tone="default" size="lg" weight="bold" class="">
|
||||
{{ d.nom_artiste_ondif }}
|
||||
</DsText>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="directionsInvite.length">
|
||||
<div v-for="d in directionsInvite" :key="d.id" class="distribution_item">
|
||||
<DsText as="p" tone="default" size="lg" v-if="d.postes_artiste_invite?.length" class="distribution_item_poste direction">
|
||||
{{ d.postes_artiste_invite.map((p) => p.nom_poste).join(', ') }}
|
||||
</DsText>
|
||||
<DsText as="p" tone="default" size="lg" weight="bold" class="">
|
||||
{{ d.nom_artiste_invite }}
|
||||
</DsText>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="artistesOndif.length">
|
||||
<div v-for="d in artistesOndif" :key="d.id" class="distribution_item">
|
||||
<DsText as="p" tone="default" size="lg" v-if="d.postes_artiste_ondif?.length" class="distribution_item_poste">
|
||||
{{ d.postes_artiste_ondif.map((p) => p.nom_poste).join(', ') }}
|
||||
</DsText>
|
||||
<DsText as="p" tone="default" size="lg" class="">
|
||||
{{ d.nom_artiste_ondif }}
|
||||
</DsText>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="artistesInvite.length">
|
||||
<div v-for="d in artistesInvite" :key="d.id" class="distribution_item">
|
||||
<DsText as="p" tone="default" size="lg" v-if="d.postes_artiste_invite?.length" class="distribution_item_poste">
|
||||
{{ d.postes_artiste_invite.map((p) => p.nom_poste).join(', ') }}
|
||||
</DsText>
|
||||
<DsText as="p" tone="default" size="lg" class="">
|
||||
{{ d.nom_artiste_invite }}
|
||||
</DsText>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section class="programme_wp">
|
||||
<div>
|
||||
<DsHeading as="h2" tone="invert" textcase="uppercase" class="programme_titre">
|
||||
PROGRAMME
|
||||
</DsHeading>
|
||||
</div>
|
||||
<div class="programme_list">
|
||||
<div v-for="(p, i) in programmes" :key="p.id || i" class="programme_item" >
|
||||
<DsText as="p" tone="default" size="lg" spacing="space-0" weight="semibold" class="programme_compositeur">
|
||||
{{ p.compositeur_programme }}
|
||||
</DsText>
|
||||
<DsText as="p" tone="default" size="lg" spacing="space-0" class="programme_oeuvre">
|
||||
{{ p.oeuvre_programme }}
|
||||
</DsText>
|
||||
<DsText as="p" tone="default" size="lg" class="" v-if="p.piece_programme">
|
||||
{{ p.piece_programme }}
|
||||
</DsText>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<div v-if="representations.length" class="representation_wp">
|
||||
<div v-for="(r, i) in representations" :key="r.id || i" class="representation_item">
|
||||
|
||||
<div>
|
||||
<DsHeading as="h6" tone="default" v-if="r.date_debut_representation">
|
||||
{{ formatDateLong(r.date_debut_representation) }} <span v-if="r.date_fin_representation">- {{ formatDateLong(r.date_fin_representation) }}</span>
|
||||
</DsHeading>
|
||||
</div>
|
||||
|
||||
|
||||
<div>
|
||||
<DsHeading as="h5" tone="default" v-if="r.lieu_representation?.nom_lieu" class="representation_item_lieu">
|
||||
{{ r.lieu_representation.nom_lieu }}
|
||||
</DsHeading>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<DsText as="p" tone="default" spacing="space-0" v-if="r.lieu_representation?.adresse_lieu">
|
||||
{{ r.lieu_representation.adresse_lieu }}
|
||||
</DsText>
|
||||
</div>
|
||||
|
||||
<div class="representation_item_comment_wp">
|
||||
<DsText as="p" tone="default" spacing="space-0" v-if="r.commentaire_representation" class="representation_item_comment">
|
||||
{{ r.commentaire_representation }}
|
||||
</DsText>
|
||||
</div>
|
||||
|
||||
<div class="representation_cta">
|
||||
<a
|
||||
v-if="r.lien_billetterie_representation"
|
||||
:href="r.lien_billetterie_representation"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
Réserver
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="description_wp">
|
||||
<StrapiBlocksConvert :blocks="concert?.description_concert" />
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
<section class="img-gallery_wp">
|
||||
<div v-if="imagesConcert.length" class="img-gallery">
|
||||
<DsMedia
|
||||
v-for="img in imagesConcert"
|
||||
:key="img.id || img.url"
|
||||
:src="img.url"
|
||||
:alt="img.alternativeText || concert?.titre_concert || ''"
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="youtube_wp">
|
||||
<div v-if="youtubeEmbeds.length" class="youtube-list">
|
||||
<div v-for="v in youtubeEmbeds" :key="v.id" class="youtube-item">
|
||||
<iframe
|
||||
:src="v.src"
|
||||
title="Vidéo YouTube"
|
||||
loading="lazy"
|
||||
referrerpolicy="strict-origin-when-cross-origin"
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
|
||||
allowfullscreen
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</PageSection>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { formatDateLong } from "@/utils/dateFormat.js"
|
||||
import DsMedia from '@root/design-system/primitives/DsMedia.vue'
|
||||
import DsHeading from '@root/design-system/primitives/DsHeading.vue'
|
||||
import DsText from '@root/design-system/primitives/DsText.vue'
|
||||
import DsButton from '@root/design-system/primitives/DsButton.vue'
|
||||
const route = useRoute()
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// RÉCUPÉRATION DU CONTENU
|
||||
//////////////////////////////////////////////////////////////
|
||||
const concertSlug = computed(() => String(route.params.id || ''))
|
||||
const populate = {
|
||||
saison_concert: true,
|
||||
genre_concert: true,
|
||||
type_audience_concert: true,
|
||||
direction_ondif_concert: { postes_artiste_ondif: true },
|
||||
direction_invite_concert: { postes_artiste_invite: true },
|
||||
artistes_ondif_concert: { postes_artiste_ondif: true },
|
||||
artistes_invite_concert: { postes_artiste_invite: true },
|
||||
image_illustration_concert: true,
|
||||
images_concert: true,
|
||||
videos_concert: true,
|
||||
audios_concert: true,
|
||||
programme_concert: true,
|
||||
representation_concert: { lieu_representation: true },
|
||||
liens_youtube_concert: true,
|
||||
}
|
||||
|
||||
const filters = computed(() => ({
|
||||
slug_concert: {
|
||||
$eq: concertSlug.value,
|
||||
},
|
||||
}))
|
||||
|
||||
const { concerts, pending, error } = useConcerts({
|
||||
locale: 'fr-FR',
|
||||
populate,
|
||||
filters,
|
||||
limit: 1,
|
||||
upcomingOnly: false,
|
||||
})
|
||||
|
||||
const concert = computed(() => concerts.value?.[0] || {})
|
||||
|
||||
useSeoMeta({
|
||||
title: () => concert.value?.titre_concert || 'Concert',
|
||||
description: () => concert.value?.resume_concert || undefined,
|
||||
})
|
||||
|
||||
const genreLabel = computed(() => {
|
||||
const g = concert.value?.genre_concert
|
||||
|
||||
// Strapi relation classique
|
||||
if (Array.isArray(g?.data)) return g.data.map(x => x?.attributes?.nom_genre).filter(Boolean).join(', ')
|
||||
if (g?.data) return g.data?.attributes?.nom_genre || ''
|
||||
|
||||
// Si déjà normalisé/flat
|
||||
if (Array.isArray(g)) return g.map(x => x?.nom_genre).filter(Boolean).join(', ')
|
||||
return g?.nom_genre || ''
|
||||
})
|
||||
|
||||
const directionsOndif = computed(() => {
|
||||
const value = concert.value?.direction_ondif_concert
|
||||
if (!value) return []
|
||||
return Array.isArray(value) ? value : [value]
|
||||
})
|
||||
const directionsInvite = computed(() => {
|
||||
const value = concert.value?.direction_invite_concert
|
||||
if (!value) return []
|
||||
return Array.isArray(value) ? value : [value]
|
||||
})
|
||||
const artistesOndif = computed(() => {
|
||||
const value = concert.value?.artistes_ondif_concert
|
||||
if (!value) return []
|
||||
return Array.isArray(value) ? value : [value]
|
||||
})
|
||||
const artistesInvite = computed(() => {
|
||||
const value = concert.value?.artistes_invite_concert
|
||||
if (!value) return []
|
||||
return Array.isArray(value) ? value : [value]
|
||||
})
|
||||
const programmes = computed(() => {
|
||||
const value = concert.value?.programme_concert
|
||||
if (!value) return []
|
||||
return Array.isArray(value) ? value : [value]
|
||||
})
|
||||
const representations = computed(() => {
|
||||
const value = concert.value?.representation_concert
|
||||
if (!value) return []
|
||||
return Array.isArray(value) ? value : [value]
|
||||
})
|
||||
|
||||
const illustration = computed(() => {
|
||||
const m = concert.value?.image_illustration_concert
|
||||
if (!m) return null
|
||||
if (m.url) return m
|
||||
return null
|
||||
})
|
||||
|
||||
const imagesConcert = computed(() => {
|
||||
const value = concert.value?.images_concert
|
||||
if (!value) return []
|
||||
if (Array.isArray(value) && value[0]?.url) return value
|
||||
return Array.isArray(value) ? value : []
|
||||
})
|
||||
const youtube = computed(() => {
|
||||
const value = concert.value?.liens_youtube_concert
|
||||
if (!value) return []
|
||||
return Array.isArray(value) ? value : [value]
|
||||
})
|
||||
function getYoutubeId(url = '') {
|
||||
try {
|
||||
const u = new URL(url)
|
||||
if (u.hostname.includes('youtu.be')) return u.pathname.slice(1)
|
||||
if (u.pathname.startsWith('/shorts/')) return u.pathname.split('/')[2]
|
||||
if (u.pathname.startsWith('/embed/')) return u.pathname.split('/')[2]
|
||||
return u.searchParams.get('v')
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
const youtubeEmbeds = computed(() =>
|
||||
youtube.value
|
||||
.map((item) => {
|
||||
const id = getYoutubeId(item?.lien_youtube)
|
||||
if (!id) return null
|
||||
return {
|
||||
id: item.id || id,
|
||||
src: `https://www.youtube-nocookie.com/embed/${id}?rel=0&modestbranding=1&iv_load_policy=3&playsinline=1`,
|
||||
}
|
||||
})
|
||||
.filter(Boolean)
|
||||
)
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
.breadcrum_wp {
|
||||
padding-top: 30px;
|
||||
}
|
||||
|
||||
.fiche_header_wp {
|
||||
display: grid;
|
||||
|
||||
|
||||
@media (min-width: 0px) and (max-width: 600px) {
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-rows: auto 510px 20px 200px;
|
||||
padding-top: 40px;
|
||||
}
|
||||
@media (min-width: 600px) {
|
||||
grid-template-columns: minmax(10px, 10px) 580px 0px;
|
||||
grid-template-rows: 40px 280px 20px 230px;
|
||||
}
|
||||
@media (min-width: 700px) {
|
||||
grid-template-columns: minmax(10px, 10px) 660px 0px;
|
||||
grid-template-rows: 70px 250px 90px 300px;
|
||||
}
|
||||
@media (min-width: 800px) {
|
||||
grid-template-columns: minmax(10px, 10px) 780px minmax(10px, 10px);
|
||||
grid-template-rows: 60px 280px 70px 300px;
|
||||
}
|
||||
@media (min-width: 900px) {
|
||||
grid-template-columns: minmax(10px, 10px) 860px minmax(10px, 10px);
|
||||
grid-template-rows: 90px 340px 100px 250px;
|
||||
}
|
||||
@media (min-width: 1000px) {
|
||||
grid-template-columns: minmax(20px, auto) 950px minmax(10px, auto);
|
||||
grid-template-rows: 90px 340px 120px 270px;
|
||||
}
|
||||
@media (min-width: 1100px) {
|
||||
grid-template-columns: minmax(20px, auto) 1020px minmax(20px, auto);
|
||||
grid-template-rows: 90px 340px 140px 290px;
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
grid-template-columns: minmax(20px, auto) 1100px minmax(20px, auto);
|
||||
grid-template-rows: 90px 340px 160px 330px;
|
||||
}
|
||||
@media (min-width: 1300px) {
|
||||
grid-template-columns: minmax(20px, auto) 1200px minmax(20px, auto);
|
||||
grid-template-rows: 90px 340px 160px 330px;
|
||||
}
|
||||
@media (min-width: 1400px) {
|
||||
grid-template-columns: minmax(20px, auto) 1300px minmax(20px, auto);
|
||||
grid-template-rows: 90px 340px 160px 380px;
|
||||
}
|
||||
@media (min-width: 1500px) {
|
||||
grid-template-columns: minmax(20px, auto) 1400px minmax(20px, auto);
|
||||
grid-template-rows: 90px 340px 160px 380px;
|
||||
}
|
||||
}
|
||||
.fiche_header_wp_gauche {
|
||||
|
||||
@media (min-width: 0px) and (max-width: 600px) {
|
||||
display: none;
|
||||
}
|
||||
@media (min-width: 600px) {
|
||||
grid-column: 1;
|
||||
}
|
||||
}
|
||||
.fiche_header_wp_gauche_carre {
|
||||
|
||||
@media (min-width: 0px) and (max-width: 600px) {
|
||||
display: none;
|
||||
}
|
||||
@media (min-width: 600px) {
|
||||
grid-column: 1;
|
||||
grid-row: 4;
|
||||
}
|
||||
background-color: var(--c-backgroud-black);
|
||||
}
|
||||
.fiche_header_wp_droite {
|
||||
|
||||
@media (min-width: 0px) and (max-width: 600px) {
|
||||
display: none;
|
||||
}
|
||||
@media (min-width: 600px) {
|
||||
grid-column: 3;
|
||||
}
|
||||
}
|
||||
|
||||
.fiche_header_inner {
|
||||
|
||||
|
||||
@media (min-width: 0px) and (max-width: 600px) {
|
||||
grid-column: 1;
|
||||
grid-row: 1/5;
|
||||
}
|
||||
@media (min-width: 600px) {
|
||||
grid-column: 2;
|
||||
grid-row: 1/5;
|
||||
}
|
||||
display: grid;
|
||||
|
||||
@media (min-width: 0px) and (max-width: 600px) {
|
||||
grid-template-columns: 4fr 1fr 0.5fr;
|
||||
grid-template-rows: auto 510px 20px 200px;
|
||||
}
|
||||
@media (min-width: 600px) {
|
||||
width: 575px;
|
||||
grid-template-columns: 4fr 0.5fr 0.5fr 6.5fr;
|
||||
grid-template-rows: 40px 280px 20px 230px;
|
||||
}
|
||||
@media (min-width: 700px) {
|
||||
width: 675px;
|
||||
grid-template-columns: 4fr 0.5fr 0.5fr 6.5fr;
|
||||
grid-template-rows: 70px 250px 90px 300px;
|
||||
}
|
||||
@media (min-width: 800px) {
|
||||
width: 780px;
|
||||
grid-template-columns: 4fr 0.5fr 0.5fr 6.5fr;
|
||||
grid-template-rows: 60px 280px 70px 300px;
|
||||
}
|
||||
@media (min-width: 900px) {
|
||||
width: 860px;
|
||||
grid-template-columns: 4fr 0.5fr 0.5fr 6.5fr;
|
||||
grid-template-rows: 90px 340px 100px 250px;
|
||||
}
|
||||
@media (min-width: 1000px) {
|
||||
width: 950px;
|
||||
grid-template-columns: 4fr 0.5fr 0.5fr 6.5fr;
|
||||
grid-template-rows: 90px 340px 120px 270px;
|
||||
}
|
||||
@media (min-width: 1100px) {
|
||||
width: 1020px;
|
||||
grid-template-columns: 4fr 0.5fr 0.5fr 6.5fr;
|
||||
grid-template-rows: 90px 340px 140px 290px;
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
width: 1100px;
|
||||
grid-template-columns: 4fr 0.5fr 0.5fr 6.5fr;
|
||||
grid-template-rows: 90px 340px 160px 330px;
|
||||
}
|
||||
@media (min-width: 1300px) {
|
||||
width: 1200px;
|
||||
grid-template-columns: 4fr 0.5fr 0.5fr 6.5fr;
|
||||
grid-template-rows: 90px 340px 160px 330px;
|
||||
}
|
||||
@media (min-width: 1400px) {
|
||||
width: 1300px;
|
||||
grid-template-columns: 4fr 0.5fr 0.5fr 6.5fr;
|
||||
grid-template-rows: 90px 340px 160px 380px;
|
||||
}
|
||||
@media (min-width: 1500px) {
|
||||
width: 1400px;
|
||||
grid-template-columns: 4fr 0.5fr 0.5fr 6.5fr;
|
||||
grid-template-rows: 90px 340px 160px 380px;
|
||||
}
|
||||
@media (min-width: 1600px) {
|
||||
width: 1400px;
|
||||
grid-template-columns: 4fr 0.5fr 0.5fr 6.5fr;
|
||||
grid-template-rows: 90px 340px 160px 380px;
|
||||
}
|
||||
@media (min-width: 1700px) {
|
||||
width: 1400px;
|
||||
grid-template-columns: 4fr 0.5fr 0.5fr 6.5fr;
|
||||
grid-template-rows: 90px 340px 160px 380px;
|
||||
}
|
||||
@media (min-width: 1800px) {
|
||||
width: 1400px;
|
||||
grid-template-columns: 4fr 0.5fr 0.5fr 6.5fr;
|
||||
grid-template-rows: 90px 340px 160px 380px;
|
||||
}
|
||||
}
|
||||
|
||||
.fiche_header_titres {
|
||||
|
||||
@media (min-width: 0px) and (max-width: 600px) {
|
||||
grid-column: 1;
|
||||
grid-row: 1;
|
||||
padding-bottom: 20px;
|
||||
padding-left: 10px;
|
||||
}
|
||||
@media (min-width: 600px) {
|
||||
grid-column: 1;
|
||||
grid-row: 2;
|
||||
}
|
||||
display: grid;
|
||||
align-content: start;
|
||||
gap: 0.75rem;
|
||||
h1 {
|
||||
font-size: 55px;
|
||||
@media (min-width: 0px) and (max-width: 600px) {
|
||||
font-size: 25px;
|
||||
}
|
||||
@media (min-width: 600px) {
|
||||
font-size: 25px;
|
||||
}
|
||||
@media (min-width: 700px) {
|
||||
font-size: 30px;
|
||||
}
|
||||
@media (min-width: 800px) {
|
||||
font-size: 30px;
|
||||
}
|
||||
@media (min-width: 900px) {
|
||||
font-size: 40px;
|
||||
}
|
||||
@media (min-width: 1000px) {
|
||||
font-size: 40px;
|
||||
}
|
||||
@media (min-width: 1100px) {
|
||||
font-size: 40px;
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
font-size: 50px;
|
||||
}
|
||||
@media (min-width: 1300px) {
|
||||
font-size: 55px;
|
||||
}
|
||||
@media (min-width: 1400px) {
|
||||
font-size: 55px;
|
||||
}
|
||||
@media (min-width: 1500px) {
|
||||
font-size: 55px;
|
||||
}
|
||||
@media (min-width: 1600px) {
|
||||
font-size: 55px;
|
||||
}
|
||||
@media (min-width: 1700px) {
|
||||
font-size: 55px;
|
||||
}
|
||||
@media (min-width: 1800px) {
|
||||
font-size: 55px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.fiche_header_img {
|
||||
|
||||
@media (min-width: 0px) and (max-width: 600px) {
|
||||
grid-column: 1 / 4;
|
||||
grid-row: 2 / 4;
|
||||
}
|
||||
@media (min-width: 600px) {
|
||||
grid-column: 3 / 5;
|
||||
grid-row: 1 / 5;
|
||||
}
|
||||
overflow: hidden;
|
||||
.ds-media {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.fiche_header_infos {
|
||||
|
||||
@media (min-width: 0px) and (max-width: 600px) {
|
||||
grid-column: 1 / 2;
|
||||
grid-row: 4;
|
||||
margin-top: -30px;
|
||||
}
|
||||
@media (min-width: 600px) {
|
||||
grid-column: 1;
|
||||
grid-row: 4;
|
||||
}
|
||||
display: grid;
|
||||
align-content: center;
|
||||
justify-content: end;
|
||||
|
||||
@media (min-width: 0px) and (max-width: 700px) {
|
||||
gap: 7px;
|
||||
}
|
||||
@media (min-width: 700px) {
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
text-align: right;
|
||||
.fiche_header_infos_genre {
|
||||
font-weight: 900;
|
||||
|
||||
}
|
||||
}
|
||||
.fiche_header_bandeau {
|
||||
|
||||
@media (min-width: 0px) and (max-width: 600px) {
|
||||
grid-column: 1 / 3;
|
||||
grid-row: 4;
|
||||
margin-top: -30px;
|
||||
}
|
||||
@media (min-width: 600px) {
|
||||
grid-column: 1 / 4;
|
||||
grid-row: 4;
|
||||
}
|
||||
background-color: var(--c-backgroud-black);
|
||||
}
|
||||
|
||||
/* ============================ */
|
||||
/* DISTRIBUTION / PROGRAMME */
|
||||
/* ============================ */
|
||||
.fiche_details_wp {
|
||||
.distribution_wp {
|
||||
padding-top: 50px;
|
||||
padding-bottom: 50px;
|
||||
padding-left: 20px;
|
||||
.distribution_item {
|
||||
display: flex;
|
||||
.distribution_item_poste {
|
||||
padding-right: 10px;
|
||||
font-weight: 200;
|
||||
}
|
||||
.direction {
|
||||
font-weight: 400;
|
||||
}
|
||||
}
|
||||
}
|
||||
.programme_wp {
|
||||
|
||||
background-color: var(--c-backgroud-brandreverse);
|
||||
margin-bottom: 70px;
|
||||
padding-top: 50px;
|
||||
padding-right: 30px;
|
||||
padding-left: 40px;
|
||||
padding-bottom: 50px;
|
||||
|
||||
/* DÉCALAGE DU BLOC VERS LA DROITE */
|
||||
position: relative;
|
||||
|
||||
@media (min-width: 0px) and (max-width: 700px) {
|
||||
width: 89vw;
|
||||
left: 5%;
|
||||
}
|
||||
@media (min-width: 700px) {
|
||||
width: 67vw;
|
||||
left: 30%;
|
||||
}
|
||||
@media (min-width: 800px) {
|
||||
width: 50vw;
|
||||
left: 49%;
|
||||
}
|
||||
transform: translateX(0px);
|
||||
margin-left: 0px;
|
||||
margin-right: 0px;
|
||||
box-sizing: border-box;
|
||||
display: block;
|
||||
justify-content: initial;
|
||||
align-items: initial;
|
||||
|
||||
.programme_titre {
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
.programme_list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
column-gap: 20px;
|
||||
row-gap: 20px;
|
||||
|
||||
}
|
||||
.programme_item {
|
||||
flex: 1 0 200px;
|
||||
|
||||
background-color: var(--c-surface);
|
||||
padding-top: 14px;
|
||||
padding-right: 20px;
|
||||
padding-left: 18px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* ============================ */
|
||||
/* REPRÉSENTATIONS */
|
||||
/* ============================ */
|
||||
.representation_wp {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
/* justify-content: center; */
|
||||
column-gap: 30px;
|
||||
row-gap: 30px;
|
||||
padding-bottom: 70px;
|
||||
@media (min-width: 0px) and (max-width: 500px) {
|
||||
padding-left: 20px;
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
.representation_item {
|
||||
|
||||
@media (min-width: 0px) and (max-width: 500px) {
|
||||
width: 100%;
|
||||
}
|
||||
@media (min-width: 500px) {
|
||||
max-width: 215px;
|
||||
}
|
||||
@media (min-width: 600px) {
|
||||
max-width: 262px;
|
||||
}
|
||||
@media (min-width: 700px) {
|
||||
max-width: 300px;
|
||||
}
|
||||
flex: 1 1 300px;
|
||||
display: grid;
|
||||
border: 2px var(--c-brand_rouge) solid;
|
||||
padding-top: 20px;
|
||||
> * {
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
}
|
||||
.representation_item_comment_wp {
|
||||
padding-top: 5px;
|
||||
}
|
||||
.representation_item_comment {
|
||||
background-color: lightgray;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
}
|
||||
.representation_cta {
|
||||
color: var(--c-surface);
|
||||
background-color: var(--c-brand_rouge);
|
||||
margin-top: 15px;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
text-align: center;
|
||||
a {
|
||||
font-family: var(--font-roboto);
|
||||
font-weight: 600;
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ============================ */
|
||||
/* DESCRIPTION */
|
||||
/* ============================ */
|
||||
.description_wp {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding-bottom: 70px;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
> * {
|
||||
max-width: 570px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
/* ============================ */
|
||||
/* GALERIES */
|
||||
/* ============================ */
|
||||
|
||||
.img-gallery_wp {
|
||||
padding-bottom: 50px;
|
||||
}
|
||||
|
||||
.img-gallery {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(220px, 520px));
|
||||
gap: 1rem;
|
||||
justify-content: center;
|
||||
margin-top: 1.5rem;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.img-gallery > * {
|
||||
display: block;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.img-gallery :deep(.ds-media) {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.img-gallery :deep(.ds-media__img) {
|
||||
display: block;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
transition: transform 0.25s ease, box-shadow 0.25s ease;
|
||||
}
|
||||
|
||||
.img-gallery :deep(.ds-media__img:hover) {
|
||||
transform: scale(1.02);
|
||||
}
|
||||
|
||||
@media (max-width: 1100px) {
|
||||
.img-gallery {
|
||||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 820px) {
|
||||
.img-gallery {
|
||||
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
|
||||
gap: 0.75rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 520px) {
|
||||
.img-gallery {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
.youtube_wp {
|
||||
margin-bottom: 70px;
|
||||
}
|
||||
.youtube-list {
|
||||
display: grid;
|
||||
justify-content: center;
|
||||
/* flex-wrap: wrap; */
|
||||
gap: 20px;
|
||||
}
|
||||
.youtube-item {
|
||||
@media (min-width: 0px) and (max-width: 300px) {
|
||||
min-width: 290px;
|
||||
}
|
||||
|
||||
@media (min-width: 300px) {
|
||||
min-width: 298px;
|
||||
}
|
||||
|
||||
@media (min-width: 400px) {
|
||||
min-width: 398px;
|
||||
}
|
||||
@media (min-width: 500px) {
|
||||
min-width: 480px;
|
||||
}
|
||||
@media (min-width: 600px) {
|
||||
min-width: 580px;
|
||||
}
|
||||
@media (min-width: 700px) {
|
||||
min-width: 670px;
|
||||
}
|
||||
}
|
||||
|
||||
.youtube-item iframe {
|
||||
|
||||
aspect-ratio: 16 / 9;
|
||||
border: 0;
|
||||
}
|
||||
</style>
|
||||
71
app/pages/concerts/agenda.vue
Normal file
71
app/pages/concerts/agenda.vue
Normal file
@@ -0,0 +1,71 @@
|
||||
<template>
|
||||
|
||||
<div>
|
||||
<PageSection tone="dark" content-size="default">
|
||||
<SectionTitle tone="invert" pad="md">
|
||||
LES CONCERTS À VENIR
|
||||
</SectionTitle>
|
||||
</PageSection>
|
||||
<PageSection padded_size="md" content-size="default" class="">
|
||||
<ConcertCardList :highlight-first="false" :limit-cards-on-breakpoint="false">
|
||||
<ConcertCard
|
||||
v-for="c in concerts"
|
||||
:key="c.id"
|
||||
:id="c.slug_concert"
|
||||
:title="c.titre_concert"
|
||||
:dateISO="c.representation_concert?.[0]?.date_debut_representation"
|
||||
:dateLabel="formatDateLong(c.representation_concert?.[0]?.date_debut_representation)"
|
||||
:lieu="c.representation_concert?.[0]?.lieu_representation?.nom_lieu"
|
||||
:adresse_lieu="c.representation_concert?.[0]?.lieu_representation?.nom_lieu"
|
||||
:description="c.resume_concert"
|
||||
:imageUrl="c.image_illustration_concert?.url"
|
||||
:imageAlt="c.image_illustration_concert?.alternativeText"
|
||||
:href="`${c.slug_concert}`"
|
||||
/>
|
||||
</ConcertCardList>
|
||||
</PageSection>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
|
||||
<script setup>
|
||||
|
||||
import { onMounted } from "vue"
|
||||
import { formatDateLong } from "@/utils/dateFormat.js"
|
||||
|
||||
const { concerts, refresh } = useConcerts({
|
||||
locale: "fr-FR",
|
||||
populate: {
|
||||
saison_concert: true,
|
||||
genre_concert: true,
|
||||
type_audience_concert: true,
|
||||
direction_ondif_concert: { postes_artiste_ondif: true },
|
||||
direction_invite_concert: { postes_artiste_invite: true },
|
||||
artistes_ondif_concert: { postes_artiste_ondif: true },
|
||||
artistes_invite_concert: { postes_artiste_invite: true },
|
||||
image_illustration_concert: true,
|
||||
images_concert: true,
|
||||
videos_concert: true,
|
||||
audios_concert: true,
|
||||
programme_concert: true,
|
||||
representation_concert: { lieu_representation: true },
|
||||
liens_youtube_concert: true,
|
||||
},
|
||||
filters: {
|
||||
saison_concert: {
|
||||
nom_saison: {
|
||||
$eq: "2025/2026",
|
||||
},
|
||||
},
|
||||
},
|
||||
upcomingOnly: true,
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
if (!concerts.value?.length) {
|
||||
refresh()
|
||||
}
|
||||
})
|
||||
|
||||
</script>
|
||||
@@ -1,24 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<div v-if="toto">
|
||||
<h1>#{{route.params.id }} / {{ toto.title }}</h1>
|
||||
<p>{{ toto.body }}</p>
|
||||
</div>
|
||||
<div v-else>
|
||||
<p>Chargement...</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const route = useRoute()
|
||||
const {data: toto} = await useFetch(() => 'https://jsonplaceholder.typicode.com/posts/' + route.params.id, { lazy: true })
|
||||
useSeoMeta({
|
||||
title: () => toto.value?.title
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
</style>
|
||||
4
app/pages/concerts/index.vue
Normal file
4
app/pages/concerts/index.vue
Normal file
@@ -0,0 +1,4 @@
|
||||
<script setup>
|
||||
await navigateTo('/concerts/agenda', { redirectCode: 301 })
|
||||
</script>
|
||||
|
||||
13
app/pages/concerts/jeune-public.vue
Normal file
13
app/pages/concerts/jeune-public.vue
Normal file
@@ -0,0 +1,13 @@
|
||||
<template>
|
||||
<div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
13
app/pages/concerts/live.vue
Normal file
13
app/pages/concerts/live.vue
Normal file
@@ -0,0 +1,13 @@
|
||||
<template>
|
||||
<div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
13
app/pages/concerts/mag.vue
Normal file
13
app/pages/concerts/mag.vue
Normal file
@@ -0,0 +1,13 @@
|
||||
<template>
|
||||
<div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
13
app/pages/concerts/mode-emploi.vue
Normal file
13
app/pages/concerts/mode-emploi.vue
Normal file
@@ -0,0 +1,13 @@
|
||||
<template>
|
||||
<div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
71
app/pages/concerts/saison.vue
Normal file
71
app/pages/concerts/saison.vue
Normal file
@@ -0,0 +1,71 @@
|
||||
<template>
|
||||
|
||||
<div>
|
||||
<PageSection tone="dark" content-size="default">
|
||||
<SectionTitle tone="invert" pad="md">
|
||||
SAISON 2025/2026
|
||||
</SectionTitle>
|
||||
</PageSection>
|
||||
<PageSection padded_size="md" content-size="default" class="">
|
||||
<ConcertCardList :highlight-first="false" :limit-cards-on-breakpoint="false">
|
||||
<ConcertCard
|
||||
v-for="c in concerts"
|
||||
:key="c.id"
|
||||
:id="c.slug_concert"
|
||||
:title="c.titre_concert"
|
||||
:dateISO="c.representation_concert?.[0]?.date_debut_representation"
|
||||
:dateLabel="formatDateLong(c.representation_concert?.[0]?.date_debut_representation)"
|
||||
:lieu="c.representation_concert?.[0]?.lieu_representation?.nom_lieu"
|
||||
:adresse_lieu="c.representation_concert?.[0]?.lieu_representation?.nom_lieu"
|
||||
:description="c.resume_concert"
|
||||
:imageUrl="c.image_illustration_concert?.url"
|
||||
:imageAlt="c.image_illustration_concert?.alternativeText"
|
||||
:href="`${c.slug_concert}`"
|
||||
/>
|
||||
</ConcertCardList>
|
||||
</PageSection>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
|
||||
<script setup>
|
||||
|
||||
import { onMounted } from "vue"
|
||||
import { formatDateLong } from "@/utils/dateFormat.js"
|
||||
|
||||
const { concerts, refresh } = useConcerts({
|
||||
locale: "fr-FR",
|
||||
populate: {
|
||||
saison_concert: true,
|
||||
genre_concert: true,
|
||||
type_audience_concert: true,
|
||||
direction_ondif_concert: { postes_artiste_ondif: true },
|
||||
direction_invite_concert: { postes_artiste_invite: true },
|
||||
artistes_ondif_concert: { postes_artiste_ondif: true },
|
||||
artistes_invite_concert: { postes_artiste_invite: true },
|
||||
image_illustration_concert: true,
|
||||
images_concert: true,
|
||||
videos_concert: true,
|
||||
audios_concert: true,
|
||||
programme_concert: true,
|
||||
representation_concert: { lieu_representation: true },
|
||||
liens_youtube_concert: true,
|
||||
},
|
||||
filters: {
|
||||
saison_concert: {
|
||||
nom_saison: {
|
||||
$eq: "2025/2026",
|
||||
},
|
||||
},
|
||||
},
|
||||
upcomingOnly: false,
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
if (!concerts.value?.length) {
|
||||
refresh()
|
||||
}
|
||||
})
|
||||
|
||||
</script>
|
||||
Reference in New Issue
Block a user