generated from gitea_admin/default
Concerts
This commit is contained in:
117
app/components/Breadcrumb.vue
Normal file
117
app/components/Breadcrumb.vue
Normal file
@@ -0,0 +1,117 @@
|
||||
<template>
|
||||
<div v-if="items.length > 1" aria-label="Fil d’Ariane" 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>
|
||||
@@ -167,7 +167,7 @@
|
||||
max-width: 210px;
|
||||
}
|
||||
@media (min-width: 300px) {
|
||||
max-width: 290px;
|
||||
max-width: 250px;
|
||||
}
|
||||
@media (min-width: 400px) {
|
||||
max-width: 390px;
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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%;
|
||||
|
||||
91
app/components/strapiconvert/StrapiBlockChildsConvert.vue
Normal file
91
app/components/strapiconvert/StrapiBlockChildsConvert.vue
Normal 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>
|
||||
222
app/components/strapiconvert/StrapiBlocksConvert.vue
Normal file
222
app/components/strapiconvert/StrapiBlocksConvert.vue
Normal 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>
|
||||
Reference in New Issue
Block a user