generated from gitea_admin/default
Formulaire academie
This commit is contained in:
896
app/pages/inscriptions/projet_academie.vue
Normal file
896
app/pages/inscriptions/projet_academie.vue
Normal file
@@ -0,0 +1,896 @@
|
||||
<template>
|
||||
<div class="inscription-page">
|
||||
<!-- ================== -->
|
||||
<!-- FILS D'ARIANE -->
|
||||
<!-- ================== -->
|
||||
<PageSection tone="" content-size="default" class="breadcrum_wp">
|
||||
<Breadcrumb/>
|
||||
</PageSection>
|
||||
|
||||
<!-- ================== -->
|
||||
<!-- EN-TÊTE -->
|
||||
<!-- ================== -->
|
||||
<PageSection tone="jaune" content-size="default" class="theme_bandeau--grid">
|
||||
<SectionContent pad="xs" class="theme_bandeau--grid--left">
|
||||
<SectionTitle tone="invert" pad="">
|
||||
CANDIDATER À L'ACADÉMIE D'ORCHESTRE
|
||||
</SectionTitle>
|
||||
<DsHeading as="h3" tone="invert">
|
||||
</DsHeading>
|
||||
</SectionContent>
|
||||
|
||||
<SectionContent pad="xs" class="theme_bandeau--grid--right">
|
||||
<DsText tone="invert" size="lg" class="theme_bandeau--grid--right--text">
|
||||
Renseignez ce formulaire pour soumettre votre candidature à l'Académie d'orchestre de l'Orchestre national d'Île-de-France.
|
||||
</DsText>
|
||||
</SectionContent>
|
||||
</PageSection>
|
||||
|
||||
<!-- ================== -->
|
||||
<!-- FORMULAIRE -->
|
||||
<!-- ================== -->
|
||||
<div class="programmer-orchestre-page text-on-surface">
|
||||
<form class="space-y-6" @submit.prevent="submitQuoteRequest">
|
||||
<div class="px-4 md:px-8 lg:px-16 py-8 max-w-7xl mx-auto">
|
||||
<FormSection title="Identité">
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<FieldInput
|
||||
id="academie-last-name"
|
||||
v-model.trim="quoteForm.lastName"
|
||||
label="Nom"
|
||||
required
|
||||
:error="quoteFormErrors.lastName"
|
||||
@input="quoteForm.lastName = quoteForm.lastName.toUpperCase()"
|
||||
/>
|
||||
<FieldInput
|
||||
id="academie-first-name"
|
||||
v-model.trim="quoteForm.firstName"
|
||||
label="Prénom"
|
||||
required
|
||||
:error="quoteFormErrors.firstName"
|
||||
/>
|
||||
<FieldSelect
|
||||
id="academie-gender"
|
||||
v-model="quoteForm.gender"
|
||||
label="Genre"
|
||||
placeholder="Choisir un genre"
|
||||
required
|
||||
:options="genderOptions"
|
||||
:error="quoteFormErrors.gender"
|
||||
/>
|
||||
<FieldInput
|
||||
id="academie-birth-date"
|
||||
v-model="quoteForm.birthDate"
|
||||
label="Date de naissance"
|
||||
type="date"
|
||||
required
|
||||
:error="quoteFormErrors.birthDate"
|
||||
/>
|
||||
<FieldInput
|
||||
id="academie-birth-place"
|
||||
v-model.trim="quoteForm.birthPlace"
|
||||
label="Lieu de naissance"
|
||||
required
|
||||
:error="quoteFormErrors.birthPlace"
|
||||
/>
|
||||
<FieldInput
|
||||
id="academie-nationality"
|
||||
v-model.trim="quoteForm.nationality"
|
||||
label="Nationalité"
|
||||
required
|
||||
:error="quoteFormErrors.nationality"
|
||||
/>
|
||||
</div>
|
||||
</FormSection>
|
||||
|
||||
<FormSection title="Coordonnées">
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<FieldInput
|
||||
id="academie-email"
|
||||
v-model.trim="quoteForm.email"
|
||||
label="Adresse mail"
|
||||
type="email"
|
||||
required
|
||||
:error="quoteFormErrors.email"
|
||||
/>
|
||||
<FieldInput
|
||||
id="academie-phone"
|
||||
v-model.trim="quoteForm.phone"
|
||||
label="Téléphone"
|
||||
type="tel"
|
||||
required
|
||||
:error="quoteFormErrors.phone"
|
||||
/>
|
||||
<FieldInput
|
||||
id="academie-address"
|
||||
v-model.trim="quoteForm.address"
|
||||
label="Adresse postale"
|
||||
required
|
||||
:error="quoteFormErrors.address"
|
||||
class="md:col-span-2"
|
||||
/>
|
||||
<FieldInput
|
||||
id="academie-city"
|
||||
v-model.trim="quoteForm.city"
|
||||
label="Ville"
|
||||
required
|
||||
:error="quoteFormErrors.city"
|
||||
/>
|
||||
<FieldInput
|
||||
id="academie-postal-code"
|
||||
v-model.trim="quoteForm.postalCode"
|
||||
label="Code postal"
|
||||
required
|
||||
:error="quoteFormErrors.postalCode"
|
||||
/>
|
||||
<FieldInput
|
||||
id="academie-country"
|
||||
v-model.trim="quoteForm.country"
|
||||
label="Pays de résidence"
|
||||
required
|
||||
:error="quoteFormErrors.country"
|
||||
/>
|
||||
</div>
|
||||
</FormSection>
|
||||
|
||||
<FormSection title="Parcours musical">
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<FieldSelect
|
||||
id="academie-instrument"
|
||||
v-model="quoteForm.instrument"
|
||||
label="Instrument"
|
||||
placeholder="Choisir un instrument"
|
||||
required
|
||||
:options="instrumentOptions"
|
||||
:error="quoteFormErrors.instrument"
|
||||
class="md:col-span-2"
|
||||
>
|
||||
<template #help>
|
||||
Pour les pupitres à instruments doubles (ex : flûte/piccolo, basson/contrebasson, etc.), merci de sélectionner l'option correspondant aux deux instruments si vous souhaitez les présenter tous les deux. Si vous ne cochez qu’un seul instrument, vous ne pourrez en présenter qu’un seul le jour de l’audition.
|
||||
</template>
|
||||
</FieldSelect>
|
||||
<FieldSelect
|
||||
id="academie-previous-participation"
|
||||
v-model="quoteForm.previousAcademyParticipation"
|
||||
label="Avez-vous déjà participé à l’académie ?"
|
||||
placeholder="Choisir une réponse"
|
||||
required
|
||||
:options="yesNoOptions"
|
||||
:error="quoteFormErrors.previousAcademyParticipation"
|
||||
/>
|
||||
<FieldInput
|
||||
v-if="quoteForm.previousAcademyParticipation === 'oui'"
|
||||
id="academie-previous-participation-count"
|
||||
v-model.trim="quoteForm.previousAcademyParticipationCount"
|
||||
label="Combien de fois ?"
|
||||
type="number"
|
||||
min="1"
|
||||
required
|
||||
:error="quoteFormErrors.previousAcademyParticipationCount"
|
||||
/>
|
||||
</div>
|
||||
</FormSection>
|
||||
|
||||
<FormSection title="Formation">
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<FieldSelect
|
||||
id="academie-training-level"
|
||||
v-model="quoteForm.trainingLevel"
|
||||
label="Niveau - cycle actuel année scolaire 2026-2027"
|
||||
placeholder="Choisir un niveau"
|
||||
required
|
||||
:options="trainingLevelOptions"
|
||||
:error="quoteFormErrors.trainingLevel"
|
||||
class="md:col-span-2"
|
||||
>
|
||||
<template #help>
|
||||
Pour rappel, vous devez être inscrit.e en 3e cycle, cycle spécialisé ou équivalent à la rentrée 2025-2026 dans un conservatoire d’Île-de-France (hors CNSMD et Pôles d’enseignement supérieur).
|
||||
</template>
|
||||
</FieldSelect>
|
||||
<FieldInput
|
||||
v-if="quoteForm.trainingLevel === 'Autre'"
|
||||
id="academie-other-training-level"
|
||||
v-model.trim="quoteForm.otherTrainingLevel"
|
||||
label="Autre formation"
|
||||
required
|
||||
:error="quoteFormErrors.otherTrainingLevel"
|
||||
class="md:col-span-2"
|
||||
/>
|
||||
<FieldSelect
|
||||
id="academie-conservatory"
|
||||
v-model="quoteForm.conservatory"
|
||||
label="Conservatoire année scolaire 2026-2027"
|
||||
placeholder="Choisir un conservatoire"
|
||||
required
|
||||
:options="conservatoryOptions"
|
||||
:error="quoteFormErrors.conservatory"
|
||||
class="md:col-span-2"
|
||||
>
|
||||
<template #help>
|
||||
Si votre conservatoire ne figure pas dans la liste mais qu’il est bien situé en Île-de-France, merci de l’ajouter manuellement en respectant le même format que les propositions déjà indiquées.
|
||||
</template>
|
||||
</FieldSelect>
|
||||
<FieldInput
|
||||
v-if="quoteForm.conservatory === 'Autre'"
|
||||
id="academie-other-conservatory"
|
||||
v-model.trim="quoteForm.otherConservatory"
|
||||
label="Autre conservatoire (Ville + Nom)"
|
||||
required
|
||||
:error="quoteFormErrors.otherConservatory"
|
||||
/>
|
||||
<FieldInput
|
||||
id="academie-teacher-name"
|
||||
v-model.trim="quoteForm.teacherName"
|
||||
label="Nom du professeur d’instrument (NOM prénom)"
|
||||
required
|
||||
:error="quoteFormErrors.teacherName"
|
||||
/>
|
||||
</div>
|
||||
</FormSection>
|
||||
|
||||
<FormSection title="3 derniers diplômes musicaux obtenus">
|
||||
<div class="space-y-8">
|
||||
<div
|
||||
v-for="(diploma, index) in quoteForm.diplomas"
|
||||
:key="`diploma-${index}`"
|
||||
class="rounded-xl border border-outline-variant/30 p-5"
|
||||
>
|
||||
<h4 class="mb-4 text-lg font-bold uppercase">Diplôme {{ index + 1 }}</h4>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<FieldSelect
|
||||
:id="`academie-diploma-${index}-type`"
|
||||
v-model="diploma.type"
|
||||
label="Type du diplôme"
|
||||
placeholder="Choisir un type"
|
||||
:options="diplomaTypeOptions"
|
||||
:error="quoteFormErrors.diplomas[index].type"
|
||||
/>
|
||||
<FieldInput
|
||||
v-if="diploma.type === 'Autre'"
|
||||
:id="`academie-diploma-${index}-other-type`"
|
||||
v-model.trim="diploma.otherType"
|
||||
label="Autre type de diplôme"
|
||||
:error="quoteFormErrors.diplomas[index].otherType"
|
||||
/>
|
||||
<FieldInput
|
||||
:id="`academie-diploma-${index}-discipline`"
|
||||
v-model.trim="diploma.discipline"
|
||||
label="Discipline"
|
||||
:error="quoteFormErrors.diplomas[index].discipline"
|
||||
/>
|
||||
<FieldInput
|
||||
:id="`academie-diploma-${index}-year`"
|
||||
v-model.trim="diploma.year"
|
||||
label="Année"
|
||||
type="number"
|
||||
min="1900"
|
||||
max="2027"
|
||||
:error="quoteFormErrors.diplomas[index].year"
|
||||
/>
|
||||
<FieldInput
|
||||
:id="`academie-diploma-${index}-establishment`"
|
||||
v-model.trim="diploma.establishment"
|
||||
label="Établissement"
|
||||
:error="quoteFormErrors.diplomas[index].establishment"
|
||||
class="md:col-span-2"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</FormSection>
|
||||
|
||||
<FormSection title="Contact d’urgence">
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<FieldInput
|
||||
id="academie-emergency-last-name"
|
||||
v-model.trim="quoteForm.emergencyLastName"
|
||||
label="Nom du contact"
|
||||
required
|
||||
:error="quoteFormErrors.emergencyLastName"
|
||||
/>
|
||||
<FieldInput
|
||||
id="academie-emergency-first-name"
|
||||
v-model.trim="quoteForm.emergencyFirstName"
|
||||
label="Prénom du contact"
|
||||
required
|
||||
:error="quoteFormErrors.emergencyFirstName"
|
||||
/>
|
||||
<FieldSelect
|
||||
id="academie-emergency-relation"
|
||||
v-model="quoteForm.emergencyRelation"
|
||||
label="Lien avec le participant"
|
||||
placeholder="Choisir un lien"
|
||||
required
|
||||
:options="emergencyRelationOptions"
|
||||
:error="quoteFormErrors.emergencyRelation"
|
||||
/>
|
||||
<FieldInput
|
||||
id="academie-emergency-phone"
|
||||
v-model.trim="quoteForm.emergencyPhone"
|
||||
label="Téléphone"
|
||||
type="tel"
|
||||
required
|
||||
:error="quoteFormErrors.emergencyPhone"
|
||||
/>
|
||||
<FieldInput
|
||||
id="academie-emergency-email"
|
||||
v-model.trim="quoteForm.emergencyEmail"
|
||||
label="Mail"
|
||||
type="email"
|
||||
required
|
||||
:error="quoteFormErrors.emergencyEmail"
|
||||
/>
|
||||
</div>
|
||||
</FormSection>
|
||||
|
||||
<FormSection title="Règlement">
|
||||
<div class="space-y-4">
|
||||
<a
|
||||
:href="regulationFileUrl"
|
||||
target="_blank"
|
||||
download
|
||||
class="inline-flex items-center justify-center rounded-full border border-primary px-6 py-3 text-sm font-bold text-primary transition-colors hover:bg-primary hover:text-on-primary"
|
||||
>
|
||||
Télécharger le règlement
|
||||
</a>
|
||||
<label class="flex items-start gap-3 text-sm font-medium text-on-surface">
|
||||
<input
|
||||
v-model="quoteForm.acceptRules"
|
||||
type="checkbox"
|
||||
class="mt-1 rounded border-outline-variant text-primary focus:ring-primary"
|
||||
>
|
||||
<span>Accepter le règlement *</span>
|
||||
</label>
|
||||
<p v-if="quoteFormErrors.acceptRules" class="text-xs text-error">{{ quoteFormErrors.acceptRules }}</p>
|
||||
</div>
|
||||
</FormSection>
|
||||
|
||||
<!-- ENVOYER LE FORMULAIRE -->
|
||||
<section class="mb-12 mt-12">
|
||||
<div v-if="quoteSubmitError" class="mb-8 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="mb-8 rounded-xl border border-primary/20 bg-primary-container/40 px-4 py-3 text-sm text-on-surface">
|
||||
<span v-if="quoteEmailsSent">Votre candidature a bien été envoyée. Un email de confirmation vous a été adressé.</span>
|
||||
<span v-else>Votre candidature a bien été enregistrée et transmise à l’équipe de l’Académie d’orchestre.</span>
|
||||
</div>
|
||||
<div v-if="quoteSubmitting" class="mb-8 rounded-xl border border-outline-variant/30 bg-white px-4 py-3 text-sm text-on-surface">
|
||||
Envoi de votre candidature en cours...
|
||||
</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 candidature' }}
|
||||
</button>
|
||||
<p class="text-xs text-on-surface-variant">
|
||||
En soumettant ce formulaire, j’accepte que les informations saisies soient utilisées dans le cadre de cette candidature.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import DsHeading from '@root/design-system/primitives/DsHeading.vue'
|
||||
import DsText from '@root/design-system/primitives/DsText.vue'
|
||||
|
||||
const inputClass = "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"
|
||||
|
||||
const FormSection = defineComponent({
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
setup(props, { slots }) {
|
||||
return () => h("section", { class: "mb-10" }, [
|
||||
h("div", { class: "flex items-center gap-4 mb-8" }, [
|
||||
h("h3", { class: "text-2xl font-bold tracking-tight uppercase" }, props.title),
|
||||
h("div", { class: "h-[2px] flex-1 bg-surface-container" }),
|
||||
]),
|
||||
slots.default?.(),
|
||||
])
|
||||
},
|
||||
})
|
||||
|
||||
const FieldInput = defineComponent({
|
||||
props: {
|
||||
id: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
label: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
modelValue: {
|
||||
type: [String, Number],
|
||||
default: "",
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: "text",
|
||||
},
|
||||
required: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
error: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
min: {
|
||||
type: [String, Number],
|
||||
default: undefined,
|
||||
},
|
||||
max: {
|
||||
type: [String, Number],
|
||||
default: undefined,
|
||||
},
|
||||
},
|
||||
emits: ["update:modelValue", "input"],
|
||||
setup(props, { emit, slots }) {
|
||||
return () => h("div", { class: "space-y-2" }, [
|
||||
h("label", { for: props.id, class: "block text-sm font-medium text-on-surface pl-[2px]" }, `${props.label}${props.required ? " *" : ""}`),
|
||||
h("input", {
|
||||
id: props.id,
|
||||
value: props.modelValue,
|
||||
type: props.type,
|
||||
min: props.min,
|
||||
max: props.max,
|
||||
class: inputClass,
|
||||
onInput: (event) => {
|
||||
emit("update:modelValue", event.target.value)
|
||||
emit("input", event)
|
||||
},
|
||||
}),
|
||||
slots.help?.(),
|
||||
props.error ? h("p", { class: "text-xs text-error" }, props.error) : null,
|
||||
])
|
||||
},
|
||||
})
|
||||
|
||||
const FieldSelect = defineComponent({
|
||||
props: {
|
||||
id: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
label: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
modelValue: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: "Choisir une option",
|
||||
},
|
||||
required: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
options: {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
error: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
},
|
||||
emits: ["update:modelValue"],
|
||||
setup(props, { emit, slots }) {
|
||||
return () => h("div", { class: "space-y-2" }, [
|
||||
h("label", { for: props.id, class: "block text-sm font-medium text-on-surface pl-[2px]" }, `${props.label}${props.required ? " *" : ""}`),
|
||||
h("select", {
|
||||
id: props.id,
|
||||
value: props.modelValue,
|
||||
class: inputClass,
|
||||
onChange: (event) => emit("update:modelValue", event.target.value),
|
||||
}, [
|
||||
h("option", { value: "" }, props.placeholder),
|
||||
...props.options.map((option) => h("option", { value: option }, option)),
|
||||
]),
|
||||
slots.help ? h("p", { class: "text-xs leading-relaxed text-on-surface-variant" }, slots.help()) : null,
|
||||
props.error ? h("p", { class: "text-xs text-error" }, props.error) : null,
|
||||
])
|
||||
},
|
||||
})
|
||||
|
||||
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',
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
const genderOptions = ["Masculin", "Féminin", "Autre"]
|
||||
const yesNoOptions = ["oui", "non"]
|
||||
const instrumentOptions = [
|
||||
"Violon",
|
||||
"Alto",
|
||||
"Violoncelle",
|
||||
"Contrebasse",
|
||||
"Flûte",
|
||||
"Piccolo",
|
||||
"Flûte + piccolo",
|
||||
"Hautbois",
|
||||
"Cor anglais jouant le 2e hautbois",
|
||||
"Clarinette",
|
||||
"Basson",
|
||||
"Contrebasson",
|
||||
"Basson + Contrebasson",
|
||||
"Cor",
|
||||
"Trompette",
|
||||
"Trombone 2",
|
||||
"Trombone basse ou trombone 3",
|
||||
"Tuba",
|
||||
"Harpe",
|
||||
"Percussions",
|
||||
"Timbales",
|
||||
"Percussions + timbales",
|
||||
]
|
||||
const trainingLevelOptions = [
|
||||
"Cycle 3 - 1ère année",
|
||||
"Cycle 3 - 2ème année",
|
||||
"Cycle 3 - 3ème année",
|
||||
"Cycle spécialisé (CPES)",
|
||||
"DEM",
|
||||
"Autre",
|
||||
]
|
||||
const conservatoryOptions = [
|
||||
"75 - Paris - Conservatoire à rayonnement régional de Paris - Ida Rubinstein",
|
||||
"75 - Paris 5 - Conservatoire municipal Gabriel Fauré",
|
||||
"75 - Paris 11 - Conservatoire municipal Charles Münch",
|
||||
"75 - Paris 12 - Conservatoire municipal Paul Dukas",
|
||||
"75 - Paris 13 - Conservatoire municipal Maurice Ravel",
|
||||
"75 - Paris 17 - Conservatoire municipal Claude Debussy",
|
||||
"78 - Versailles - Conservatoire à rayonnement régional de Versailles Grand Parc",
|
||||
"92 - Rueil-Malmaison - Conservatoire à rayonnement régional",
|
||||
"92 - Boulogne-Billancourt - Conservatoire à rayonnement régional",
|
||||
"92 - Clamart - Conservatoire à rayonnement départemental Henri Dutilleux",
|
||||
"92 - Gennevilliers - Conservatoire Edgar Varèse",
|
||||
"92 - Meudon - Conservatoire Marcel Dupré",
|
||||
"93 - Aubervilliers - Conservatoire à rayonnement régional",
|
||||
"93 - Aulnay-sous-Bois - Conservatoire à rayonnement départemental",
|
||||
"93 - Drancy - Conservatoire",
|
||||
"93 - Bobigny - Conservatoire Jean Wiener",
|
||||
"94 - Créteil - Conservatoire à rayonnement régional Marcel Dadi",
|
||||
"94 - Saint-Maur-des-Fossés - Conservatoire à rayonnement régional",
|
||||
"94 - Cachan - Conservatoire à rayonnement départemental du Val-de-Bièvre",
|
||||
"94 - Villeneuve-Saint-Georges - Conservatoire",
|
||||
"95 - Cergy-Pontoise - Conservatoire à rayonnement régional",
|
||||
"Autre",
|
||||
]
|
||||
const diplomaTypeOptions = ["fin de cycle 2", "DEM", "CEM", "Autre"]
|
||||
const emergencyRelationOptions = ["Parent", "Frère - sœur", "Conjoint.e", "Ami", "Autre"]
|
||||
//const regulationFileUrl = "/contenus/reglement-academie-orchestre.pdf"
|
||||
const regulationFileUrl = "https://media.orchestre-ile.com/uploads/25_26_ONDIF_reglement_academie_57934f522a.pdf"
|
||||
|
||||
function createDiploma() {
|
||||
return {
|
||||
type: "",
|
||||
otherType: "",
|
||||
discipline: "",
|
||||
year: "",
|
||||
establishment: "",
|
||||
}
|
||||
}
|
||||
|
||||
function createDiplomaErrors() {
|
||||
return {
|
||||
type: "",
|
||||
otherType: "",
|
||||
discipline: "",
|
||||
year: "",
|
||||
establishment: "",
|
||||
}
|
||||
}
|
||||
|
||||
const quoteForm = reactive({
|
||||
lastName: "",
|
||||
firstName: "",
|
||||
gender: "",
|
||||
birthDate: "",
|
||||
birthPlace: "",
|
||||
nationality: "",
|
||||
email: "",
|
||||
phone: "",
|
||||
address: "",
|
||||
city: "",
|
||||
postalCode: "",
|
||||
country: "",
|
||||
instrument: "",
|
||||
previousAcademyParticipation: "",
|
||||
previousAcademyParticipationCount: "",
|
||||
trainingLevel: "",
|
||||
otherTrainingLevel: "",
|
||||
conservatory: "",
|
||||
otherConservatory: "",
|
||||
teacherName: "",
|
||||
diplomas: [createDiploma(), createDiploma(), createDiploma()],
|
||||
emergencyLastName: "",
|
||||
emergencyFirstName: "",
|
||||
emergencyRelation: "",
|
||||
emergencyPhone: "",
|
||||
emergencyEmail: "",
|
||||
acceptRules: false,
|
||||
})
|
||||
|
||||
const quoteFormErrors = reactive({
|
||||
lastName: "",
|
||||
firstName: "",
|
||||
gender: "",
|
||||
birthDate: "",
|
||||
birthPlace: "",
|
||||
nationality: "",
|
||||
email: "",
|
||||
phone: "",
|
||||
address: "",
|
||||
city: "",
|
||||
postalCode: "",
|
||||
country: "",
|
||||
instrument: "",
|
||||
previousAcademyParticipation: "",
|
||||
previousAcademyParticipationCount: "",
|
||||
trainingLevel: "",
|
||||
otherTrainingLevel: "",
|
||||
conservatory: "",
|
||||
otherConservatory: "",
|
||||
teacherName: "",
|
||||
diplomas: [createDiplomaErrors(), createDiplomaErrors(), createDiplomaErrors()],
|
||||
emergencyLastName: "",
|
||||
emergencyFirstName: "",
|
||||
emergencyRelation: "",
|
||||
emergencyPhone: "",
|
||||
emergencyEmail: "",
|
||||
acceptRules: "",
|
||||
})
|
||||
|
||||
const quoteSubmitting = ref(false)
|
||||
const quoteSubmitSuccess = ref(false)
|
||||
const quoteSubmitError = ref("")
|
||||
const quoteEmailsSent = ref(false)
|
||||
|
||||
const requiredFieldLabels = {
|
||||
lastName: "Le nom est obligatoire.",
|
||||
firstName: "Le prénom est obligatoire.",
|
||||
gender: "Le genre est obligatoire.",
|
||||
birthDate: "La date de naissance est obligatoire.",
|
||||
birthPlace: "Le lieu de naissance est obligatoire.",
|
||||
nationality: "La nationalité est obligatoire.",
|
||||
email: "L’adresse mail est obligatoire.",
|
||||
phone: "Le téléphone est obligatoire.",
|
||||
address: "L’adresse est obligatoire.",
|
||||
city: "La ville est obligatoire.",
|
||||
postalCode: "Le code postal est obligatoire.",
|
||||
country: "Le pays de résidence est obligatoire.",
|
||||
instrument: "L’instrument est obligatoire.",
|
||||
previousAcademyParticipation: "La participation précédente est obligatoire.",
|
||||
trainingLevel: "Le niveau de formation est obligatoire.",
|
||||
conservatory: "Le conservatoire est obligatoire.",
|
||||
teacherName: "Le nom du professeur d’instrument est obligatoire.",
|
||||
emergencyLastName: "Le nom du contact d’urgence est obligatoire.",
|
||||
emergencyFirstName: "Le prénom du contact d’urgence est obligatoire.",
|
||||
emergencyRelation: "Le lien avec le participant est obligatoire.",
|
||||
emergencyPhone: "Le téléphone du contact d’urgence est obligatoire.",
|
||||
emergencyEmail: "Le mail du contact d’urgence est obligatoire.",
|
||||
}
|
||||
|
||||
function resetQuoteFormErrors() {
|
||||
Object.keys(quoteFormErrors).forEach((key) => {
|
||||
if (key === "diplomas") {
|
||||
quoteFormErrors.diplomas = [createDiplomaErrors(), createDiplomaErrors(), createDiplomaErrors()]
|
||||
} else {
|
||||
quoteFormErrors[key] = ""
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function isValidEmail(email) {
|
||||
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)
|
||||
}
|
||||
|
||||
function validateQuoteForm() {
|
||||
resetQuoteFormErrors()
|
||||
|
||||
let isValid = true
|
||||
|
||||
Object.entries(requiredFieldLabels).forEach(([field, message]) => {
|
||||
if (!quoteForm[field]) {
|
||||
quoteFormErrors[field] = message
|
||||
isValid = false
|
||||
}
|
||||
})
|
||||
|
||||
if (quoteForm.email && !isValidEmail(quoteForm.email)) {
|
||||
quoteFormErrors.email = "L’adresse mail n’est pas valide."
|
||||
isValid = false
|
||||
}
|
||||
|
||||
if (quoteForm.emergencyEmail && !isValidEmail(quoteForm.emergencyEmail)) {
|
||||
quoteFormErrors.emergencyEmail = "Le mail du contact d’urgence n’est pas valide."
|
||||
isValid = false
|
||||
}
|
||||
|
||||
if (quoteForm.previousAcademyParticipation === "oui") {
|
||||
const count = Number(quoteForm.previousAcademyParticipationCount)
|
||||
if (!quoteForm.previousAcademyParticipationCount) {
|
||||
quoteFormErrors.previousAcademyParticipationCount = "Le nombre de participations est obligatoire."
|
||||
isValid = false
|
||||
} else if (!Number.isInteger(count) || count <= 0) {
|
||||
quoteFormErrors.previousAcademyParticipationCount = "Le nombre de participations doit être supérieur à 0."
|
||||
isValid = false
|
||||
}
|
||||
}
|
||||
|
||||
if (quoteForm.trainingLevel === "Autre" && !quoteForm.otherTrainingLevel) {
|
||||
quoteFormErrors.otherTrainingLevel = "L’autre formation est obligatoire."
|
||||
isValid = false
|
||||
}
|
||||
|
||||
if (quoteForm.conservatory === "Autre" && !quoteForm.otherConservatory) {
|
||||
quoteFormErrors.otherConservatory = "L’autre conservatoire est obligatoire."
|
||||
isValid = false
|
||||
}
|
||||
|
||||
quoteForm.diplomas.forEach((diploma, index) => {
|
||||
const hasDiplomaData = Boolean(diploma.type || diploma.otherType || diploma.discipline || diploma.year || diploma.establishment)
|
||||
|
||||
if (!hasDiplomaData) {
|
||||
return
|
||||
}
|
||||
|
||||
if (!diploma.type) {
|
||||
quoteFormErrors.diplomas[index].type = "Le type du diplôme est obligatoire."
|
||||
isValid = false
|
||||
}
|
||||
|
||||
if (diploma.type === "Autre" && !diploma.otherType) {
|
||||
quoteFormErrors.diplomas[index].otherType = "L’autre type de diplôme est obligatoire."
|
||||
isValid = false
|
||||
}
|
||||
|
||||
if (!diploma.discipline) {
|
||||
quoteFormErrors.diplomas[index].discipline = "La discipline est obligatoire."
|
||||
isValid = false
|
||||
}
|
||||
|
||||
if (!diploma.year) {
|
||||
quoteFormErrors.diplomas[index].year = "L’année est obligatoire."
|
||||
isValid = false
|
||||
}
|
||||
|
||||
if (!diploma.establishment) {
|
||||
quoteFormErrors.diplomas[index].establishment = "L’établissement est obligatoire."
|
||||
isValid = false
|
||||
}
|
||||
})
|
||||
|
||||
if (!quoteForm.acceptRules) {
|
||||
quoteFormErrors.acceptRules = "Vous devez accepter le règlement."
|
||||
isValid = false
|
||||
}
|
||||
|
||||
return isValid
|
||||
}
|
||||
|
||||
function resetQuoteForm() {
|
||||
Object.assign(quoteForm, {
|
||||
lastName: "",
|
||||
firstName: "",
|
||||
gender: "",
|
||||
birthDate: "",
|
||||
birthPlace: "",
|
||||
nationality: "",
|
||||
email: "",
|
||||
phone: "",
|
||||
address: "",
|
||||
city: "",
|
||||
postalCode: "",
|
||||
country: "",
|
||||
instrument: "",
|
||||
previousAcademyParticipation: "",
|
||||
previousAcademyParticipationCount: "",
|
||||
trainingLevel: "",
|
||||
otherTrainingLevel: "",
|
||||
conservatory: "",
|
||||
otherConservatory: "",
|
||||
teacherName: "",
|
||||
diplomas: [createDiploma(), createDiploma(), createDiploma()],
|
||||
emergencyLastName: "",
|
||||
emergencyFirstName: "",
|
||||
emergencyRelation: "",
|
||||
emergencyPhone: "",
|
||||
emergencyEmail: "",
|
||||
acceptRules: false,
|
||||
})
|
||||
}
|
||||
|
||||
async function submitQuoteRequest() {
|
||||
quoteSubmitSuccess.value = false
|
||||
quoteSubmitError.value = ""
|
||||
quoteEmailsSent.value = false
|
||||
|
||||
if (!validateQuoteForm()) {
|
||||
return
|
||||
}
|
||||
|
||||
quoteSubmitting.value = true
|
||||
|
||||
try {
|
||||
const response = await $fetch("/api/projet-academie", {
|
||||
method: "POST",
|
||||
body: {
|
||||
...quoteForm,
|
||||
diplomas: quoteForm.diplomas.map((diploma) => ({ ...diploma })),
|
||||
},
|
||||
})
|
||||
|
||||
quoteSubmitSuccess.value = true
|
||||
quoteEmailsSent.value = Boolean(response?.emailsSent)
|
||||
resetQuoteForm()
|
||||
resetQuoteFormErrors()
|
||||
} catch (error) {
|
||||
quoteSubmitError.value = error?.data?.statusMessage || "L’envoi de la candidature a échoué."
|
||||
} finally {
|
||||
quoteSubmitting.value = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.breadcrum_wp {
|
||||
padding-top: 30px;
|
||||
}
|
||||
|
||||
// =======================
|
||||
// SPÉCIFIQUE À CETTE PAGE
|
||||
// =======================
|
||||
.inscription-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>
|
||||
@@ -33,7 +33,7 @@
|
||||
<div class="programmer-orchestre-page text-on-surface">
|
||||
<!-- FORM -->
|
||||
<form class="space-y-6" @submit.prevent="submitQuoteRequest">
|
||||
<div class="px-12 py-8 max-w-7xl mx-auto">
|
||||
<div class="px-4 md:px-8 lg:px-16 py-8 max-w-7xl mx-auto">
|
||||
<!-- SOUS-TITRE -->
|
||||
<section class="mb-8">
|
||||
<div class="flex items-center gap-4 mb-8">
|
||||
|
||||
Reference in New Issue
Block a user