diff --git a/src/components/contact-form/contact-form.component.jsx b/src/components/contact-form/contact-form.component.jsx index 805ec1b..caa900f 100644 --- a/src/components/contact-form/contact-form.component.jsx +++ b/src/components/contact-form/contact-form.component.jsx @@ -1,4 +1,4 @@ -import React, { useState, useRef } from "react"; +import React, { useState, useRef, useEffect } from "react"; import axios from "axios"; import { useTranslation } from "react-i18next"; import "./contact-form.style.scss"; @@ -9,6 +9,28 @@ import YellowPlanet from "../../assets/images/main/contact-form/Planet Yellow.sv import FormInput from "../form-input/form-input.component"; import CustomButton from "../custom-button/custom-button.component"; +const verifyCaptcha = async (captchaToken) => { + const keyId = "8e5272fb9c08"; + + try { + const response = await axios.post( + `https://cap.midcreative.eu/${keyId}/siteverify`, + { + response: captchaToken, + }, + { + headers: { + "Content-Type": "application/json", + }, + } + ); + return response.data.success; + } catch (error) { + console.error("Captcha verification failed:", error); + return false; + } +}; + const newPost = async (data) => { return axios .post("https://midcreative.eu/mail/", data, { @@ -17,7 +39,10 @@ const newPost = async (data) => { }, }) .then((res) => true) - .catch((err) => err); + .catch((err) => { + console.error("Form submission error:", err); + return false; + }); }; const ContactForm = () => { @@ -34,6 +59,8 @@ const ContactForm = () => { const [success, setSuccess] = useState(); const [error, setError] = useState(); + const [captchaToken, setCaptchaToken] = useState(null); + const [captchaError, setCaptchaError] = useState(false); const setName = (name) => { setFormData({ ...formData, name: name }); @@ -53,21 +80,69 @@ const ContactForm = () => { phoneInputRef.current.clean(); }; - const handlePost = (e) => { + useEffect(() => { + const handleCaptchaCompleted = (event) => { + if (event.detail && event.detail.token) { + setCaptchaToken(event.detail.token); + setCaptchaError(false); + } + }; + + const captchaWidget = document.querySelector('cap-widget'); + if (captchaWidget) { + captchaWidget.addEventListener('cap-completed', handleCaptchaCompleted); + } + + return () => { + if (captchaWidget) { + captchaWidget.removeEventListener('cap-completed', handleCaptchaCompleted); + } + }; + }, []); + + const handlePost = async (e) => { e.preventDefault(); - newPost(formData).then((res) => { - if (res === true) { + if (!captchaToken) { + setCaptchaError(true); + return; + } + + const isCaptchaValid = await verifyCaptcha(captchaToken); + + if (!isCaptchaValid) { + setCaptchaError(true); + setCaptchaToken(null); + const captchaWidget = document.querySelector('cap-widget'); + if (captchaWidget && captchaWidget.reset) { + captchaWidget.reset(); + } + return; + } + + try { + const response = await newPost(formData); + + if (response === true) { cleanFields(); setError(false); setSuccess(true); + setCaptchaToken(null); + setCaptchaError(false); + const captchaWidget = document.querySelector('cap-widget'); + if (captchaWidget && captchaWidget.reset) { + captchaWidget.reset(); + } setTimeout(() => setSuccess(false), 6000); } else { - cleanFields(); setError(true); setSuccess(false); } - }); + } catch (err) { + console.error("Form submission failed:", err); + setError(true); + setSuccess(false); + } }; return ( @@ -113,6 +188,16 @@ const ContactForm = () => { required /> + + + {captchaError && ( +

+ {t("contacts.captchaError") || "Please complete the captcha"} +

+ )} + diff --git a/src/components/footer/footer.component.jsx b/src/components/footer/footer.component.jsx index 2a1ead9..24a3a41 100644 --- a/src/components/footer/footer.component.jsx +++ b/src/components/footer/footer.component.jsx @@ -1,7 +1,9 @@ import React from "react"; +import { Link } from "gatsby"; import "./footer.style.scss"; import { useTranslation } from "react-i18next"; +import { getLocalizedPath } from "../../utils/navigation"; import Contacts from "../contacts/contacts.component"; import TopLine from "../../assets/images/main/footer/top-line.png"; @@ -27,21 +29,21 @@ const MidFooter = () => {
diff --git a/src/components/header/header.component.jsx b/src/components/header/header.component.jsx index 970e998..f3f7d93 100644 --- a/src/components/header/header.component.jsx +++ b/src/components/header/header.component.jsx @@ -4,6 +4,7 @@ import { Link } from "gatsby"; import { useTranslation } from "react-i18next"; import LanguageSwitch from "../language-switch/language-switch.component"; +import { getLocalizedPath } from "../../utils/navigation"; import Logo from "../../assets/images/main/header/logo.svg"; import Logo2 from "../../assets/images/main/footer/logo.svg"; @@ -64,10 +65,10 @@ const MidHeader = () => { MID
@@ -91,11 +92,11 @@ const MidHeader = () => { MID Creative Digital Agency
diff --git a/src/components/language-switch/language-switch.component.jsx b/src/components/language-switch/language-switch.component.jsx index 67e1396..3698b37 100644 --- a/src/components/language-switch/language-switch.component.jsx +++ b/src/components/language-switch/language-switch.component.jsx @@ -1,4 +1,5 @@ import React from "react"; +import { navigate } from "gatsby"; import i18n from "../../i18n"; import "./language-switch.style.scss"; @@ -6,6 +7,13 @@ import "./language-switch.style.scss"; const LanguageSwitch = ({ t }) => { const changeLanguage = (lng) => { i18n.changeLanguage(lng); + + // Navigate to the appropriate route + if (lng === "lv") { + navigate("/lv"); + } else { + navigate("/"); + } }; return ( diff --git a/src/components/seo.jsx b/src/components/seo.jsx index ca53945..16f6183 100644 --- a/src/components/seo.jsx +++ b/src/components/seo.jsx @@ -33,6 +33,10 @@ export const Seo = ({ title, description, pathname, children }) => { gtag('config', 'G-8M9CZ79T4L'); `} +