ldc-showroom/components/ProductModal.vue.not_used
2024-01-17 10:00:51 +01:00

209 lines
6.5 KiB
Text

<template>
<div :id="id" ref="modal" class="modal fade" tabindex="-1">
<div class="modal-dialog modal-xxl">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">
{{ `${item.name} - ${item.teaser}` }}
</h5>
<button
type="button"
class="btn-close"
data-bs-dismiss="modal"
aria-label="Close"
/>
</div>
<div class="modal-body">
<div class="row">
<div class="col-4 text-center">
<img class="img-fluid" :src="item.img" :title="item.name" :alt="item.name">
</div>
<div class="col-8">
<div v-sane-html="item.description" class="bg-secondary text-bg-secondary p-3 m-3 rounded" />
<form ref="form" action="#" class="p-3 needs-validation" novalidate>
<label for="validationEmail" class="form-label mt-5">Votre email</label>
<div class="input-group has-validation mb-5">
<span class="input-group-text">@</span>
<input
id="validationEmail"
ref="email"
v-model="email"
type="email"
class="form-control"
placeholder="monemail@example.fr"
aria-label="Email"
aria-describedby="emailHelp"
required
autocomplete="off"
@blur="validateEmail"
>
<div class="invalid-feedback">
Veuillez vérifier la saisie de votre email.
</div>
</div>
<div class="form-check mb-5">
<input
id="btn-check-agreed"
ref="checkbox"
v-model="interested"
type="checkbox"
class="form-check-input d-none"
autocomplete="off"
required
aria-describedby="btn-check-agreed-feedback"
>
<label class="form-check-label btn btn-light" for="btn-check-agreed">
<FontAwesomeIcon v-if="!interested" icon="square" />
<FontAwesomeIcon v-if="interested" icon="square-check" />
{{ settings.ctaBtnText }}
</label>
<div id="btn-check-agreed-feedback" class="invalid-feedback">
Vous devez cocher la case pour enregistrer votre demande
</div>
<div v-sane-html="settings.ctaDisclaimerText" />
</div>
</form>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" @click="($refs.form as HTMLFormElement).requestSubmit()">
{{ settings.ctaSaveBtn }}
</button>
</div>
</div>
</div>
</div>
</template>
<script lang="ts">
// eslint-disable-next-line import/named
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
import DOMPurify from "dompurify";
import type { DirectiveBinding, PropType } from "vue";
import { defineComponent } from "vue";
const saneHtml = {
mounted: (el: HTMLElement, binding: DirectiveBinding) => {
el.innerHTML = DOMPurify.sanitize(binding.value);
},
};
export default defineComponent({
name: "ProductModal",
components: { FontAwesomeIcon },
directives: {
saneHtml,
},
props: {
id: {
type: String,
required: true,
},
item: {
type: Object as PropType<Item>,
required: true,
},
settings: {
type: Object as PropType<Settings>,
required: true,
}
},
emits: ["saved"],
data(): {
modalShow: boolean;
emailIsValid: boolean;
email: string;
interested: boolean;
} {
return {
modalShow: false,
emailIsValid: false,
email: "",
interested: false,
};
},
watch: {
item() {
this.modalShow = true;
},
emailIsValid(newValue:boolean) {
this.setEmailValidity(newValue);
},
interested(newValue:boolean) {
this.setInterestedValidity(newValue);
},
},
mounted() {
this.$nextTick(() => {
const modal = this.$refs.modal as HTMLElement;
const form = this.$refs.form as HTMLFormElement;
form.addEventListener("submit", event => {
// * Empecher le submit dans tout les cas
event.preventDefault();
event.stopPropagation();
this.validateEmail();
this.setEmailValidity(!!this.emailIsValid);
this.setInterestedValidity(this.interested);
// ? Validation Ok ?
if(this.emailIsValid && this.interested) {
this.SaveContact();
}
}, false);
modal.addEventListener("hide.bs.modal", () => {
this.email = "";
this.interested = false;
this.clearValidation();
});
});
},
methods: {
matchEmail(email:string):RegExpMatchArray | null {
return String(email)
.toLowerCase()
.match(
/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|.(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
);
},
validateEmail():void {
this.emailIsValid = !!this.matchEmail(this.email);
},
SaveContact() {
const contact: Contact = {
product_id: this.item.id,
email: this.email,
consent: this.interested
};
this.$emit("saved", contact);
},
setEmailValidity(validity: boolean): void {
const email = this.$refs.email as HTMLInputElement;
this.setInputValidity(email, validity);
},
setInterestedValidity(validity: boolean): void {
const checkbox = this.$refs.checkbox as HTMLInputElement;
this.setInputValidity(checkbox, validity);
},
setInputValidity(input: HTMLInputElement, validity: boolean): void {
input.classList.remove("is-valid");
input.classList.remove("is-invalid");
if (validity) {
input.classList.add("is-valid");
} else {
input.classList.add("is-invalid");
}
},
clearValidation(): void {
const email = this.$refs.email as HTMLInputElement;
const checkbox = this.$refs.checkbox as HTMLInputElement;
email.classList.remove("is-valid");
checkbox.classList.remove("is-valid");
email.classList.remove("is-invalid");
checkbox.classList.remove("is-invalid");
}
},
});
</script>