This commit is contained in:
2026-02-16 07:59:52 +01:00
parent 1fc267faa8
commit b8b8e53f07
70 changed files with 3088 additions and 272 deletions

View File

@@ -0,0 +1,117 @@
<template>
<div v-if="items.length > 1" aria-label="Fil dAriane" class="breadcrumb">
<ul class="breadcrumb__list">
<li v-for="(item, i) in items" :key="item.to" class="breadcrumb__item">
<NuxtLink v-if="i < items.length - 1" :to="item.to">
<img
v-if="i === 0"
src="/img/icones/house-grey.svg"
alt="Accueil"
class="breadcrumb__home-icon"
/>
<span v-else>{{ item.label }}</span>
</NuxtLink>
<span v-else aria-current="page">{{ item.label }}</span>
</li>
</ul>
</div>
</template>
<script setup>
const props = defineProps({
currentLabel: { type: String, default: '' } // utile pour les pages dynamiques
})
const route = useRoute()
const labelMap = {
concerts: 'Concerts',
agenda: 'Agenda',
saison: 'Saison',
orchestre: "L'Orchestre",
professionnels: "Professionnels"
}
function humanize(segment) {
return segment
.replace(/-/g, ' ')
.replace(/\b\w/g, (m) => m.toUpperCase())
}
const items = computed(() => {
const parts = route.path.split('/').filter(Boolean)
const crumbs = [{ to: '/', label: 'Accueil' }]
let acc = ''
parts.forEach((part, index) => {
acc += `/${part}`
const isLast = index === parts.length - 1
const label = isLast && props.currentLabel
? props.currentLabel
: (labelMap[part] || humanize(decodeURIComponent(part)))
crumbs.push({ to: acc, label })
})
return crumbs
})
</script>
<style lang="scss">
.breadcrumb {
padding-top: 10px;
padding-bottom: 10px;
font-size: 15px;
font-family: var(--font-roboto);
font-weight: var(--fw-extralight);
color: #6D798A;
position: relative;
z-index: 1;
@media (min-width: 0px) {
padding-left: 20px;
}
@media (min-width: 600px) {
padding-left: 20px;
}
@media (min-width: 700px) {
padding-left: 20px;
}
}
.breadcrumb__list {
display: flex;
flex-wrap: wrap;
gap: 8px;
list-style: none;
padding: 0;
}
.breadcrumb__item { display: inline-flex; align-items: center; }
.breadcrumb a {
display: inline-flex;
align-items: center;
cursor: pointer;
pointer-events: auto;
}
.breadcrumb__item:not(:last-child)::after {
content: "";
display: inline-block;
width: 11px;
height: 11px;
margin-left: 8px;
background: url('/img/icones/angle-right-grey.svg') no-repeat center / contain;
vertical-align: middle;
position: relative;
top: -1px; /* ajuste entre 0 et 2px selon ton rendu */
pointer-events: none;
}
.breadcrumb__home-icon {
width: 14px;
height: 14px;
display: inline-block;
vertical-align: middle;
margin-bottom: 4px;
}
</style>

View File

