|
|
@@ -2,9 +2,7 @@
|
|
|
<LayoutContainer>
|
|
|
<div id="anchor" />
|
|
|
|
|
|
- <h4>
|
|
|
- <span class="line" /> Veuillez remplir le formulaire ci-dessous
|
|
|
- </h4>
|
|
|
+ <h4><span class="line" /> Veuillez remplir le formulaire ci-dessous</h4>
|
|
|
|
|
|
<v-form
|
|
|
v-if="!contactRequestSent"
|
|
|
@@ -13,21 +11,17 @@
|
|
|
@submit.prevent="submit"
|
|
|
>
|
|
|
<v-container>
|
|
|
- <i>Les champs dont le nom est suivi d'un astérisque (*) sont obligatoires</i>
|
|
|
+ <i
|
|
|
+ >Les champs dont le nom est suivi d'un astérisque (*) sont
|
|
|
+ obligatoires</i
|
|
|
+ >
|
|
|
|
|
|
- <h6>
|
|
|
- Vos coordonnées
|
|
|
- </h6>
|
|
|
+ <h6>Vos coordonnées</h6>
|
|
|
|
|
|
<!-- Gender selection -->
|
|
|
<v-row>
|
|
|
<v-col cols="12">
|
|
|
- <v-radio-group
|
|
|
- v-model="contactRequest.gender"
|
|
|
- row
|
|
|
- mandatory
|
|
|
- inline
|
|
|
- >
|
|
|
+ <v-radio-group v-model="contactRequest.gender" row mandatory inline>
|
|
|
<v-radio label="Madame" value="Madame" />
|
|
|
<v-radio label="Monsieur" value="Monsieur" />
|
|
|
</v-radio-group>
|
|
|
@@ -108,9 +102,7 @@
|
|
|
</v-col>
|
|
|
</v-row>
|
|
|
|
|
|
- <h6>
|
|
|
- Votre demande concerne *
|
|
|
- </h6>
|
|
|
+ <h6>Votre demande concerne *</h6>
|
|
|
|
|
|
<!-- Request type and product concerned -->
|
|
|
<v-row>
|
|
|
@@ -136,9 +128,7 @@
|
|
|
</v-col>
|
|
|
</v-row>
|
|
|
|
|
|
- <h6>
|
|
|
- Votre message
|
|
|
- </h6>
|
|
|
+ <h6>Votre message</h6>
|
|
|
|
|
|
<!-- Message -->
|
|
|
<v-row class="mb-8">
|
|
|
@@ -150,14 +140,19 @@
|
|
|
required
|
|
|
maxlength="400"
|
|
|
/>
|
|
|
- <span class="remaining-cars-notice">{{ leftCars }} caractères restants</span>
|
|
|
+ <span class="remaining-cars-notice"
|
|
|
+ >{{ leftCars }} caractères restants</span
|
|
|
+ >
|
|
|
</v-col>
|
|
|
</v-row>
|
|
|
|
|
|
<!-- Policy and checkboxes -->
|
|
|
<v-checkbox
|
|
|
v-model="contactRequest.privacyPolicyAccepted"
|
|
|
- :rules="[(v: boolean) => v || 'Vous devez accepter la politique de confidentialité']"
|
|
|
+ :rules="[
|
|
|
+ (v: boolean) =>
|
|
|
+ v || 'Vous devez accepter la politique de confidentialité',
|
|
|
+ ]"
|
|
|
label="J'ai pris connaissance de la politique de confidentialité et j'accepte le traitement de mes données personnelles par Opentalent. *"
|
|
|
/>
|
|
|
|
|
|
@@ -168,7 +163,7 @@
|
|
|
|
|
|
<div class="d-flex flex-row justify-center">
|
|
|
<!-- @see https://github.com/hCaptcha/vue-hcaptcha -->
|
|
|
- <LayoutCaptcha/>
|
|
|
+ <LayoutCaptcha />
|
|
|
</div>
|
|
|
|
|
|
<!-- Submit Button -->
|
|
|
@@ -190,84 +185,98 @@
|
|
|
</v-container>
|
|
|
|
|
|
<div class="legal">
|
|
|
- Les données recueillies par Opentalent sont utilisées pour le traitement de votre demande et pour vous informer sur nos offres.
|
|
|
- Elles sont destinées aux services Opentalent et à ses sous-traitants pour l’exécution des contrats. Conformément à la loi
|
|
|
- "Informatique et Libertés du 6 Janvier 1978", vous disposez d’un droit d’accès, de modifications, de rectification et de suppression
|
|
|
- des données vous concernant. Pour toute demande, adressez-vous à : Opentalent, 217 rue Raoul Follereau, 74300 CLUSES,
|
|
|
- opentalent.fr s’engage à la confidentialité et à la protection de vos données.
|
|
|
+ Les données recueillies par Opentalent sont utilisées pour le traitement
|
|
|
+ de votre demande et pour vous informer sur nos offres. Elles sont
|
|
|
+ destinées aux services Opentalent et à ses sous-traitants pour
|
|
|
+ l’exécution des contrats. Conformément à la loi "Informatique et
|
|
|
+ Libertés du 6 Janvier 1978", vous disposez d’un droit d’accès, de
|
|
|
+ modifications, de rectification et de suppression des données vous
|
|
|
+ concernant. Pour toute demande, adressez-vous à : Opentalent, 217 rue
|
|
|
+ Raoul Follereau, 74300 CLUSES, opentalent.fr s’engage à la
|
|
|
+ confidentialité et à la protection de vos données.
|
|
|
</div>
|
|
|
</v-form>
|
|
|
|
|
|
<div v-else class="confirmation-message d-flex flex-row justify-center">
|
|
|
<v-card>
|
|
|
- <v-icon icon="fas fa-check mr-1"/>
|
|
|
- Votre demande de contact a bien été enregistrée, nous reviendrons vers vous dès que possible.
|
|
|
+ <v-icon icon="fas fa-check mr-1" />
|
|
|
+ Votre demande de contact a bien été enregistrée, nous reviendrons vers
|
|
|
+ vous dès que possible.
|
|
|
</v-card>
|
|
|
</div>
|
|
|
</LayoutContainer>
|
|
|
</template>
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
+import { useRouter } from "vue-router";
|
|
|
+import { type ComputedRef, reactive, Ref } from "vue";
|
|
|
import ContactRequest from "~/models/Maestro/ContactRequest";
|
|
|
import { useEntityManager } from "~/composables/data/useEntityManager";
|
|
|
-import { useRouter } from "vue-router";
|
|
|
|
|
|
const route = useRoute();
|
|
|
-const router = useRouter()
|
|
|
-const { em } = useEntityManager()
|
|
|
-
|
|
|
-const form: Ref<any | null> = ref(null)
|
|
|
-
|
|
|
-const requestTypes: Array<{id: string, label: string}> = [
|
|
|
- { id: "CONTACT_REQUEST_INFORMATION", label: "Demande d'information"},
|
|
|
- { id: "CONTACT_REQUEST_ESTIMATE", label: "Demande de devis"},
|
|
|
- { id: "CONTACT_REQUEST_DEMO", label: "Demande de démonstration"},
|
|
|
- { id: "CONTACT_REQUEST_OPTION", label: "Demande d'option supplémentaire"},
|
|
|
- { id: "CONTACT_REQUEST_OTHER", label: "Autre"}
|
|
|
-]
|
|
|
-
|
|
|
-const products: Array<{id: string, label: string}> = [
|
|
|
- { id: "PRODUCT_AGENDA", label: "Agenda culturel"},
|
|
|
- { id: "PRODUCT_ARTIST", label: "Opentalent Artist"},
|
|
|
- { id: "PRODUCT_SCHOOL", label: "Opentalent School"},
|
|
|
- { id: "PRODUCT_MANAGER", label: "Opentalent Manager"},
|
|
|
- { id: "PRODUCT_ADVERTISING", label: "Publicité"},
|
|
|
- { id: "PRODUCT_OTHER", label: "Autre"}
|
|
|
-]
|
|
|
-
|
|
|
-const defaultRequestType = route.query.request ?? 'CONTACT_REQUEST_INFORMATION'
|
|
|
-
|
|
|
-//@ts-ignore
|
|
|
-const contactRequest: ContactRequest = reactive(em.newInstance(ContactRequest, { requestType: defaultRequestType }))
|
|
|
+const router = useRouter();
|
|
|
+const { em } = useEntityManager();
|
|
|
+
|
|
|
+const form: Ref<HTMLElement | null> = ref(null);
|
|
|
+
|
|
|
+const requestTypes: Array<{ id: string; label: string }> = [
|
|
|
+ { id: "CONTACT_REQUEST_INFORMATION", label: "Demande d'information" },
|
|
|
+ { id: "CONTACT_REQUEST_ESTIMATE", label: "Demande de devis" },
|
|
|
+ { id: "CONTACT_REQUEST_DEMO", label: "Demande de démonstration" },
|
|
|
+ { id: "CONTACT_REQUEST_OPTION", label: "Demande d'option supplémentaire" },
|
|
|
+ { id: "CONTACT_REQUEST_OTHER", label: "Autre" },
|
|
|
+];
|
|
|
+
|
|
|
+const products: Array<{ id: string; label: string }> = [
|
|
|
+ { id: "PRODUCT_AGENDA", label: "Agenda culturel" },
|
|
|
+ { id: "PRODUCT_ARTIST", label: "Opentalent Artist" },
|
|
|
+ { id: "PRODUCT_SCHOOL", label: "Opentalent School" },
|
|
|
+ { id: "PRODUCT_MANAGER", label: "Opentalent Manager" },
|
|
|
+ { id: "PRODUCT_ADVERTISING", label: "Publicité" },
|
|
|
+ { id: "PRODUCT_OTHER", label: "Autre" },
|
|
|
+];
|
|
|
+
|
|
|
+const defaultRequestType = route.query.request ?? "CONTACT_REQUEST_INFORMATION";
|
|
|
+
|
|
|
+// @ts-ignore
|
|
|
+const contactRequest: ContactRequest = reactive(
|
|
|
+ em.newInstance(ContactRequest, { requestType: defaultRequestType }),
|
|
|
+);
|
|
|
|
|
|
// --- Validation ---
|
|
|
-const maxMessageLength = 2000
|
|
|
+const maxMessageLength = 2000;
|
|
|
|
|
|
-const leftCars: ComputedRef<number> = computed(() =>
|
|
|
- maxMessageLength - (contactRequest.message ? contactRequest.message.length : 0)
|
|
|
-)
|
|
|
+const leftCars: ComputedRef<number> = computed(
|
|
|
+ () =>
|
|
|
+ maxMessageLength -
|
|
|
+ (contactRequest.message ? contactRequest.message.length : 0),
|
|
|
+);
|
|
|
|
|
|
-const validateName = (name: string | null) => !!name || "Le nom est obligatoire";
|
|
|
+const validateName = (name: string | null) =>
|
|
|
+ !!name || "Le nom est obligatoire";
|
|
|
|
|
|
-const validateSurname = (surname: string | null) => !!surname || "Le prénom est obligatoire";
|
|
|
+const validateSurname = (surname: string | null) =>
|
|
|
+ !!surname || "Le prénom est obligatoire";
|
|
|
|
|
|
const validatePostalCode = (postalCode: string | null) =>
|
|
|
- (!!postalCode && /^\d{5}$/.test(postalCode)) || "Le code postal doit être valide";
|
|
|
+ (!!postalCode && /^\d{5}$/.test(postalCode)) ||
|
|
|
+ "Le code postal doit être valide";
|
|
|
|
|
|
-const validateCity = (city: string | null) => !!city || "La ville est obligatoire";
|
|
|
+const validateCity = (city: string | null) =>
|
|
|
+ !!city || "La ville est obligatoire";
|
|
|
|
|
|
const validateEmail = (email: string | null) =>
|
|
|
(!!email && /.+@.+\..+/.test(email)) || "L'adresse e-mail doit être valide";
|
|
|
|
|
|
const validatePhone = (email: string | null) =>
|
|
|
- (!!email && /^((\+|00)33\s?|0)[1-7]([\s.]?\d{2}){4}$/.test(email)) || "Le numéro de téléphone doit être valide";
|
|
|
+ (!!email && /^((\+|00)33\s?|0)[1-7]([\s.]?\d{2}){4}$/.test(email)) ||
|
|
|
+ "Le numéro de téléphone doit être valide";
|
|
|
|
|
|
const validateStructureName = (structureName: string | null) =>
|
|
|
!!structureName || "Le nom de la structure est requis";
|
|
|
|
|
|
const validateNonEmptyMessage = (message: string | null) =>
|
|
|
- (!!message && message.length > 0) ||
|
|
|
- "Le message ne peut pas être vide";
|
|
|
+ (!!message && message.length > 0) || "Le message ne peut pas être vide";
|
|
|
|
|
|
const validateMessageLength = (message: string | null) =>
|
|
|
(!!message && message.length <= maxMessageLength) ||
|
|
|
@@ -275,7 +284,7 @@ const validateMessageLength = (message: string | null) =>
|
|
|
|
|
|
const contactRequestSent: Ref<boolean> = ref(false);
|
|
|
|
|
|
-const errorMsg: Ref<string | null> = ref(null)
|
|
|
+const errorMsg: Ref<string | null> = ref(null);
|
|
|
|
|
|
/**
|
|
|
* Submits the contact form.
|
|
|
@@ -287,33 +296,30 @@ const errorMsg: Ref<string | null> = ref(null)
|
|
|
* @returns {void}
|
|
|
*/
|
|
|
const submit = async (): Promise<void> => {
|
|
|
- const { valid } = await form.value.validate()
|
|
|
+ const { valid } = await form.value.validate();
|
|
|
|
|
|
if (!valid) {
|
|
|
- contactRequestSent.value = false
|
|
|
- return
|
|
|
+ contactRequestSent.value = false;
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
try {
|
|
|
- await em.persist(ContactRequest, contactRequest)
|
|
|
+ await em.persist(ContactRequest, contactRequest);
|
|
|
} catch (e) {
|
|
|
- errorMsg.value = "Une erreur s'est produite, nous sommes navrés pour le désagrément. Veuillez réessayer plus tard."
|
|
|
- return
|
|
|
+ errorMsg.value =
|
|
|
+ "Une erreur s'est produite, nous sommes navrés pour le désagrément. Veuillez réessayer plus tard.";
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
contactRequestSent.value = true;
|
|
|
- errorMsg.value = null
|
|
|
+ errorMsg.value = null;
|
|
|
|
|
|
// Défile vers le début de page pour afficher le message de confirmation
|
|
|
- setTimeout(
|
|
|
- () => router.push({ path: '', hash: '#anchor' }),
|
|
|
- 30
|
|
|
- )
|
|
|
+ setTimeout(() => router.push({ path: "", hash: "#anchor" }), 30);
|
|
|
};
|
|
|
</script>
|
|
|
|
|
|
<style scoped lang="scss">
|
|
|
-
|
|
|
h4 {
|
|
|
display: flex;
|
|
|
flex-direction: row;
|