From 033bdf6625b53abb2921294d7f9073da6c435360 Mon Sep 17 00:00:00 2001 From: null Date: Wed, 27 May 2026 20:57:55 -0500 Subject: [PATCH] Form now POSTs to Zoho --- src/pages/Contact.jsx | 233 +++++++++++++++++++++--------------------- 1 file changed, 114 insertions(+), 119 deletions(-) diff --git a/src/pages/Contact.jsx b/src/pages/Contact.jsx index 356ce6f..c0e06f5 100644 --- a/src/pages/Contact.jsx +++ b/src/pages/Contact.jsx @@ -1,49 +1,71 @@ import SEO from '@/components/SEO' -import { useState } from 'react' +import { useState, useRef, useEffect } from 'react' import { toast } from 'sonner' import { Button } from '@/components/ui/Button' import { Input } from '@/components/ui/Input' import { Textarea } from '@/components/ui/Textarea' -import { Select } from '@/components/ui/Select' import RecaptchaPlaceholder from '@/components/RecaptchaPlaceholder' -import { submitLead } from '@/lib/api' -import { useDebounce } from '@/hooks/useDebounce' import { ArrowRight } from 'lucide-react' const Contact = () => { + const formRef = useRef(null) const [formState, setFormState] = useState({ - company: '', - name: '', - email: '', - phone: '', - zip: '', - message: '', - service_interest: '', - recaptcha_token: '', - company_website: '', + 'Last Name': '', + Company: '', + Email: '', + Phone: '', + 'Zip Code': '', + Description: '', }) const [errors, setErrors] = useState({ - company: '', - name: '', - email: '', - zip: '', - message: '', + 'Last Name': '', + Company: '', + Email: '', + 'Zip Code': '', + Description: '', recaptcha_token: '', }) - const debouncedErrors = useDebounce(errors, 300) + const [debouncedErrors, setDebouncedErrors] = useState(errors) const [isSubmitting, setIsSubmitting] = useState(false) + useEffect(() => { + const t = setTimeout(() => setDebouncedErrors(errors), 300) + return () => clearTimeout(t) + }, [errors]) + + useEffect(() => { + const iframe = document.getElementById('zoho_webform_iframe') + if (!iframe) return + const handleLoad = () => { + if (!isSubmitting) return + setIsSubmitting(false) + toast.success("Thanks! We'll be in touch shortly.") + setFormState({ 'Last Name': '', Company: '', Email: '', Phone: '', 'Zip Code': '', Description: '' }) + setErrors({ 'Last Name': '', Company: '', Email: '', 'Zip Code': '', Description: '', recaptcha_token: '' }) + } + iframe.addEventListener('load', handleLoad) + return () => iframe.removeEventListener('load', handleLoad) + }, [isSubmitting]) + + useEffect(() => { + const script = document.createElement('script') + script.id = 'wf_anal' + script.src = 'https://crm.zohopublic.com/crm/WebFormAnalyticsServeServlet?rid=e44e9662530fc5bd9cdd3c43501fc243f89ba03759e7946c4b5e5016795b606b59b54d0e73c68671b2140fac5c8e788agid3b907524e85f9cba94899d77d7200771ee5d0ea567c43ec341d7b2ce40324d40gid26922a9cd1e8191a5f58ecb2524e0d22b8dd027eb943658ee681ab6890436af2gidefa1b1002d15951a0a2ac36cb33cdb4b5c6aeb110e6f4ac68b764345b9429653&tw=e048253ca680b107993ed5922e00cc1ebab3de97e797fce56fc6ad6af0dfc0bc' + document.body.appendChild(script) + return () => { document.getElementById('wf_anal')?.remove() } + }, []) + const validateForm = () => { - const newErrors = { company: '', name: '', email: '', zip: '', message: '', recaptcha_token: '' } - if (!formState.company.trim()) newErrors.company = 'Company name is required' - if (!formState.name.trim()) newErrors.name = 'Name is required' - if (!formState.zip.trim()) newErrors.zip = 'ZIP code is required' - if (!formState.message.trim()) newErrors.message = 'Message is required' + const newErrors = { 'Last Name': '', Company: '', Email: '', 'Zip Code': '', Description: '', recaptcha_token: '' } + if (!formState.Company.trim()) newErrors.Company = 'Company name is required' + if (!formState['Last Name'].trim()) newErrors['Last Name'] = 'Name is required' + if (!formState['Zip Code'].trim()) newErrors['Zip Code'] = 'ZIP code is required' + if (!formState.Description.trim()) newErrors.Description = 'Message is required' const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/ - if (!formState.email.trim()) { - newErrors.email = 'Email is required' - } else if (!emailRegex.test(formState.email)) { - newErrors.email = 'Please enter a valid email address' + if (!formState.Email.trim()) { + newErrors.Email = 'Email is required' + } else if (!emailRegex.test(formState.Email)) { + newErrors.Email = 'Please enter a valid email address' } const hasErrors = Object.values(newErrors).some(error => error !== '') setErrors(newErrors) @@ -57,28 +79,8 @@ const Contact = () => { const handleSubmit = (e) => { e.preventDefault() if (!validateForm()) return - handleSubmitForm() - } - - const handleSubmitForm = async () => { setIsSubmitting(true) - try { - await submitLead(formState) - toast.success("Thanks! We'll be in touch shortly.") - setFormState({ company: '', name: '', email: '', phone: '', zip: '', message: '', service_interest: '', recaptcha_token: '', company_website: '' }) - setErrors({ company: '', name: '', email: '', zip: '', message: '', recaptcha_token: '' }) - } catch (error) { - if (error.response?.status === 409) { - toast.success("We already have your submission! We'll be in touch.") - } else if (error.response?.status === 400 && error.fields) { - setErrors(prev => ({ ...prev, ...error.fields })) - toast.error('Please fix the errors in the form') - } else { - toast.error(error.message || 'Failed to submit form. Please try again.') - } - } finally { - setIsSubmitting(false) - } + formRef.current.submit() } const handleChange = (e) => { @@ -221,147 +223,133 @@ const Contact = () => {

Send Us a Message

We typically respond within one business day.

-
+ + {/* Zoho required hidden fields */} + + + + + + + {/* Honeypot */} + + {/* Company */}
-
{/* Name + Email */}
-
-
{/* Phone + ZIP */}
-
-
- {/* Service Interest */} -
- - -
- {/* Message */}
-