/** * This file is part of the SplendidBear Websites' projects. * * Copyright (c) 2026 @ www.splendidbear.org * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ import { useEffect, useRef } from 'react'; /** * ContactForm Component * * Handles reCAPTCHA v3 integration for the contact form. * Intercepts form submission, executes reCAPTCHA, and submits the form with the token. * * @param {string} siteKey - Google reCAPTCHA site key * @param {string} recaptchaFieldId - ID of the hidden recaptcha input field */ const ContactForm = ({ siteKey, recaptchaFieldId }) => { const formRef = useRef(null); const isSubmittingRef = useRef(false); useEffect(() => { const form = document.querySelector('.auth-form'); if (!form) { console.warn('ContactForm: No .auth-form found'); return; } formRef.current = form; const handleSubmit = e => { e.preventDefault(); if (isSubmittingRef.current) { return; } isSubmittingRef.current = true; if ('undefined' !== typeof grecaptcha) { grecaptcha.ready(() => { grecaptcha .execute(siteKey, { action: 'contact' }) .then(token => { const recaptchaField = document.getElementById(recaptchaFieldId); if (recaptchaField) { recaptchaField.value = token; } else { console.error(`ContactForm: Recaptcha field with ID "${recaptchaFieldId}" not found`); } isSubmittingRef.current = false; form.submit(); }) .catch(error => { console.error('ContactForm: reCAPTCHA execution failed', error); isSubmittingRef.current = false; }); }); } else { console.error('ContactForm: grecaptcha is not loaded'); isSubmittingRef.current = false; } }; form.addEventListener('submit', handleSubmit); return () => { if (formRef.current) { formRef.current.removeEventListener('submit', handleSubmit); } }; }, [siteKey, recaptchaFieldId]); return null; }; export default ContactForm;