Files
wondif_vue/app/pages/professionnels/parc.vue
2026-05-20 00:45:23 +02:00

867 lines
36 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

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

<template>
<div class="parc-page">
<!-- ================== -->
<!-- FILS D'ARIANE -->
<!-- ================== -->
<PageSection tone="" content-size="default" class="breadcrum_wp">
<Breadcrumb/>
</PageSection>
<!-- ================== -->
<!-- EN-TêTE -->
<!-- ================== -->
<section class="fiche_header_simple_wp">
<div class="fiche_header_wp_gauche"></div>
<div class="fiche_header_inner">
<div class="fiche_header_titres">
<div>
<DsHeading as="h1" tone="default" textcase="uppercase" class="concert-card__title">
{{ parc_contenus?.header_titre }}
</DsHeading>
</div>
<DsText as="p" align="justify">
{{ parc_contenus?.header_text }}
</DsText>
</div>
<div class="fiche_header_img">
<DsMedia
v-if="parc_contenus?.image_illustration_header?.url"
:src="parc_contenus.image_illustration_header.url"
:alt="parc_contenus.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>
<!-- ================== -->
<!-- DESCRIPTION -->
<!-- ================== -->
<PageSection tone="" content-size="default" padded_size="md" class="fiche_description">
<SectionContent v-if="parc_contenus?.description_generale" class="description_wp">
<StrapiBlocksConvert :blocks="parc_contenus.description_generale" />
</SectionContent>
</PageSection>
<!-- ================== -->
<!-- LES INSTRUMENTS -->
<!-- ================== -->
<PageSection :content="false" padded_size="md">
<Decalage
tone="dark"
title-tone="invert"
position="left"
button-tone="invert"
ensavoirplus-target="texte_cache_1"
ensavoirplus-group="parc-details"
>
<template #title>
LES INSTRUMENTS
</template>
<DsText as="p" tone="invert" align="justify">
Découvrer les 3 000 instruments à la location
</DsText>
</Decalage>
</PageSection>
<PageSection
id="texte_cache_1"
data-ensavoirplus-group="parc-details"
tone=""
content-size="default"
padded_size=""
class="decalage_ensavoirplus--hidden"
>
<div>
<!-- PDF -->
<a
v-if="parc_contenus?.documents?.[0]?.url"
:href="parc_contenus.documents[0].url"
:download="parc_contenus.documents[0].name || true"
class="flex flex-wrap items-center gap-2 px-6 py-2 max-w-[334px] bg-primary-container text-on-primary-container rounded-full font-bold text-sm hover:bg-primary-fixed"
target="_blank"
rel="noopener noreferrer"
>
<span class="material-symbols-outlined text-lg">picture_as_pdf</span>
CATALOGUE DU PARC
<span v-if="parc_contenus.documents[0].size">
(PDF • {{ formatKoToMo(parc_contenus.documents[0].size) }})
</span>
</a>
</div>
<!-- PAR CATEGORIES -->
<section class="space-y-12 mt-16 mb-16">
<div
v-for="categorie in instruments_categories"
:key="categorie.id"
class="space-y-4"
>
<div class="flex items-center gap-4">
<h3 v-if="categorie.nom_categorie" class="text-2xl font-bold tracking-tight">
{{ categorie.nom_categorie }}
</h3>
<div class="h-[2px] flex-1 bg-surface-container"></div>
</div>
<div class="space-y-4">
<div
class="bg-surface-container-lowest rounded-xl p-8 hover:shadow-xl transition-shadow border border-outline-variant/10"
>
<div class="flex flex-col lg:flex-row gap-8">
<div class="border-surface-container pl-8 grid grid-cols-2 md:grid-cols-5 gap-6 items-start">
<div
v-for="instrument in categorie.instruments_list || []"
:key="instrument.id"
class="flex flex-col gap-3 group"
>
<div class="w-full aspect-[1/1] bg-surface-container-low rounded-lg flex items-center justify-center group-hover:bg-primary-container transition-colors">
<img
v-if="instrument.illustration_instrument?.url"
:src="instrument.illustration_instrument.url"
:alt="instrument.illustration_instrument.alternativeText || instrument.illustration_instrument.caption || instrument.illustration_instrument.name || ''"
class="w-full aspect-[1/1] object-contain rounded-lg"
>
</div>
<div class="text-center">
<p v-if="instrument.instrument_nom" class="text-xs font-bold uppercase tracking-tighter">
{{ instrument.instrument_nom }}
</p>
</div>
<button
type="button"
class="px-3 py-1.5 bg-surface-container-low text-on-surface-variant rounded-full text-sm font-medium hover:bg-primary-container hover:text-primary transition-colors"
@click="toggleInstrumentDescription(instrument.id)"
>
En savoir plus
</button>
<div v-if="openedInstrumentDescriptions[instrument.id]" class="text-center">
<StrapiBlocksConvert
v-if="instrument.instrument_description"
:blocks="instrument.instrument_description"
/>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
</PageSection>
<!-- ================== -->
<!-- DEVIS -->
<!-- ================== -->
<PageSection :content="false">
<Decalage
tone="brand"
title-tone="invert"
position="right"
button-tone="invert"
ensavoirplus-target="texte_cache_3"
ensavoirplus-group="parc-details"
>
<template #title>
Devis
</template>
<DsText as="p" tone="invert" align="justify">
Formulaire de demande de devis ou d'information sur la location de matériel ou sur l'organisation d'un événement en salle d'activités
</DsText>
</Decalage>
</PageSection>
<PageSection
id="texte_cache_3"
data-ensavoirplus-group="parc-details"
tone=""
content-size="default"
padded_size=""
class="mt-16 mb-16 decalage_ensavoirplus--hidden"
>
<div class="fiche_description">
<div class="w-full max-w-3xl rounded-2xl border border-outline-variant/20 bg-surface-container-lowest p-8 shadow-sm">
<div class="mb-8">
<h3 class="text-2xl font-bold tracking-tight">Faire une demande</h3>
<p class="mt-2 text-sm text-on-surface-variant">
Remplissez ce formulaire pour une demande de devis ou d'information. Les champs marqués dun astérisque sont obligatoires.
</p>
</div>
<form class="space-y-6" @submit.prevent="submitQuoteRequest">
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div class="space-y-2">
<label for="quote-request-type" class="block text-sm font-medium text-on-surface">
Type de demande *
</label>
<select
id="quote-request-type"
v-model="quoteForm.requestType"
class="w-full rounded-xl border border-outline-variant/30 bg-white px-4 py-3 text-sm text-on-surface outline-none transition-colors focus:border-primary"
>
<option value="">Choisir un type</option>
<option value="location-materiel">Location de matériel</option>
<option value="organisation-salle-activites">Organisation dun événement en salle dactivités</option>
</select>
<p v-if="quoteFormErrors.requestType" class="text-xs text-error">{{ quoteFormErrors.requestType }}</p>
</div>
<div class="space-y-2">
<label for="quote-name" class="block text-sm font-medium text-on-surface">
Nom complet *
</label>
<input
id="quote-name"
v-model.trim="quoteForm.name"
type="text"
class="w-full rounded-xl border border-outline-variant/30 bg-white px-4 py-3 text-sm text-on-surface outline-none transition-colors focus:border-primary"
placeholder="Votre nom et prénom"
>
<p v-if="quoteFormErrors.name" class="text-xs text-error">{{ quoteFormErrors.name }}</p>
</div>
<div class="space-y-2">
<label for="quote-email" class="block text-sm font-medium text-on-surface">
Email *
</label>
<input
id="quote-email"
v-model.trim="quoteForm.email"
type="email"
class="w-full rounded-xl border border-outline-variant/30 bg-white px-4 py-3 text-sm text-on-surface outline-none transition-colors focus:border-primary"
placeholder="nom@exemple.fr"
>
<p v-if="quoteFormErrors.email" class="text-xs text-error">{{ quoteFormErrors.email }}</p>
</div>
<div class="space-y-2">
<label for="quote-phone" class="block text-sm font-medium text-on-surface">
Téléphone *
</label>
<input
id="quote-phone"
v-model.trim="quoteForm.phone"
type="tel"
class="w-full rounded-xl border border-outline-variant/30 bg-white px-4 py-3 text-sm text-on-surface outline-none transition-colors focus:border-primary"
placeholder="06 00 00 00 00"
>
<p v-if="quoteFormErrors.phone" class="text-xs text-error">{{ quoteFormErrors.phone }}</p>
</div>
<div class="space-y-2">
<label for="quote-organisation" class="block text-sm font-medium text-on-surface">
Structure / organisme *
</label>
<input
id="quote-organisation"
v-model.trim="quoteForm.organization"
type="text"
class="w-full rounded-xl border border-outline-variant/30 bg-white px-4 py-3 text-sm text-on-surface outline-none transition-colors focus:border-primary"
placeholder="Nom de votre structure"
>
<p v-if="quoteFormErrors.organization" class="text-xs text-error">{{ quoteFormErrors.organization }}</p>
</div>
</div>
<div class="space-y-2">
<label for="quote-message" class="block text-sm font-medium text-on-surface">
Message *
</label>
<textarea
id="quote-message"
v-model.trim="quoteForm.message"
rows="6"
class="w-full rounded-xl border border-outline-variant/30 bg-white px-4 py-3 text-sm text-on-surface outline-none transition-colors focus:border-primary"
placeholder="Précisez votre besoin, les dates de retrait et retour (le Parc est fermé le weekend). Nous ne faisons pas de livraisons."
></textarea>
<p v-if="quoteFormErrors.message" class="text-xs text-error">{{ quoteFormErrors.message }}</p>
</div>
<div v-if="quoteSubmitError" class="rounded-xl border border-error/20 bg-error-container/20 px-4 py-3 text-sm text-error">
{{ quoteSubmitError }}
</div>
<div v-if="quoteSubmitSuccess" class="rounded-xl border border-primary/20 bg-primary-container/40 px-4 py-3 text-sm text-on-surface">
<span v-if="quoteEmailsSent">Votre demande a bien été envoyée. Un email de confirmation vous a été adressé.</span>
<span v-else>Votre demande a bien été enregistrée et transmise à léquipe du Parc.</span>
</div>
<div class="flex items-center gap-4">
<button
type="submit"
class="inline-flex items-center justify-center rounded-full bg-primary px-6 py-3 text-sm font-bold text-on-primary transition-colors hover:bg-primary-dim disabled:cursor-not-allowed disabled:opacity-60"
:disabled="quoteSubmitting"
>
{{ quoteSubmitting ? 'Envoi en cours...' : 'Envoyer la demande' }}
</button>
<p class="text-xs text-on-surface-variant">
En soumettant ce formulaire, jaccepte que les informations saisies soient utilisées dans le cadre de la demande de devis ou dinformation.
</p>
</div>
</form>
</div>
</div>
</PageSection>
<!-- ================== -->
<!-- INFOS PRATIQUES -->
<!-- ================== -->
<PageSection :content="false">
<Decalage tone="brandreverse" title-tone="invert" position="left" button-tone="invert" ensavoirplus-target="texte_cache_2"
ensavoirplus-group="parc-details">
<template #title>
Infos pratiques
</template>
<DsText tone="invert" as="p" align="justify">
Accès au parc instrumental de lOrchestre national dÎle-de-France
</DsText>
</Decalage>
</PageSection>
<!-- ================== -->
<!-- INFOS PRATIQUES -->
<!-- PARTIE CACHÉE -->
<!-- ================== -->
<div id="texte_cache_2" data-ensavoirplus-group="parc-details" class="decalage_ensavoirplus--hidden">
<PageSection tone="" content-size="default" padded_size="md">
<SectionContent class="fiche_description strapi-blocks">
<div class="">
<h1>Horaires</h1>
<p>De 9h30 à 12h et de 14h à 18h</p>
<p>Du lundi au vendredi</p>
<p><strong>Uniquement sur rendez-vous</strong></p>
</div>
</SectionContent>
</PageSection>
<PageSection tone="" content-size="default" padded_size="md">
<SectionContent class="fiche_description strapi-blocks">
<div>
<div class="mb-8"><iframe src="https://maps.google.com/maps?width=781&amp;height=538&amp;hl=en&amp;q=1,%20rue%20du%20Capitaine%20Alfred-Dreyfus%20Alfortvillle+(Parc%20instrumental)&amp;t=&amp;z=14&amp;ie=UTF8&amp;iwloc=B&amp;output=embed" width="600" height="450" style="border:0;" allowfullscreen="" loading="lazy" referrerpolicy="no-referrer-when-downgrade"></iframe></div>
<div>
<h1>Comment venir ?</h1>
<h2>Accès pour le transport dinstruments</h2>
<p>Depuis le 1, rue du Capitaine Alfred-Dreyfus, 94140 Alfortville</p>
<ul>
<li>Contourner le corps de bâtiment de droite en passant par la circulation du Centre technique municipal.</li>
<li>Stationner sur le parking du Parc instrumental.</li>
</ul>
<section class="img-gallery_wp">
<div class="img-gallery">
<div class="ds-media ds-media--">
<img class="ds-media__img ds-media__img--cover" src="/img/photos/acces1.jpg" alt="" loading="lazy" decoding="async">
</div>
</div>
</section>
<h2>Accès Évènement public</h2>
<p>Rendez-vous au 9, allée Jean-Baptiste Preux.</p>
<ul>
<li>Accès au parking par le grand portail coulissant.</li>
<li>Suivre le cheminement jusquà la salle dactivités.</li>
</ul>
<section class="img-gallery_wp">
<div class="img-gallery">
<div class="ds-media ds-media--">
<img class="ds-media__img ds-media__img--cover" src="/img/photos/acces2.jpg" alt="" loading="lazy" decoding="async">
</div>
</div>
</section>
</div>
</div>
</SectionContent>
</PageSection>
</div>
<!-- ================== -->
<!-- CONDITIONS -->
<!-- ================== -->
<PageSection :content="false">
<Decalage
tone="dark"
title-tone="invert"
position="right"
button-tone="invert"
ensavoirplus-target="texte_cache_4"
ensavoirplus-group="parc-details"
>
<template #title>
Les conditions
</template>
<DsText as="p" tone="invert" align="justify">
Procédure daccès à un prêt dinstruments, Exécution des opérations de prêt, conditions matérielles, tarifs, facturation et modalités de paiement, attestation sur l'honneur
</DsText>
</Decalage>
</PageSection>
<PageSection
id="texte_cache_4"
data-ensavoirplus-group="parc-details"
tone=""
content-size="default"
padded_size=""
class="mt-16 mb-16 decalage_ensavoirplus--hidden"
>
<!-- PDF -->
<div class="fiche_description">
<SectionContent class="fiche_description">
<div class="">
<a
href="https://media.orchestre-ile.com/uploads/parc_attestation_sur_l_honneur_fd039769c5.pdf"
download="https://media.orchestre-ile.com/uploads/parc_attestation_sur_l_honneur_fd039769c5.pdf"
class="flex flex-wrap items-center gap-2 px-6 py-2 max-w-[334px] bg-primary-container text-on-primary-container rounded-full font-bold text-sm hover:bg-primary-fixed"
target="_blank"
rel="noopener noreferrer"
>
<span class="material-symbols-outlined text-lg">picture_as_pdf</span>
Attestation sur lhonneur
<span v-if="parc_contenus.documents[0].size">
(PDF)
</span>
</a>
</div>
</SectionContent>
</div>
<div class="fiche_description">
<SectionContent class="fiche_description strapi-blocks">
<div class="">
<h1>CONDITIONS ADMINISTRATIVES</h1>
<h2>Procédure daccès à un prêt dinstruments</h2>
<p>Le parc adresse aux utilisateurs un devis correspondant aux demandes exprimées.</p>
<p>Le devis et loption de réservation quil constitue sont valables 21 jours.</p>
<p>Le devis accepté (ou un bon de commande) sera retourné au Parc, comportant obligatoirement les mentions suivantes :</p>
<ul>
<li>les coordonnées de la structure demandant le prêt et de la personne responsable de l'opération,</li>
<li>la liste des instruments et du matériel,</li>
<li>le prix de la location,</li>
<li>le jour de l'enlèvement des instruments et du matériel,</li>
<li>le jour de retour de l'ensemble,</li>
<li>les coordonnées de l'assureur couvrant l'opération,</li>
<li>les renseignements demandés concernant lopération.</li>
</ul>
<p>Ce document servira, à l'exclusion de tout autre, à déterminer la structure utilisatrice, seule destinataire de la facturation.</p>
<h2>Exécution des opérations de prêt</h2>
<p>Les personnes procédant à lenlèvement, au transport et au retour des instruments sont réputées de ce fait être mandatées par la structure utilisatrice et, à ce titre, visent et lui transmettent les documents.</p>
<p>L'utilisateur est responsable des instruments hors des locaux du Parc instrumental de l'Orchestre national d'Île-de-France et se charge de tout contentieux impliquant un transporteur tiers qu'il aurait mandaté. Il appartient à l'utilisateur d'assurer le matériel contre tous les risques encourus. Lors de lenlèvement et du retour du matériel, un contrôle de la liste de ce dernier est effectué. Le constat de l'état du matériel est établi contradictoirement par l'utilisateur et par le(s) régisseur(s) du Parc instrumental de l'Orchestre national d'Île-de-France.</p>
<p>Au départ, une fiche d'enlèvement est délivrée, comportant la liste des instruments et les dates de début et de fin de l'opération.
<br>
Au retour, une fiche est éventuellement à nouveau délivrée, comportant la mention des instruments non restitués et des détériorations survenues sil y a lieu.</p>
<p>Les instruments restent la propriété exclusive du Parc instrumental de l'Orchestre national d'Île-de-France.</p>
<p>D'une manière générale et dans tous les cas, le matériel pris en charge ne peut être ni inscrit à l'actif de l'utilisateur, ni saisi ou donné en gage.</p>
<h1>CONDITIONS MATÉRIELLES</h1>
<ul>
<li>l'accord des instruments (orgues, clavecins, percussions, etc.),</li>
<li>l'assurance entre le départ et le retour dans ses locaux,</li>
<li>l'emballage et l'envoi du matériel et des instruments par colis, messagerie, etc</li>
<li>la fourniture de la "baguetterie", qui reste le fait des percussionnistes</li>
</ul>
<p>En outre, les utilisateurs sont avisés que certaines conditions sont requises pour la prise en charge des instruments :</p>
<ul>
<li>le véhicule utilisé doit être adapté à la nature et à la quantité des instruments. Les instruments seront protégés par des couvertures ou des garnitures, attachés dans le véhicule, non empilés lorsque leur nature linterdit. Les couvertures et les sangles ne sont pas fournies par le Parc instrumental de l'Orchestre national d'Île-de-France,</li>
<li>en particulier, les gros instruments (clavecins et orgues) ne seront pas confiés en cas de présentation d'un utilisateur avec un véhicule non adapté, dans lequel l'instrument ne pourrait être chargé sur un plancher plat et continu, un clavecin étant indifféremment disposé sur l'échine ou à plat. Certains instruments sont fournis montés. Les utilisateurs qui se verraient obligés de les démonter devront assurer eux-mêmes, sous leur responsabilité, les opérations de démontage et de remontage. Le contrôle après restitution prendra particulièrement en compte les conséquences éventuelles de ces opérations,</li>
<li>les opérations de manutention (chargement et déchargement des véhicules) sont de la responsabilité des utilisateurs.</li>
</ul>
<h1>TARIFS - FACTURATION - MODALITÉS DE PAIEMENT</h1>
<p>Le prix de location des instruments est indiqué sur le devis.</p>
<p>Une facture est établie après restitution du matériel. Les instruments manquants seront facturés à leur valeur de remplacement. Les dégradations seront facturées pour le prix de la réparation. La restitution tardive du fait de l'utilisateur donne lieu à une facturation supplémentaire.</p>
<p>Le paiement s'effectue à réception de la facture, sauf stipulation contraire lors de l'élaboration du devis ou du bon de commande. La loi du 31 décembre 1992 fait obligation de vous indiquer que le non-respect des conditions de paiement entraîne des intérêts de retard suivant modalités et taux définis par ladite loi.</p>
<h1>LITIGES</h1>
<p>En cas de retard ou d'incident de paiement, à quelque titre que ce soit, le Parc instrumental de l'Orchestre national d'Île-de-France pourra refuser toute nouvelle commande. En cas de litige et seulement après épuisement des voies de recours amiable, les deux parties conviennent de s'en remettre exclusivement à l'appréciation du Tribunal de Commerce de Créteil.</p>
</div>
</SectionContent>
</div>
</PageSection>
<!-- ================== -->
<!-- CONTACT -->
<!-- ================== -->
<PageSection tone="" content-size="default" padded_size="md" class="contact_spe_wp">
<ContactSpecifique
titre="Contacter les régisseurs"
nom="Stéphane Borsellino / Stéphane Nguyen Phu Khai"
poste=""
numero="01 88 15 00 80"
mail="leparcinstrumental@orchestre-ile.com"
adresse="1, rue du Capitaine Alfred-Dreyfus 94140 Alfortvillle"
/>
</PageSection>
<!-- ================== -->
<!-- L'ORCHESTRE POUR LES PROS -->
<!-- ================== -->
<PageSection padded_size="lg">
<SectionContent>
<SectionTitle tone="" pad="xs">
L'ORCHESTRE POUR LES PROS
</SectionTitle>
</SectionContent>
<SectionContent>
<BannierePros />
</SectionContent>
</PageSection>
</div>
</template>
<script setup>
import DsHeading from '@root/design-system/primitives/DsHeading.vue'
import DsText from '@root/design-system/primitives/DsText.vue'
import DsMedia from '@root/design-system/primitives/DsMedia.vue'
import DsButton from '@root/design-system/primitives/DsButton.vue'
import logoparc from '/img/logos/logo_le_parc_noir.png'
import catalogue_parc from '/contenus/catalogue-du-parc-instrumental.pdf'
useHead({
link: [
{
rel: 'preconnect',
href: 'https://fonts.googleapis.com',
},
{
rel: 'preconnect',
href: 'https://fonts.gstatic.com',
crossorigin: '',
},
{
rel: 'stylesheet',
href: 'https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap',
},
{
rel: 'stylesheet',
href: 'https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap',
},
],
})
//--------------------
// RÉCUPÉRATION DES DONNÉES STRAPI
//--------------------
const parc_strapi = ref({
data: {
id: 1,
documentId: "parc123456",
header_titre: "Un parc riche de plus de 3 000 instruments à la location",
header_text: "",
image_illustration_header: {
id: 301,
documentId: "img123456",
name: "parc_header.jpg",
alternativeText: "Vue du parc instrumental de l'Orchestre",
caption: "Parc instrumental",
width: 1600,
height: 900,
formats: {
thumbnail: {
url: "/"
}
},
ext: ".jpg",
mime: "image/jpeg",
size: 245.8,
url: logoparc
},
"description_generale": [
{
"type": "paragraph",
"children": [
{
"text": "Le Parc instrumental de lOrchestre, dont la mission principale est de faciliter les manifestations musicales en Île-de-France, dispose dun catalogue de plus de 3 000 instruments et contribue à plus de 500 manifestations par an (concerts, répétitions, cours, masterclasses...).",
"type": "text"
}
]
},
{
"type": "paragraph",
"children": [
{
"text": "Il sadresse aux municipalités, communautés dagglomération, communautés de communes, conservatoires et écoles de musique, ensembles instrumentaux ou vocaux professionnels ou amateurs, organisateurs de concerts (théâtre, festival, association...), structures culturelles ainsi quaux particuliers.",
"type": "text"
}
]
},
{
"type": "paragraph",
"children": [
{
"text": "Situé dans un local industriel, sur 2 niveaux, il offre un espace total de 650m2 dont 400m2 dévolus au stockage des 3 000 instruments.",
"type": "text"
}
]
},
{
"type": "paragraph",
"children": [
{
"text": " Une salle polyvalente dédiée aux activités permet de recevoir des groupes pour de multiples actions culturelles.",
"type": "text"
}
]
}
],
"documents": [
{
"id": 246,
"documentId": "h38c6ppljk084pdgnngcbe0b",
"name": "catalogue-du-parc-instrumental",
"alternativeText": "catalogue-du-parc-instrumental",
"caption": "Catalogue du Parc",
"width": null,
"height": null,
"formats": null,
"hash": "catalogue-du-parc-instrumental",
"ext": ".pdf",
"mime": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"size": 2065.92,
"url": catalogue_parc,
"previewUrl": null,
"provider": "aws-s3",
"provider_metadata": null,
"createdAt": "2026-04-20T09:04:05.924Z",
"updatedAt": "2026-04-20T09:04:39.849Z",
"publishedAt": "2026-04-20T09:04:05.924Z",
"focalPoint": null
},
]
},
meta: {}
})
const parc_contenus = computed(() => parc_strapi.value?.data || null)
const endpointInstruments = "/api/__strapi__/instruments"
const populateInstruments = {
illustration_instrument: true,
}
const { items: instrumentsItems, refresh: refreshInstruments } = useStrapi(
endpointInstruments,
{
locale: "fr-FR",
populate: populateInstruments,
pageSize: 100,
fetchAll: true,
}
)
onMounted(() => {
if (!instrumentsItems.value?.length) {
refreshInstruments()
}
})
const instruments_categories = computed(() => {
const groups = new Map()
for (const instrument of instrumentsItems.value || []) {
const categoryName = instrument.instrument_categorie || "Sans catégorie"
if (!groups.has(categoryName)) {
groups.set(categoryName, {
id: categoryName,
nom_categorie: categoryName,
instruments_list: [],
})
}
groups.get(categoryName).instruments_list.push(instrument)
}
return Array.from(groups.values()).map((category) => ({
...category,
instruments_list: category.instruments_list.sort((a, b) =>
String(a.instrument_nom || "").localeCompare(String(b.instrument_nom || ""), "fr", {
sensitivity: "base",
})
),
}))
})
const openedInstrumentDescriptions = ref({})
const quoteForm = reactive({
requestType: "",
name: "",
email: "",
phone: "",
organization: "",
message: "",
})
const quoteFormErrors = reactive({
requestType: "",
name: "",
email: "",
phone: "",
organization: "",
message: "",
})
const quoteSubmitting = ref(false)
const quoteSubmitSuccess = ref(false)
const quoteSubmitError = ref("")
const quoteEmailsSent = ref(false)
function toggleInstrumentDescription(instrumentId) {
openedInstrumentDescriptions.value[instrumentId] = !openedInstrumentDescriptions.value[instrumentId]
}
function resetQuoteFormErrors() {
quoteFormErrors.requestType = ""
quoteFormErrors.name = ""
quoteFormErrors.email = ""
quoteFormErrors.phone = ""
quoteFormErrors.organization = ""
quoteFormErrors.message = ""
}
function validateQuoteForm() {
resetQuoteFormErrors()
let isValid = true
if (!quoteForm.requestType) {
quoteFormErrors.requestType = "Le type de demande est obligatoire."
isValid = false
}
if (!quoteForm.name) {
quoteFormErrors.name = "Le nom est obligatoire."
isValid = false
}
if (!quoteForm.email) {
quoteFormErrors.email = "Lemail est obligatoire."
isValid = false
} else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(quoteForm.email)) {
quoteFormErrors.email = "Lemail nest pas valide."
isValid = false
}
if (!quoteForm.phone) {
quoteFormErrors.phone = "Le téléphone est obligatoire."
isValid = false
}
if (!quoteForm.organization) {
quoteFormErrors.organization = "La structure est obligatoire."
isValid = false
}
if (!quoteForm.message) {
quoteFormErrors.message = "Le message est obligatoire."
isValid = false
}
return isValid
}
async function submitQuoteRequest() {
quoteSubmitSuccess.value = false
quoteSubmitError.value = ""
quoteEmailsSent.value = false
if (!validateQuoteForm()) {
return
}
quoteSubmitting.value = true
try {
const response = await $fetch("/api/parc-demandes", {
method: "POST",
body: {
requestType: quoteForm.requestType,
name: quoteForm.name,
email: quoteForm.email,
phone: quoteForm.phone,
organization: quoteForm.organization,
message: quoteForm.message,
},
})
quoteSubmitSuccess.value = true
quoteEmailsSent.value = Boolean(response?.emailsSent)
quoteForm.requestType = ""
quoteForm.name = ""
quoteForm.email = ""
quoteForm.phone = ""
quoteForm.organization = ""
quoteForm.message = ""
resetQuoteFormErrors()
} catch (error) {
quoteSubmitError.value = error?.data?.statusMessage || "Lenvoi de la demande a échoué."
} finally {
quoteSubmitting.value = false
}
}
function formatKoToMo(sizeInKo) {
if (typeof sizeInKo !== "number") return ""
return `${(sizeInKo / 1024).toFixed(1)} Mo`
}
</script>
<style lang="scss">
.breadcrum_wp {
padding-top: 30px;
}
// =======================
// SPÉCIFIQUE À CETTE PAGE
// =======================
.parc-page {
.fiche_description {
display: flex;
justify-content: center;
padding-top: 10px;
padding-bottom: 10px;
padding-left: 10px;
padding-right: 10px;
> * {
max-width: 640px;
display: flex;
flex-direction: column;
}
}
.contact_spe_wp {
background-color: var(--c-background-jaune-clair);
margin-top: 50px;
margin-bottom: 20px;
}
}
</style>