add captcha

This commit is contained in:
Rivaland Tawouafo 2024-02-10 16:10:44 +01:00
parent 72e31a8d8a
commit aecbccf7a6
7 changed files with 119 additions and 171 deletions

View file

@ -1,6 +1,9 @@
<script setup lang="ts">
const { locale, setLocale, t } = useI18n({ useScope: 'global' })
import { useRecaptchaProvider } from 'vue-recaptcha'
useRecaptchaProvider()
const currentLang = computed(() => {
return locale.value === 'de' ? 'de' : 'en'
})

View file

@ -5,6 +5,7 @@ import { toTypedSchema } from '@vee-validate/yup';
import * as yup from 'yup';
import { setLocale } from 'yup';
const { t, locale } = useI18n({ useScope: 'global' })
@ -25,6 +26,7 @@ const schema = toTypedSchema(
email: yup.string().required().email(),
phone: yup.string().required(),
message: yup.string().required(),
recaptcha: yup.string().required(),
}),
);
@ -36,68 +38,33 @@ const [name, nameAttrs] = defineField('name');
const [email, emailAttrs] = defineField('email');
const [phone, phoneAttrs] = defineField('phone');
const [message, messageAttrs] = defineField('message');
const [recaptcha, recaptchaAttrs] = defineField('recaptcha');
const mail = useMail()
// const { $mail } = useNuxtApp()
// const toggle = ref(false)
// const token = ref("")
// const turnstile = ref()
// function reset() {
// turnstile.value?.reset()
// }
const config = useRuntimeConfig()
const recaptchaSiteKey = config.public.recaptchaSiteKey
const sendingEmail = ref(false)
const sendSuccessFull = ref(false)
const onSubmit = handleSubmit(async (values) => {
// toggle.value = true
sendingEmail.value = true
// const captchaResponse = grecaptcha.getResponse();
// try {
// mail.send({
// from: values.email,
// subject: 'Contact from conop-systems.com',
// text: 'Name: ' + values.name + '\nMessage: ' + values.message + '\nTelephone: ' + values.phone,
// });
// } catch (error) {
// alert("Sommething went wrong, please try again!")
// }
// setTimeout(() => {
// sendingEmail.value = false
// }, 2000);
// watch(token, () => {
// if (token.value !== "") {
// try {
// mail.send({
// from: values.email,
// subject: 'Contact from conop-systems.com',
// text: 'Name: ' + values.name + '\nMessage: ' + values.message + '\nTelephone: ' + values.phone,
// });
// } catch (error) {
// alert("Sommething went wrong, please try again!")
// }
// setTimeout(() => {
// sendingEmail.value = false
// }, 2000);
// toggle.value = false
// } else {
// alert("Please complete the captcha!")
// toggle.value = false
// sendingEmail.value = false
// }
// })
try {
mail.send({
from: values.email,
subject: 'Contact from conop-systems.com',
text: 'Name: ' + values.name + '\nMessage: ' + values.message + '\nTelephone: ' + values.phone,
});
sendSuccessFull.value = true
} catch (error) {
alert("Sommething went wrong, please try again!")
}
setTimeout(() => {
sendingEmail.value = false
sendSuccessFull.value = false
}, 2000);
});
</script>
@ -138,8 +105,12 @@ const onSubmit = handleSubmit(async (values) => {
{{ errors.message }}
</p>
</div>
<!-- <NuxtTurnstile v-if="toggle" ref="turnstile" v-model="token" :key="locale" :options="{ action: 'native' }" /> -->
<div class="g-recaptcha" :data-sitekey="recaptchaSiteKey"></div>
<div class="footer__form__field flex flex-col mb-3">
<RecaptchaCheckbox v-model="recaptcha" v-bind="recaptchaAttrs" />
<p class="text-red-500 ml-3 mt-1 transition-all">
{{ errors.recaptcha }}
</p>
</div>
<button type="submit"
class="btn__contact bg-c-blue text-c-darkblue px-7 py-2 uppercase text-xl rounded-full mt-3 flex justify-center">
<span v-if="!sendingEmail">
@ -147,6 +118,17 @@ const onSubmit = handleSubmit(async (values) => {
</span>
<div v-else class="spinner"></div>
</button>
<div id="toast-simple" v-if="sendSuccessFull"
class="mt-4 flex items-center w-full max-w-xs p-4 space-x-4 rtl:space-x-reverse divide-x rtl:divide-x-reverse rounded-lg shadow text-gray-400 divide-gray-700 space-x bg-gray-800"
role="alert">
<svg class="w-5 h-5 text-blue-600 dark:text-blue-500 rotate-45" aria-hidden="true"
xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 18 20">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="m9 17 8 2L9 1 1 19l8-2Zm0 0V9" />
</svg>
<div class="ps-4 text-sm font-normal">Message sent successfully.</div>
</div>
</form>
</template>

View file

@ -19,7 +19,8 @@
"phone": "Ihr Telefon",
"phone_placeholder": "Beispiel: +49 30 12345678",
"message": "Ihre Nachricht",
"btn_form": "Jetzt kontaktieren"
"btn_form": "Jetzt kontaktieren",
"send": "Nachricht erfolgreich gesendet"
},
"conop": {
"title": "Conop-Systems",
@ -68,7 +69,8 @@
"name": "Name",
"email": "E-Mail",
"message": "Nachricht",
"phone": "Telefon"
"phone": "Telefon",
"recaptcha": "ReCaptcha"
}
}
}

View file

@ -19,7 +19,8 @@
"phone": "Your Phone",
"phone_placeholder": "Example: +49 30 12345678",
"message": "Your Message",
"btn_form": "Contact Now"
"btn_form": "Contact Now",
"send": "Message send successfully"
},
"conop": {
"title": "Conop-Systems",
@ -68,7 +69,8 @@
"name": "Name",
"email": "Email",
"message": "Message",
"phone": "Phone"
"phone": "Phone",
"recaptcha": "Recaptcha"
}
}
}

