This commit is contained in:
2026-04-10 12:01:17 +02:00
parent 22cf847ad5
commit 17605e9ec6
8 changed files with 424 additions and 86 deletions

View File

@@ -15,3 +15,7 @@ a {
color: inherit; color: inherit;
text-decoration: none; text-decoration: none;
} }
.display_none {
display: none !important;
}

View File

@@ -29,6 +29,32 @@
</template> </template>
</blockquote> </blockquote>
<!-- Code -->
<pre
v-else-if="block.type === 'code'"
class="strapi-blocks__code"
><code :class="getCodeLanguageClass(block.language)">{{ getCodeContent(block.children) }}</code></pre>
<!-- Image -->
<figure
v-else-if="block.type === 'image' && block.image?.url"
class="strapi-blocks__figure"
>
<img
:src="block.image.url"
:alt="getImageAlt(block.image)"
:width="block.image.width || undefined"
:height="block.image.height || undefined"
class="strapi-blocks__image"
>
<figcaption
v-if="block.image.caption"
class="strapi-blocks__caption"
>
{{ block.image.caption }}
</figcaption>
</figure>
<!-- Lists --> <!-- Lists -->
<ul <ul
v-else-if="block.type === 'list' && block.format === 'unordered'" v-else-if="block.type === 'list' && block.format === 'unordered'"
@@ -56,6 +82,9 @@
</li> </li>
</ol> </ol>
<!-- Fallback --> <!-- Fallback -->
<div v-else class="strapi-blocks--unknown"> <div v-else class="strapi-blocks--unknown">
<!-- debug éventuel --> <!-- debug éventuel -->
@@ -95,6 +124,26 @@
return normalized return normalized
} }
const getImageAlt = (image = {}) => (
image.alternativeText
|| image.caption
|| image.name
|| ''
)
const getCodeContent = (children = []) => (
Array.isArray(children)
? children
.filter((child) => child?.type === 'text')
.map((child) => child.text ?? '')
.join('')
: ''
)
const getCodeLanguageClass = (language) => (
language ? `language-${language}` : undefined
)
</script> </script>
<style lang="scss"> <style lang="scss">
@@ -221,11 +270,43 @@
margin-top: 30px; margin-top: 30px;
} }
&__figure {
margin: 30px 0 30px;
}
&__image {
display: block;
max-width: 100%;
height: auto;
border-radius: 6px;
}
&__caption {
margin-top: 8px;
font-size: 14px;
line-height: 18px;
color: var(--c-text-muted);
}
&__code {
overflow-x: auto;
margin: 20px 0 25px;
padding: 14px 16px;
background: var(--c-bg-muted, #f3f3f3);
border-radius: 4px;
font-family: monospace;
font-size: 15px;
line-height: 1.5;
white-space: pre-wrap;
}
// Espace uniquement avant un titre s'il suit un bloc de contenu // Espace uniquement avant un titre s'il suit un bloc de contenu
&--p + &__h, &--p + &__h,
ul + &__h, ul + &__h,
ol + &__h, ol + &__h,
blockquote + &__h { blockquote + &__h,
&__code + &__h,
&__figure + &__h {
margin-top: 13px; margin-top: 13px;
} }

View File

@@ -0,0 +1,270 @@
<template>
<div class="scolaire--page">
<!-- ================== -->
<!-- FILS D'ARIANE -->
<!-- ================== -->
<PageSection tone="" content-size="default" class="breadcrum_wp">
<Breadcrumb/>
</PageSection>
<!-- ================== -->
<!-- EN-TêTE -->
<!-- ================== -->
<section class="fiche_header_simple_wp">
<div class="fiche_header_wp_gauche"></div>
<div class="fiche_header_inner">
<div class="fiche_header_titres">
<div>
<DsHeading as="h1" tone="default" textcase="uppercase" class="concert-card__title">
{{scolaire_donnees_servies.header_titre}}
</DsHeading>
</div>
<DsText as="p" align="justify">
{{scolaire_donnees_servies.header_text}}
</DsText>
</div>
<div class="fiche_header_img">
<DsMedia
v-if="scolaire_donnees_servies?.header_illustration?.[0]?.url"
:src="scolaire_donnees_servies.header_illustration[0].url"
:alt="scolaire_donnees_servies.header_illustration[0].alternativeText || ''"
fit="cover"
ratio="square"
/>
<div v-else class="img_placeholder" aria-hidden="true" />
</div>
</div>
<div class="fiche_header_wp_droite"></div>
</section>
<!-- ================== -->
<!-- CHIFFRES -->
<!-- ================== -->
<PageSection tone="" content-size="default" padded_size="md" class="chiffres_wp">
<Chiffres
:title= "scolaire_donnees_servies?.chiffres_scolaires?.[0]?.Titre"
:items="scolairesChiffres"
/>
</PageSection>
<!-- ================== -->
<!-- AFFICHAGE DES PARTIE EN DÉCALLAGE AVEC LE CONTENU PROVENANT DE STRAPI -->
<!-- ================== -->
<template v-for="(t, index) in tiroirs" :key="index">
<PageSection :content="false">
<Decalage
:tone="t.decalage_couleur"
title-tone="invert"
:position="t.decalage_sens"
button-tone="invert"
:ensavoirplus-target="`texte_cache_${index + 3}`"
ensavoirplus-group="scolaires-details"
>
<template #title>
{{ t.decalage_titre }}
</template>
<DsText as="p" tone="invert" align="justify">
{{ t.decalage_texte }}
</DsText>
</Decalage>
</PageSection>
<PageSection
:id="`texte_cache_${index + 3}`"
data-ensavoirplus-group="scolaires-details"
tone=""
content-size="default"
padded_size="md"
class="decalage_ensavoirplus--hidden"
>
<SectionContent class="description_wp">
<StrapiBlocksConvert :blocks="t.tiroir_description" />
</SectionContent>
<section v-if="t.tiroir_galerie.length" class="img-gallery_wp">
<div class="img-gallery">
<DsMedia
v-for="img in t.tiroir_galerie"
:key="img.id || img.url"
:src="img.url"
:alt="img.alternativeText"
/>
</div>
</section>
<section v-if="t.tiroir_videos.length" class="youtube_wp">
<div class="youtube-list">
<div v-for="v in t.tiroir_videos" :key="v.id" class="youtube-item">
<iframe
:src="v.lien_youtube"
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>
<!-- ================== -->
<!-- CONTACT -->
<!-- ================== -->
<PageSection tone="" content-size="default" padded_size="md" class="contact_spe_wp">
<ContactSpecifique
titre="Contacter le service des actions culturelles"
nom="Vanessa Gasztowtt"
poste="Responsable de laction éducative et culturelle
et de la programmation jeune public"
numero="01 41 79 03 43"
mail="vanessa.gasztowtt@orchestre-ile.com"
/>
</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'
import { computed } from 'vue'
// ======================================
// RÉCUPÉRATION DES DONNÉES DANS STRAPI
// ======================================
const endpoint = "/api/__strapi__/scolaires"
const populate = {
header_illustration: true,
chiffres_scolaires: {chiffres: true},
tiroirs_scolaires: {
decalage_parametres: true,
tiroir_galerie: true,
tiroir_videos: true,
},
}
const { items: scolaires, pending, error } = useStrapi(
endpoint,
{
locale: "fr-FR",
populate,
limit: 1,
}
)
console.log("scolaires:", scolaires.value)
watchEffect(() => {
console.log("client ?", import.meta.client)
console.log("server ?", import.meta.server)
console.log("pending:", pending.value)
console.log("error:", error.value)
console.log("scolaires:", scolaires.value)
})
watchEffect(() => {
if (!pending.value && scolaires.value?.length) {
console.log("scolaires dans le watch effect:", scolaires.value)
console.log("scolaires header_titre :", scolaires.value[0].header_titre)
console.log("scolaires illustration url :", scolaires.value[0].header_illustration[0].url)
}
})
console.log("scolaires header_titre :", scolaires.value?.[0]?.header_titre)
// ======================================
// PRÉPARATION DES DONNÉES POUR AFFICHAGE DANS LA PAGE
// ======================================
const scolaire_donnees_servies = computed(() => scolaires.value?.[0] || {})
watchEffect(() => {
console.log("scolaire_donnees_servies JSON:", JSON.stringify(scolaire_donnees_servies.value, null, 2))
})
const scolairesChiffres = computed(() =>
(scolaires.value?.[0]?.chiffres_scolaires?.[0]?.chiffres || []).map((item) => ({
value: item.chiffre,
label: item.label,
}))
)
const tiroirs = computed(() =>
(scolaires.value?.[0]?.tiroirs_scolaires || []).map((tiroir_item) => ({
decalage_titre: tiroir_item.decalage_parametres?.decalage_titre,
decalage_texte: tiroir_item.decalage_parametres?.decalage_texte,
decalage_sens:
tiroir_item.decalage_parametres?.decalage_sens === "droite" ? "right" : "left",
decalage_couleur:
tiroir_item.decalage_parametres?.decalage_couleur === "rouge"
? "brand"
: tiroir_item.decalage_parametres?.decalage_couleur === "vert clair"
? "brandreverse"
: tiroir_item.decalage_parametres?.decalage_couleur === "jaune"
? "jaune"
: "dark",
tiroir_description: tiroir_item.tiroir_description,
tiroir_galerie: (tiroir_item.tiroir_galerie || []).map((tiroir_item_img) => ({
id: tiroir_item_img.id,
url: tiroir_item_img.url,
alt: tiroir_item_img.alternativeText,
})),
tiroir_videos: (tiroir_item.tiroir_videos || [])
.map((tiroir_item_video) => {
const id = getYoutubeId(tiroir_item_video?.lien_youtube)
if (!id) return null
return {
id: tiroir_item_video.id || id,
lien_youtube: `https://www.youtube-nocookie.com/embed/${id}?rel=0&modestbranding=1&iv_load_policy=3&playsinline=1`,
}
})
.filter(Boolean),
}))
)
watchEffect(() => {
console.log("scolairesChiffres JSON:", JSON.stringify(scolairesChiffres.value, null, 2))
console.log("tiroirs JSON:", JSON.stringify(tiroirs.value, null, 2))
})
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
}
}
</script>
<style lang="scss">
// =======================
// SPÉCIFIQUE À CETTE PAGE
// =======================
.scolaire--page {
.chiffres_wp {
background-color: var(--c-background-jaune);
margin-bottom: 50px;
}
.contact_spe_wp {
background-color: var(--c-background-jaune-clair);
margin-bottom: 20px;
}
}
/* ============================ */
/* GALERIES */
/* ============================ */
</style>