@@ -167,7 +167,7 @@
max-width: 210px;
}
@media (min-width: 300px) {
max-width: 290px;
max-width: 250px;
}
@media (min-width: 400px) {
max-width: 390px;

View File

@@ -15,7 +15,7 @@
<!-- Meta : date + lieu -->
<div class="concert-card__meta">
<DsHeading as="h5" tone="default">
{{ venue }}
{{ lieu }}
</DsHeading>
<DsHeading as="h6" tone="default">
<time :datetime="dateISO">{{ dateLabel }}</time>
@@ -29,8 +29,8 @@
<!-- Actions -->
<div class="concert-card__actions">
<DsButtonArrow :to="`/concerts/${id}`" variant="secondary">
Réserver
<DsButtonArrow :to="`${href}`" variant="secondary">
Découvrir
</DsButtonArrow>
</div>
</div>
@@ -49,12 +49,13 @@
defineProps({
id: { type: [String, Number], required: true },
title: { type: String, required: true },
venue: { type: String, required: true },
lieu: { type: String, required: true },
dateISO: { type: String, required: true }, // ex: "2026-01-15T20:00:00+01:00"
dateLabel: { type: String, required: true }, // ex: "Jeu. 15 jan. 2026 — 20h"
description: { type: String, default: '' },
imageUrl: { type: String, default: '' },
imageAlt: { type: String, default: '' },
href: { type: String, default: '' },
})
</script>

View File

@@ -1,30 +1,47 @@
<!-- app/components/concert/ConcertCardList.vue -->
<template>
<div class="concert-card-list">
<div
class="concert-card-list"
:class="{
'concert-card-list--highlight-first': highlightFirst,
'concert-card-list--limit-cards': limitCardsOnBreakpoint,
}"
>
<slot />
</div>
</template>
<script setup>
defineProps({
highlightFirst: { type: Boolean, default: true },
limitCardsOnBreakpoint: { type: Boolean, default: true },
})
</script>
<style lang="scss">
.concert-card-list {
display: flex;
flex-wrap: wrap;
gap: var(--gap-cards);
justify-content: center;
.concert-card {
max-width: 452px;
}
}
// Afficher seulement 1 cards < 600px
@media (max-width: 599px) {
.concert-card-list > .concert-card:nth-child(2) {
.concert-card-list.concert-card-list--limit-cards > .concert-card:nth-child(2) {
display: none;
}
.concert-card-list > .concert-card:nth-child(3) {
.concert-card-list.concert-card-list--limit-cards > .concert-card:nth-child(3) {
display: none;
}
}
// Afficher seulement 2 cards < 900px
@media (max-width: 899px) {
.concert-card-list > .concert-card:nth-child(3) {
.concert-card-list.concert-card-list--limit-cards > .concert-card:nth-child(3) {
display: none;
}
}
@@ -40,7 +57,7 @@
.concert-card-list > .concert-card {
flex: 1 1 260px;
}
.concert-card-list > .concert-card:first-child {
.concert-card-list.concert-card-list--highlight-first > .concert-card:first-child {
flex: 2 1 280px;
}
}
@@ -48,7 +65,7 @@
.concert-card-list > .concert-card {
flex: 1 1 280px;
}
.concert-card-list > .concert-card:first-child {
.concert-card-list.concert-card-list--highlight-first > .concert-card:first-child {
flex: 2 1 300px;
}
}
@@ -56,7 +73,7 @@
.concert-card-list > .concert-card {
flex: 1 1 280px;
}
.concert-card-list > .concert-card:first-child {
.concert-card-list.concert-card-list--highlight-first > .concert-card:first-child {
flex: 2 1 300px;
}
}
@@ -65,7 +82,7 @@
flex: 1 1 260px;
}
.concert-card-list > .concert-card:first-child {
.concert-card-list.concert-card-list--highlight-first > .concert-card:first-child {
flex: 2 1 300px;
}
}
@@ -75,7 +92,7 @@
flex: 1 1 280px;
}
.concert-card-list > .concert-card:first-child {
.concert-card-list.concert-card-list--highlight-first > .concert-card:first-child {
flex: 2 1 340px;
}
}
@@ -85,7 +102,7 @@
flex: 1 1 300px;
}
.concert-card-list > .concert-card:first-child {
.concert-card-list.concert-card-list--highlight-first > .concert-card:first-child {
flex: 2 1 380px;
}
}
@@ -95,7 +112,7 @@
flex: 1 1 320px;
}
.concert-card-list > .concert-card:first-child {
.concert-card-list.concert-card-list--highlight-first > .concert-card:first-child {
flex: 2 1 400px;
}
}
@@ -105,7 +122,7 @@
flex: 1 1 340px;
}
.concert-card-list > .concert-card:first-child {
.concert-card-list.concert-card-list--highlight-first > .concert-card:first-child {
flex: 2 1 440px;
}
}
@@ -116,7 +133,7 @@
flex: 1 1 360px;
}
//règle spécifique après la règle générale
.concert-card-list > .concert-card:first-child {
.concert-card-list.concert-card-list--highlight-first > .concert-card:first-child {
flex: 2 1 480px;
}
}

View File

@@ -10,7 +10,9 @@
<template>
<HeaderNav burger-color="hamburger_black">
<template #logo>
<NuxtImg :src="logoDefault" :alt="brand.logoAlt" class="logo-img" />
<NuxtLink to="/" aria-label="Accueil">
<NuxtImg :src="logoDefault" :alt="brand.logoAlt" class="logo-img" />
</NuxtLink>
</template>
<template #agenda-icon>
@@ -44,4 +46,4 @@
}
</style>
</style>

View File

