diff --git a/src/components/layout/Footer.jsx b/src/components/layout/Footer.jsx index 9a53472..c5cf408 100644 --- a/src/components/layout/Footer.jsx +++ b/src/components/layout/Footer.jsx @@ -6,8 +6,8 @@ const Footer = () => { const companyInfo = { name: 'Queue North', tagline: 'Modern communications infrastructure without the vendor noise.', - address: 'Orlando, FL', - email: 'info@queuenorth.com', + addressLine1: '7901 4th St N', + addressLine2: 'St. Petersburg, FL 33702', phone: '(321) 730-8020', tollFree: '(888) 656-2850', } @@ -53,11 +53,17 @@ const Footer = () => { Queue North

{companyInfo.tagline}

-

{companyInfo.address}

+ + {companyInfo.addressLine1} + {companyInfo.addressLine2} +
-
- {companyInfo.email} -
{companyInfo.phone}
@@ -143,9 +149,30 @@ const Footer = () => { © {currentYear} Queue North Technologies. All rights reserved.

-
- - LinkedIn +
+ + + LinkedIn + + + + Facebook
diff --git a/src/components/layout/Header.jsx b/src/components/layout/Header.jsx index d906231..fdbf1c0 100644 --- a/src/components/layout/Header.jsx +++ b/src/components/layout/Header.jsx @@ -130,59 +130,98 @@ const Header = () => { Navigation Menu -
-
- - Queue North - Queue North + + {/* Logo */} +
+ + Queue North + Queue North + +
+ + {/* Scrollable nav */} + + + {/* CTA */} +
+ + Get a Free Quote + + + +
diff --git a/src/components/ui/Sheet.jsx b/src/components/ui/Sheet.jsx index e02da07..3f98d60 100644 --- a/src/components/ui/Sheet.jsx +++ b/src/components/ui/Sheet.jsx @@ -33,7 +33,7 @@ const SheetContent = React.forwardRef(({ className, children, side = 'right', .. {...props} > {children} - + Close diff --git a/src/pages/About.jsx b/src/pages/About.jsx index 89164b0..a06080a 100644 --- a/src/pages/About.jsx +++ b/src/pages/About.jsx @@ -47,10 +47,10 @@ const About = () => {
- Queue North Technologies team providing business communications solutions
@@ -58,6 +58,43 @@ const About = () => {
+ {/* The Meaning Behind Queue North */} +
+
+
+

The Meaning Behind Queue North

+

+ Queue is stability. North is responsible progress. The compass is how we guide customers with both. +

+
+
+
+
+ + + + +
+

Queue

+

+ Rooted in technology that works — proven, stable, and repeatable. We focus on environments that behave predictably in real production conditions. +

+
+
+
+ + + +
+

North

+

+ A responsible direction forward — evaluating and adopting new technology carefully, with governance, security, and long-term ownership in mind. +

+
+
+
+
+ {/* Our Values */}
diff --git a/src/pages/Contact.jsx b/src/pages/Contact.jsx index f0790d2..7429134 100644 --- a/src/pages/Contact.jsx +++ b/src/pages/Contact.jsx @@ -5,7 +5,6 @@ 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 { Link } from 'react-router-dom' import { submitLead } from '@/lib/api' import { useDebounce } from '@/hooks/useDebounce' @@ -18,7 +17,7 @@ const Contact = () => { zip: '', message: '', service_interest: '', - company_website: '', // Honeypot field - hidden from humans, bots will fill it + company_website: '', }) const [errors, setErrors] = useState({ company: '', @@ -26,39 +25,26 @@ const Contact = () => { email: '', message: '', }) - // 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 = { - company: '', - name: '', - email: '', - message: '', - } - - // Validate required fields + const newErrors = { company: '', name: '', email: '', message: '' } if (!formState.company.trim()) newErrors.company = 'Company name is required' if (!formState.name.trim()) newErrors.name = 'Name is required' if (!formState.message.trim()) newErrors.message = 'Message is required' - - // 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' } - 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 } @@ -72,26 +58,12 @@ const Contact = () => { setIsSubmitting(true) try { await submitLead(formState) - toast.success("Thanks! We\'ll be in touch shortly.") - setFormState({ - company: '', - name: '', - email: '', - phone: '', - zip: '', - message: '', - service_interest: '', - }) - setErrors({ - company: '', - name: '', - email: '', - message: '', - }) + toast.success("Thanks! We'll be in touch shortly.") + setFormState({ company: '', name: '', email: '', phone: '', zip: '', message: '', service_interest: '' }) + setErrors({ company: '', name: '', email: '', message: '' }) } catch (error) { - // 409 means duplicate email - this is actually good news if (error.response?.status === 409) { - toast.success("We already have your submission! We\'ll be in touch.") + toast.success("We already have your submission! We'll be in touch.") } else { toast.error(error.message || 'Failed to submit form. Please try again.') } @@ -103,12 +75,62 @@ const Contact = () => { 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]: '' })) - } + if (errors[name]) setErrors(prev => ({ ...prev, [name]: '' })) } + 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', + 'Veteran-owned — 25+ years of experience', + 'SMB to Enterprise solutions', + 'No vendor bias — we recommend what fits', + ] + return ( <> @@ -121,93 +143,65 @@ const Contact = () => { - {/* Page Hero */} -
-
-
-

Contact Us

-

- Have questions about our services? We're here to help. Fill out the form and we'll get back to you shortly. -

-
-
- - - - (321) 730-8020 -
-
- - - - (888) 656-2850 -
- -
-
+ {/* Hero */} +
+
+

Let's Talk

+

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

- {/* Contact Form */} -
+ {/* Contact Body */} +
-
- {/* Left - Info */} -
-
-

Get in Touch

-

- Our team of communications and infrastructure experts is ready to help you find the right solution for your business needs. -

-
-
-

Hours of Operation

-

Monday - Friday: 8:00 AM - 6:00 PM CT

+
+ + {/* Left: Info panel */} +
+
+ {contactDetails.map((item) => ( +
+
+ {item.icon} +
+
+

{item.label}

+ {item.content} +
- -
-

Contact Us

-

Use the form on the right to get in touch with our team.

-
-
+ ))}
-
-

Why Choose Queue North?

-
    - {[ - '8x8 Certified Partner with proven expertise', - '25+ years of industry experience', - 'SMB to Enterprise solutions', - 'Focus on your business outcomes', - ].map((item, index) => ( -
  • - - +
    + +
    +

    Why Queue North

    +
      + {trustPoints.map((point, i) => ( +
    • + + - {item} + {point}
    • ))}
    - {/* Right - Form */} -
    -
    + {/* Right: Form panel */} +
    +

    Send Us a Message

    +

    We typically respond within one business day.

    + + + {/* Company */}
    -
    -
    - - - {debouncedErrors.name && ( -

    {debouncedErrors.name}

    - )} + {/* Name + Email */} +
    +
    + + + {debouncedErrors.name &&

    {debouncedErrors.name}

    } +
    +
    + + + {debouncedErrors.email &&

    {debouncedErrors.email}

    } +
    -
    - - - {debouncedErrors.email && ( -

    {debouncedErrors.email}

    - )} + {/* Phone + Service Interest */} +
    +
    + + +
    +
    + + +
    + {/* Message */}
    - - -
    - -
    - - -
    - -
    - - -
    - -
    -