View File

@@ -81,9 +81,6 @@
padded_size="md" padded_size="md"
class="decalage_ensavoirplus--hidden" class="decalage_ensavoirplus--hidden"
> >
<SectionContent class="description_wp">
<StrapiBlocksConvert :blocks="t.tiroir_description" />
</SectionContent>
<section v-if="t.tiroir_galerie.length" class="img-gallery_wp"> <section v-if="t.tiroir_galerie.length" class="img-gallery_wp">
<div class="img-gallery"> <div class="img-gallery">
<DsMedia <DsMedia
@@ -94,6 +91,9 @@
/> />
</div> </div>
</section> </section>
<SectionContent class="description_wp">
<StrapiBlocksConvert :blocks="t.tiroir_description" />
</SectionContent>
<section v-if="t.tiroir_videos.length" class="youtube_wp"> <section v-if="t.tiroir_videos.length" class="youtube_wp">
<div class="youtube-list"> <div class="youtube-list">
<div v-for="v in t.tiroir_videos" :key="v.id" class="youtube-item"> <div v-for="v in t.tiroir_videos" :key="v.id" class="youtube-item">

View File

@@ -1,5 +1,5 @@
<template> <template>
<div> <div class="artiste_invitee-wp">
<section v-if="pending" aria-busy="true" aria-live="polite"> <section v-if="pending" aria-busy="true" aria-live="polite">
<p>en cours de chargement...</p> <p>en cours de chargement...</p>
</section> </section>
@@ -645,6 +645,7 @@
/* ============================ */ /* ============================ */
/* DESCRIPTION */ /* DESCRIPTION */
/* ============================ */ /* ============================ */
.artiste_invitee-wp {
.fiche_description { .fiche_description {
display: flex; display: flex;
justify-content: center; justify-content: center;
@@ -658,6 +659,7 @@
flex-direction: column; flex-direction: column;
} }
} }
}
/* ============================ */ /* ============================ */
/* GALERIES */ /* GALERIES */
/* ============================ */ /* ============================ */

