generated from gitea_admin/default
318 lines
8.8 KiB
Vue
318 lines
8.8 KiB
Vue
<template>
|
||
<div>
|
||
<!-- ================== -->
|
||
<!-- Fond noir -->
|
||
<!-- ================== -->
|
||
<PageSection tone="dark" content-size="default" class="theme_bandeau--grid">
|
||
<SectionContent pad="xs" class="theme_bandeau--grid--left">
|
||
<SectionTitle tone="invert" pad="">
|
||
LES MUSICIENS
|
||
</SectionTitle>
|
||
<DsHeading as="h3" tone="invert">
|
||
95 musiciens engagés Partout et pour tous en Île-de-France !
|
||
</DsHeading>
|
||
</SectionContent>
|
||
|
||
|
||
<SectionContent pad="xs" class="theme_bandeau--grid--right">
|
||
<DsText tone="invert" size="lg" class="theme_bandeau--grid--right--text" >
|
||
Les 95 musiciennes et musiciens proposent chaque saison plus de 120 concerts dans des salles et théâtres, des lieux culturels et des espaces atypiques de la région francilienne. Porté par une forte mission territoriale, l’orchestre s’engage à rendre la musique symphonique accessible à toutes et tous, en la faisant vivre au plus près des habitants grâce notamment à des actions culturelles, pédagogiques et participatives au cœur du territoire.
|
||
</DsText>
|
||
</SectionContent>
|
||
</PageSection>
|
||
|
||
<!-- ================== -->
|
||
<!-- Listes des musiciens -->
|
||
<!-- ================== -->
|
||
|
||
<!-- ================== -->
|
||
<!-- DIRECTION -->
|
||
<!-- ================== -->
|
||
|
||
<PageSection padded_size="md" content-size="default" class="musiciens_list_section remonter_artistes_list">
|
||
|
||
|
||
<section v-if="pending" aria-busy="true" aria-live="polite">
|
||
<DsText as="p" tone="default">Chargement des artistes...</DsText>
|
||
</section>
|
||
|
||
<section v-else-if="error">
|
||
<DsText as="p" tone="default">Impossible de charger les artistes.</DsText>
|
||
</section>
|
||
|
||
<section v-else-if="artistesDirection.length" class="musiciens_list">
|
||
<article v-for="a in artistesDirection" :key="a.id" class="musicien_card">
|
||
<DsMedia
|
||
v-if="a.image?.url"
|
||
:src="a.image.url"
|
||
:alt="a.image.alternativeText || a.nom_artiste_ondif || ''"
|
||
ratio="square"
|
||
/>
|
||
<div v-else class="musicien_card_media-placeholder" aria-hidden="true" />
|
||
|
||
<DsHeading as="h4" tone="default" class="musicien_card_nom">
|
||
<NuxtLink :to="`/orchestre/artiste-${a.slug_artiste_ondif}`">
|
||
{{ a.nom_artiste_ondif }}
|
||
</NuxtLink>
|
||
</DsHeading>
|
||
|
||
<DsText
|
||
v-if="a.postesLabel"
|
||
as="p"
|
||
tone="default"
|
||
size="md"
|
||
class="musicien_card_postes"
|
||
>
|
||
{{ a.postesLabel }}
|
||
</DsText>
|
||
</article>
|
||
</section>
|
||
|
||
<section v-else>
|
||
<DsText as="p" tone="default">Aucun artiste pour la direction.</DsText>
|
||
</section>
|
||
</PageSection>
|
||
|
||
<!-- ================== -->
|
||
<!-- MUSICIENS -->
|
||
<!-- ================== -->
|
||
|
||
<PageSection padded_size="md" content-size="default" class="musiciens_list_section musiciens_list_wp">
|
||
|
||
|
||
<section v-if="pending" aria-busy="true" aria-live="polite">
|
||
<DsText as="p" tone="default">Chargement des artistes...</DsText>
|
||
</section>
|
||
|
||
<section v-else-if="error">
|
||
<DsText as="p" tone="default">Impossible de charger les artistes.</DsText>
|
||
</section>
|
||
|
||
<section v-else-if="artistesAutres.length" class="musiciens_list">
|
||
<article v-for="a in artistesAutres" :key="a.id" class="musicien_card">
|
||
<DsMedia
|
||
v-if="a.image?.url"
|
||
:src="a.image.url"
|
||
:alt="a.image.alternativeText || a.nom_artiste_ondif || ''"
|
||
ratio="square"
|
||
/>
|
||
<div v-else class="musicien_card_media-placeholder" aria-hidden="true" />
|
||
|
||
<DsHeading as="h4" tone="default" class="musicien_card_nom">
|
||
<NuxtLink :to="`/orchestre/artiste-${a.slug_artiste_ondif}`">
|
||
{{ a.nom_artiste_ondif }}
|
||
</NuxtLink>
|
||
</DsHeading>
|
||
|
||
<DsText
|
||
v-if="a.postesLabel"
|
||
as="p"
|
||
tone="default"
|
||
size="md"
|
||
class="musicien_card_postes"
|
||
>
|
||
{{ a.postesLabel }}
|
||
</DsText>
|
||
</article>
|
||
</section>
|
||
|
||
<section v-else>
|
||
<DsText as="p" tone="default">Aucun autre artiste trouvé.</DsText>
|
||
</section>
|
||
</PageSection>
|
||
|
||
|
||
</div>
|
||
</template>
|
||
|
||
<script setup>
|
||
import DsHeading from '@root/design-system/primitives/DsHeading.vue'
|
||
import DsText from '@root/design-system/primitives/DsText.vue'
|
||
import DsMedia from '@root/design-system/primitives/DsMedia.vue'
|
||
const runtimeConfig = useRuntimeConfig()
|
||
const saisonFiltre = computed(() => String(runtimeConfig.public.saison || '').trim())
|
||
const artistesFilters = computed(() => {
|
||
if (!saisonFiltre.value) return null
|
||
return {
|
||
saisons_artiste_ondif: {
|
||
nom_saison: {
|
||
$eq: saisonFiltre.value,
|
||
},
|
||
},
|
||
}
|
||
})
|
||
|
||
//--------------------
|
||
// DONNÉES POUR LES ARTISTES
|
||
//--------------------
|
||
const { artistes, pending, error } = useArtistes({
|
||
locale: "fr-FR",
|
||
sort: "ordre_artiste_ondif:asc",
|
||
populate: {
|
||
saisons_artiste_ondif: true,
|
||
image_illustration_artiste_ondif: true,
|
||
postes_artiste_ondif: true,
|
||
},
|
||
filters: artistesFilters,
|
||
})
|
||
|
||
const artistesDisplay = computed(() => {
|
||
return (artistes.value || []).map((artiste) => ({
|
||
...artiste,
|
||
image: getArtisteImage(artiste),
|
||
postesLabel: getPostesLabel(artiste),
|
||
}))
|
||
})
|
||
|
||
const postesDirection = [
|
||
"direction",
|
||
"cheffe assistante",
|
||
"chef assistante",
|
||
]
|
||
|
||
const artistesDirection = computed(() =>
|
||
artistesDisplay.value.filter((a) => isDirectionArtist(a))
|
||
)
|
||
|
||
const artistesAutres = computed(() =>
|
||
artistesDisplay.value.filter((a) => !isDirectionArtist(a))
|
||
)
|
||
|
||
function getArtisteImage(artiste) {
|
||
const media = artiste?.image_illustration_artiste_ondif
|
||
const rows = extractStrapiList(media)
|
||
if (rows.length) return rows[0]
|
||
if (media && typeof media === "object" && media.url) return media
|
||
return null
|
||
}
|
||
|
||
function getPostesLabel(artiste) {
|
||
const postes = extractStrapiList(artiste?.postes_artiste_ondif)
|
||
return postes
|
||
.map((p) => p?.nom_poste)
|
||
.filter(Boolean)
|
||
.join(", ")
|
||
}
|
||
|
||
function isDirectionArtist(artiste) {
|
||
const postes = extractStrapiList(artiste?.postes_artiste_ondif)
|
||
.map((p) => String(p?.nom_poste || "").trim().toLowerCase())
|
||
.filter(Boolean)
|
||
|
||
return postes.some((poste) => postesDirection.includes(poste))
|
||
}
|
||
|
||
function extractStrapiList(value) {
|
||
if (!value) return []
|
||
if (Array.isArray(value)) return value.map(normalizeStrapiItem).filter(Boolean)
|
||
if (value?.data) {
|
||
const rows = Array.isArray(value.data) ? value.data : [value.data]
|
||
return rows.map(normalizeStrapiItem).filter(Boolean)
|
||
}
|
||
if (typeof value === "object") return [normalizeStrapiItem(value)].filter(Boolean)
|
||
return []
|
||
}
|
||
|
||
function normalizeStrapiItem(item) {
|
||
if (!item || typeof item !== "object") return null
|
||
if (item.attributes && typeof item.attributes === "object") {
|
||
return { id: item.id, ...item.attributes }
|
||
}
|
||
return item
|
||
}
|
||
|
||
|
||
</script>
|
||
|
||
<style lang="scss">
|
||
|
||
|
||
.remonter_artistes_list {
|
||
transform: translateY(-90px);
|
||
}
|
||
|
||
.theme_bandeau--grid {
|
||
> .page-section--inner {
|
||
padding-top: 70px;
|
||
padding-bottom: 150px;
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
column-gap: 120px;
|
||
row-gap: 30px;
|
||
}
|
||
&--left {
|
||
max-width: 40%;
|
||
h1 {
|
||
padding-bottom: 20px;
|
||
}
|
||
}
|
||
&--right {
|
||
max-width: 60%;
|
||
&--text {
|
||
max-width: 500px;
|
||
}
|
||
}
|
||
}
|
||
|
||
.musiciens_list_wp {
|
||
// parce que le bloc du dessus à un transform: translateY(-170px); alors cela laisse un espace vide que l'on comble avec ce margin-top négatif
|
||
margin-top: -120px;
|
||
}
|
||
.musiciens_list {
|
||
display: grid;
|
||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||
gap: 28px;
|
||
}
|
||
|
||
.musicien_card {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 10px;
|
||
}
|
||
|
||
.musicien_card_media-placeholder {
|
||
width: 100%;
|
||
aspect-ratio: 1 / 1;
|
||
background: rgba(0, 0, 0, 0.04);
|
||
}
|
||
|
||
.musicien_card_nom {
|
||
margin-top: 8px;
|
||
margin-left: 5px;
|
||
&:hover {
|
||
color: var(--c-brand_rouge);
|
||
}
|
||
}
|
||
.musicien_card_postes {
|
||
margin-left: 5px;
|
||
text-transform: lowercase;
|
||
&::first-letter {
|
||
text-transform: uppercase;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
@media (max-width: 980px) {
|
||
.musiciens_list {
|
||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||
}
|
||
}
|
||
|
||
@media (max-width: 400px) {
|
||
.musiciens_list {
|
||
grid-template-columns: 1fr;
|
||
padding-left: 5px;
|
||
padding-right: 5px;
|
||
}
|
||
}
|
||
|
||
@media (max-width: 600px) {
|
||
.musiciens_list {
|
||
padding-left: 5px;
|
||
padding-right: 5px;
|
||
}
|
||
}
|
||
|
||
</style>
|