@@ -3,15 +3,15 @@
<div class="height_10"></div>
<ul class="header_navigation_topbar" aria-label="Language selector">
<li class="header_nav_topbar_item">
<li class="header_nav_topbar_item" :class="{ 'is-active': isPro }">
Professionnels
<ul class="header_nav_topbar_submenu">
<li class="header_nav_topbar_submenu_item"><NuxtLink to="/">Programmer l'Orchestre</NuxtLink></li>
<li class="header_nav_topbar_submenu_item"><NuxtLink to="/">Le studio et les espaces</NuxtLink></li>
<li class="header_nav_topbar_submenu_item"><NuxtLink to="/">Louer des instruments</NuxtLink></li>
<li class="header_nav_topbar_submenu_item"><NuxtLink to="/">Recrutement / Concours</NuxtLink></li>
<li class="header_nav_topbar_submenu_item"><NuxtLink to="/">Espace candidats</NuxtLink></li>
<li class="header_nav_topbar_submenu_item"><NuxtLink to="/">Presse</NuxtLink></li>
<li class="header_nav_topbar_submenu_item"><NuxtLink to="/professionnels/programmer-orchestre">Programmer l'Orchestre</NuxtLink></li>
<li class="header_nav_topbar_submenu_item"><NuxtLink to="/professionnels/studio">Le studio et les espaces</NuxtLink></li>
<li class="header_nav_topbar_submenu_item"><NuxtLink to="/professionnels/louer">Louer des instruments</NuxtLink></li>
<li class="header_nav_topbar_submenu_item"><NuxtLink to="/professionnels/recrutement">Recrutement / Concours</NuxtLink></li>
<li class="header_nav_topbar_submenu_item"><NuxtLink to="/professionnels/candidats">Espace candidats</NuxtLink></li>
<li class="header_nav_topbar_submenu_item"><NuxtLink to="/professionnels/presse">Presse</NuxtLink></li>
</ul>
</li>
<li class="header_nav_topbar_item header_nav_lang">
@@ -32,55 +32,56 @@
<nav class="header_nav_cont" aria-label="Primary navigation">
<!-- Desktop nav -->
<ul class="header_nav header_nav--desktop">
<li class="header_nav_item">
<li class="header_nav_item" :class="{ 'is-active': isOrchestre }">
L'Orchestre
<ul class="header_nav_sub_menu">
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Nos missions</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Direction musicale</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Les musiciens</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Les artistes invités</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Discographie</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Nos partenaires</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Nous soutenir</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/orchestre/missions">Nos missions</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/orchestre/direction">Direction musicale</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/orchestre/musiciens">Les musiciens</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/orchestre/artistes-invitees">Les artistes invités</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/orchestre/discographie">Discographie</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/orchestre/partenaires">Nos partenaires</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/mecenat/soutenir">Nous soutenir</NuxtLink></li>
</ul>
</li>
<li class="header_nav_item">
<li class="header_nav_item" :class="{ 'is-active': isConcerts }">
Concerts
<ul class="header_nav_sub_menu">
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Saison</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Jeune public</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Concert mode d'emploi</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/">ONDIF MAG</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/">ONDIF LIVE !</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/concerts/saison">Saison</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/concerts/jeune-public">Jeune public</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/concerts/mode-emploi">Concert mode d'emploi</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/concerts/mag">ONDIF MAG</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/concerts/live">ONDIF LIVE !</NuxtLink></li>
</ul>
</li>
<li class="header_nav_item">
<li class="header_nav_item" :class="{ 'is-active': isMediation }">
Éducation et médiation
<ul class="header_nav_sub_menu">
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Petite enfance</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Scolaires</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Champ social</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Insertion professionnelle</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Pratiques amateurs</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Ressources pédagogiques</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/social">Champ social</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/mediation/insertion-pro">Insertion professionnelle</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/mediation/amateurs">Pratiques amateurs</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/mediation/ressources-pedagogiques">Ressources pédagogiques</NuxtLink></li>
</ul>
</li>
<li class="header_nav_item">
<li class="header_nav_item" :class="{ 'is-active': isMecenat }">
Mécénat
<ul class="header_nav_sub_menu">
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Entreprises</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Les projets</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Particuliers</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Ils nous font confiance</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/mecenat/soutenir">Nous soutenir</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/mecenat/entreprises">Entreprises</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/mecenat/projets">Les projets</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/mecenat/particuliers">Particuliers</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/mecenat/mecenes">Ils nous font confiance</NuxtLink></li>
</ul>
</li>
<li class="header_nav_item header_nav_icones">
<div class="">
<NuxtLink to="/agenda">
<NuxtLink to="/concerts/agenda">
<div class="nav_icone">
<div class="nav_icone_img nav_icone_img--agenda">
<!-- ICÔNE injectée -->
@@ -91,7 +92,7 @@
</NuxtLink>
</div>
<div class=" padding_top_1">
<NuxtLink to="/agenda">
<NuxtLink to="https://orchestre-ile.com/shop" external target="_blank" rel="noopener noreferrer">
<div class="nav_icone">
<div class="nav_icone_img nav_icone_img--ticket">
<!-- ICÔNE injectée -->
@@ -124,7 +125,7 @@
<!-- Mobile icons -->
<div class="header_nav header_nav--mobile-icons">
<div class="header_nav_item">
<NuxtLink to="/agenda">
<NuxtLink to="/concerts/agenda">
<div class="nav_icone">
<div class="nav_icone_img nav_icone_img--agenda">
<!-- ICÔNE injectée -->
@@ -136,7 +137,7 @@
</div>
<div class="header_nav_item padding_top_1">
<NuxtLink to="/agenda">
<NuxtLink to="https://orchestre-ile.com/shop" external target="_blank" rel="noopener noreferrer">
<div class="nav_icone">
<div class="nav_icone_img nav_icone_img--ticket">
<!-- ICÔNE injectée -->
@@ -157,33 +158,33 @@
<ul class="header_drawer_inner">
<li
class="header_drawer_link"
:class="{ 'is-open': activeDrawer === 'orchestre' }"
:class="{ 'is-open': activeDrawer === 'orchestre','is-active': isOrchestre }"
@click="toggleDrawer('orchestre')"
>
L'Orchestre
<ul class="header_drawer_sub_menu">
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Nos missions</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Direction musicale</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Les musiciens</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Les artistes invités</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Discographie</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Nos partenaires</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Nous soutenir</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/orchestre/missions">Nos missions</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/orchestre/direction">Direction musicale</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/orchestre/musiciens">Les musiciens</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/orchestre/artistes-invitees">Les artistes invités</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/orchestre/discographie">Discographie</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/orchestre/partenaires">Nos partenaires</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/mecenat/soutenir">Nous soutenir</NuxtLink></li>
</ul>
</li>
<li
class="header_drawer_link"
:class="{ 'is-open': activeDrawer === 'concerts' }"
:class="{ 'is-open': activeDrawer === 'concerts','is-active': isConcerts }"
@click="toggleDrawer('concerts')"
>
Concerts
<ul class="header_drawer_sub_menu">
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Saison</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Jeune public</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Concert mode d'emploi</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">ONDIF MAG</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">ONDIF LIVE !</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/concerts/saison">Saison</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/concerts/jeune-public">Jeune public</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/concerts/mode-emploi">Concert mode d'emploi</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/concerts/mag">ONDIF MAG</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/concerts/live">ONDIF LIVE !</NuxtLink></li>
</ul>
</li>
@@ -194,12 +195,12 @@
>
Éducation et médiation
<ul class="header_drawer_sub_menu">
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Petite enfance</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Scolaires</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Champ social</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Insertion professionnelle</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Pratiques amateurs</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Ressources pédagogiques</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/social">Champ social</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/mediation/insertion-pro">Insertion professionnelle</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/mediation/amateurs">Pratiques amateurs</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/mediation/ressources-pedagogiques">Ressources pédagogiques</NuxtLink></li>
</ul>
</li>
@@ -210,20 +211,21 @@
>
Mécénat
<ul class="header_drawer_sub_menu">
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Entreprises</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Les projets</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Particuliers</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Ils nous font confiance</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/mecenat/soutenir">Nous soutenir</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/mecenat/entreprises">Entreprises</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/mecenat/projets">Les projets</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/mecenat/particuliers">Particuliers</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/mecenat/mecenes">Ils nous font confiance</NuxtLink></li>
</ul>
</li>
<li class="icon_mobile">
<NuxtLink class="header_drawer_link icon_mobile_agenda" to="/agenda" @click="close">
<NuxtLink class="header_drawer_link icon_mobile_agenda" to="/concerts/agenda" @click="close">
<!-- ICÔNE injectée -->
<slot name="mobile_agenda_icon" />
</NuxtLink>
<NuxtLink class="header_drawer_link icon_mobile_ticket" to="/agenda" @click="close">
<NuxtLink class="header_drawer_link icon_mobile_ticket" to="https://orchestre-ile.com/shop" external target="_blank" rel="noopener noreferrer" @click="close">
<!-- ICÔNE injectée -->
<slot name="mobile_ticket" />
</NuxtLink>
@@ -241,12 +243,16 @@
<script setup>
import { ref } from 'vue'
import { useRoute } from 'vue-router'
const route = useRoute()
import { watch } from 'vue'
defineProps({
burgerColor: { type: String, default: 'hamburger_black' }
})
/////////////////////////////////
// MENU MOBILE
/////////////////////////////////
const isOpen = ref(false)
const activeDrawer = ref(null)
const toggle = () => (isOpen.value = !isOpen.value)
@@ -256,11 +262,38 @@
}
// ✅ ferme automatiquement le mobile drawer si on navigue
const route = useRoute()
watch(() => route.fullPath, () => {
close()
activeDrawer.value = null
})
/////////////////////////////////
// MENU ACTIF
/////////////////////////////////
// L'Orchestre
const isOrchestre = computed(() =>
route.path.startsWith('/orchestre')
)
// Concerts
const isConcerts = computed(() =>
route.path.startsWith('/concerts')
)
// Éducation et médiation
const isMediation = computed(() =>
route.path.startsWith('/mediation')
)
// Mécénat
const isMecenat = computed(() =>
route.path.startsWith('/mecenat')
)
// professionnels
const isPro = computed(() =>
route.path.startsWith('/professionnels')
)
</script>
<style lang="scss">

