import SEO from '@/components/SEO' import { 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 { Select } from '@/components/ui/Select' import RecaptchaPlaceholder from '@/components/RecaptchaPlaceholder' import { submitSupport } from '@/lib/api' import { useDebounce } from '@/hooks/useDebounce' import { AlertCircle, ArrowRight, CheckCircle2, Clock3, ExternalLink, Headphones, LifeBuoy, ShieldCheck, TicketCheck, Wrench } from 'lucide-react' const portalLinks = [ { label: 'Sign in', href: 'https://queuenorthtechnologiesllc.zohodesk.com/portal/en/signin', }, { label: 'Create account', href: 'https://queuenorthtechnologiesllc.zohodesk.com/portal/en/signup', }, ] const responseTargets = [ { priority: 'Low', context: 'General request', target: '24 hours' }, { priority: 'Medium', context: 'Standard issue', target: '4 hours' }, { priority: 'High', context: 'Critical outage', target: '1 hour' }, ] const supportedSystems = [ '8x8 Communications Platform', 'VoIP Phone Systems', 'Contact Center Solutions', 'Network Infrastructure', 'Cloud Migration Support', ] const Support = () => { const [formState, setFormState] = useState({ name: '', company: '', email: '', phone: '', issue: '', priority: 'medium', recaptcha_token: '', company_website: '', // Honeypot field - hidden from humans, bots will fill it }) const [errors, setErrors] = useState({ name: '', company: '', email: '', issue: '', recaptcha_token: '', }) // Debounce validation errors so they don't flash on every keystroke const debouncedErrors = useDebounce(errors, 300) const [isSubmitting, setIsSubmitting] = useState(false) const validateForm = () => { const newErrors = { name: '', company: '', email: '', issue: '', recaptcha_token: '', } // Validate required fields if (!formState.name.trim()) newErrors.name = 'Name is required' if (!formState.company.trim()) newErrors.company = 'Company name is required' if (!formState.issue.trim()) newErrors.issue = 'Please describe your issue' // Validate email format 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' } // Validate issue minimum length (10 chars matches server-side Zod rule) if (formState.issue.trim() && formState.issue.trim().length < 10) { newErrors.issue = 'Issue description must be at least 10 characters' } 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 handleSubmit = (e) => { e.preventDefault() if (!validateForm()) return handleSubmitForm() } const handleSubmitForm = async () => { setIsSubmitting(true) try { await submitSupport(formState) toast.success("Thanks! We\'ll get back to you soon.") setFormState({ name: '', company: '', email: '', phone: '', issue: '', priority: 'medium', recaptcha_token: '', company_website: '', }) setErrors({ name: '', company: '', email: '', issue: '', recaptcha_token: '', }) } catch (error) { 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) } } const handleChange = (e) => { const { name, value } = e.target setFormState(prev => ({ ...prev, [name]: value })) // Clear error for this field as user types if (errors[name]) { setErrors(prev => ({ ...prev, [name]: '' })) } } return ( <> {/* Page Hero */}
Support team managing communications requests

Get help without getting handed off.

Open a support request, access the client portal, or escalate a service-impacting issue through one clear path.

Choose the right path

Existing client

Submit the form or use the portal to track requests.

Active outage

Call (321) 730-8020

Planned work

Use the request form for moves, adds, changes, and deployments.

{/* Support Form */}
{/* Left - Info — order 2 on mobile so form appears first */}

Support Center

Sign in to manage existing tickets, create an account, or submit the form on this page for a new request.

{portalLinks.map((link, index) => ( {link.label} ))}

Response Targets

{responseTargets.map((item) => (

{item.priority}

{item.target}

{item.context}

))}

Covered Systems

    {supportedSystems.map((item) => (
  • ))}
{/* Right - Form — order 1 on mobile so it appears first */}

Submit a Request

Include who is affected, what changed, and how urgent the issue is.

{debouncedErrors.name && (

{debouncedErrors.name}

)}
{debouncedErrors.company && (

{debouncedErrors.company}

)}
{debouncedErrors.email && (

{debouncedErrors.email}

)}