import SEO from '@/components/SEO' import { useCallback, useEffect, useState } 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 RecaptchaPlaceholder from '@/components/RecaptchaPlaceholder' import { ArrowRight } from 'lucide-react' import { submitLead } from '@/lib/api' const isRecaptchaConfigured = Boolean(import.meta.env.VITE_RECAPTCHA_SITE_KEY) const Contact = () => { const [formState, setFormState] = useState({ 'Last Name': '', Company: '', Email: '', Phone: '', 'Zip Code': '', Description: '', company_website: '', }) const [errors, setErrors] = useState({ 'Last Name': '', Company: '', Email: '', 'Zip Code': '', Description: '', recaptcha_token: '', }) const [debouncedErrors, setDebouncedErrors] = useState(errors) const [isSubmitting, setIsSubmitting] = useState(false) const [recaptchaToken, setRecaptchaToken] = useState('') const [recaptchaResetKey, setRecaptchaResetKey] = useState(0) useEffect(() => { const t = setTimeout(() => setDebouncedErrors(errors), 300) return () => clearTimeout(t) }, [errors]) const validateForm = () => { 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 (isRecaptchaConfigured && !recaptchaToken) { newErrors.recaptcha_token = 'Security verification is required' } const hasErrors = Object.values(newErrors).some(error => error !== '') setErrors(newErrors) if (hasErrors) { toast.error('Please fix the errors in the form') return false } return true } const resetForm = () => { setFormState({ 'Last Name': '', Company: '', Email: '', Phone: '', 'Zip Code': '', Description: '', company_website: '', }) setErrors({ 'Last Name': '', Company: '', Email: '', 'Zip Code': '', Description: '', recaptcha_token: '' }) setRecaptchaToken('') setRecaptchaResetKey(prev => prev + 1) } const mapApiErrors = (fields = {}) => ({ 'Last Name': fields.name || '', Company: fields.company || '', Email: fields.email || '', 'Zip Code': fields.zip || '', Description: fields.message || '', recaptcha_token: fields.recaptcha_token || '', }) const handleSubmit = async (e) => { e.preventDefault() if (!validateForm()) return setIsSubmitting(true) try { const result = await submitLead({ company: formState.Company, name: formState['Last Name'], email: formState.Email, phone: formState.Phone, zip: formState['Zip Code'], message: formState.Description, recaptcha_token: recaptchaToken, company_website: formState.company_website, }) toast.success(result.message || "Thanks! We'll be in touch shortly.") resetForm() } catch (err) { if (err.fields) { setErrors(mapApiErrors(err.fields)) if (err.fields.recaptcha_token) { setRecaptchaToken('') setRecaptchaResetKey(prev => prev + 1) } } toast.error(err.message || 'Failed to submit lead') } finally { setIsSubmitting(false) } } const handleChange = (e) => { const { name, value } = e.target setFormState(prev => ({ ...prev, [name]: value })) if (errors[name]) setErrors(prev => ({ ...prev, [name]: '' })) } const handleRecaptchaVerify = useCallback((token) => { setRecaptchaToken(token) setErrors(prev => ({ ...prev, recaptcha_token: '' })) }, []) const handleRecaptchaExpired = useCallback(() => { setRecaptchaToken('') setErrors(prev => ({ ...prev, recaptcha_token: 'Security verification expired. Please try again.' })) }, []) const contactDetails = [ { label: 'Phone', icon: ( ), content: (
(321) 730-8020 (888) 656-2850 Toll-Free
), }, { label: 'Office', icon: ( ), content: ( 7901 4th St N St. Petersburg, FL 33702 ), }, { label: 'Hours', icon: ( ), content:

Mon – Fri: 8:00 AM – 6:00 PM CT

, }, ] const trustPoints = [
8x8 Certified Partner with proven expertise
, 'Cisco Certified Partner',
25+ years of experience
, 'SMB to Enterprise solutions', 'No vendor bias — we recommend what fits', ] return ( <> {/* Hero */}
Queue North communications infrastructure consultation
Contact

Let's Talk

Tell us about your business and we'll cut through the noise to find what actually works for you.

Send a Message
{/* Contact Body */}
{/* Left: Info panel — order 2 on mobile so form appears first */}
{contactDetails.map((item) => (
{item.icon}

{item.label}

{item.content}
))}

Why Queue North Technologies

    {trustPoints.map((point, i) => (
  • {point}
  • ))}
{/* Right: Form panel — order 1 on mobile so it appears first */}

Send Us a Message

We typically respond within one business day.

{/* Honeypot */} {/* Company */}
{debouncedErrors.Company &&

{debouncedErrors.Company}

}
{/* Name + Email */}
{debouncedErrors['Last Name'] &&

{debouncedErrors['Last Name']}

}
{debouncedErrors.Email &&

{debouncedErrors.Email}

}
{/* Phone + ZIP */}
{debouncedErrors['Zip Code'] &&

{debouncedErrors['Zip Code']}

}
{/* Message */}