Files
website-old/src/components/ContactForm.vue
2021-07-02 18:02:14 +02:00

165 lines
5.2 KiB
Vue
Executable File

<template>
<section class="w-full flex items-center justify-center flex-col">
<h2 class="text-center mb-10 font-bold text-gray-700 text-2xl md:text-3xl my-4 dark:text-gray-400">
{{ $t('contact.form.title.main') }} <br class="lg:hidden"/><a class="email text-black dark:text-white" href="mailto:me@arthurdanjou.fr" target="_blank">{{ $t('contact.form.title.email') }}</a> 📬
</h2>
<form class="w-full lg:w-1/2">
<div class="w-full lg:flex justify-center mb-8 lg:mb-12">
<div class="form-div lg:w-1/2 mb-8 lg:mb-0 lg:mr-4">
<input
id="name"
v-model="form.name"
required
type="text"
placeholder=" "
class="first-input w-full"
/>
<label for="name" class="form-label">{{ $t('contact.form.name') }}</label>
</div>
<div class="form-div lg:w-1/2">
<input
id="email"
v-model="form.email"
required
type="email"
placeholder=" "
class="second-input w-full"
/>
<label for="email" class="form-label">{{ $t('contact.form.email') }}</label>
</div>
</div>
<div class="form-div w-full mb-8 lg:mb-12">
<input
id="subject"
v-model="form.subject"
required
type="text"
placeholder=" "
class="form-input w-full"
/>
<label for="subject" class="form-label">{{ $t('contact.form.subject') }}</label>
</div>
<div class="form-div w-full">
<textarea
id="content"
v-model="form.content"
required
placeholder=" "
class="form-input w-full"
minlength="30"
rows="4"
/>
<label for="content" class="form-label">{{ $t('contact.form.content') }}</label>
</div>
</form>
<div v-if="error" class="mt-4 px-3 py-1 rounded-full bg-red-300 font-bold text-black">
{{ $t('contact.form.error') }}
</div>
<div v-if="success" class="mt-4 px-3 py-1 rounded-full bg-green-300 font-bold text-black">
{{ $t('contact.form.success') }}
</div>
<div class="my-12">
<button :disabled="!isSendable" :class="{'disabled': !isSendable}" @click.prevent="handleForm" class="font-bold px-6 py-3 border-2 rounded-full border-indigo-600 text-indigo-600 hover:(bg-indigo-600 text-white) hover:dark:text-black duration-300 cursor-pointer">
{{ $t('contact.form.submit') }}
</button>
</div>
</section>
</template>
<script lang="ts">
import {computed, defineComponent, ref, useContext} from "@nuxtjs/composition-api";
import {Form} from "../../types/types";
export default defineComponent({
name: "ContactForm",
setup() {
const error = ref(false)
const success = ref(false)
const {$axios, $sentry} = useContext()
const form = ref<Form>({} as Form)
const handleForm = async () => {
const {data} = await $axios.post('form',
{
email: form.value.email,
name: form.value.name,
content: form.value.content,
subject: form.value.subject
}, {
headers: {
'Authorization': `Bearer ${process.env.API_TOKEN}`
}
})
if (data && data.status === 200) {
success.value = true
setTimeout(() => {
success.value = false
form.value = {} as Form
}, 5000)
} else {
$sentry.captureEvent(data)
error.value = true
setTimeout(() => {
error.value = false
}, 5000)
}
}
const isSendable = computed(() => {
const {email, name, content, subject} = form.value
return isNotEmpty(email) && isNotEmpty(name) && isNotEmpty(content) && isNotEmpty(subject)
})
const isNotEmpty = (object: string | undefined) => {
return object !== undefined && object.length > 0 && object !== "" && object !== ''
}
return {
error,
success,
isSendable,
form,
handleForm
}
}
})
</script>
<style scoped lang="scss">
input:focus-within ~ label, input:not(:placeholder-shown) ~ label {
@apply transform scale-75 -translate-y-6 -translate-x-7;
}
textarea:focus-within ~ label, textarea:not(:placeholder-shown) ~ label {
@apply transform scale-75 -translate-y-6 -translate-x-6;
}
.first-input:focus-within ~ label, .first-input:not(:placeholder-shown) ~ label {
@apply transform scale-75 -translate-y-6 -translate-x-5;
}
.second-input:focus-within ~ label, .second-input:not(:placeholder-shown) ~ label {
@apply transform scale-75 -translate-y-6 -translate-x-7;
}
.form-div {
@apply relative border-b border-gray-200 dark:border-gray-800 focus-within:border-black dark:focus-within:border-white
}
.second-input, .first-input, .form-input {
@apply block w-full appearance-none focus:outline-none bg-transparent
}
.form-label {
@apply absolute top-0 -z-1 duration-300 text-gray-700 dark:text-gray-400
}
.email {
@apply duration-300 border-b-2 border-gray-200 dark:border-gray-800 hover:(border-black dark:border-white)
}
.disabled {
@apply bg-gray-300 cursor-not-allowed border-gray-300 hover:text-black text-black
}
</style>