View file

@ -17,18 +17,10 @@ export default defineNuxtConfig({
host: "smtp.conop-systems.com"
},
}],
'vue-recaptcha/nuxt'
],
app: {
pageTransition: { name: 'page', mode: 'out-in' },
head: {
script: [
{
src: "https://www.google.com/recaptcha/api.js",
async: true,
defer: true
}
]
}
},
postcss: {
plugins: {
@ -74,10 +66,16 @@ export default defineNuxtConfig({
}
},
runtimeConfig: {
recaptchaSecretKey: '', // can be overridden by NUXT_API_SECRET environment variable
recaptchaSecretKey: '',
public: {
recaptchaSiteKey: '6LdqNG4pAAAAAHAMtgsTv7cx8TZXwwxOXzeXppB8', // can be overridden by NUXT_PUBLIC_API_BASE environment variable
recaptchaSiteKey: '6LdqNG4pAAAAAHAMtgsTv7cx8TZXwwxOXzeXppB8',
recaptcha: {
v2SiteKey: '6LdqNG4pAAAAAHAMtgsTv7cx8TZXwwxOXzeXppB8'
}
}
},
recaptcha: {
plugin: true
}
});

162
package-lock.json generated
View file

@ -13,7 +13,8 @@
"@vee-validate/yup": "^4.12.5",
"@vueuse/motion": "^2.0.0",
"nuxt-mail": "^4.0.2",
"vee-validate": "^4.12.5"
"vee-validate": "^4.12.5",
"vue-recaptcha": "^3.0.0-alpha.6"
},
"devDependencies": {
"@dargmuesli/nuxt-cookie-control": "^7.2.4",
@ -2339,31 +2340,6 @@
}
}
},
"node_modules/@nuxtjs/i18n/node_modules/vue-demi": {
"version": "0.14.6",
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.6.tgz",
"integrity": "sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==",
"hasInstallScript": true,
"bin": {
"vue-demi-fix": "bin/vue-demi-fix.js",
"vue-demi-switch": "bin/vue-demi-switch.js"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
},
"peerDependencies": {
"@vue/composition-api": "^1.0.0-rc.1",
"vue": "^3.0.0-0 || ^2.6.0"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
}
}
},
"node_modules/@nuxtjs/i18n/node_modules/vue-i18n-routing": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/vue-i18n-routing/-/vue-i18n-routing-1.2.0.tgz",
@ -3861,31 +3837,6 @@
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/@vueuse/core/node_modules/vue-demi": {
"version": "0.14.6",
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.6.tgz",
"integrity": "sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==",
"hasInstallScript": true,
"bin": {
"vue-demi-fix": "bin/vue-demi-fix.js",
"vue-demi-switch": "bin/vue-demi-switch.js"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
},
"peerDependencies": {
"@vue/composition-api": "^1.0.0-rc.1",
"vue": "^3.0.0-0 || ^2.6.0"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
}
}
},
"node_modules/@vueuse/head": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@vueuse/head/-/head-2.0.0.tgz",
@ -3945,31 +3896,6 @@
"nuxt": "^3.0.0"
}
},
"node_modules/@vueuse/nuxt/node_modules/vue-demi": {
"version": "0.14.6",
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.6.tgz",
"integrity": "sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==",
"hasInstallScript": true,
"bin": {
"vue-demi-fix": "bin/vue-demi-fix.js",
"vue-demi-switch": "bin/vue-demi-switch.js"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
},
"peerDependencies": {
"@vue/composition-api": "^1.0.0-rc.1",
"vue": "^3.0.0-0 || ^2.6.0"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
}
}
},
"node_modules/@vueuse/shared": {
"version": "10.7.2",
"resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-10.7.2.tgz",
@ -3981,31 +3907,6 @@
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/@vueuse/shared/node_modules/vue-demi": {
"version": "0.14.6",
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.6.tgz",
"integrity": "sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==",
"hasInstallScript": true,
"bin": {
"vue-demi-fix": "bin/vue-demi-fix.js",
"vue-demi-switch": "bin/vue-demi-switch.js"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
},
"peerDependencies": {
"@vue/composition-api": "^1.0.0-rc.1",
"vue": "^3.0.0-0 || ^2.6.0"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
}
}
},
"node_modules/@webassemblyjs/ast": {
"version": "1.11.6",
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz",
@ -10255,6 +10156,17 @@
"url": "https://github.com/chalk/supports-color?sponsor=1"
}
},
"node_modules/p-defer": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/p-defer/-/p-defer-4.0.0.tgz",
"integrity": "sha512-Vb3QRvQ0Y5XnF40ZUWW7JfLogicVh/EnA5gBIvKDJoYpeI82+1E3AlB9yOcKFS0AhHrWVnAQO39fbR0G99IVEQ==",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/p-map": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz",
@ -13993,6 +13905,31 @@
"integrity": "sha512-0vOfAtI67UjeO1G6UiX5Kd76CqaQ67wrRZiOe7UAb9Jm6GzlUr/fC7CV90XfwapJRjpCMaZFhv1V0ajWRmE9Dg==",
"dev": true
},
"node_modules/vue-demi": {
"version": "0.14.7",
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.7.tgz",
"integrity": "sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==",
"hasInstallScript": true,
"bin": {
"vue-demi-fix": "bin/vue-demi-fix.js",
"vue-demi-switch": "bin/vue-demi-switch.js"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
},
"peerDependencies": {
"@vue/composition-api": "^1.0.0-rc.1",
"vue": "^3.0.0-0 || ^2.6.0"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
}
}
},
"node_modules/vue-devtools-stub": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/vue-devtools-stub/-/vue-devtools-stub-0.1.0.tgz",
@ -14017,6 +13954,29 @@
"vue": "^3.0.0"
}
},
"node_modules/vue-recaptcha": {
"version": "3.0.0-alpha.6",
"resolved": "https://registry.npmjs.org/vue-recaptcha/-/vue-recaptcha-3.0.0-alpha.6.tgz",
"integrity": "sha512-hwxxAXENLN6GKJhH6s+NJV1f6llSFEQ0jMTxjEunpR6CMbQ5xc7DAHFtwrsDutGnbS8wl9yp30jsYcCToZEhTQ==",
"dependencies": {
"@nuxt/kit": "^3.4.3",
"@nuxt/schema": "^3.4.3",
"@vueuse/shared": "^10.1.0",
"defu": "^6.1.2",
"p-defer": "^4.0.0",
"std-env": "^3.3.2",
"type-fest": "^3.9.0",
"vue-demi": "^0.14.0"
},
"peerDependencies": {
"vue": "^3.0.0"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
}
}
},
"node_modules/vue-router": {
"version": "4.2.5",
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.2.5.tgz",

View file

@ -30,6 +30,7 @@
"@vee-validate/yup": "^4.12.5",
"@vueuse/motion": "^2.0.0",
"nuxt-mail": "^4.0.2",
"vee-validate": "^4.12.5"
"vee-validate": "^4.12.5",
"vue-recaptcha": "^3.0.0-alpha.6"
}
}