View File

@@ -12,7 +12,8 @@
size: { type: String, default: 'default' }, // default / wide / narrow
padb : { type: String, default: '' },
padt : { type: String, default: '' },
position : { type: String, dafault : ''}
position : { type: String, dafault : ''},
overflow : { type: String, default: '' }
})
</script>
@@ -39,9 +40,6 @@
&--default {
/* mobile / small screens */
@media (max-width: 700px) {
//padding-inline: var(--page-padding-mobile);
}
@media (min-width: 0px) {
max-width: 100%;

View File

@@ -0,0 +1,91 @@
<template>
<component v-if="isText && hasTextValue && wrapTag" :is="wrapTag">
{{ textValue }}
</component>
<template v-else-if="isText && hasTextValue">
{{ textValue }}
</template>
<component v-else-if="isList" :is="listTag">
<StrapiBlockChildsConvert
v-for="(child, i) in children"
:key="i"
:node="child"
/>
</component>
<li v-else-if="isListItem">
<StrapiBlockChildsConvert
v-for="(child, i) in children"
:key="i"
:node="child"
/>
</li>
<a
v-else-if="isLink"
:href="href"
class="strapi-inline__link"
rel="noopener noreferrer"
target="_blank"
>
<StrapiBlockChildsConvert
v-for="(child, i) in children"
:key="i"
:node="child"
/>
</a>
<template v-else>
<StrapiBlockChildsConvert
v-for="(child, i) in children"
:key="i"
:node="child"
/>
</template>
</template>
<script setup>
import { computed } from 'vue'
const props = defineProps({
node: { type: Object, required: true },
})
const isText = computed(() => props.node?.type === 'text')
const isLink = computed(() => props.node?.type === 'link')
const isList = computed(() => props.node?.type === 'list')
const isListItem = computed(() => props.node?.type === 'list-item')
const children = computed(() => props.node?.children || [])
const listTag = computed(() => (
props.node?.format === 'ordered' ? 'ol' : 'ul'
))
const textValue = computed(() => (props.node?.text ?? '').toString())
const hasTextValue = computed(() => textValue.value.length > 0)
// Dans Strapi blocks, les liens peuvent être "url" ou "href" selon les versions/plugins
const href = computed(() => props.node?.url || props.node?.href || '#')
/**
* Gestion des "marks" (bold/italic/underline/...)
* Ici on choisit une stratégie simple : UN seul wrapper.
* -> si tu veux combiner plusieurs marks (bold + italic), on le fait après.
*/
const wrapTag = computed(() => {
const n = props.node || {}
if (!isText.value) return null
if (n.code) return 'code'
if (n.bold) return 'strong'
if (n.italic) return 'em'
if (n.underline) return 'u'
if (n.strikethrough) return 's'
return null
})
</script>
<style lang="scss">
</style>

View File

@@ -0,0 +1,222 @@
<template>
<div class="strapi-blocks">
<template v-for="(block, i) in blocks" :key="i">
<!-- Paragraph -->
<p v-if="block.type === 'paragraph'" class="strapi-blocks--p">
<template v-for="(child, j) in (block.children)" :key="j">
<StrapiBlockChildsConvert :node="child" />
</template>
</p>
<!-- Heading -->
<component
v-else-if="block.type === 'heading'"
:is="`h${block.level}`"
class="strapi-blocks__h"
>
<template v-for="(child, j) in (block.children)" :key="j">
<StrapiBlockChildsConvert :node="child" />
</template>
</component>
<!-- Quote -->
<blockquote
v-else-if="block.type === 'quote'"
>
<template v-for="(child, j) in (block.children)" :key="j">
<StrapiBlockChildsConvert :node="child" />
</template>
</blockquote>
<!-- Lists -->
<ul
v-else-if="block.type === 'list' && block.format === 'unordered'"
>
<li
v-for="(item, j) in normalizeListItems(block.children)"
:key="j"
>
<template v-for="(child, k) in (item.children)" :key="k">
<StrapiBlockChildsConvert :node="child" />
</template>
</li>
</ul>
<ol
v-else-if="block.type === 'list' && block.format === 'ordered'"
>
<li
v-for="(item, j) in normalizeListItems(block.children)"
:key="j"
>
<template v-for="(child, k) in (item.children)" :key="k">
<StrapiBlockChildsConvert :node="child" />
</template>
</li>
</ol>
<!-- Fallback -->
<div v-else class="strapi-blocks--unknown">
<!-- debug éventuel -->
</div>
</template>
</div>
</template>
<script setup>
import StrapiBlockChildsConvert from './StrapiBlockChildsConvert.vue'
const props = defineProps({
blocks: { type: Array, default: () => [] },
})
const normalizeListItems = (children = []) => {
const normalized = []
for (const child of children) {
if (!child || typeof child !== 'object') continue
if (child.type === 'list-item') {
normalized.push({
...child,
children: Array.isArray(child.children) ? [...child.children] : [],
})
continue
}
// Certains contenus Strapi placent une sous-liste comme sibling d'un list-item.
// On la rattache au dernier list-item pour produire un HTML imbriqué valide.
if (child.type === 'list' && normalized.length > 0) {
normalized[normalized.length - 1].children.push(child)
}
}
return normalized
}
</script>
<style lang="scss">
.strapi-blocks {
font-family: var(--font-roboto);
&--p {
font-weight: var(--fw-light);
font-size: 17px;
line-height: 22px;
margin-bottom: 5px;
}
h1 {
padding-bottom: 10px;
font-weight: var(--fw-bold);
font-size: 30px;
}
h2 {
padding-bottom: 7px;
font-weight: var(--fw-bold);
font-size: 27px;
color: var(--c-brand_rouge);
}
h3 {
padding-bottom: 5px;
font-weight: var(--fw-semibold);
font-size: 26px;
}
h4 {
padding-bottom: 3px;
font-weight: var(--fw-medium);
font-size: 22px;
}
h4 {
padding-bottom: 3px;
font-weight: var(--fw-medium);
font-size: 22px;
}
h4 {
padding-bottom: 3px;
font-weight: var(--fw-medium);
font-size: 22px;
}
a {
text-decoration: underline;
color: var(--c-brand_rouge-weak);
text-decoration-thickness: from-font;
}
ul,
ol {
list-style: none;
margin: 0 0 5px;
padding-left: 0;
}
li {
position: relative;
margin: 0;
padding-left: 23px;
margin-bottom: 5px;
}
ul > li::before {
content: "•";
position: absolute;
left: 0;
top: -7px;
width: 0.5rem;
height: 0.5rem;
/*background-image: var(--strapi-li-icon);
background-repeat: no-repeat;
background-size: contain;
background-position: center;*/
font-size: 39px;
line-height: 1;
/* color: var(--c-brand_rouge); /* couleur */
}
ol {
counter-reset: item;
}
ol > li {
counter-increment: item;
}
ol > li::before {
content: counter(item) ". ";
}
li > ul,
li > ol {
margin-top: 4px;
padding-left: 1rem;
}
li > ul > li::before {
/* background-image: var(--strapi-li-icon-nested); */
content: "◦";
top: -6px;
font-size: 30px;
line-height: 1;
color: var(--c-text); /* couleur */
}
blockquote {
border-left: 11px var(--c-text-muted) solid;
padding-left: 20px;
margin-left: 2%;
margin-bottom: 30px;
margin-top: 30px;
}
// Espace uniquement avant un titre s'il suit un bloc de contenu
&--p + &__h,
&--ul + &__h,
&--ol + &__h,
&--quote + &__h {
margin-top: 13px;
}
}
</style>