/var/www/sites/twin-fin/js/config.js
/* =============================================================
⚙️ TWIN FIN — SITE CONFIGURATION
=============================================================
Edit this file to update contact details and form settings.
Changes here apply across the whole website automatically.
============================================================= */
const TWIN_FIN_CONFIG = {
/* -----------------------------------------------------------
📧 CONTACT EMAIL
Where all form submissions are sent (set in contact.php too).
----------------------------------------------------------- */
contactEmail: "bookings@twinfin.com.au",
/* -----------------------------------------------------------
🔒 reCAPTCHA v3 SITE KEY (public — safe to be here)
Secret key lives only in contact.php (server-side).
----------------------------------------------------------- */
recaptchaSiteKey: "6LfxBbIsAAAAACh80vIMNsOmA-P2k_rqt_XLaU3_",
/* -----------------------------------------------------------
📞 PHONE NUMBER
----------------------------------------------------------- */
phone: "(08) 6424-9503",
phoneHref: "tel:+61864249503",
};
/* =============================================================
⚠️ DO NOT EDIT BELOW THIS LINE
============================================================= */
// Wire up all forms on the page to contact.php with reCAPTCHA v3
document.addEventListener('DOMContentLoaded', () => {
const forms = document.querySelectorAll('form[data-twinfin-form]');
// Only load reCAPTCHA on pages that actually have forms
if (forms.length === 0) return;
// Inject reCAPTCHA v3 script dynamically
const script = document.createElement('script');
script.src = `https://www.google.com/recaptcha/api.js?render=${TWIN_FIN_CONFIG.recaptchaSiteKey}`;
script.async = true;
document.head.appendChild(script);
forms.forEach(form => {
// Point every form at the PHP handler
form.setAttribute('action', 'contact.php');
form.setAttribute('method', 'POST');
// Hidden field: which form is this?
const formNameField = document.createElement('input');
formNameField.type = 'hidden';
formNameField.name = '_form_name';
formNameField.value = form.dataset.twinfinForm;
form.appendChild(formNameField);
// Honeypot — hidden from real users, bots fill it in
const honeypot = document.createElement('input');
honeypot.type = 'text';
honeypot.name = 'website';
honeypot.autocomplete = 'off';
honeypot.style.cssText = 'position:absolute;left:-9999px;height:0;width:0;opacity:0;';
honeypot.tabIndex = -1;
honeypot.ariaHidden = 'true';
form.appendChild(honeypot);
// Hidden reCAPTCHA token field
const tokenField = document.createElement('input');
tokenField.type = 'hidden';
tokenField.name = 'g-recaptcha-response';
form.appendChild(tokenField);
// Handle submit
form.addEventListener('submit', async (e) => {
e.preventDefault();
const btn = form.querySelector('[type="submit"]');
const originalText = btn.textContent;
btn.textContent = 'Sending…';
btn.disabled = true;
try {
// Get reCAPTCHA v3 token
const token = [REDACTED] grecaptcha.execute(
TWIN_FIN_CONFIG.recaptchaSiteKey,
{ action: form.dataset.twinfinForm.toLowerCase().replace(/\s+/g, '_') }
);
tokenField.value = token;
// Submit via fetch
const res = await fetch('contact.php', {
method: 'POST',
body: new FormData(form),
});
const data = await res.json();
if (data.ok) {
const emailInput = form.querySelector('input[type="email"]');
form.innerHTML = `
<div class="form-success">
<div class="form-success__icon">✅</div>
<h3>Message sent!</h3>
<p>Thanks for getting in touch. We'll get back to you shortly${emailInput ? ' at <strong>' + emailInput.value + '</strong>' : ''}.</p>
</div>
`;
} else {
throw new Error(data.message || 'Server error');
}
} catch (err) {
btn.textContent = originalText;
btn.disabled = false;
let errEl = form.querySelector('.form-error');
if (!errEl) {
errEl = document.createElement('p');
errEl.className = 'form-error';
form.appendChild(errEl);
}
errEl.textContent =[REDACTED]