187 lines
4.1 KiB
Vue
187 lines
4.1 KiB
Vue
<script>
|
||
|
||
export default {
|
||
data() {
|
||
return {
|
||
endpoint: process.env.NODE_ENV === 'production'
|
||
? '/api/contact'
|
||
: 'http://127.0.0.1:3001/contact',
|
||
|
||
labelStyle: "block text-lg text-primary-dark mb-2",
|
||
inputStyle: "w-full px-5 py-2 " +
|
||
"border border-gray-300 " +
|
||
"text-primary-dark bg-ternary-light " +
|
||
"rounded-md shadow-sm text-md " +
|
||
"focus:border-primary-dark focus:ring-0",
|
||
|
||
name: "",
|
||
contacts: "",
|
||
message: "",
|
||
|
||
captchaSolved: false
|
||
};
|
||
},
|
||
|
||
computed: {
|
||
formReady() {
|
||
let isNotEmpty = this.name !== '' && this.contacts !== ''
|
||
let isValid = this.$refs.name.checkValidity() && this.$refs.contacts.checkValidity()
|
||
return this.captchaSolved && isNotEmpty && isValid
|
||
}
|
||
},
|
||
|
||
async mounted() {
|
||
await this.$recaptcha.init()
|
||
},
|
||
|
||
beforeDestroy() {
|
||
this.$recaptcha.destroy()
|
||
},
|
||
|
||
methods: {
|
||
async resetCaptcha() {
|
||
await this.$recaptcha.reset()
|
||
this.captchaSolved = false
|
||
},
|
||
|
||
async onSubmit() {
|
||
// To prevent `:invalid` CSS class to be applied on page load
|
||
this.$refs.form.classList.add("submitted")
|
||
|
||
if (!this.formReady) {
|
||
return
|
||
}
|
||
|
||
try {
|
||
let formData = new FormData()
|
||
formData.append('name', this.name)
|
||
formData.append('contacts', this.contacts)
|
||
formData.append('message', this.message)
|
||
formData.append('g-recaptcha-response', await this.$recaptcha.getResponse())
|
||
|
||
fetch(this.endpoint,
|
||
{
|
||
method: "post",
|
||
mode: "cors",
|
||
body: formData,
|
||
})
|
||
.then((response) => {
|
||
if (response.ok) {
|
||
return;
|
||
}
|
||
|
||
return Promise.reject(response);
|
||
})
|
||
.then(_ => {
|
||
alert("Спасибо за обращение!")
|
||
this.resetCaptcha()
|
||
})
|
||
.catch(error => {
|
||
alert("Произошла ошибка, повторите отправку формы позднее")
|
||
console.error('Error:', error);
|
||
this.resetCaptcha()
|
||
});
|
||
|
||
|
||
} catch (error) {
|
||
console.error(error)
|
||
}
|
||
}
|
||
},
|
||
};
|
||
</script>
|
||
|
||
<template>
|
||
<div
|
||
class="
|
||
leading-loose
|
||
max-w-xl
|
||
p-7
|
||
bg-secondary-light
|
||
|
||
rounded-xl
|
||
shadow-xl
|
||
text-left
|
||
"
|
||
>
|
||
<p
|
||
class="
|
||
font-general-medium
|
||
text-primary-dark
|
||
|
||
text-2xl
|
||
mb-8
|
||
"
|
||
>
|
||
Свяжитесь со мной
|
||
</p>
|
||
|
||
<form
|
||
class="font-general-regular space-y-7"
|
||
ref="form"
|
||
novalidate
|
||
>
|
||
<div class="">
|
||
<label :class="labelStyle" for="name">Ваше имя*</label>
|
||
|
||
<input
|
||
ref="name"
|
||
v-model="name"
|
||
:class="inputStyle"
|
||
type="text"
|
||
placeholder=""
|
||
aria-label="Name"
|
||
required
|
||
/>
|
||
</div>
|
||
<div>
|
||
<label :class="labelStyle" for="contacts">Контактный телефон/WhatsApp/Telegram/электронная почта*</label>
|
||
|
||
<input
|
||
ref="contacts"
|
||
v-model="contacts"
|
||
:class="inputStyle"
|
||
placeholder=""
|
||
aria-label="Contacts"
|
||
required
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<label :class="labelStyle" for="message">Сообщение</label>
|
||
|
||
<textarea
|
||
ref="message"
|
||
:class="inputStyle"
|
||
v-model="message"
|
||
cols="14"
|
||
rows="6"
|
||
aria-label="Message"
|
||
></textarea>
|
||
</div>
|
||
|
||
<recaptcha
|
||
@error="captchaSolved = false"
|
||
@expired="captchaSolved = false"
|
||
@success="captchaSolved = true"
|
||
/>
|
||
|
||
<div>
|
||
<RoundButton
|
||
@click.native.prevent="onSubmit()"
|
||
class="px-6 inline-flex items-center"
|
||
aria-label="Send Message"
|
||
>
|
||
Отправить
|
||
</RoundButton>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</template>
|
||
|
||
<style lang="css" scoped>
|
||
form.submitted input:invalid {
|
||
@apply invalid:border-red-500;
|
||
}
|
||
</style>
|