View File

@@ -1,5 +1,5 @@
<template> <template>
<div> <div class="artiste_invitee-wp">
<section v-if="pending" aria-busy="true" aria-live="polite"> <section v-if="pending" aria-busy="true" aria-live="polite">
<p>en cours de chargement...</p> <p>en cours de chargement...</p>
</section> </section>
@@ -226,7 +226,6 @@
.fiche_header_wp { .fiche_header_wp {
display: grid; display: grid;
@media (min-width: 0px) and (max-width: 600px) { @media (min-width: 0px) and (max-width: 600px) {
grid-template-columns: 1fr; grid-template-columns: 1fr;
grid-template-rows: auto 510px 20px 200px; grid-template-rows: auto 510px 20px 200px;
@@ -643,6 +642,7 @@
/* ============================ */ /* ============================ */
/* DESCRIPTION */ /* DESCRIPTION */
/* ============================ */ /* ============================ */
.artiste_invitee-wp {
.fiche_description { .fiche_description {
display: flex; display: flex;
justify-content: center; justify-content: center;
@@ -656,6 +656,7 @@
flex-direction: column; flex-direction: column;
} }
} }
}
/* ============================ */ /* ============================ */
/* GALERIES */ /* GALERIES */
/* ============================ */ /* ============================ */

View File

@@ -45,7 +45,7 @@
<!-- ================== --> <!-- ================== -->
<!-- PARTIE 1 --> <!-- PARTIE 1 -->
<!-- ================== --> <!-- ================== -->
<PageSection tone="" content-size="default" padded_size="md" class="fiche_description"> <PageSection tone="" content-size="default" padded_size="" class="fiche_description">
<SectionContent v-if="missions?.partie_1" class="description_wp"> <SectionContent v-if="missions?.partie_1" class="description_wp">
<StrapiBlocksConvert :blocks="missions.partie_1" /> <StrapiBlocksConvert :blocks="missions.partie_1" />
</SectionContent> </SectionContent>
@@ -86,6 +86,23 @@
</SectionContent> </SectionContent>
</PageSection> </PageSection>
<!-- ================== -->
<!-- decalage_gauche 1 -->
<!-- ================== -->
<PageSection :content="false">
<Decalage tone="dark" title-tone="invert" position="left" button-tone="invert">
<template #title>
Studio denregistrement et location dinstruments
</template>
<DsText as="p" tone="invert" align="justify">
LOrchestre national dÎle-de-France accompagne les professionnels et les amateurs dans leurs activités musicales.<br>
Aux portes de Paris, nous mettons à leur disposition un studio denregistrement high-tech et plusieurs espaces de répétition. Nous leur proposons également plus de 3000 instruments à la location à travers un parc instrumental ouvert sur le monde et ses traditions musicales les plus inattendues !
</DsText>
</Decalage>
</PageSection>
<!-- ================== --> <!-- ================== -->
<!-- decalage_droite_2 --> <!-- decalage_droite_2 -->
<!-- ================== --> <!-- ================== -->
@@ -102,8 +119,9 @@
<!-- ================== --> <!-- ================== -->
<!-- PARTIE 3 --> <!-- PARTIE 3 -->
<!-- 🚫 DISPLAY NONE -->
<!-- ================== --> <!-- ================== -->
<PageSection tone="" content-size="default" padded_size="md" class="fiche_description"> <PageSection tone="" content-size="default" padded_size="md" class="fiche_description display_none">
<SectionContent v-if="missions?.partie_3" class="description_wp"> <SectionContent v-if="missions?.partie_3" class="description_wp">
<StrapiBlocksConvert :blocks="missions.partie_3" /> <StrapiBlocksConvert :blocks="missions.partie_3" />
</SectionContent> </SectionContent>
@@ -113,9 +131,10 @@
<!-- ================== --> <!-- ================== -->
<!-- decalage_droite_clic_4 --> <!-- decalage_droite_clic_4 -->
<!-- RSE -->
<!-- ================== --> <!-- ================== -->
<PageSection :content="false"> <PageSection :content="false">
<Decalage tone="brand" title-tone="invert" position="right" button-tone="invert" ensavoirplus-target="texte_cache"> <Decalage tone="brand" title-tone="invert" position="left" button-tone="invert" ensavoirplus-target="texte_cache">
<template #title> <template #title>
{{ missions?.decalage_droite_clic_4?.decalage_titre }} {{ missions?.decalage_droite_clic_4?.decalage_titre }}
</template> </template>
@@ -125,8 +144,8 @@
</Decalage> </Decalage>
</PageSection> </PageSection>
<PageSection> <PageSection tone="" content-size="default" padded_size="" class="fiche_description">
<div id="texte_cache" class="decalage_ensavoirplus--hidden">Texte caché</div> <div id="texte_cache" class="decalage_ensavoirplus--hidden"><StrapiBlocksConvert :blocks="missions.partie_ouvrable_4" /></div>
</PageSection> </PageSection>
<!-- ================== --> <!-- ================== -->
@@ -196,6 +215,20 @@
background-color: var(--c-background-vert); background-color: var(--c-background-vert);
margin-bottom: 50px; margin-bottom: 50px;
} }
.fiche_description {
display: flex;
justify-content: center;
padding-top: 10px;
padding-bottom: 70px;
padding-left: 10px;
padding-right: 10px;
> * {
max-width: 640px;
display: flex;
flex-direction: column;
}
}
} }
</style> </style>

