front end

This commit is contained in:
2026-03-18 12:00:19 +01:00
parent b0352c963c
commit bc6ad43ea5
31 changed files with 832 additions and 166 deletions

View File

@@ -122,6 +122,12 @@ populate[liens_youtube_concert]=true
| A| B| C| | A| B| C|
| A| B| C| | A| B| C|
API pour avoir la page Les Missions
https://bo.orchestre-ile.com/api/mission?locale=fr-FR&populate=image_illustration_header
https://bo.orchestre-ile.com/api/mission?locale=fr-FR&populate=*
## SAISIE DU CONTENU ## SAISIE DU CONTENU
### slug ### slug
- concert - concert

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

View File

@@ -48,7 +48,7 @@
padding-right: 16px; padding-right: 16px;
padding-bottom: 5px; padding-bottom: 5px;
text-align: left; text-align: left;
background-color: rgba(255, 255, 255, 0.95); background-color: var(--c-surface);
border-radius: 3px; border-radius: 3px;
.header_nav_topbar_submenu_item { .header_nav_topbar_submenu_item {
@@ -169,6 +169,19 @@
//font-family: 'brandontext_regular'; //font-family: 'brandontext_regular';
font-family: var(--font-roboto); font-family: var(--font-roboto);
// wght Graisse
// YTLC Hauteur miniscule
// YTUC Hauteur majuscule
// YTAS Hauteur des hampes ascendantes
// YTDE Hauteur des hampes descendantes
// wdth largeur horizontale des lettres
font-variation-settings:
"wdth" 41,
"wght" 662,
"YTLC" 570,
"YTUC" 760,
"YTAS" 794,
"YTDE" -275;
@include media_queries.media_min(tablet_600) { @include media_queries.media_min(tablet_600) {
font-size: 18px; font-size: 18px;
@@ -255,13 +268,15 @@
padding-right: 12px; padding-right: 12px;
padding-bottom: 10px; padding-bottom: 10px;
text-align: left; text-align: left;
background-color: rgba(255, 255, 255, 0.97); background-color: var(--c-surface);
border-radius: 3px; border-radius: 3px;
.header_nav_sub_menu_item { .header_nav_sub_menu_item {
list-style: circle; list-style: circle;
//font-family: 'brandontext_regular'; //font-family: 'brandontext_regular';
font-family: var(--font-roboto); font-family: var(--font-roboto);
font-variation-settings:
"wdth" 41, "wght" 552, "YTLC" 570, "YTUC" 760, "YTAS" 794, "YTDE" -275;
@media (min-width: 0px) { @media (min-width: 0px) {
font-size: 16px; font-size: 16px;
} }
@@ -422,6 +437,13 @@
margin-top: 47px; margin-top: 47px;
font-family: var(--font-roboto); font-family: var(--font-roboto);
font-variation-settings:
"wdth" 41,
"wght" 662,
"YTLC" 570,
"YTUC" 760,
"YTAS" 794,
"YTDE" -275;
padding-bottom: 10px; padding-bottom: 10px;
padding-right: 10px; padding-right: 10px;
@@ -489,6 +511,8 @@
list-style: none; list-style: none;
//font-family: 'brandontext_regular'; //font-family: 'brandontext_regular';
font-family: var(--font-roboto); font-family: var(--font-roboto);
font-variation-settings:
"wdth" 41, "wght" 552, "YTLC" 570, "YTUC" 760, "YTAS" 794, "YTDE" -275;
font-size: 18px; font-size: 18px;
padding-bottom: 4px; padding-bottom: 4px;
list-style: circle; list-style: circle;

View File

@@ -78,7 +78,7 @@
} }
@media (min-width: 500px) { @media (min-width: 500px) {
.banniere_pros_wp { .banniere_pros_wp {
grid-template-columns: 150px 270px 40px 40px; grid-template-columns: 150px 250px 35px 35px;
grid-template-rows: auto; grid-template-rows: auto;
//justify-content: center; //justify-content: center;
align-items: center; align-items: center;

View File

@@ -118,13 +118,13 @@
position: relative; position: relative;
z-index: 1; z-index: 1;
@media (min-width: 0px) { @media (min-width: 0px) {
padding-left: 20px; padding-left: 10px;
} }
@media (min-width: 600px) { @media (min-width: 600px) {
padding-left: 20px; padding-left: 0px;
} }
@media (min-width: 700px) { @media (min-width: 700px) {
padding-left: 20px; padding-left: 0px;
} }
} }
.breadcrumb__list { .breadcrumb__list {

View File

@@ -57,7 +57,7 @@
</li> </li>
<li class="header_nav_item" :class="{ 'is-active': isMediation }"> <li class="header_nav_item" :class="{ 'is-active': isMediation }">
Éducation et médiation Action culturelle
<ul class="header_nav_sub_menu"> <ul class="header_nav_sub_menu">
<li class="header_nav_sub_menu_item"><NuxtLink to="/mediation/petite-enfance">Petite enfance</NuxtLink></li> <li class="header_nav_sub_menu_item"><NuxtLink to="/mediation/petite-enfance">Petite enfance</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/mediation/scolaires">Scolaires</NuxtLink></li> <li class="header_nav_sub_menu_item"><NuxtLink to="/mediation/scolaires">Scolaires</NuxtLink></li>
@@ -193,7 +193,7 @@
:class="{ 'is-open': activeDrawer === 'education' }" :class="{ 'is-open': activeDrawer === 'education' }"
@click="toggleDrawer('education')" @click="toggleDrawer('education')"
> >
Éducation et médiation Action culturelle
<ul class="header_drawer_sub_menu"> <ul class="header_drawer_sub_menu">
<li class="header_drawer_sub_menu_item"><NuxtLink to="/mediation/petite-enfance">Petite enfance</NuxtLink></li> <li class="header_drawer_sub_menu_item"><NuxtLink to="/mediation/petite-enfance">Petite enfance</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/mediation/scolaires">Scolaires</NuxtLink></li> <li class="header_drawer_sub_menu_item"><NuxtLink to="/mediation/scolaires">Scolaires</NuxtLink></li>
@@ -280,7 +280,7 @@
route.path.startsWith('/concerts') route.path.startsWith('/concerts')
) )
// Éducation et médiation // Action culturelle
const isMediation = computed(() => const isMediation = computed(() =>
route.path.startsWith('/mediation') route.path.startsWith('/mediation')
) )

View File

@@ -2,7 +2,7 @@
<div class="decalage_cont" <div class="decalage_cont"
:class="[ :class="[
`decalage_cont--${position}` `decalage_cont--${position}`
]"" ]"
> >
<div class="decalage" <div class="decalage"
:class="[ :class="[
@@ -11,7 +11,7 @@
]" ]"
> >
<div class="decalage_inner"> <div class="decalage_inner">
<DsHeading v-if="$slots.title" :tone=titleTone as="h2" textcase="uppercase"> <DsHeading v-if="$slots.title" :tone="titleTone" as="h2" textcase="uppercase">
<slot name="title" /> <slot name="title" />
</DsHeading> </DsHeading>
<slot /> <slot />
@@ -19,7 +19,7 @@
<slot name="button" /> <slot name="button" />
</div> </div>
<div v-if="ensavoirplusTarget" class="decalage_button"> <div v-if="ensavoirplusTarget" class="decalage_button">
<DsButton :textColor=buttonTone :borderColor="buttonTone" @click="toggleTarget(ensavoirplusTarget)">En savoir +</DsButton> <DsButton :textColor="buttonTone" :borderColor="buttonTone" @click="toggleTarget(ensavoirplusTarget)">En savoir +</DsButton>
</div> </div>
</div> </div>
</div> </div>
@@ -72,7 +72,7 @@ import DsButton from '@root/design-system/primitives/DsButton.vue'
width: 67vw; width: 67vw;
} }
@media (min-width: 800px) { @media (min-width: 800px) {
width: 50vw; width: 60vw;
} }
/* tons = arrière-plan section */ /* tons = arrière-plan section */
@@ -86,23 +86,26 @@ import DsButton from '@root/design-system/primitives/DsButton.vue'
&--right { &--right {
.decalage_inner { .decalage_inner {
padding-right: 20px;
padding-left: 50px; padding-left: 50px;
@media (max-width: 599px) { @media (max-width: 599px) {
padding-left: 40px; padding-right: 15px;
padding-left: 40px;
} }
} }
} }
&--left { &--left {
justify-content: flex-end; justify-content: flex-end;
.decalage_inner { .decalage_inner {
padding-right: 50px; padding-right: 50px;
padding-left: 20px;
@media (max-width: 599px) { @media (max-width: 599px) {
padding-right: 40px; padding-right: 40px;
padding-left: 15px;
} }
} }
@@ -113,38 +116,38 @@ import DsButton from '@root/design-system/primitives/DsButton.vue'
.decalage_inner { .decalage_inner {
@media (min-width: 0px) { @media (min-width: 0px) {
width: 100%; width: 100%;
} }
@media (min-width: 600px) { @media (min-width: 600px) {
width: calc(290px + 39vw); width: calc(290px + 39vw);
} }
@media (min-width: 700px) { @media (min-width: 700px) {
width: calc(330px + 17vw); width: calc(330px + 17vw);
} }
@media (min-width: 800px) { @media (min-width: 800px) {
width: 390px; width: calc(330px + 17vw);
} }
@media (min-width: 900px) { @media (min-width: 900px) {
width: 430px; width: 600px;
} }
@media (min-width: 1000px) { @media (min-width: 1000px) {
width: 475px; width: 600px;
} }
@media (min-width: 1100px) { @media (min-width: 1100px) {
width: 510px; width: 600px;
} }
@media (min-width: 1200px) { @media (min-width: 1200px) {
width: 550px; width: 600px;
} }
@media (min-width: 1300px) { @media (min-width: 1300px) {
width: 600px; width: 600px;
} }
@media (min-width: 1400px) { @media (min-width: 1400px) {
width: 650px; width: 600px;
} }
@media (min-width: 1500px) { @media (min-width: 1500px) {
width: 700px; width: 600px;
} }
} }
.decalage_button { .decalage_button {
@@ -155,4 +158,4 @@ import DsButton from '@root/design-system/primitives/DsButton.vue'
.decalage_ensavoirplus--hidden { .decalage_ensavoirplus--hidden {
display: none; display: none;
} }
</style> </style>

View File

@@ -27,8 +27,6 @@
</template> </template>
<script setup> <script setup>
import { computed } from 'vue'
const props = defineProps({ const props = defineProps({
tone: { type: String, default: 'default' }, // default / brand / muted / dark… tone: { type: String, default: 'default' }, // default / brand / muted / dark…
padded_size: { type: String, default: '' }, // none | sm | md | lg padded_size: { type: String, default: '' }, // none | sm | md | lg
@@ -39,7 +37,6 @@
position : { type: String, default: '' }, position : { type: String, default: '' },
overflow : { type: String, default: '' } overflow : { type: String, default: '' }
}) })
</script> </script>
<style lang="scss"> <style lang="scss">
@@ -57,6 +54,9 @@
&--dark { background: var(--c-backgroud-black); } &--dark { background: var(--c-backgroud-black); }
&--brandreverse { background: var(--c-backgroud-brandreverse); } &--brandreverse { background: var(--c-backgroud-brandreverse); }
&--jaune { background: var(--c-background-jaune); } &--jaune { background: var(--c-background-jaune); }
&--bleu { background: var(--c-background-bleu); }
&--rouge45 { background: var(--c-brand_rouge45); }
&--rouge-weak { background: var(--c-brand_rouge-weak); }
// padding en haut et en bas // padding en haut et en bas
&--padded { &--padded {
@@ -69,7 +69,6 @@
padding-bottom: 120px; padding-bottom: 120px;
} }
} }
} }
</style> </style>

View File

@@ -43,7 +43,6 @@
@media (min-width: 0px) { @media (min-width: 0px) {
max-width: 100%; max-width: 100%;
} }
@media (min-width: 600px) { @media (min-width: 600px) {
max-width: 580px; max-width: 580px;

View File

@@ -102,16 +102,17 @@
font-family: var(--font-roboto); font-family: var(--font-roboto);
&--p { &--p {
font-weight: var(--fw-light); font-weight: var(--fw-light);
font-size: 17px; font-size: 17px;
line-height: 22px; line-height: 22px;
margin-bottom: 5px; margin-bottom: 5px;
text-align: justify;
} }
h1 { h1 {
padding-bottom: 10px; padding-bottom: 10px;
font-weight: var(--fw-bold); font-weight: var(--fw-bold);
font-size: 30px; font-size: 30px;
text-transform: uppercase;
} }
h2 { h2 {
padding-bottom: 7px; padding-bottom: 7px;

View File

@@ -0,0 +1,101 @@
export function useStrapi(endpoint, options = {}) {
const queryString = computed(() => {
const locale = unref(options.locale) ?? "fr-FR"
const sort = unref(options.sort) ?? null
const populate = unref(options.populate) ?? null
const filters = unref(options.filters) ?? null
const query = new URLSearchParams()
query.set("locale", locale)
if (sort) {
query.set("sort[0]", sort)
}
if (populate && typeof populate === "object") {
appendPopulate(query, populate)
}
if (filters && typeof filters === "object") {
appendFilters(query, filters)
}
return query.toString()
})
const { data, pending, error, refresh } = useFetch(
() => `${endpoint}?${queryString.value}`,
{
server: true,
key: () => `${endpoint}:${queryString.value}`,
watch: [queryString],
}
)
const items = computed(() => {
const raw = data.value?.data
let list = []
if (Array.isArray(raw)) {
list = raw.map(normalizeStrapiItem)
} else if (raw && typeof raw === "object") {
list = [normalizeStrapiItem(raw)]
}
const limit = unref(options.limit)
if (typeof limit === "number") {
list = list.slice(0, Math.max(0, limit))
}
return list
})
return {
items,
pending,
error,
refresh,
}
}
function appendPopulate(query, populate, prefix = "populate") {
Object.entries(populate).forEach(([key, value]) => {
if (value === true) {
query.set(`${prefix}[${key}]`, "true")
return
}
if (value && typeof value === "object") {
const entries = Object.entries(value)
const allTrue = entries.length > 0 && entries.every(([, v]) => v === true)
if (allTrue) {
const list = entries.map(([k]) => k).join(",")
query.set(`${prefix}[${key}][populate]`, list)
return
}
appendPopulate(query, value, `${prefix}[${key}][populate]`)
}
})
}
function appendFilters(query, filters, prefix = "filters") {
Object.entries(filters).forEach(([key, value]) => {
if (value === null || value === undefined) return
if (typeof value !== "object") {
query.set(`${prefix}[${key}]`, String(value))
return
}
Object.entries(value).forEach(([k, v]) => {
if (v === null || v === undefined) return
if (typeof v !== "object") {
query.set(`${prefix}[${key}][${k}]`, String(v))
return
}
appendFilters(query, v, `${prefix}[${key}][${k}]`)
})
})
}
function normalizeStrapiItem(item) {
const a = item.attributes || item || {}
return {
id: item.id,
...a,
}
}

View File

@@ -6,7 +6,7 @@
LES CONCERTS À VENIR LES CONCERTS À VENIR
</SectionTitle> </SectionTitle>
</PageSection> </PageSection>
<PageSection padded_size="md" content-size="default" class=""> <PageSection padded_size="md" content-size="default" class="remonter_concert_list">
<ConcertCardList :highlight-first="false" :limit-cards-on-breakpoint="false"> <ConcertCardList :highlight-first="false" :limit-cards-on-breakpoint="false">
<ConcertCard <ConcertCard
v-for="c in concerts" v-for="c in concerts"

View File

@@ -6,7 +6,7 @@
LA SAISON 2025/2026 POUR LES JEUNES LA SAISON 2025/2026 POUR LES JEUNES
</SectionTitle> </SectionTitle>
</PageSection> </PageSection>
<PageSection padded_size="md" content-size="default" class=""> <PageSection padded_size="md" content-size="default" class="remonter_concert_list">
<ConcertCardList :highlight-first="false" :limit-cards-on-breakpoint="false"> <ConcertCardList :highlight-first="false" :limit-cards-on-breakpoint="false">
<ConcertCard <ConcertCard
v-for="c in concerts" v-for="c in concerts"

View File

@@ -6,7 +6,7 @@
SAISON 2025/2026 SAISON 2025/2026
</SectionTitle> </SectionTitle>
</PageSection> </PageSection>
<PageSection padded_size="md" content-size="default" class=""> <PageSection padded_size="md" content-size="default" class="remonter_concert_list">
<ConcertCardList :highlight-first="false" :limit-cards-on-breakpoint="false"> <ConcertCardList :highlight-first="false" :limit-cards-on-breakpoint="false">
<ConcertCard <ConcertCard
v-for="c in concerts" v-for="c in concerts"

View File

@@ -2,17 +2,17 @@
<div> <div>
<!-- ================== --> <!-- ================== -->
<!-- Fond noir --> <!-- PROCHAIN CONCERTS -->
<!-- ================== --> <!-- ================== -->
<!-- Fond noir -->
<PageSection tone="dark" content-size="default"> <PageSection tone="dark" content-size="default">
<SectionTitle tone="invert" pad="md"> <SectionTitle tone="invert" pad="md">
CONCERTS À VENIR CONCERTS À VENIR
</SectionTitle> </SectionTitle>
</PageSection> </PageSection>
<!-- ================== -->
<!-- Listes des prochains conncerts --> <!-- Listes des prochains conncerts -->
<!-- ================== -->
<PageSection padded_size="md" content-size="default" class="remonter_concert_list"> <PageSection padded_size="md" content-size="default" class="remonter_concert_list">
<ConcertCardList> <ConcertCardList>
<ConcertCard <ConcertCard
@@ -31,13 +31,38 @@
</ConcertCardList> </ConcertCardList>
</PageSection> </PageSection>
<PageSection tone="dark" padded_size="md" content-size="default" padb="xs" class="theme_tao photo_orchestre_wp remonter_bloc_dessous">
<SectionContent>
<SectionTitle tone="invert" pad="xs">
LORCHESTRE NATIONAL D'ÎLE-DE-FRANCE
</SectionTitle>
<DsMedia :src="orchestre_img" alt="L'Orchestre" class="photo_orchestre_img"/>
</SectionContent>
<SectionContent pad="xs" class="photo_orchestre_cta">
<DsButtonArrow to="/" variant="invert">
Découvrir les musiciens
</DsButtonArrow>
</SectionContent>
</PageSection>
<!-- ================== --> <!-- ================== -->
<!-- Carte Île-De-France Partout et pour tous --> <!-- PARTOUT ET POUR TOUS -->
<!-- ================== --> <!-- ================== -->
<PageSection padded_size="md" class="theme_ppt_wp"> <PageSection padded_size="md" class="theme_ppt_wp">
<SectionContent class="theme_ppt"> <SectionContent class="theme_ppt">
<!-- PHOTO DE L'ORCHETSRE -->
<!-- <DsMedia :src="orchestre_img" alt="L'Orchestre" class="theme_ppt--img"/> -->
<!-- PHOTO DE LA CARTE IDF -->
<DsMedia :src="ppt_img" alt="Carte Île-De-France" class="theme_ppt--img"/> <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"> <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"> <SectionTitle tone="invert" pad="xs">
PARTOUT ET POUR TOUS PARTOUT ET POUR TOUS
</SectionTitle> </SectionTitle>
@@ -45,6 +70,7 @@
<DsText tone="invert" size="lg" class="theme_ppt--txt" > <DsText tone="invert" size="lg" class="theme_ppt--txt" >
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, lorchestre sengage à 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. 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, lorchestre sengage à 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> </DsText>
<!-- UN CTA / LIEN SUR L'IMAGE -->
<DsButtonArrow to="/" variant="invert"> <DsButtonArrow to="/" variant="invert">
Carte des événements Carte des événements
</DsButtonArrow> </DsButtonArrow>
@@ -52,6 +78,15 @@
</SectionContent> </SectionContent>
</SectionContent> </SectionContent>
</PageSection> </PageSection>
<!-- CARTES PARTOUT ET POUR TOUS -->
<PageSection padded_size="md" class="theme_ppt_wp">
<SectionContent class="theme_ppt">
<SquareCardBlocTextList >
</SquareCardBlocTextList>
</SectionContent>
</PageSection>
<!-- ================== --> <!-- ================== -->
<!-- Tous à l'Orchestre --> <!-- Tous à l'Orchestre -->
@@ -78,11 +113,11 @@
<PageSection padded_size="md"> <PageSection padded_size="md">
<SectionContent> <SectionContent>
<SectionTitle tone="" pad="xs"> <SectionTitle tone="" pad="xs">
LES DERNIÈRES ACTUALITÉS ACTUALITÉS
</SectionTitle> </SectionTitle>
</SectionContent> </SectionContent>
<SquareCardList > <SquareCardBlocTextList >
<SquareCard <SquareCardBlocText
v-for="actuscard in actuscards" v-for="actuscard in actuscards"
:key="actuscard.id" :key="actuscard.id"
:id="actuscard.id" :id="actuscard.id"
@@ -91,8 +126,8 @@
:title="actuscard.title" :title="actuscard.title"
:description="actuscard.description" :description="actuscard.description"
:url="actuscard.url" :url="actuscard.url"
></SquareCard> ></SquareCardBlocText>
</SquareCardList> </SquareCardBlocTextList>
</PageSection> </PageSection>
<!-- ================== --> <!-- ================== -->
@@ -155,6 +190,7 @@
import DsMedia from '@root/design-system/primitives/DsMedia.vue' import DsMedia from '@root/design-system/primitives/DsMedia.vue'
import DsButton from '@root/design-system/primitives/DsButton.vue' import DsButton from '@root/design-system/primitives/DsButton.vue'
import DsButtonArrow from '@root/design-system/primitives/DsButtonArrow.vue' import DsButtonArrow from '@root/design-system/primitives/DsButtonArrow.vue'
import orchestre_img from '@/assets/img/illustrations/orchestre_1.jpg'
import ppt_img from '@/assets/img/illustrations/map_idf.jpg' import ppt_img from '@/assets/img/illustrations/map_idf.jpg'
import DsCard from '@root/design-system/components/DsCard.vue' import DsCard from '@root/design-system/components/DsCard.vue'
@@ -269,11 +305,35 @@
.remonter_concert_list { .remonter_concert_list {
transform: translateY(-170px); 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: -170px;
}
.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_wp { .theme_ppt_wp {
margin-bottom: 50px; margin-bottom: 50px;
// 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: -170px;
} }
.theme_ppt { .theme_ppt {
display: grid; display: grid;
@@ -281,6 +341,7 @@
&--img { &--img {
grid-row: 1; grid-row: 1;
grid-column: 1; grid-column: 1;
max-height: 400px;
} }
&--content { &--content {
grid-row: 1; grid-row: 1;
@@ -299,6 +360,9 @@
} }
} }
//========================
// TOUS A L'ORCHESTRE
//========================
.theme_tao { .theme_tao {
margin-bottom: 50px; margin-bottom: 50px;
@@ -379,14 +443,13 @@
width: clamp(360px, 28vw, 560px); width: clamp(360px, 28vw, 560px);
} }
} }
} }
} }
//========================
// MAGAZINE
//========================
.theme_mag { .theme_mag {

View File

@@ -89,7 +89,7 @@
</div> </div>
</div> </div>
</section> </section>
</PageSection> </PageSection>
</template> </template>
</div> </div>
</template> </template>
@@ -101,26 +101,28 @@
const route = useRoute() const route = useRoute()
////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////
// RÉCUPÉRATION DU CONTENU // RÉCUPÉRATION DU CONTENU STRAPI
////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////
const artisteSlug = computed(() => String(route.params.id || '')) const artisteSlug = computed(() => String(route.params.id || ''))
const populate = { const populate = {
image_illustration_artiste_ondif: true, image_illustration_artiste_ondif: true,
postes_artiste_ondif: true, postes_artiste_ondif: true,
} }
const filters = computed(() => ({ const filters = computed(() => ({
slug_artiste_ondif: { slug_artiste_ondif: {
$eq: artisteSlug.value, $eq: artisteSlug.value,
}, },
})) }))
const { artistes, pending, error } = useArtistes({ const { items: artistes, pending, error } = useStrapi(
locale: 'fr-FR', "/api/__strapi__/artistes",
populate, {
filters, locale: "fr-FR",
limit: 1, populate,
}) filters,
limit: 1,
}
)
const artiste = computed(() => artistes.value?.[0] || {}) const artiste = computed(() => artistes.value?.[0] || {})

View File

@@ -115,12 +115,15 @@
}, },
})) }))
const { artistesinvitees, pending, error } = useArtistesInvitees({ const { items: artistesinvitees, pending, error } = useStrapi(
locale: 'fr-FR', "/api/__strapi__/artistesinvitees",
populate, {
filters, locale: "fr-FR",
limit: 1, populate,
}) filters,
limit: 1,
}
)
const artiste = computed(() => artistesinvitees.value?.[0] || {}) const artiste = computed(() => artistesinvitees.value?.[0] || {})

