fix(ui): UI fixes across header, contact, home, about, support, services, industries (#132 #133 #134 #154 #165 #172 #173)
This commit is contained in:
parent
fdc6eaeab5
commit
de61d5e625
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "queuenorth-website",
|
||||
"private": true,
|
||||
"version": "0.7.2",
|
||||
"version": "0.7.3",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "concurrently \"vite\" \"node server/index.js\"",
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 151 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 102 KiB |
|
|
@ -74,7 +74,7 @@ const Header = () => {
|
|||
</Link>
|
||||
{/* Services Dropdown */}
|
||||
{link.name === 'Services' && (
|
||||
<div className="absolute top-full left-0 w-64 bg-white rounded-lg shadow-xl border border-gray-200 hidden group-hover:block pt-2">
|
||||
<div className="absolute top-full left-0 w-64 bg-white rounded-md shadow-xl border border-gray-200 hidden group-hover:block pt-2">
|
||||
<div className="p-2">
|
||||
{serviceLinks.map((service) => (
|
||||
<Link
|
||||
|
|
@ -90,7 +90,7 @@ const Header = () => {
|
|||
)}
|
||||
{/* Industries Dropdown */}
|
||||
{link.name === 'Industries' && (
|
||||
<div className="absolute top-full left-0 w-64 bg-white rounded-lg shadow-xl border border-gray-200 hidden group-hover:block pt-2">
|
||||
<div className="absolute top-full left-0 w-64 bg-white rounded-md shadow-xl border border-gray-200 hidden group-hover:block pt-2">
|
||||
<div className="p-2">
|
||||
{industryLinks.map((industry) => (
|
||||
<Link
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ const Card = React.forwardRef(
|
|||
({ className = '', ...props }, ref) => (
|
||||
<div
|
||||
ref={ref}
|
||||
className={`rounded-xl border border-border bg-card text-text shadow-sm ${className}`}
|
||||
className={`rounded-md border border-border bg-card text-text shadow-sm ${className}`}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
|
|
@ -62,4 +62,4 @@ const CardFooter = React.forwardRef(
|
|||
)
|
||||
CardFooter.displayName = 'CardFooter'
|
||||
|
||||
export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }
|
||||
export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ We support Cisco Webex Contact Center, 8x8 Contact Center, and other leading pla
|
|||
homeDesc: 'Bad cabling means dropped calls and slow networks. We build it right the first time.',
|
||||
fullDesc: 'Clean structured cabling that gives your business the physical foundation for reliable communication and growth.',
|
||||
icon: 'link',
|
||||
image: '/assets/cabling.webp',
|
||||
image: '/assets/cabling-unsplash.jpg',
|
||||
benefits: [
|
||||
'Cat6/Cat6a and fiber optic installations',
|
||||
'Data center cabling solutions',
|
||||
|
|
@ -120,6 +120,7 @@ We support Cisco Webex Contact Center, 8x8 Contact Center, and other leading pla
|
|||
homeDesc: 'Wi-Fi that just works — everywhere in your building. No dead zones, no complaints.',
|
||||
fullDesc: 'Business Wi-Fi designed for usable coverage, dependable performance, and fewer support headaches across your environment.',
|
||||
icon: 'wifi',
|
||||
image: '/assets/wireless.webp',
|
||||
benefits: [
|
||||
'Enterprise Wi-Fi design and deployment',
|
||||
'High-density coverage solutions',
|
||||
|
|
@ -140,7 +141,6 @@ We support Cisco Webex Contact Center, 8x8 Contact Center, and other leading pla
|
|||
homeDesc: 'A network that doesn\'t go down when it matters. Secure, fast, and built for your workload.',
|
||||
fullDesc: 'Switching and routing built for stability, visibility, and secure local network performance.',
|
||||
icon: 'network',
|
||||
image: '/assets/local-networking.webp',
|
||||
benefits: [
|
||||
'Enterprise-grade routing and switching',
|
||||
'Network security and segmentation',
|
||||
|
|
|
|||
|
|
@ -29,8 +29,7 @@ const About = () => {
|
|||
{/* Company Story */}
|
||||
<section className="bg-background py-16">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-12">
|
||||
<div>
|
||||
<div className="max-w-3xl">
|
||||
<h2 className="text-3xl font-bold text-primary-navy mb-4">Our Story</h2>
|
||||
<p className="text-lg text-soft-text mb-6 leading-relaxed">
|
||||
Founded by military veterans, Queue North Technologies began with a simple mission: help businesses navigate the complex world of communications technology. What started as a small team of communications specialists has grown into a full-service provider for SMB and enterprise organizations across multiple industries.
|
||||
|
|
@ -44,16 +43,6 @@ const About = () => {
|
|||
<p className="text-lg text-soft-text mt-4 leading-relaxed">
|
||||
We continue the mission — bringing the same discipline, reliability, and commitment to every client relationship that we brought to our service.
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<div className="rounded-xl overflow-hidden shadow-lg">
|
||||
<img
|
||||
src="/assets/about-image.webp"
|
||||
alt="Compass representing Queue North's guiding philosophy"
|
||||
className="w-full h-72 object-cover object-top"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
|
@ -68,8 +57,8 @@ const About = () => {
|
|||
</p>
|
||||
</div>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6 max-w-4xl mx-auto">
|
||||
<div className="bg-white/10 border border-white/20 rounded-xl p-8">
|
||||
<div className="w-12 h-12 bg-primary-cyan/20 rounded-lg flex items-center justify-center mb-5">
|
||||
<div className="bg-white/10 border border-white/20 rounded-md p-8">
|
||||
<div className="w-12 h-12 bg-primary-cyan/20 rounded-md flex items-center justify-center mb-5">
|
||||
<svg className="h-6 w-6 text-primary-cyan" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={1.5}>
|
||||
<rect x="7" y="7" width="10" height="10" rx="1" strokeLinejoin="round" />
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M9 7V5M12 7V5M15 7V5M9 17v2M12 17v2M15 17v2M7 9H5M7 12H5M7 15H5M17 9h2M17 12h2M17 15h2" />
|
||||
|
|
@ -80,8 +69,8 @@ const About = () => {
|
|||
Rooted in technology that works — proven, stable, and repeatable. We focus on environments that behave predictably in real production conditions.
|
||||
</p>
|
||||
</div>
|
||||
<div className="bg-white/10 border border-white/20 rounded-xl p-8">
|
||||
<div className="w-12 h-12 bg-primary-cyan/20 rounded-lg flex items-center justify-center mb-5">
|
||||
<div className="bg-white/10 border border-white/20 rounded-md p-8">
|
||||
<div className="w-12 h-12 bg-primary-cyan/20 rounded-md flex items-center justify-center mb-5">
|
||||
<svg className="h-6 w-6 text-primary-cyan" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M5 10l7-7m0 0l7 7m-7-7v18" />
|
||||
</svg>
|
||||
|
|
@ -108,7 +97,7 @@ const About = () => {
|
|||
{ title: 'Reliability', desc: 'When we say we will do something, we do it' },
|
||||
{ title: 'Support', desc: 'Our job doesn\'t end when installation completes' },
|
||||
].map((value, index) => (
|
||||
<div key={index} className="p-6 rounded-lg border border-border bg-card shadow-sm hover:shadow-md transition-shadow">
|
||||
<div key={index} className="p-6 rounded-md border border-border bg-card shadow-sm hover:shadow-md transition-shadow">
|
||||
<h3 className="text-xl font-semibold text-primary-navy mb-3">{value.title}</h3>
|
||||
<p className="text-soft-text">{value.desc}</p>
|
||||
</div>
|
||||
|
|
@ -132,7 +121,7 @@ const About = () => {
|
|||
'Disaster Recovery Planning',
|
||||
'24/7 Support & Monitoring',
|
||||
].map((expertise, index) => (
|
||||
<div key={index} className="flex items-center gap-2 p-3 rounded-lg border border-border bg-card">
|
||||
<div key={index} className="flex items-center gap-2 p-3 rounded-md border border-border bg-card">
|
||||
<div className="h-5 w-5 rounded-full bg-primary-navy text-white flex items-center justify-center flex-shrink-0">
|
||||
<svg className="h-3 w-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M5 13l4 4L19 7" />
|
||||
|
|
|
|||
|
|
@ -145,7 +145,7 @@ const Contact = () => {
|
|||
</Helmet>
|
||||
|
||||
{/* Hero */}
|
||||
<section className="bg-primary-navy py-16 lg:py-20">
|
||||
<section className="bg-primary-navy py-12 lg:py-20">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<h1 className="text-4xl md:text-5xl font-bold text-white mb-4">Let's Talk</h1>
|
||||
<p className="text-xl text-white/70 max-w-2xl">
|
||||
|
|
@ -155,16 +155,16 @@ const Contact = () => {
|
|||
</section>
|
||||
|
||||
{/* Contact Body */}
|
||||
<section className="bg-background py-16 lg:py-20">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-5 rounded-2xl overflow-hidden shadow-xl border border-border">
|
||||
<section className="bg-background py-12 lg:py-20">
|
||||
<div className="max-w-7xl mx-auto px-0 sm:px-6 lg:px-8">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-5 rounded-none sm:rounded-md overflow-hidden shadow-none sm:shadow-xl border-y sm:border border-border">
|
||||
|
||||
{/* Left: Info panel */}
|
||||
<div className="lg:col-span-2 bg-primary-navy text-white p-8 lg:p-10 flex flex-col gap-10">
|
||||
{/* Left: Info panel — order 2 on mobile so form appears first */}
|
||||
<div className="lg:col-span-2 order-2 lg:order-1 bg-primary-navy text-white p-8 lg:p-10 flex flex-col gap-10">
|
||||
<div className="space-y-7">
|
||||
{contactDetails.map((item) => (
|
||||
<div key={item.label} className="flex items-start gap-4">
|
||||
<div className="w-10 h-10 bg-white/10 rounded-lg flex items-center justify-center flex-shrink-0">
|
||||
<div className="w-10 h-10 bg-white/10 rounded-md flex items-center justify-center flex-shrink-0">
|
||||
{item.icon}
|
||||
</div>
|
||||
<div>
|
||||
|
|
@ -192,8 +192,8 @@ const Contact = () => {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{/* Right: Form panel */}
|
||||
<div className="lg:col-span-3 bg-white p-8 lg:p-10">
|
||||
{/* Right: Form panel — order 1 on mobile so it appears first */}
|
||||
<div className="lg:col-span-3 order-1 lg:order-2 bg-white p-6 sm:p-8 lg:p-10">
|
||||
<h2 className="text-2xl font-bold text-primary-navy mb-1">Send Us a Message</h2>
|
||||
<p className="text-soft-text text-sm mb-8">We typically respond within one business day.</p>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
import { Helmet } from 'react-helmet-async'
|
||||
import { Button } from '@/components/ui/Button'
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/Card'
|
||||
import { services } from '@/data/services'
|
||||
import { industries } from '@/data/industries'
|
||||
import { Link } from 'react-router-dom'
|
||||
import { MapPin, MessageCircle, Users, LifeBuoy, GraduationCap, Link as LinkIcon, Wifi, Network, Headphones, UserCheck, Activity, ShieldCheck, HeartPulse, ShoppingCart, Factory, Landmark, Building2, Award } from 'lucide-react'
|
||||
import { ArrowRight, MapPin, MessageCircle, Users, LifeBuoy, GraduationCap, Link as LinkIcon, Wifi, Network, Headphones, UserCheck, Activity, ShieldCheck, HeartPulse, ShoppingCart, Factory, Landmark, Building2, Award } from 'lucide-react'
|
||||
|
||||
// Icon map for industries - converts icon string to lucide component
|
||||
const industryIcons = {
|
||||
|
|
@ -71,183 +70,67 @@ const Home = () => {
|
|||
<script type="application/ld+json">{JSON.stringify(localBusinessLd)}</script>
|
||||
</Helmet>
|
||||
{/* Hero Section */}
|
||||
<section className="bg-gradient-to-br from-primary-navy via-primary-navy to-teal-900 text-white py-16 md:py-24">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-8 md:gap-12 items-center">
|
||||
<div className="flex flex-col gap-6 md:gap-8">
|
||||
<h1 className="text-4xl md:text-5xl lg:text-6xl font-bold">
|
||||
Reliable Business Communications — Without the Runaround
|
||||
</h1>
|
||||
<p className="text-xl md:text-2xl text-section-alt max-w-2xl">
|
||||
We handle your phones, internet, and IT so you can focus on running your business. 8x8 Certified Partner with 25+ years of proven reliability.
|
||||
</p>
|
||||
<div className="flex flex-col sm:flex-row gap-4">
|
||||
<Link to="/contact" className="inline-flex items-center justify-center rounded-md text-sm font-medium h-10 px-4 py-2 bg-white text-primary-navy hover:bg-gray-100 transition-colors" aria-label="Schedule a consultation">
|
||||
Schedule Consultation
|
||||
</Link>
|
||||
<Link to="/services" className="inline-flex items-center justify-center rounded-md text-sm font-medium h-10 px-4 py-2 border border-white text-white hover:bg-white/10 transition-colors" aria-label="View our services">
|
||||
View Services
|
||||
</Link>
|
||||
</div>
|
||||
<div className="flex flex-wrap gap-4">
|
||||
<div className="flex items-center gap-2 px-4 py-2 bg-white/20 rounded-lg text-sm font-medium">
|
||||
<img src="/assets/8x8_Logo_White.svg" alt="8x8 Certified Partner logo" className="h-5 w-5" />
|
||||
<span>8x8 Certified Partner</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2 px-4 py-2 bg-white/20 rounded-lg text-sm font-medium">
|
||||
<Award className="h-5 w-5 text-primary-navy" />
|
||||
<span>Veteran Owned</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2 px-4 py-2 bg-white/20 rounded-lg text-sm font-numeric">
|
||||
<span>25+</span>
|
||||
<span className="text-sm">Years Experience</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2 px-4 py-2 bg-white/20 rounded-lg text-sm font-medium">
|
||||
<span>SMB to Enterprise</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="md:order-2 md:mt-0">
|
||||
<div className="relative rounded-xl overflow-hidden shadow-2xl">
|
||||
<img
|
||||
src="/assets/hero-tech.webp"
|
||||
alt="Business communications and IT infrastructure solutions by Queue North Technologies"
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
<div className="absolute inset-0 bg-gradient-to-t from-primary-navy/50 to-transparent" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<section className="relative isolate overflow-hidden bg-primary-navy text-white">
|
||||
<div className="absolute inset-0 -z-10">
|
||||
<img
|
||||
src="/assets/hero-tech.webp"
|
||||
alt="Queue North technician working inside a communications rack"
|
||||
className="h-full w-full object-cover object-center"
|
||||
/>
|
||||
<div className="absolute inset-0 bg-primary-navy/65" />
|
||||
<div className="absolute inset-0 bg-gradient-to-r from-primary-navy via-primary-navy/90 to-primary-navy/25" />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Trusted Partners */ }
|
||||
<section className="bg-primary-navy py-16 md:py-24">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 text-center">
|
||||
<h2 className="text-2xl md:text-3xl font-bold text-white mb-8">Trusted Partners</h2>
|
||||
<div className="flex flex-wrap justify-center items-center gap-8 md:gap-16 opacity-90">
|
||||
<div className="flex items-center gap-3">
|
||||
<img src="/assets/8x8_Logo_White.svg" alt="8x8 Certified Partner" className="h-10 w-auto" />
|
||||
<span className="font-medium text-white">8x8 Certified Partner</span>
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-20 md:py-24 lg:py-28">
|
||||
<div className="max-w-3xl">
|
||||
<div className="inline-flex items-center gap-2 rounded-md border border-white/20 bg-white/10 px-3 py-2 text-xs font-semibold uppercase tracking-wide text-primary-cyan">
|
||||
<span className="h-1.5 w-1.5 rounded-full bg-primary-cyan" />
|
||||
Veteran-owned communications and infrastructure partner
|
||||
</div>
|
||||
<div className="flex items-center gap-3">
|
||||
<ShieldCheck className="h-10 w-10 text-primary-cyan flex-shrink-0" />
|
||||
<span className="font-medium text-white">Cisco Certified Partner</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-3">
|
||||
<Award className="h-10 w-10 text-primary-cyan flex-shrink-0" />
|
||||
<span className="font-medium text-white">Veteran Owned</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Trust Signals Section */}
|
||||
<section className="bg-section-alt py-16 md:py-24">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="text-center mb-12">
|
||||
<h2 className="text-2xl md:text-3xl font-semibold text-primary-navy mb-2">Trusted by Thousands of Businesses</h2>
|
||||
<p className="text-xl text-soft-text max-w-2xl mx-auto mb-6">
|
||||
Why Queue North? Proven reliability, decades of experience, and unwavering support
|
||||
<h1 className="mt-6 text-4xl md:text-6xl lg:text-7xl font-bold leading-tight">
|
||||
Queue North Technologies
|
||||
</h1>
|
||||
<p className="mt-6 text-lg md:text-2xl text-white/80 max-w-2xl leading-relaxed">
|
||||
Business phone, contact center, network, and IT support built around one accountable implementation partner.
|
||||
</p>
|
||||
<div>
|
||||
<Link to="/contact" className="inline-flex items-center justify-center rounded-md text-sm font-medium h-10 px-4 py-2 bg-primary-navy text-white hover:bg-primary-navy-dark transition-colors" aria-label="Request a consultation">
|
||||
Request Consultation
|
||||
<div className="mt-8 flex flex-col sm:flex-row gap-3">
|
||||
<Link to="/contact" className="inline-flex h-11 items-center justify-center gap-2 rounded-md bg-white px-5 text-sm font-semibold text-primary-navy hover:bg-section-alt transition-colors" aria-label="Schedule a consultation">
|
||||
Schedule Consultation
|
||||
<ArrowRight className="h-4 w-4" aria-hidden="true" />
|
||||
</Link>
|
||||
<Link to="/services" className="inline-flex h-11 items-center justify-center rounded-md border border-white/45 px-5 text-sm font-semibold text-white hover:bg-white/10 transition-colors" aria-label="View our services">
|
||||
View Services
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
{/* 8x8 Certified Partner */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-6 mb-12">
|
||||
<div className="bg-white rounded-xl p-8 shadow-lg hover:shadow-xl transition-shadow">
|
||||
<div className="flex items-center gap-4 mb-4">
|
||||
<div className="bg-primary-navy text-white p-3 rounded-lg">
|
||||
<img src="/assets/8x8_Logo_White.svg" alt="8x8 Certified Partner logo" className="h-8 w-auto" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-lg font-semibold text-primary-navy">8x8 Certified Partner</h3>
|
||||
<p className="text-sm text-soft-text">Certification #25432</p>
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-sm text-soft-text leading-relaxed mb-4">
|
||||
Queue North holds 8x8 Sales, Sales Engineer, Build, Deployment, and Support Certifications — enabling full lifecycle delivery.
|
||||
</p>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{['Sales', 'Sales Engineer', 'Build', 'Deployment', 'Support'].map((cert) => (
|
||||
<span key={cert} className="inline-flex items-center gap-1.5 px-3 py-1.5 bg-teal-50 text-teal-700 text-xs font-medium rounded-md border border-teal-100">
|
||||
<span className="w-1.5 h-1.5 rounded-full bg-teal-500" />
|
||||
{cert}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Cisco Partnership */}
|
||||
<div className="bg-white rounded-xl p-8 shadow-lg hover:shadow-xl transition-shadow">
|
||||
<div className="flex items-center gap-4 mb-4">
|
||||
<div className="bg-primary-navy text-white p-3 rounded-lg">
|
||||
<ShieldCheck className="w-6 h-6" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-lg font-semibold text-primary-navy">Cisco Certified Partner</h3>
|
||||
<p className="text-sm text-soft-text">Authorized Reseller & Implementer</p>
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-sm text-soft-text leading-relaxed">
|
||||
As a Cisco Certified Partner, we deliver enterprise-grade solutions using Cisco Meraki, Cisco Webex, and Cisco Unified Communications Manager. We help businesses leverage Cisco's industry-leading networking and communications platforms.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Veteran Owned */}
|
||||
<div className="bg-white rounded-xl p-8 shadow-lg hover:shadow-xl transition-shadow">
|
||||
<div className="flex items-center gap-4 mb-4">
|
||||
<div className="bg-primary-navy text-white p-3 rounded-lg">
|
||||
<Award className="w-6 h-6" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-lg font-semibold text-primary-navy">Veteran Owned</h3>
|
||||
<p className="text-sm text-soft-text">VCERT Verified (VOSB #12847)</p>
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-sm text-soft-text leading-relaxed">
|
||||
Founded by military veterans, we bring discipline, reliability, and service-first values to every client relationship. Your success is our mission.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Years Experience */}
|
||||
<div className="bg-white rounded-xl p-8 shadow-lg hover:shadow-xl transition-shadow">
|
||||
<div className="flex items-center gap-4 mb-4">
|
||||
<div className="bg-teal-600 text-white p-3 rounded-lg">
|
||||
<span className="font-numeric text-3xl">25+</span>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-lg font-semibold text-primary-navy">25+ Years Experience</h3>
|
||||
<p className="text-sm text-soft-text">1999–Present</p>
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-sm text-soft-text leading-relaxed">
|
||||
We've been helping businesses navigate communications challenges since before cloud telephony existed. Our experience means fewer surprises, faster solutions.
|
||||
</p>
|
||||
</div>
|
||||
{/* Partner Proof */}
|
||||
<section className="bg-white border-b border-border py-6">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="grid grid-cols-2 gap-4 md:grid-cols-4">
|
||||
<div className="flex items-center gap-3">
|
||||
<span className="flex h-10 w-10 items-center justify-center rounded-md bg-primary-navy">
|
||||
<img src="/assets/8x8_Logo_White.svg" alt="8x8 Certified Partner logo" className="h-6 w-6" />
|
||||
</span>
|
||||
<span className="text-sm font-semibold text-primary-navy">8x8 Certified Partner</span>
|
||||
</div>
|
||||
|
||||
{/* Metrics Grid */}
|
||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-6">
|
||||
<div className="text-center">
|
||||
<div className="font-numeric text-4xl md:text-5xl text-primary-navy mb-2">99.99%</div>
|
||||
<div className="text-sm text-soft-text uppercase tracking-wide font-medium">Uptime Guarantee</div>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<div className="font-numeric text-4xl md:text-5xl text-primary-navy mb-2"><15m</div>
|
||||
<div className="text-sm text-soft-text uppercase tracking-wide font-medium">Avg. Response</div>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<div className="font-numeric text-4xl md:text-5xl text-primary-navy mb-2">24/7</div>
|
||||
<div className="text-sm text-soft-text uppercase tracking-wide font-medium">Support</div>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<div className="font-numeric text-4xl md:text-5xl text-primary-navy mb-2">100%</div>
|
||||
<div className="text-sm text-soft-text uppercase tracking-wide font-medium">Satisfaction</div>
|
||||
</div>
|
||||
<div className="flex items-center gap-3">
|
||||
<span className="flex h-10 w-10 items-center justify-center rounded-md bg-section-alt text-primary-navy">
|
||||
<ShieldCheck className="h-5 w-5" aria-hidden="true" />
|
||||
</span>
|
||||
<span className="text-sm font-semibold text-primary-navy">Cisco Certified Partner</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-3">
|
||||
<span className="flex h-10 w-10 items-center justify-center rounded-md bg-section-alt text-primary-navy">
|
||||
<Award className="h-5 w-5" aria-hidden="true" />
|
||||
</span>
|
||||
<span className="text-sm font-semibold text-primary-navy">Veteran Owned</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-3">
|
||||
<span className="font-numeric flex h-10 w-10 items-center justify-center rounded-md bg-section-alt text-lg text-primary-navy">25+</span>
|
||||
<span className="text-sm font-semibold text-primary-navy">Years Experience</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -264,10 +147,10 @@ const Home = () => {
|
|||
</div>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
{services.map((service) => (
|
||||
<Card key={service.id} className="hover:shadow-md transition-shadow cursor-pointer">
|
||||
<Card key={service.id} className="h-full transition-all hover:border-primary-blue/40 hover:shadow-md">
|
||||
<CardHeader>
|
||||
<div className="flex items-center gap-3 mb-2">
|
||||
<div className="bg-primary-navy/10 p-2 rounded-lg" aria-hidden="true">
|
||||
<div className="bg-primary-navy/10 p-2 rounded-md" aria-hidden="true">
|
||||
{service.icon === 'message-circle' && <MessageCircle className="w-6 h-6 text-primary-navy" />}
|
||||
{service.icon === 'users' && <Users className="w-6 h-6 text-primary-navy" />}
|
||||
{service.icon === 'life-buoy' && <LifeBuoy className="w-6 h-6 text-primary-navy" />}
|
||||
|
|
@ -282,11 +165,9 @@ const Home = () => {
|
|||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="flex flex-col gap-2">
|
||||
<Link to={`/services/${service.id}`} className="text-primary-navy p-0 h-auto text-sm hover:underline" aria-label={`Learn more about ${service.name}`}>
|
||||
Learn more →
|
||||
</Link>
|
||||
<Link to="/contact" className="inline-flex items-center justify-center rounded-md text-sm font-medium h-10 px-4 py-2 border border-primary-navy text-primary-navy hover:bg-primary-navy hover:text-white transition-colors" aria-label="Learn more about services">
|
||||
Request Consultation
|
||||
<Link to={`/services/${service.id}`} className="inline-flex items-center gap-1 text-sm font-semibold text-primary-navy hover:text-primary-blue" aria-label={`Learn more about ${service.name}`}>
|
||||
Learn more
|
||||
<ArrowRight className="h-4 w-4" aria-hidden="true" />
|
||||
</Link>
|
||||
</div>
|
||||
</CardContent>
|
||||
|
|
@ -311,9 +192,9 @@ const Home = () => {
|
|||
</div>
|
||||
</div>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
|
||||
<Card>
|
||||
<Card className="bg-white/80">
|
||||
<CardContent className="pt-6">
|
||||
<div className="bg-primary-navy text-white p-3 rounded-lg mb-4 inline-flex">
|
||||
<div className="bg-primary-navy text-white p-3 rounded-md mb-4 inline-flex">
|
||||
<Headphones className="w-6 h-6" />
|
||||
</div>
|
||||
<h3 className="text-lg font-semibold text-primary-navy mb-2">Responsiveness</h3>
|
||||
|
|
@ -322,9 +203,9 @@ const Home = () => {
|
|||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<Card>
|
||||
<Card className="bg-white/80">
|
||||
<CardContent className="pt-6">
|
||||
<div className="bg-primary-navy text-white p-3 rounded-lg mb-4 inline-flex">
|
||||
<div className="bg-primary-navy text-white p-3 rounded-md mb-4 inline-flex">
|
||||
<UserCheck className="w-6 h-6" />
|
||||
</div>
|
||||
<h3 className="text-lg font-semibold text-primary-navy mb-2">Direct Support</h3>
|
||||
|
|
@ -333,9 +214,9 @@ const Home = () => {
|
|||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<Card>
|
||||
<Card className="bg-white/80">
|
||||
<CardContent className="pt-6">
|
||||
<div className="bg-primary-navy text-white p-3 rounded-lg mb-4 inline-flex">
|
||||
<div className="bg-primary-navy text-white p-3 rounded-md mb-4 inline-flex">
|
||||
<Activity className="w-6 h-6" />
|
||||
</div>
|
||||
<h3 className="text-lg font-semibold text-primary-navy mb-2">Proactive Monitoring</h3>
|
||||
|
|
@ -344,9 +225,9 @@ const Home = () => {
|
|||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<Card>
|
||||
<Card className="bg-white/80">
|
||||
<CardContent className="pt-6">
|
||||
<div className="bg-primary-navy text-white p-3 rounded-lg mb-4 inline-flex">
|
||||
<div className="bg-primary-navy text-white p-3 rounded-md mb-4 inline-flex">
|
||||
<ShieldCheck className="w-6 h-6" />
|
||||
</div>
|
||||
<h3 className="text-lg font-semibold text-primary-navy mb-2">Vendor Neutrality</h3>
|
||||
|
|
@ -372,15 +253,16 @@ const Home = () => {
|
|||
{industries.map((industry) => {
|
||||
const IconComponent = industryIcons[industry.icon] || Building2
|
||||
return (
|
||||
<Card key={industry.id} className="hover:shadow-md transition-shadow cursor-pointer">
|
||||
<Card key={industry.id} className="h-full transition-all hover:border-primary-blue/40 hover:shadow-md">
|
||||
<CardContent className="p-6">
|
||||
<div className="w-14 h-14 rounded-xl bg-teal-50 flex items-center justify-center mb-4" aria-hidden="true">
|
||||
<div className="w-14 h-14 rounded-md bg-teal-50 flex items-center justify-center mb-4" aria-hidden="true">
|
||||
<IconComponent className="w-8 h-8 text-teal-600" />
|
||||
</div>
|
||||
<h3 className="text-xl font-semibold text-primary-navy mb-3" aria-label={industry.name}>{industry.name}</h3>
|
||||
<p className="text-sm text-soft-text mb-4" aria-label={industry.homeDesc || 'Industry-specific solutions designed to address your unique challenges and requirements.'}>{industry.homeDesc || 'Industry-specific solutions designed to address your unique challenges and requirements.'}</p>
|
||||
<Link to={`/industries/${industry.id}`} className="text-primary-navy p-0 h-auto text-sm hover:underline" aria-label={`Learn more about ${industry.name} industry solutions`}>
|
||||
Learn more →
|
||||
<Link to={`/industries/${industry.id}`} className="inline-flex items-center gap-1 text-sm font-semibold text-primary-navy hover:text-primary-blue" aria-label={`Learn more about ${industry.name} industry solutions`}>
|
||||
Learn more
|
||||
<ArrowRight className="h-4 w-4" aria-hidden="true" />
|
||||
</Link>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
|
@ -398,7 +280,7 @@ const Home = () => {
|
|||
</h2>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4 mb-8">
|
||||
<div className="flex items-start gap-3">
|
||||
<div className="bg-primary-navy/10 p-2 rounded-lg flex-shrink-0">
|
||||
<div className="bg-primary-navy/10 p-2 rounded-md flex-shrink-0">
|
||||
<MapPin className="w-5 h-5 text-primary-navy" />
|
||||
</div>
|
||||
<p className="text-left text-sm md:text-base text-soft-text">
|
||||
|
|
@ -406,7 +288,7 @@ const Home = () => {
|
|||
</p>
|
||||
</div>
|
||||
<div className="flex items-start gap-3">
|
||||
<div className="bg-teal-500/10 p-2 rounded-lg flex-shrink-0">
|
||||
<div className="bg-teal-500/10 p-2 rounded-md flex-shrink-0">
|
||||
<Users className="w-5 h-5 text-teal-600" />
|
||||
</div>
|
||||
<p className="text-left text-sm md:text-base text-soft-text">
|
||||
|
|
@ -414,7 +296,7 @@ const Home = () => {
|
|||
</p>
|
||||
</div>
|
||||
<div className="flex items-start gap-3">
|
||||
<div className="bg-teal-500/10 p-2 rounded-lg flex-shrink-0">
|
||||
<div className="bg-teal-500/10 p-2 rounded-md flex-shrink-0">
|
||||
<Network className="w-5 h-5 text-teal-600" />
|
||||
</div>
|
||||
<p className="text-left text-sm md:text-base text-soft-text">
|
||||
|
|
@ -422,7 +304,7 @@ const Home = () => {
|
|||
</p>
|
||||
</div>
|
||||
<div className="flex items-start gap-3">
|
||||
<div className="bg-teal-600/10 p-2 rounded-lg flex-shrink-0">
|
||||
<div className="bg-teal-600/10 p-2 rounded-md flex-shrink-0">
|
||||
<ShieldCheck className="w-5 h-5 text-teal-600" />
|
||||
</div>
|
||||
<p className="text-left text-sm md:text-base text-teal-700 font-semibold">
|
||||
|
|
|
|||
|
|
@ -43,11 +43,11 @@ const Industries = () => {
|
|||
{industries.map((industry) => {
|
||||
const IconComponent = industryIcons[industry.icon] || Building2
|
||||
return (
|
||||
<div key={industry.id} className="group cursor-pointer">
|
||||
<div className="rounded-xl overflow-hidden shadow-sm hover:shadow-md transition-shadow bg-card border border-border">
|
||||
<div key={industry.id} className="group">
|
||||
<div className="rounded-md overflow-hidden shadow-sm hover:shadow-md transition-shadow bg-card border border-border">
|
||||
<div className="p-6">
|
||||
<div className="flex items-center gap-4 mb-4">
|
||||
<div className="h-12 w-12 rounded-lg bg-section-alt flex items-center justify-center flex-shrink-0">
|
||||
<div className="h-12 w-12 rounded-md bg-section-alt flex items-center justify-center flex-shrink-0">
|
||||
<IconComponent className="h-6 w-6 text-primary-navy" />
|
||||
</div>
|
||||
<h2 className="text-xl font-semibold text-primary-navy group-hover:text-primary-navy-dark transition-colors">
|
||||
|
|
|
|||
|
|
@ -3,6 +3,13 @@ import { useParams } from 'react-router-dom'
|
|||
import { services } from '@/data/services'
|
||||
import { Link } from 'react-router-dom'
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/Card'
|
||||
import { ArrowRight, CheckCircle2, Zap } from 'lucide-react'
|
||||
|
||||
const serviceImageAlt = {
|
||||
'contact-center': 'Modern contact center operations dashboard and support team',
|
||||
'infrastructure-cabling': 'Close-up of network cabling connected to infrastructure equipment',
|
||||
'wireless-access': 'Wireless coverage planning map used for enterprise Wi-Fi design',
|
||||
}
|
||||
|
||||
const ServiceDetail = () => {
|
||||
const { slug } = useParams()
|
||||
|
|
@ -31,6 +38,7 @@ const ServiceDetail = () => {
|
|||
const serviceTitle = `${service.name} | Queue North Technologies`
|
||||
const serviceDesc = service.shortDesc || `Learn about ${service.name} from Queue North Technologies.`
|
||||
const serviceUrl = `https://queuenorth.com/services/${service.id}`
|
||||
const hasServiceImage = Boolean(service.image)
|
||||
|
||||
const serviceDetailLd = {
|
||||
'@context': 'https://schema.org',
|
||||
|
|
@ -62,23 +70,33 @@ const ServiceDetail = () => {
|
|||
<script type="application/ld+json">{JSON.stringify(serviceDetailLd)}</script>
|
||||
</Helmet>
|
||||
{/* Page Hero */}
|
||||
<section className="bg-background py-16 md:py-24">
|
||||
<section className="bg-background py-14 md:py-20">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div>
|
||||
<h1 className="text-4xl md:text-5xl font-bold text-primary-navy mb-6">{service.name}</h1>
|
||||
{service.image && (
|
||||
<div className="relative mb-8 rounded-xl overflow-hidden">
|
||||
<div className={hasServiceImage ? 'grid grid-cols-1 lg:grid-cols-[0.9fr_1.1fr] gap-10 lg:gap-14 items-center' : 'max-w-3xl'}>
|
||||
<div>
|
||||
<Link to="/services" className="mb-5 inline-flex text-sm font-semibold text-primary-blue hover:text-primary-navy">
|
||||
Services
|
||||
</Link>
|
||||
<h1 className="text-4xl md:text-5xl font-bold text-primary-navy mb-6">{service.name}</h1>
|
||||
<p className="text-xl text-soft-text max-w-3xl leading-relaxed">{service.shortDesc}</p>
|
||||
<div className="mt-8">
|
||||
<Link to="/contact" className="inline-flex h-11 items-center justify-center gap-2 rounded-md bg-primary-navy px-5 text-sm font-semibold text-white hover:bg-primary-navy-dark transition-colors">
|
||||
Request This Service
|
||||
<ArrowRight className="h-4 w-4" aria-hidden="true" />
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{hasServiceImage && (
|
||||
<div className="relative overflow-hidden rounded-md border border-border bg-white shadow-sm">
|
||||
<img
|
||||
src={service.image}
|
||||
alt={service.id === 'infrastructure-cabling' ? 'Professional structured cabling installation'
|
||||
: service.id === 'contact-center' ? 'Modern contact center operations with agents and dashboard'
|
||||
: 'Network engineer with laptop configuring infrastructure'}
|
||||
className="w-full h-64 md:h-80 object-cover"
|
||||
alt={serviceImageAlt[service.id] || `${service.name} service visual`}
|
||||
className="h-72 w-full object-cover md:h-96 lg:h-[28rem]"
|
||||
/>
|
||||
<div className="absolute inset-0 bg-gradient-to-t from-primary-navy/60 to-transparent rounded-xl" />
|
||||
<div className="absolute inset-x-0 bottom-0 h-24 bg-gradient-to-t from-primary-navy/55 to-transparent" />
|
||||
</div>
|
||||
)}
|
||||
<p className="text-xl text-soft-text max-w-3xl">{service.shortDesc}</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
|
@ -101,11 +119,7 @@ const ServiceDetail = () => {
|
|||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
{service.benefits.map((benefit, index) => (
|
||||
<div key={index} className="flex items-start gap-3">
|
||||
<div className="h-6 w-6 rounded-full bg-primary-navy text-white flex items-center justify-center flex-shrink-0 mt-1">
|
||||
<svg className="h-3 w-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M5 13l4 4L19 7" />
|
||||
</svg>
|
||||
</div>
|
||||
<CheckCircle2 className="h-6 w-6 text-primary-blue flex-shrink-0 mt-1" aria-hidden="true" />
|
||||
<span className="text-lg text-text">{benefit}</span>
|
||||
</div>
|
||||
))}
|
||||
|
|
@ -117,11 +131,7 @@ const ServiceDetail = () => {
|
|||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
{service.idealFor.map((item, index) => (
|
||||
<div key={index} className="flex items-start gap-3">
|
||||
<div className="h-6 w-6 rounded-full bg-primary-navy text-white flex items-center justify-center flex-shrink-0 mt-1">
|
||||
<svg className="h-3 w-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M13 10V3L4 14h7v7l9-11h-7z" />
|
||||
</svg>
|
||||
</div>
|
||||
<Zap className="h-6 w-6 text-primary-blue flex-shrink-0 mt-1" aria-hidden="true" />
|
||||
<span className="text-lg text-text">{item}</span>
|
||||
</div>
|
||||
))}
|
||||
|
|
|
|||
|
|
@ -49,11 +49,11 @@ const Services = () => {
|
|||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
{services.map((service) => (
|
||||
<div key={service.id} className="group cursor-pointer">
|
||||
<div className="rounded-xl overflow-hidden shadow-sm hover:shadow-md transition-shadow bg-card border border-border">
|
||||
<div key={service.id} className="group">
|
||||
<div className="rounded-md overflow-hidden shadow-sm hover:shadow-md transition-shadow bg-card border border-border">
|
||||
<div className="p-6">
|
||||
<div className="flex items-center gap-4 mb-4">
|
||||
<div className="h-12 w-12 rounded-lg bg-section-alt flex items-center justify-center flex-shrink-0">
|
||||
<div className="h-12 w-12 rounded-md bg-section-alt flex items-center justify-center flex-shrink-0">
|
||||
{service.icon === 'message-circle' && <MessageCircle className="h-6 w-6 text-primary-navy" />}
|
||||
{service.icon === 'users' && <Users className="h-6 w-6 text-primary-navy" />}
|
||||
{service.icon === 'life-buoy' && <LifeBuoy className="h-6 w-6 text-primary-navy" />}
|
||||
|
|
|
|||
|
|
@ -5,9 +5,34 @@ 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 { 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({
|
||||
|
|
@ -51,7 +76,7 @@ const Support = () => {
|
|||
}
|
||||
|
||||
// Validate issue minimum length (10 chars matches server-side Zod rule)
|
||||
if (formState.issue.trim().length < 10) {
|
||||
if (formState.issue.trim() && formState.issue.trim().length < 10) {
|
||||
newErrors.issue = 'Issue description must be at least 10 characters'
|
||||
}
|
||||
|
||||
|
|
@ -84,6 +109,7 @@ const Support = () => {
|
|||
phone: '',
|
||||
issue: '',
|
||||
priority: 'medium',
|
||||
company_website: '',
|
||||
})
|
||||
setErrors({
|
||||
name: '',
|
||||
|
|
@ -120,105 +146,141 @@ const Support = () => {
|
|||
<meta property="og:site_name" content="Queue North Technologies" />
|
||||
</Helmet>
|
||||
{/* Page Hero */}
|
||||
<section className="bg-background py-16 md:py-24">
|
||||
<section className="bg-primary-navy py-16 lg:py-20 text-white">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div>
|
||||
<h1 className="text-4xl md:text-5xl font-bold text-primary-navy mb-6">Support</h1>
|
||||
<p className="text-xl text-soft-text max-w-3xl mb-8">
|
||||
Need help with your communications or infrastructure? Submit a support request and we'll get back to you promptly.
|
||||
</p>
|
||||
<div className="flex flex-wrap gap-4 mb-8">
|
||||
<div className="flex items-center gap-2 px-4 py-2 bg-primary-navy/10 rounded-lg text-primary-navy">
|
||||
<svg className="h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M3 5a2 2 0 012-2h3.28a1 1 0 01.948.684l1.498 4.493a1 1 0 01-.502 1.21l-2.257 5.13a1 1 0 01-1.31.42a2 2 0 00-2.63-.54l-2.238 5.03a2 2 0 01-2.71.319L2.663 12H4a2 2 0 012 2v2a2 2 0 01-2 2H2a2 2 0 01-2-2V5z" />
|
||||
</svg>
|
||||
<p className="text-sm font-medium"><a href="tel:+13217308020" className="text-primary-cyan hover:text-cyan-700 underline" aria-label="Call (321) 730-8020">(321) 730-8020</a></p>
|
||||
<div className="grid grid-cols-1 lg:grid-cols-[1fr_0.72fr] gap-10 lg:gap-14 items-center">
|
||||
<div>
|
||||
<div className="inline-flex items-center gap-2 rounded-md border border-white/20 bg-white/10 px-3 py-2 text-xs font-semibold uppercase tracking-wide text-primary-cyan">
|
||||
<LifeBuoy className="h-4 w-4" aria-hidden="true" />
|
||||
Queue North Support
|
||||
</div>
|
||||
<h1 className="mt-6 text-4xl md:text-5xl lg:text-6xl font-bold leading-tight">
|
||||
Get help without getting handed off.
|
||||
</h1>
|
||||
<p className="mt-6 text-lg md:text-xl text-white/75 max-w-2xl leading-relaxed">
|
||||
Open a support request, access the client portal, or escalate a service-impacting issue through one clear path.
|
||||
</p>
|
||||
<div className="mt-8 flex flex-col sm:flex-row gap-3">
|
||||
<a href="#support-request" className="inline-flex h-11 items-center justify-center gap-2 rounded-md bg-white px-5 text-sm font-semibold text-primary-navy hover:bg-section-alt transition-colors">
|
||||
Submit Request
|
||||
<ArrowRight className="h-4 w-4" aria-hidden="true" />
|
||||
</a>
|
||||
<a
|
||||
href={portalLinks[0].href}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="inline-flex h-11 items-center justify-center gap-2 rounded-md border border-white/40 px-5 text-sm font-semibold text-white hover:bg-white/10 transition-colors"
|
||||
>
|
||||
Open Portal
|
||||
<ExternalLink className="h-4 w-4" aria-hidden="true" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mb-8">
|
||||
<Link to="/contact" className="inline-flex items-center justify-center rounded-md text-sm font-medium h-10 px-6 bg-primary-navy text-white hover:bg-primary-navy-dark transition-colors">
|
||||
Request Consultation
|
||||
</Link>
|
||||
|
||||
<div className="rounded-md border border-white/15 bg-white/10 p-6 shadow-xl backdrop-blur">
|
||||
<h2 className="text-lg font-semibold mb-5">Choose the right path</h2>
|
||||
<div className="space-y-4">
|
||||
<div className="flex gap-4">
|
||||
<span className="flex h-10 w-10 shrink-0 items-center justify-center rounded-md bg-white/10 text-primary-cyan">
|
||||
<TicketCheck className="h-5 w-5" aria-hidden="true" />
|
||||
</span>
|
||||
<div>
|
||||
<h3 className="font-semibold">Existing client</h3>
|
||||
<p className="text-sm text-white/70">Submit the form or use the portal to track requests.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex gap-4">
|
||||
<span className="flex h-10 w-10 shrink-0 items-center justify-center rounded-md bg-white/10 text-primary-cyan">
|
||||
<AlertCircle className="h-5 w-5" aria-hidden="true" />
|
||||
</span>
|
||||
<div>
|
||||
<h3 className="font-semibold">Active outage</h3>
|
||||
<a href="tel:+13217308020" className="text-sm font-semibold text-primary-cyan hover:text-white transition-colors" aria-label="Call Queue North support">
|
||||
Call (321) 730-8020
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex gap-4">
|
||||
<span className="flex h-10 w-10 shrink-0 items-center justify-center rounded-md bg-white/10 text-primary-cyan">
|
||||
<Wrench className="h-5 w-5" aria-hidden="true" />
|
||||
</span>
|
||||
<div>
|
||||
<h3 className="font-semibold">Planned work</h3>
|
||||
<p className="text-sm text-white/70">Use the request form for moves, adds, changes, and deployments.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Support Form */}
|
||||
<section className="bg-background py-16">
|
||||
<section id="support-request" className="bg-background py-16 lg:py-20">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-12">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-[0.9fr_1.1fr] gap-8 lg:gap-10 items-start">
|
||||
{/* Left - Info */}
|
||||
<div>
|
||||
<div className="mb-8">
|
||||
<h2 className="text-2xl font-bold text-primary-navy mb-4">Support Services</h2>
|
||||
<p className="text-soft-text mb-6">
|
||||
We provide comprehensive support for all our services, including 24/7 monitoring, rapid response, and dedicated support engineers.
|
||||
</p>
|
||||
<div className="space-y-4">
|
||||
<div className="bg-section-alt rounded-lg p-6">
|
||||
<h3 className="font-semibold text-primary-navy mb-4">Queue North Support Center</h3>
|
||||
<p className="text-text mb-6">
|
||||
Need to sign up for the Queue North Support Center? Create an account to access our knowledge base and submit support tickets.
|
||||
</p>
|
||||
<div className="flex flex-wrap gap-4 mb-4">
|
||||
<a
|
||||
href="https://queuenorthtechnologiesllc.zohodesk.com/portal/en/signup"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="inline-flex items-center justify-center px-6 py-3 bg-primary-navy text-white font-medium rounded-md hover:bg-primary-navy-dark transition-colors"
|
||||
>
|
||||
Sign Up
|
||||
<svg className="ml-2 h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" />
|
||||
</svg>
|
||||
</a>
|
||||
<a
|
||||
href="https://queuenorthtechnologiesllc.zohodesk.com/portal/en/signin"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="inline-flex items-center justify-center px-6 py-3 bg-white text-primary-navy font-medium rounded-md hover:bg-gray-50 transition-colors"
|
||||
>
|
||||
Already a member? Sign In
|
||||
</a>
|
||||
</div>
|
||||
<p className="text-sm text-soft-text">
|
||||
Or call our support team <a href="tel:+13217308020" className="text-primary-cyan hover:text-cyan-700 underline" aria-label="Call (321) 730-8020">(321) 730-8020</a>
|
||||
</p>
|
||||
</div>
|
||||
<div className="space-y-6">
|
||||
<div className="rounded-md border border-border bg-white p-6 shadow-sm">
|
||||
<div className="flex items-start gap-4">
|
||||
<span className="flex h-11 w-11 shrink-0 items-center justify-center rounded-md bg-primary-navy text-white">
|
||||
<Headphones className="h-5 w-5" aria-hidden="true" />
|
||||
</span>
|
||||
<div>
|
||||
<h3 className="font-semibold text-text mb-2">Phone</h3>
|
||||
<p className="text-soft-text"><a href="tel:+13217308020" className="text-primary-cyan hover:text-cyan-700 underline" aria-label="Call (321) 730-8020">(321) 730-8020</a></p>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-text mb-2">Support Hours</h3>
|
||||
<p className="text-soft-text">24/7 Monitoring with rapid response SLAs</p>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-text mb-2">Priority Levels</h3>
|
||||
<p className="text-soft-text">
|
||||
Low: General inquiries (response within 24 hours)<br/>
|
||||
Medium: Standard issues (response within 4 hours)<br/>
|
||||
High: Critical issues (response within 1 hour)
|
||||
<h2 className="text-xl font-bold text-primary-navy">Support Center</h2>
|
||||
<p className="mt-2 text-sm leading-relaxed text-soft-text">
|
||||
Sign in to manage existing tickets, create an account, or submit the form on this page for a new request.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-6 flex flex-col sm:flex-row gap-3">
|
||||
{portalLinks.map((link, index) => (
|
||||
<a
|
||||
key={link.label}
|
||||
href={link.href}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className={`inline-flex h-10 items-center justify-center gap-2 rounded-md px-4 text-sm font-semibold transition-colors ${index === 0 ? 'bg-primary-navy text-white hover:bg-primary-navy-dark' : 'border border-border bg-white text-primary-navy hover:bg-section-alt'}`}
|
||||
>
|
||||
{link.label}
|
||||
<ExternalLink className="h-4 w-4" aria-hidden="true" />
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="bg-section-alt rounded-lg p-6">
|
||||
<h3 className="font-semibold text-primary-navy mb-4">What We Support</h3>
|
||||
<div className="rounded-md border border-border bg-white p-6 shadow-sm">
|
||||
<div className="flex items-center gap-3 mb-5">
|
||||
<span className="flex h-10 w-10 items-center justify-center rounded-md bg-section-alt text-primary-navy">
|
||||
<Clock3 className="h-5 w-5" aria-hidden="true" />
|
||||
</span>
|
||||
<h2 className="text-xl font-bold text-primary-navy">Response Targets</h2>
|
||||
</div>
|
||||
<div className="grid gap-3 sm:grid-cols-3 lg:grid-cols-1">
|
||||
{responseTargets.map((item) => (
|
||||
<div key={item.priority} className="rounded-md border border-border bg-background p-4">
|
||||
<div className="flex items-center justify-between gap-3">
|
||||
<p className="font-semibold text-text">{item.priority}</p>
|
||||
<p className="font-numeric text-xl text-primary-navy">{item.target}</p>
|
||||
</div>
|
||||
<p className="mt-1 text-sm text-soft-text">{item.context}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="rounded-md border border-border bg-section-alt p-6">
|
||||
<div className="flex items-center gap-3 mb-5">
|
||||
<span className="flex h-10 w-10 items-center justify-center rounded-md bg-white text-primary-navy">
|
||||
<ShieldCheck className="h-5 w-5" aria-hidden="true" />
|
||||
</span>
|
||||
<h2 className="text-xl font-bold text-primary-navy">Covered Systems</h2>
|
||||
</div>
|
||||
<ul className="space-y-3">
|
||||
{[
|
||||
'8x8 Communications Platform',
|
||||
'VoIP Phone Systems',
|
||||
'Contact Center Solutions',
|
||||
'Network Infrastructure',
|
||||
'Cloud Migration Support',
|
||||
].map((item, index) => (
|
||||
<li key={index} className="flex items-center gap-3 text-text">
|
||||
<svg className="h-5 w-5 text-primary-navy" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M5 13l4 4L19 7" />
|
||||
</svg>
|
||||
{supportedSystems.map((item) => (
|
||||
<li key={item} className="flex items-center gap-3 text-sm text-text">
|
||||
<CheckCircle2 className="h-5 w-5 shrink-0 text-primary-blue" aria-hidden="true" />
|
||||
{item}
|
||||
</li>
|
||||
))}
|
||||
|
|
@ -228,76 +290,87 @@ const Support = () => {
|
|||
|
||||
{/* Right - Form */}
|
||||
<div>
|
||||
<form onSubmit={handleSubmit} noValidate className={`space-y-6 ${isSubmitting ? 'opacity-70 pointer-events-none' : ''}`}>
|
||||
<div>
|
||||
<label htmlFor="name" className="block text-sm font-medium text-text mb-2">
|
||||
Name <span className="text-red-600">*</span>
|
||||
</label>
|
||||
<Input
|
||||
type="text"
|
||||
id="name"
|
||||
name="name"
|
||||
value={formState.name}
|
||||
onChange={handleChange}
|
||||
required
|
||||
placeholder="Your full name"
|
||||
className={errors.name ? 'border-red-500 focus-visible:ring-red-500' : ''}
|
||||
/>
|
||||
{debouncedErrors.name && (
|
||||
<p className="text-xs text-red-600 mt-1">{debouncedErrors.name}</p>
|
||||
)}
|
||||
<form onSubmit={handleSubmit} noValidate className={`rounded-md border border-border bg-white p-6 shadow-sm lg:p-8 space-y-5 ${isSubmitting ? 'opacity-70 pointer-events-none' : ''}`}>
|
||||
<div className="border-b border-border pb-5">
|
||||
<h2 className="text-2xl font-bold text-primary-navy">Submit a Request</h2>
|
||||
<p className="mt-2 text-sm text-soft-text">
|
||||
Include who is affected, what changed, and how urgent the issue is.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label htmlFor="company" className="block text-sm font-medium text-text mb-2">
|
||||
Company Name <span className="text-red-600">*</span>
|
||||
</label>
|
||||
<Input
|
||||
type="text"
|
||||
id="company"
|
||||
name="company"
|
||||
value={formState.company}
|
||||
onChange={handleChange}
|
||||
required
|
||||
placeholder="Your company name"
|
||||
className={errors.company ? 'border-red-500 focus-visible:ring-red-500' : ''}
|
||||
/>
|
||||
{debouncedErrors.company && (
|
||||
<p className="text-xs text-red-600 mt-1">{debouncedErrors.company}</p>
|
||||
)}
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||
<div>
|
||||
<label htmlFor="name" className="block text-sm font-medium text-text mb-2">
|
||||
Name <span className="text-red-600">*</span>
|
||||
</label>
|
||||
<Input
|
||||
type="text"
|
||||
id="name"
|
||||
name="name"
|
||||
value={formState.name}
|
||||
onChange={handleChange}
|
||||
required
|
||||
placeholder="Your full name"
|
||||
className={errors.name ? 'border-red-500 focus-visible:ring-red-500' : ''}
|
||||
/>
|
||||
{debouncedErrors.name && (
|
||||
<p className="text-xs text-red-600 mt-1">{debouncedErrors.name}</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label htmlFor="company" className="block text-sm font-medium text-text mb-2">
|
||||
Company <span className="text-red-600">*</span>
|
||||
</label>
|
||||
<Input
|
||||
type="text"
|
||||
id="company"
|
||||
name="company"
|
||||
value={formState.company}
|
||||
onChange={handleChange}
|
||||
required
|
||||
placeholder="Company name"
|
||||
className={errors.company ? 'border-red-500 focus-visible:ring-red-500' : ''}
|
||||
/>
|
||||
{debouncedErrors.company && (
|
||||
<p className="text-xs text-red-600 mt-1">{debouncedErrors.company}</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label htmlFor="email" className="block text-sm font-medium text-text mb-2">
|
||||
Email <span className="text-red-600">*</span>
|
||||
</label>
|
||||
<Input
|
||||
type="email"
|
||||
id="email"
|
||||
name="email"
|
||||
value={formState.email}
|
||||
onChange={handleChange}
|
||||
required
|
||||
placeholder="your.email@example.com"
|
||||
className={errors.email ? 'border-red-500 focus-visible:ring-red-500' : ''}
|
||||
/>
|
||||
{debouncedErrors.email && (
|
||||
<p className="text-xs text-red-600 mt-1">{debouncedErrors.email}</p>
|
||||
)}
|
||||
</div>
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||
<div>
|
||||
<label htmlFor="email" className="block text-sm font-medium text-text mb-2">
|
||||
Email <span className="text-red-600">*</span>
|
||||
</label>
|
||||
<Input
|
||||
type="email"
|
||||
id="email"
|
||||
name="email"
|
||||
value={formState.email}
|
||||
onChange={handleChange}
|
||||
required
|
||||
placeholder="you@example.com"
|
||||
className={errors.email ? 'border-red-500 focus-visible:ring-red-500' : ''}
|
||||
/>
|
||||
{debouncedErrors.email && (
|
||||
<p className="text-xs text-red-600 mt-1">{debouncedErrors.email}</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label htmlFor="phone" className="block text-sm font-medium text-text mb-2">
|
||||
Phone (Optional)
|
||||
</label>
|
||||
<Input
|
||||
type="tel"
|
||||
id="phone"
|
||||
name="phone"
|
||||
value={formState.phone}
|
||||
onChange={handleChange}
|
||||
placeholder="(555) 123-4567"
|
||||
/>
|
||||
<div>
|
||||
<label htmlFor="phone" className="block text-sm font-medium text-text mb-2">
|
||||
Phone <span className="text-soft-text">(optional)</span>
|
||||
</label>
|
||||
<Input
|
||||
type="tel"
|
||||
id="phone"
|
||||
name="phone"
|
||||
value={formState.phone}
|
||||
onChange={handleChange}
|
||||
placeholder="(555) 123-4567"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
|
|
@ -318,7 +391,7 @@ const Support = () => {
|
|||
|
||||
<div>
|
||||
<label htmlFor="issue" className="block text-sm font-medium text-text mb-2">
|
||||
Describe Your Issue <span className="text-red-600">*</span>
|
||||
Issue Details <span className="text-red-600">*</span>
|
||||
</label>
|
||||
<Textarea
|
||||
id="issue"
|
||||
|
|
@ -326,7 +399,7 @@ const Support = () => {
|
|||
value={formState.issue}
|
||||
onChange={handleChange}
|
||||
required
|
||||
placeholder="Please describe your issue in detail..."
|
||||
placeholder="What changed, who is affected, and what have you already tried?"
|
||||
className={`w-full rounded-md border bg-background px-3 py-2 text-sm ring-offset-[#F8FAFC] placeholder:text-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-navy focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 ${errors.issue ? 'border-red-500 focus-visible:ring-red-500' : ''}`}
|
||||
rows={5}
|
||||
/>
|
||||
|
|
@ -348,7 +421,7 @@ const Support = () => {
|
|||
|
||||
<Button
|
||||
type="submit"
|
||||
className="w-full"
|
||||
className="w-full gap-2"
|
||||
disabled={isSubmitting}
|
||||
>
|
||||
{isSubmitting ? (
|
||||
|
|
@ -360,7 +433,10 @@ const Support = () => {
|
|||
Submitting...
|
||||
</>
|
||||
) : (
|
||||
'Submit Request'
|
||||
<>
|
||||
Submit Request
|
||||
<ArrowRight className="h-4 w-4" aria-hidden="true" />
|
||||
</>
|
||||
)}
|
||||
</Button>
|
||||
</form>
|
||||
|
|
|
|||
Loading…
Reference in New Issue