View File

@@ -25,13 +25,7 @@
<!-- Listes des musiciens --> <!-- Listes des musiciens -->
<!-- ================== --> <!-- ================== -->
<!-- ================== -->
<!-- DIRECTION -->
<!-- ================== -->
<PageSection padded_size="md" content-size="default" class="musiciens_list_section remonter_artistes_list"> <PageSection padded_size="md" content-size="default" class="musiciens_list_section remonter_artistes_list">
<section v-if="pending" aria-busy="true" aria-live="polite"> <section v-if="pending" aria-busy="true" aria-live="polite">
<DsText as="p" tone="default">Chargement des artistes...</DsText> <DsText as="p" tone="default">Chargement des artistes...</DsText>
</section> </section>
@@ -100,53 +94,7 @@
</section> </section>
</PageSection> </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}?from=musiciens`">
{{ 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> </div>
@@ -158,6 +106,7 @@
import DsMedia from '@root/design-system/primitives/DsMedia.vue' import DsMedia from '@root/design-system/primitives/DsMedia.vue'
const runtimeConfig = useRuntimeConfig() const runtimeConfig = useRuntimeConfig()
const saisonFiltre = computed(() => String(runtimeConfig.public.saison || '').trim()) const saisonFiltre = computed(() => String(runtimeConfig.public.saison || '').trim())
// Filtre non utilisé
const artistesFilters = computed(() => { const artistesFilters = computed(() => {
if (!saisonFiltre.value) return null if (!saisonFiltre.value) return null
return { return {
@@ -179,11 +128,9 @@
sort: "ordre_artiste_ondif:asc", sort: "ordre_artiste_ondif:asc",
pageSize: 200, pageSize: 200,
populate: { populate: {
saisons_artiste_ondif: true,
image_illustration_artiste_ondif: true, image_illustration_artiste_ondif: true,
postes_artiste_ondif: true, postes_artiste_ondif: true,
}, },
filters: artistesFilters,
} }
) )