View File

@@ -145,16 +145,19 @@
//-------------------- //--------------------
// DONNÉES POUR LES ARTISTES // DONNÉES POUR LES ARTISTES
//-------------------- //--------------------
const { artistesinvitees, pending, error } = useArtistesInvitees({ const { items: artistesinvitees, pending, error } = useStrapi(
locale: "fr-FR", "/api/__strapi__/artistesinvitees",
sort: "nom_artiste_invite:asc", {
populate: { locale: "fr-FR",
saisons_artiste_invite: true, sort: "nom_artiste_invite:asc",
image_illustration_artiste_invite: true, populate: {
postes_artiste_invite: true, saisons_artiste_invite: true,
}, image_illustration_artiste_invite: true,
filters: artistesFilters, postes_artiste_invite: true,
}) },
filters: artistesFilters,
}
)
const artistesDisplay = computed(() => { const artistesDisplay = computed(() => {
return (artistesinvitees.value || []).map((artiste) => ({ return (artistesinvitees.value || []).map((artiste) => ({

View File

@@ -1,51 +1,474 @@
<template> <template>
<div> <div>
<PageSection> <!-- ================== -->
<DsHeading as="h2" tone="invert" textcase="uppercase" class="programme_titre"> <!-- FILS D'ARIANE -->
PROGRAMME <!-- ================== -->
</DsHeading> <PageSection tone="" content-size="default" class="breadcrum_wp">
<DsText as="p"> <Breadcrumb/>
Créé en 1974, lOrchestre national dÎle-de-France se compose de 95 musiciens engagés et passionnés. Notre formation symphonique propose de nombreux concerts, spectacles et ateliers musicaux sur lensemble du territoire francilien. Notre devise : porter la musique classique partout et pour tous ! Programmation, actions éducatives, initiatives culturelles, toute lactivité de lOrchestre exprime ses valeurs et les missions qui laniment. </PageSection>
</DsText>
</Pagesection> <!-- ================== -->
<!-- EN-TêTE -->
<PageSection :content=false> <!-- ================== -->
<Decalage tone="dark" title-tone="invert" position="left" button-tone="invert" ensavoirplus-target="texte_cache"> <section class="fiche_header_wp">
<template #title> <div class="fiche_header_wp_gauche"></div>
La Région Île-de-France, le territoire de lOrchestre
</template> <div class="fiche_header_inner">
<DsText as="p" tone="invert" > <div class="fiche_header_titres">
LOrchestre national dÎle-de-France se déploie sur les 8 départements de la région parisienne, pour amener la musique classique auprès de publics variés. Il se produit dans les salles de spectacle et les théâtres dÎle-de-France comme dans les lieux dépourvus doffre culturelle. Cest ainsi que ses musiciens investissent régulièrement certains endroits atypiques tels que les hôpitaux, les usines ou les centres pénitentiaires. <div>
</DsText>s <DsHeading as="h1" tone="default" textcase="uppercase" class="concert-card__title">
</Decalage> {{ missions?.header_titre }}
</Pagesection> </DsHeading>
</div>
<DsText as="p" align="justify">
{{ missions?.header_text }}
</DsText>
</div>
<div class="fiche_header_img">
<DsMedia
v-if="missions?.image_illustration_header?.url"
:src="missions.image_illustration_header.url"
:alt="missions.image_illustration_header.alternativeText || ''"
fit="contain"
ratio="square"
/>
<div v-else class="img_placeholder" aria-hidden="true" />
</div>
</div>
<div class="fiche_header_wp_droite"></div>
</section>
<!-- ================== -->
<!-- PARTIE 1 -->
<!-- ================== -->
<PageSection tone="" content-size="default" padded_size="md" class="fiche_description">
<SectionContent v-if="missions?.partie_1" class="description_wp">
<StrapiBlocksConvert :blocks="missions.partie_1" />
</SectionContent>
</PageSection>
<!-- ================== -->
<!-- decalage_gauche 1 -->
<!-- ================== -->
<PageSection :content="false">
<Decalage tone="dark" title-tone="invert" position="left" button-tone="invert">
<template #title>
{{ missions?.decalage_gauche_1?.decalage_titre }}
</template>
<DsText as="p" tone="invert" align="justify">
{{ missions?.decalage_gauche_1?.decalage_texte }}
</DsText>
</Decalage>
</PageSection>
<!-- ================== -->
<!-- PARTIE 2 -->
<!-- ================== -->
<PageSection tone="" content-size="default" padded_size="md" class="fiche_description">
<SectionContent v-if="missions?.partie_2" class="description_wp">
<StrapiBlocksConvert :blocks="missions.partie_2" />
</SectionContent>
</PageSection>
<!-- ================== -->
<!-- decalage_droite_2 -->
<!-- ================== -->
<PageSection :content="false">
<Decalage tone="brandreverse" title-tone="invert" position="right" button-tone="invert">
<template #title>
{{ missions?.decalage_droite_2?.decalage_titre }}
</template>
<DsText as="p" align="justify">
{{ missions?.decalage_droite_2?.decalage_texte }}
</DsText>
</Decalage>
</PageSection>
<!-- ================== -->
<!-- PARTIE 3 -->
<!-- ================== -->
<PageSection tone="" content-size="default" padded_size="md" class="fiche_description">
<SectionContent v-if="missions?.partie_3" class="description_wp">
<StrapiBlocksConvert :blocks="missions.partie_3" />
</SectionContent>
</PageSection>
<!-- ================== -->
<!-- decalage_droite_clic_4 -->
<!-- ================== -->
<PageSection :content="false">
<Decalage tone="brand" title-tone="invert" position="right" button-tone="invert" ensavoirplus-target="texte_cache">
<template #title>
{{ missions?.decalage_droite_clic_4?.decalage_titre }}
</template>
<DsText as="p" tone="invert" align="justify">
{{ missions?.decalage_droite_clic_4?.decalage_texte }}
</DsText>
</Decalage>
</PageSection>
<PageSection> <PageSection>
<div id="texte_cache" class="decalage_ensavoirplus--hidden">Texte caché</div> <div id="texte_cache" class="decalage_ensavoirplus--hidden">Texte caché</div>
</Pagesection> </PageSection>
<PageSection :content=false> <!-- ================== -->
<Decalage tone="brandreverse" " title-tone="invert" position="right"> <!-- L'ORCHESTRE POUR LES PROS -->
<template #title> <!-- ================== -->
Studio denregistrement et location dinstruments <PageSection padded_size="lg">
</template> <SectionContent>
<DsText as="p"> <SectionTitle tone="" pad="xs">
LOrchestre national dÎle-de-France accompagne les professionnels et les amateurs dans leurs activités musicales. L'ORCHESTRE POUR LES PROS
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 ! </SectionTitle>
</DsText> </SectionContent>
</Decalage> <SectionContent>
</Pagesection> <BannierePros />
</div> </SectionContent>
</PageSection>
</div>
</template> </template>
<script setup> <script setup>
import DsHeading from '@root/design-system/primitives/DsHeading.vue' import DsHeading from '@root/design-system/primitives/DsHeading.vue'
import DsText from '@root/design-system/primitives/DsText.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 DsButton from '@root/design-system/primitives/DsButton.vue'
//--------------------
// RÉCUPÉRATION DES DONNÉES STRAPI
//--------------------
const { items: mission, pending, error, refresh } = useStrapi(
"/api/__strapi__/missions",
{ locale: "fr-FR",
populate: {
decalage_gauche_1: true,
decalage_droite_2: true,
decalage_gauche_3: true,
decalage_droite_clic_4: true,
image_illustration_header: true,
},
}
)
const missions = computed(() => mission.value?.[0] || null)
</script> </script>
<style> <style lang="scss">
</style>
.breadcrum_wp {
padding-top: 30px;
}
.fiche_header_wp {
display: grid;
justify-content: center;
padding-bottom: 100px;
@media (min-width: 0px) and (max-width: 600px) {
grid-template-columns: 1fr;
grid-template-rows: auto 510px;
padding-top: 40px;
}
@media (min-width: 600px) {
grid-template-columns: minmax(10px, 10px) 580px 0px;
grid-template-rows: 40px 380px;
}
@media (min-width: 700px) {
grid-template-columns: minmax(10px, 10px) 660px 0px;
grid-template-rows: 40px 380px;
}
@media (min-width: 800px) {
grid-template-columns: minmax(10px, 10px) auto minmax(10px, 10px);
grid-template-rows: 40px 340px;
}
@media (min-width: 900px) {
grid-template-columns: minmax(10px, 10px) 860px minmax(10px, 10px);
grid-template-rows: 40px 400px;
}
@media (min-width: 1000px) {
grid-template-columns: minmax(20px, auto) 950px minmax(10px, auto);
grid-template-rows: 40px 400px;
}
@media (min-width: 1100px) {
grid-template-columns: minmax(20px, auto) 1020px minmax(20px, auto);
grid-template-rows: 40px 400px;
}
@media (min-width: 1200px) {
grid-template-columns: minmax(20px, auto) 1100px minmax(20px, auto);
grid-template-rows: 40px 400px;
}
@media (min-width: 1300px) {
grid-template-columns: minmax(20px, auto) 1200px minmax(20px, auto);
grid-template-rows: 40px 400px;
}
@media (min-width: 1400px) {
grid-template-columns: minmax(20px, auto) 1300px minmax(20px, auto);
grid-template-rows: 40px 400px;
}
@media (min-width: 1500px) {
grid-template-columns: minmax(20px, auto) 1400px minmax(20px, auto);
grid-template-rows: 40px 400px;
}
}
.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;
}
}
.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/3;
}
@media (min-width: 600px) {
grid-column: 2;
grid-row: 1/3;
}
display: grid;
@media (min-width: 0px) and (max-width: 600px) {
grid-template-columns: 1fr;
grid-template-rows: auto 510px;
}
@media (min-width: 600px) {
width: 575px;
grid-template-columns: 4fr 0.5fr 3.5fr;
grid-template-rows: 40px 380px;
}
@media (min-width: 700px) {
width: 675px;
grid-template-columns: 4fr 0.5fr 3.5fr;
grid-template-rows: 40px 380px;
}
@media (min-width: 800px) {
width: 780px;
grid-template-columns: 4fr 0.5fr 3.5fr;
grid-template-rows: 40px 340px;
}
@media (min-width: 900px) {
width: 860px;
grid-template-columns: 4fr 0.5fr 3.5fr;
grid-template-rows: 40px 400px;
}
@media (min-width: 1000px) {
width: 950px;
grid-template-columns: 4fr 0.5fr 3.5fr;
grid-template-rows: 40px 400px;
}
@media (min-width: 1100px) {
width: 1020px;
grid-template-columns: 4fr 0.5fr 3.5fr;
grid-template-rows: 40px 400px;
}
@media (min-width: 1200px) {
width: 1100px;
grid-template-columns: 4fr 0.5fr 3.5fr;
grid-template-rows: 40px 400px;
}
@media (min-width: 1300px) {
width: 1200px;
grid-template-columns: 4fr 0.5fr 3.5fr;
grid-template-rows: 40px 400px;
}
@media (min-width: 1400px) {
width: 1300px;
grid-template-columns: 4fr 0.5fr 3.5fr;
grid-template-rows: 40px 400px;
}
@media (min-width: 1500px) {
width: 1400px;
grid-template-columns: 4fr 0.5fr 3.5fr;
grid-template-rows: 40px 400px;
}
@media (min-width: 1600px) {
width: 1400px;
grid-template-columns: 4fr 0.5fr 3.5fr;
grid-template-rows: 40px 400px;
}
@media (min-width: 1700px) {
width: 1400px;
grid-template-columns: 4fr 0.5fr 3.5fr;
grid-template-rows: 40px 400px;
}
@media (min-width: 1800px) {
width: 1400px;
grid-template-columns: 4fr 0.5fr 3.5fr;
grid-template-rows: 40px 400px;
}
}
.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;
max-width: 475px;
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 / 3;
padding-left: 10px;
padding-right: 10px;
}
@media (min-width: 600px) {
grid-column: 3 / 5;
grid-row: 1 / 3;
}
overflow: hidden;
.ds-media {
@media (min-width: 600px) {
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);
}
.fiche_description > * {
max-width: 570px;
display: flex;
flex-direction: column;
}
.fiche_description {
.page-section--inner {
@media (max-width: 599px) {
padding-left: 10px;
padding-right: 10px;
}
}
}
</style>

View File

@@ -3,7 +3,7 @@
<!-- ================== --> <!-- ================== -->
<!-- Fond noir --> <!-- Fond noir -->
<!-- ================== --> <!-- ================== -->
<PageSection tone="dark" content-size="default" class="theme_bandeau--grid"> <PageSection tone="bleu" content-size="default" class="theme_bandeau--grid">
<SectionContent pad="xs" class="theme_bandeau--grid--left"> <SectionContent pad="xs" class="theme_bandeau--grid--left">
<SectionTitle tone="invert" pad=""> <SectionTitle tone="invert" pad="">
LES MUSICIENS LES MUSICIENS
@@ -145,16 +145,19 @@
//-------------------- //--------------------
// DONNÉES POUR LES ARTISTES // DONNÉES POUR LES ARTISTES
//-------------------- //--------------------
const { artistes, pending, error } = useArtistes({ const { items: artistes, pending, error } = useStrapi(
locale: "fr-FR", "/api/__strapi__/artistes",
sort: "ordre_artiste_ondif:asc", {
populate: { locale: "fr-FR",
saisons_artiste_ondif: true, sort: "ordre_artiste_ondif:asc",
image_illustration_artiste_ondif: true, populate: {
postes_artiste_ondif: true, saisons_artiste_ondif: true,
}, image_illustration_artiste_ondif: true,
filters: artistesFilters, postes_artiste_ondif: true,
}) },
filters: artistesFilters,
}
)
const artistesDisplay = computed(() => { const artistesDisplay = computed(() => {
return (artistes.value || []).map((artiste) => ({ return (artistes.value || []).map((artiste) => ({

View File

@@ -1,7 +1,8 @@
<template> <template>
<div class="ds-media" :class="`ds-media--${ratio}`"> <div class="ds-media" :class="[`ds-media--${ratio}`]">
<img <img
class="ds-media__img" class="ds-media__img"
:class="[`ds-media__img--${fit}`]"
:src="src" :src="src"
:alt="alt" :alt="alt"
loading="lazy" loading="lazy"
@@ -14,25 +15,29 @@
defineProps({ defineProps({
src: { type: String, required: true }, src: { type: String, required: true },
alt: { type: String, default: '' }, alt: { type: String, default: '' },
fit: { type: String, default: 'cover' },
ratio: { type: String, default: '' }, // 16-9 / 4-3 / square ratio: { type: String, default: '' }, // 16-9 / 4-3 / square
}) })
</script> </script>
<style lang="scss"> <style lang="scss">
.ds-media { .ds-media {
width: 100%;
background: rgba(0,0,0,0.04);
overflow: hidden;
&--16-9 { aspect-ratio: 16 / 9; }
&--4-3 { aspect-ratio: 4 / 3; }
&--3-4 { aspect-ratio: 3 / 4; }
&--square { aspect-ratio: 1 / 1; }
.ds-media__img {
width: 100%; width: 100%;
height: 100%; background: rgba(0,0,0,0.04);
object-fit: cover; overflow: hidden;
display: block; &--16-9 { aspect-ratio: 16 / 9; }
&--4-3 { aspect-ratio: 4 / 3; }
&--3-4 { aspect-ratio: 3 / 4; }
&--square { aspect-ratio: 1 / 1; }
.ds-media__img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
&--cover { object-fit:cover; }
&--contain { object-fit:contain; }
}
} }
}
</style> </style>

View File

@@ -8,6 +8,7 @@
`ds-text--${props.weight || resolvedWeight}`, //si la classe weight n'est pas donné dans la classe on prend la mapping par défaut `ds-text--${props.weight || resolvedWeight}`, //si la classe weight n'est pas donné dans la classe on prend la mapping par défaut
`ds-text--${props.spacing || resolvedspacing}`, `ds-text--${props.spacing || resolvedspacing}`,
`ds-text--${props.tone}`, `ds-text--${props.tone}`,
`ds-text--${props.align}`,
props.clamp ? `ds-text--clamp_${props.clamp}` : '', props.clamp ? `ds-text--clamp_${props.clamp}` : '',
]" ]"
> >
@@ -25,6 +26,7 @@
spacing: { type: String, default: '' }, spacing: { type: String, default: '' },
tone: { type: String, default: 'default' }, // default/muted/invert tone: { type: String, default: 'default' }, // default/muted/invert
weight: { type: String, default: 'regular' }, // regular/medium weight: { type: String, default: 'regular' }, // regular/medium
align: { type: String, default: '' },
clamp: { type: Number, default: undefined }, // nombre de lignes du contenu clamp: { type: Number, default: undefined }, // nombre de lignes du contenu
}) })
@@ -113,6 +115,10 @@
&--bleu_fonce { color: var(--c-bleu_fonce); } &--bleu_fonce { color: var(--c-bleu_fonce); }
&--bleu_clair { color: var(--c-bleu_clair); } &--bleu_clair { color: var(--c-bleu_clair); }
&--justify {
text-align: justify;
}
// clampé sur 2 lignes pour les cartes (résumé, programme, etc.). // clampé sur 2 lignes pour les cartes (résumé, programme, etc.).
// Si ça dépasse, ça coupe proprement. Pour du texte de description qui doit tenir dans un cadre, mais qui a été écrit trop long, pour ne pas casser le design du site, on va limiter l'affichage à 2 lignes. c'est pour des espace réduit. Pour ne pas casser le design de la page. J'ai presque écrit 2 lignes, je vais bientôt être censurée. // Si ça dépasse, ça coupe proprement. Pour du texte de description qui doit tenir dans un cadre, mais qui a été écrit trop long, pour ne pas casser le design du site, on va limiter l'affichage à 2 lignes. c'est pour des espace réduit. Pour ne pas casser le design de la page. J'ai presque écrit 2 lignes, je vais bientôt être censurée.
&--clamp_3 { &--clamp_3 {

View File

@@ -9,12 +9,13 @@
/* Marque / accent (ex: rouge ONDIF) */ /* Marque / accent (ex: rouge ONDIF) */
//--c-brand_rouge: #E30613; //--c-brand_rouge: #E30613;
--c-brand_rouge: #E20018; --c-brand_rouge: #E20018;
--c-brand_rouge45: rgba(226, 0, 24, 0.45); --c-brand_rouge45: #e2001873;
--c-brand_rouge-weak: #e3061391; --c-brand_rouge-weak: #e3061391;
--c-backgroud-black: #111; --c-backgroud-black: #111;
--c-backgroud-brandreverse: #ACCFCF; --c-backgroud-brandreverse: #ACCFCF;
--c-background-blanc-casse: #FCFCFC; --c-background-blanc-casse: #FCFCFC;
--c-background-jaune: #fac020; --c-background-jaune: #fac020;
--c-background-bleu: #002b95;
/* États */ /* États */
--c-success: green; --c-success: green;

View File

@@ -0,0 +1,24 @@
import { createError, getRouterParam } from "h3"
import { createStrapiProxyHandler } from "~~/server/utils/strapiEndpoint"
const COLLECTION_MAP = {
artistes: "/api/artistes-ondifs",
artistesinvitees: "/api/artistes-invites",
concerts: "/api/concerts",
missions: "/api/mission",
mission: "/api/mission",
}
export default defineEventHandler(async (event) => {
const collection = getRouterParam(event, "collection")
const strapiPath = COLLECTION_MAP[collection]
if (!strapiPath) {
throw createError({
statusCode: 404,
statusMessage: "Unknown Strapi collection",
})
}
return createStrapiProxyHandler({ strapiPath })(event)
})