Files
wondif_vue/app/pages/index.vue
2026-06-22 11:08:49 +02:00

615 lines
17 KiB
Vue
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div>
<!-- ================== -->
<!-- PROCHAIN CONCERTS -->
<!-- ================== -->
<!-- Fond noir -->
<PageSection tone="dark" content-size="default">
<SectionTitle tone="invert" pad="md">
CONCERTS À VENIR
</SectionTitle>
</PageSection>
<!-- Listes des prochains conncerts -->
<PageSection padded_size="md" content-size="default" class="remonter_concert_list">
<ConcertCardList>
<ConcertCard
v-for="c in concerts"
:key="c.id"
:id="c.slug_concert"
:title="c.titre_concert"
:lieu="c.representation_concert?.[0]?.lieu_representation?.nom_lieu"
:dateISO="c.representation_concert?.[0]?.date_debut_representation"
:dateLabel="formatDateLong(c.representation_concert?.[0]?.date_debut_representation)"
:lien_billetterie_representation="c.representation_concert?.[0]?.lien_billetterie_representation"
:description="c.resume_concert"
:imageUrl="c.image_illustration_concert?.url"
:imageAlt="c.image_illustration_concert?.alternativeText"
:href="`/concerts/concert-${c.slug_concert}?from=agenda`"
/>
</ConcertCardList>
</PageSection>
<!-- ================== -->
<!-- PARTOUT ET POUR TOUS -->
<!-- ================== -->
<PageSection padded_size="" class="theme_ppt_wp remonter_bloc_dessous">
<SectionContent class="theme_ppt">
<!-- PHOTO DE L'ORCHETSRE -->
<DsMedia :src="homePartoutPourTousImageSrc" :alt="homePartoutPourTousImageAlt" class="theme_ppt--img"/>
<!-- PHOTO DE LA CARTE IDF -->
<!-- <DsMedia :src="ppt_img" alt="Carte Île-De-France" class="theme_ppt--img"/> -->
<!-- Avec couleur rouge par dessus -->
<!-- <SectionContent tone="brand_rouge45" pad="" class="theme_ppt--content"> -->
<!-- Sans couleur rouge par dessus -->
<SectionContent tone="" pad="" class="theme_ppt--content">
<SectionTitle tone="invert" pad="xs">
{{ homePartoutPourTousTitle }}
</SectionTitle>
<SectionContent pad="xs" class="theme_ppt--description">
<StrapiBlocksConvert
v-if="homePartoutPourTousDescription?.length"
:blocks="homePartoutPourTousDescription"
class="theme_ppt--txt theme_ppt--txt-strapi"
/>
<!-- UN CTA / LIEN SUR L'IMAGE -->
<!-- <DsButtonArrow to="/" variant="invert"> -->
<!-- Carte des événements -->
<!-- </DsButtonArrow> -->
</SectionContent>
</SectionContent>
</SectionContent>
</PageSection>
<!-- CARTES PARTOUT ET POUR TOUS -->
<PageSection padded_size="" class="theme_ppt_cards_wp">
<SectionContent class="theme_ppt">
<RoundedCardList >
<RoundedCard
v-for="ppt_card in cards_ppt"
:key="ppt_card.id"
:id="ppt_card.id"
:imgSrc="ppt_card.imgSrc"
:imgAlt="ppt_card.imgAlt"
:title="ppt_card.title"
:description="ppt_card.description"
:url="ppt_card.url"
></RoundedCard>
</RoundedCardList>
</SectionContent>
</PageSection>
<!-- ================== -->
<!-- Tous à l'Orchestre -->
<!-- ================== -->
<PageSection tone="brandreverse" padded_size="md" content-size="default" padb="xs" class="theme_tao">
<SectionContent>
<SectionTitle tone="invert" pad="xs">
TOUS À LORCHESTRE
</SectionTitle>
<SectionContent pad="xs" class="theme_tao--description">
<DsText tone="invert" size="lg" class="theme_tao--txt" >
<!-- Phrase daccroche / explicative de cette rubrique par tous et pour tous -->
</DsText>
</SectionContent>
</SectionContent>
<!-- LES CARTES -->
<FilteredCards />
</PageSection>
<!-- ================== -->
<!-- ACTUALITÉS -->
<!-- ================== -->
<PageSection padded_size="md">
<SectionContent>
<SectionTitle tone="" pad="xs">
ACTUALITÉS
</SectionTitle>
</SectionContent>
<SquareCardBlocTextList >
<SquareCardBlocText
v-for="actuscard in homeActuscards"
:key="actuscard.id"
:id="actuscard.id"
:imgSrc="actuscard.imgSrc"
:imgAlt="actuscard.imgAlt"
:title="actuscard.title"
:description="actuscard.description"
:url="actuscard.url"
></SquareCardBlocText>
</SquareCardBlocTextList>
</PageSection>
<!-- ================== -->
<!-- ONDIF MAG -->
<!-- ================== -->
<PageSection padded_size="md" position="relative" overflow="hidden" class="theme_mag">
<div class="decoration--mag"><img src="/img/decoration/ellipse_mag.svg" alt=""></div>
<SectionContent>
<SectionTitle tone="" pad="xs">
ONDIF MAG
</SectionTitle>
<SectionContent pad="xs" class="theme_tao--description">
<DsText tone="" size="lg" class="theme_tao--txt" >
Le magazine en ligne de lOrchestre national dÎle-de-France
</DsText>
</SectionContent>
</SectionContent>
<SectionContent pad="xs">
<TextCardLeftList >
<TextCardLeft
v-for="magcard in magcards"
:key="magcard.id"
:id="magcard.id"
:title="magcard.title"
:description="magcard.description"
:url="magcard.url"
></TextCardLeft>
</TextCardLeftList>
</SectionContent>
</PageSection>
<!-- ================== -->
<!-- L'ORCHESTRE POUR LES PROS -->
<!-- ================== -->
<PageSection padded_size="lg">
<SectionContent>
<SectionTitle tone="" pad="xs">
L'ORCHESTRE POUR LES PROS
</SectionTitle>
</SectionContent>
<SectionContent>
<BannierePros />
</SectionContent>
</PageSection>
</div>
</template>
<script setup>
import { onMounted, computed } from 'vue'
const runtimeConfig = useRuntimeConfig()
const config = useAppConfig()
import { clientLog } from '~/utils/clientLog'
import { formatDateLong } from "@/utils/dateFormat.js"
import SectionContent from '../components/section/SectionContent.vue'
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 DsButton from '@root/design-system/primitives/DsButton.vue'
import DsButtonArrow from '@root/design-system/primitives/DsButtonArrow.vue'
import orchestre_img from '@/assets/img/illustrations/orchestre_3.jpg'
import ppt_img from '@/assets/img/illustrations/map_idf.jpg'
import DsCard from '@root/design-system/components/DsCard.vue'
// Layout utilisé
definePageMeta({ layout: 'default' })
const STRAPI_URL = runtimeConfig.public.strapiUrl
// Config app (pour SEO)
useSeoMeta({
title: config.title
})
console.log("Bienvenue : ",config.title)
//--------------------
// DONNÉES POUR LES CONCERTS À VENIR …
//--------------------
const saisonsFiltre = computed(() => {
const values = [String(runtimeConfig.public.saison || "").trim(), "2025/2026"]
.filter(Boolean)
return [...new Set(values)]
})
console.log("saisonsFiltre.value : ",saisonsFiltre.value)
const { concerts, refresh } = useConcerts({
locale: "fr-FR",
pageSize: 200,
populate: {
saison_concert: true,
image_illustration_concert: true,
representation_concert: { lieu_representation: true },
},
filters: {
saison_concert: {
nom_saison: {
$in: saisonsFiltre.value,
},
},
},
upcomingOnly: true,
limit: 3,
})
onMounted(() => {
if (!concerts.value?.length) {
refresh()
}
})
//--------------------------------------------------------------------------
// DONNÉES POUR LES CARTES PARTOUT ET POUR TOUS
//--------------------------------------------------------------------------
const { items: homePartoutPourTous } = useStrapi(
"/api/__strapi__/home-partout-pour-tous",
{
locale: "fr-FR",
populate: {
illustration: true,
},
limit: 1,
}
)
const { items: homeCardsPartoutPourTous } = useStrapi(
"/api/__strapi__/home-cards",
{
locale: "fr-FR",
populate: {
illustration: true,
},
filters: {
type: {
$eq: "Partout et pour tous",
},
},
sort: "ordre:asc",
pageSize: 1000,
}
)
const homePartoutPourTousContent = computed(() => homePartoutPourTous.value?.[0] || null)
const homePartoutPourTousTitle = computed(() =>
homePartoutPourTousContent.value?.titre || "LA MUSIQUE PARTOUT ET POUR TOUS"
)
const homePartoutPourTousDescription = computed(() => {
const description = homePartoutPourTousContent.value?.description
if (Array.isArray(description)) return description
if (typeof description === "string" && description.trim()) {
return [
{
type: "paragraph",
children: [
{
type: "text",
text: description,
},
],
},
]
}
return []
})
const homePartoutPourTousIllustration = computed(() =>
normalizeStrapiMedia(homePartoutPourTousContent.value?.illustration)
)
const homePartoutPourTousImageSrc = computed(() =>
homePartoutPourTousIllustration.value?.url || orchestre_img
)
const homePartoutPourTousImageAlt = computed(() =>
homePartoutPourTousIllustration.value?.alternativeText ||
homePartoutPourTousContent.value?.titre ||
"L'Orchestre"
)
const cards_ppt = computed(() => {
const publishedCards = homeCardsPartoutPourTous.value.filter((carte) => carte.publication !== false)
return publishedCards.map((carte, index) => {
const image = getStrapiCardImage(carte)
return {
id: carte.id || String(index + 1),
imgSrc: image?.url || "",
imgAlt: image?.alternativeText || image?.caption || carte.titre || "",
title: carte.titre || "",
description: strapiBlocksToText(carte.description),
url: carte.url || "",
}
})
})
function getStrapiCardImage(carte) {
const image = carte.illustration || null
return Array.isArray(image) ? image[0] : image
}
function strapiBlocksToText(blocks) {
if (!blocks) return ""
if (typeof blocks === "string") return blocks
if (!Array.isArray(blocks)) return ""
return blocks
.map((block) =>
(block.children || [])
.map((child) => child.text || "")
.join("")
)
.filter(Boolean)
.join("\n")
}
//--------------------
// DONNÉES POUR LES ACTUS
//--------------------
const actuscards = ref([
{
id: '1',
imgSrc: '/contenus/actu1_1.jpg',
imgAlt: 'Femme en mouvement tenant deux cymbales, lune devant elle et lautre derrière, sur fond de mur blanc, dans une posture dynamique évoquant la musique et le rythme',
title: "La nouvelle saison est là !",
description: ``,
url:"https://www.orchestre-ile.com/concerts/saison?saison=2026/2027",
},
{
id: '2',
imgSrc: '/contenus/academie_web_muet.jpg',
imgAlt: "Académie d'Orchestre 2027",
title: "Académie d'Orchestre 2027",
description: ``,
url:"https://www.orchestre-ile.com/mediation/academie",
},
{
id: '3',
imgSrc: '/contenus/atelier0-3ans.jpg',
imgAlt: 'Du sur-mesure pour les petites oreilles',
title: "Du sur-mesure pour les petites oreilles",
description: ``,
url:"/mediation/petite-enfance",
},
])
const { items: actualitesAccueilItems } = useStrapi(
"/api/__strapi__/actualites",
{
locale: "fr-FR",
sort: "date_actu:desc",
fetchAll: true,
filters: {
accueil_actu: {
$eq: true,
},
},
populate: {
image_illustration_actu: true,
},
}
)
const actualitesAccueilCards = computed(() => {
return actualitesAccueilItems.value.map((actu) => {
const image = normalizeStrapiMedia(actu.image_illustration_actu)
return {
id: `actualite-${actu.id || actu.documentId || actu.slug_actu}`,
imgSrc: image?.url || "",
imgAlt: image?.alternativeText || actu.titre_actu || "",
title: actu.titre_actu || "",
description: actu.sous_titre_actu || "",
url: actu.slug_actu ? `/orchestre/actus?actu=${actu.slug_actu}` : "/orchestre/actus",
}
})
})
const homeActuscards = computed(() => [
...actuscards.value,
...actualitesAccueilCards.value,
])
function normalizeStrapiMedia(media) {
const item = Array.isArray(media) ? media[0] : media
if (!item?.url) return null
return {
id: item.id || item.documentId || item.url,
url: item.url,
alternativeText: item.alternativeText || item.caption || item.name || "",
}
}
//--------------------
// DONNÉES POUR ONDIF MAG
//--------------------
const magcards = ref([
{
id: '1',
title: "LA FANTASTIQUE DE BERLIOZ",
description: `Lauteur suppose quun jeune musicien, affecté de cette maladie morale quun écrivain célèbre appelle le vague des passions, voit pour la première fois une femme qui réunit tous les charmes de lêtre idéal que rêvait son imagination...`,
url:"#",
},
{
id: '2',
title: "LITALIE BAROQUE, BERCEAU DU CONCERTO",
description: `Cest dans lItalie baroque du début du XVIIe siècle que naît le Stile Concertato (style concertant), et plus précisément à Venise, autour des grands maîtres qui ont œuvré à la basilique Saint-Marc, comme les Gabrieli.`,
url:"#",
},
{
id: '3',
title: "BEETHOVEN : LA SYMPHONIE N°4, CHEF-DOEUVRE À LA FOIS CLASSIQUE ET ROMANTIQUE",
description: `Avant la première exécution publique de lœuvre au Theater an der Wien, la partition de la Quatrième symphonie de Beethoven avait dabord été créée dans le palais du prince Lobkowitz en mars 1807.`,
url:"#",
},
])
</script>
<style lang="scss">
.remonter_concert_list {
transform: translateY(-170px);
}
.remonter_bloc_dessous {
// 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: -110px;
}
.photo_orchestre_wp {
.photo_orchestre_img {
.page-section--inner--default {
max-width: calc(+500px)
}
img {
border-radius: 50px;
max-height: 660px;
}
}
.photo_orchestre_cta {
padding-top: 20px;
}
}
//========================
// PARTOUT ET POUR TOUS
//========================
.theme_ppt {
display: grid;
&--img {
grid-row: 1;
grid-column: 1;
max-height: 400px;
position: relative;
z-index: 1;
img {
filter: brightness(0.7);
}
}
&--content {
grid-row: 1;
grid-column: 1;
position: relative;
z-index: 2;
display: grid;
align-items: center;
}
&--description {
max-width: 800px;
align-self: self-start;
// margin-top: 35px;
}
&--txt {
margin-bottom: 35px;
}
&--txt-strapi {
color: var(--c-text-invert, #fff);
.strapi-blocks--p {
color: inherit;
font-family: var(--font-roboto);
font-size: var(--text-lg);
font-weight: var(--fw-regular);
line-height: var(--lh-base);
margin: 0 0 var(--sp-6);
}
strong {
font-size: var(--fs-18);
font-weight: var(--fw-black);
}
}
}
.theme_ppt_cards_wp {
padding-top: 30px;
padding-bottom: 80px;
}
//========================
// TOUS A L'ORCHESTRE
//========================
//========================
// MAGAZINE
//========================
.theme_mag {
@media (max-width: 499px) {
min-height: 650px;
}
@media (min-width: 500px) {
min-height: 650px;
}
@media (min-width: 700px) {
min-height: 650px;
}
@media (min-width: 900px) {
min-height: 650px;
}
@media (min-width: 1100px) {
min-height: 650px;
}
@media (min-width: 1300px) {
min-height: 650px;
}
@media (min-width: 1500px) {
min-height: 650px;
}
.decoration--mag {
position: absolute;
top: -20px;
@media (max-width: 499px) {
right: -150px;
}
@media (min-width: 500px) {
right: -120px;
}
@media (min-width: 700px) {
right: -100px;
}
@media (min-width: 900px) {
right: -100px;
}
@media (min-width: 1100px) {
right: -140px;
}
@media (min-width: 1300px) {
right: -100px;
}
@media (min-width: 1500px) {
right: -50px;
}
img {
height: 600px;
}
}
}
</style>