feat(seo): add react-helmet-async, per-page meta/OG tags, JSON-LD, sitemap, robots.txt, heading fixes (#71)
- Added react-helmet-async + HelmetProvider to main.jsx - Per-page Helmet components on all 8 pages (title, description, OG tags) - JSON-LD structured data (Organization, LocalBusiness, Service) - Created public/sitemap.xml with all 17 routes - Created public/robots.txt - Fixed heading hierarchy (no h1->h3 skips) - Improved image alt text throughout - Fixed docs/zoho-setup.md env defaults clarification
This commit is contained in:
parent
2a9eef0e71
commit
1b0d5adc36
|
|
@ -34,3 +34,4 @@ pnpm-debug.log*
|
|||
.vscode/
|
||||
.idea/
|
||||
.learnings/
|
||||
Levi.md
|
||||
|
|
|
|||
|
|
@ -74,15 +74,19 @@ curl -X POST https://accounts.zoho.com/oauth/v2/token \
|
|||
Add these to your `.env` file:
|
||||
|
||||
```env
|
||||
ZOHO_ENABLED=true
|
||||
# Zoho integration is OFF by default — set to true to enable
|
||||
ZOHO_ENABLED=false
|
||||
ZOHO_API_DOMAIN=https://www.zohoapis.com
|
||||
ZOHO_ACCOUNTS_DOMAIN=https://accounts.zoho.com
|
||||
ZOHO_CLIENT_ID=<from Step 1>
|
||||
ZOHO_CLIENT_SECRET=<from Step 1>
|
||||
ZOHO_REFRESH_TOKEN=<from Step 3>
|
||||
ZOHO_CASES_ENABLED=true
|
||||
# Cases forwarding is also OFF by default
|
||||
ZOHO_CASES_ENABLED=false
|
||||
```
|
||||
|
||||
> **Note:** Both `ZOHO_ENABLED` and `ZOHO_CASES_ENABLED` default to `false`. Set them to `true` only after completing Steps 1–3 and verifying your credentials.
|
||||
|
||||
### Datacenter Variants
|
||||
|
||||
If your Zoho datacenter is **outside the US**, adjust the domains:
|
||||
|
|
@ -165,12 +169,13 @@ Website Contact Form → SQLite (always saved)
|
|||
|
||||
## What Happens Next?
|
||||
|
||||
After configuration, your team (Ripley + Bishop) will:
|
||||
1. Deploy environment variables to production
|
||||
2. Run integration tests
|
||||
3. Verify data flows to Zoho CRM
|
||||
4. Update `PROJECT.md` with the integration status
|
||||
After configuration:
|
||||
1. Deploy the environment variables to production
|
||||
2. Set `ZOHO_ENABLED=true` and `ZOHO_CASES_ENABLED=true` in production `.env`
|
||||
3. Restart the application
|
||||
4. Submit a test lead and support case to verify data flows to Zoho CRM
|
||||
5. Check Zoho CRM Leads and Cases tabs to confirm both appear
|
||||
|
||||
---
|
||||
|
||||
**Questions?** Contact Ripley (Infrastructure) or Neo (Backend).
|
||||
**Need help?** Contact your site administrator.
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "queuenorth-website",
|
||||
"version": "0.4.8",
|
||||
"version": "0.6.6",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "queuenorth-website",
|
||||
"version": "0.4.8",
|
||||
"version": "0.6.6",
|
||||
"dependencies": {
|
||||
"@radix-ui/react-dialog": "^1.1.0",
|
||||
"@radix-ui/react-visually-hidden": "^1.2.4",
|
||||
|
|
@ -19,6 +19,7 @@
|
|||
"lucide-react": "^0.468.0",
|
||||
"react": "^19.0.0",
|
||||
"react-dom": "^19.0.0",
|
||||
"react-helmet-async": "^3.0.0",
|
||||
"react-router-dom": "^7.1.3",
|
||||
"sonner": "^1.7.0",
|
||||
"tailwindcss-animate": "^1.0.7",
|
||||
|
|
@ -3132,6 +3133,15 @@
|
|||
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/invariant": {
|
||||
"version": "2.2.4",
|
||||
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
|
||||
"integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ip-address": {
|
||||
"version": "10.2.0",
|
||||
"resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.2.0.tgz",
|
||||
|
|
@ -3230,7 +3240,6 @@
|
|||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/jsesc": {
|
||||
|
|
@ -3277,6 +3286,18 @@
|
|||
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/loose-envify": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
|
||||
"integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"js-tokens": "^3.0.0 || ^4.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"loose-envify": "cli.js"
|
||||
}
|
||||
},
|
||||
"node_modules/lru-cache": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
|
||||
|
|
@ -3913,6 +3934,26 @@
|
|||
"react": "^19.2.6"
|
||||
}
|
||||
},
|
||||
"node_modules/react-fast-compare": {
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz",
|
||||
"integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/react-helmet-async": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/react-helmet-async/-/react-helmet-async-3.0.0.tgz",
|
||||
"integrity": "sha512-nA3IEZfXiclgrz4KLxAhqJqIfFDuvzQwlKwpdmzZIuC1KNSghDEIXmyU0TKtbM+NafnkICcwx8CECFrZ/sL/1w==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"invariant": "^2.2.4",
|
||||
"react-fast-compare": "^3.2.2",
|
||||
"shallowequal": "^1.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.6.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-refresh": {
|
||||
"version": "0.17.0",
|
||||
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz",
|
||||
|
|
@ -4305,6 +4346,12 @@
|
|||
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/shallowequal": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz",
|
||||
"integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/shell-quote": {
|
||||
"version": "1.8.3",
|
||||
"resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz",
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
"lucide-react": "^0.468.0",
|
||||
"react": "^19.0.0",
|
||||
"react-dom": "^19.0.0",
|
||||
"react-helmet-async": "^3.0.0",
|
||||
"react-router-dom": "^7.1.3",
|
||||
"sonner": "^1.7.0",
|
||||
"tailwindcss-animate": "^1.0.7",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,4 @@
|
|||
User-agent: *
|
||||
Allow: /
|
||||
|
||||
Sitemap: https://queuenorth.com/sitemap.xml
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||
<url>
|
||||
<loc>https://queuenorth.com</loc>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>1.0</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://queuenorth.com/about</loc>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://queuenorth.com/services</loc>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.9</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://queuenorth.com/services/unified-communications</loc>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://queuenorth.com/services/contact-center</loc>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://queuenorth.com/services/managed-support</loc>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://queuenorth.com/services/consulting-training</loc>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://queuenorth.com/services/infrastructure-cabling</loc>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://queuenorth.com/services/wireless-access</loc>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://queuenorth.com/services/local-networking</loc>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://queuenorth.com/industries</loc>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://queuenorth.com/industries/healthcare</loc>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://queuenorth.com/industries/retail</loc>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://queuenorth.com/industries/manufacturing</loc>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://queuenorth.com/industries/education-finance</loc>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://queuenorth.com/contact</loc>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.9</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://queuenorth.com/support</loc>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
</urlset>
|
||||
|
|
@ -3,6 +3,7 @@ import { createRoot } from 'react-dom/client'
|
|||
import { RouterProvider } from 'react-router-dom'
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
|
||||
import { Toaster } from 'sonner'
|
||||
import { HelmetProvider } from 'react-helmet-async'
|
||||
import router from './router.jsx'
|
||||
import App from './App.jsx'
|
||||
|
||||
|
|
@ -17,10 +18,12 @@ const queryClient = new QueryClient({
|
|||
// Wrap the router with providers
|
||||
const Root = () => (
|
||||
<StrictMode>
|
||||
<HelmetProvider>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<RouterProvider router={router} />
|
||||
<Toaster position="top-right" />
|
||||
</QueryClientProvider>
|
||||
</HelmetProvider>
|
||||
</StrictMode>
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,19 @@
|
|||
import { Helmet } from 'react-helmet-async'
|
||||
import { Link } from 'react-router-dom'
|
||||
|
||||
const About = () => {
|
||||
return (
|
||||
<>
|
||||
<Helmet>
|
||||
<title>About Queue North | Veteran-Owned 8x8 Partner — 25+ Years of Service</title>
|
||||
<meta name="description" content="Queue North Technologies is a veteran-owned 8x8 and Cisco Certified Partner with 25+ years serving businesses in Houghton, MI and the Upper Peninsula. Learn our story, values, and expertise." />
|
||||
<meta property="og:title" content="About Queue North | Veteran-Owned 8x8 Partner — 25+ Years of Service" />
|
||||
<meta property="og:description" content="Veteran-owned 8x8 and Cisco Certified Partner with 25+ years serving Houghton, MI and the Upper Peninsula." />
|
||||
<meta property="og:url" content="https://queuenorth.com/about" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:image" content="https://queuenorth.com/logo.svg" />
|
||||
<meta property="og:site_name" content="Queue North Technologies" />
|
||||
</Helmet>
|
||||
{/* Page Hero */}
|
||||
<section className="bg-background py-16 lg:py-24">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
|
|
@ -38,7 +49,7 @@ const About = () => {
|
|||
<div className="rounded-xl overflow-hidden shadow-lg">
|
||||
<img
|
||||
src="/assets/about-image.png"
|
||||
alt="Our Team"
|
||||
alt="Queue North Technologies team providing business communications solutions"
|
||||
className="w-full max-h-96 h-auto object-cover"
|
||||
/>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { Helmet } from 'react-helmet-async'
|
||||
import { useState } from 'react'
|
||||
import { useMutation } from '@tanstack/react-query'
|
||||
import { toast } from 'sonner'
|
||||
|
|
@ -102,6 +103,16 @@ const Contact = () => {
|
|||
|
||||
return (
|
||||
<>
|
||||
<Helmet>
|
||||
<title>Contact Queue North | Schedule a Consultation</title>
|
||||
<meta name="description" content="Contact Queue North Technologies to schedule a free consultation. Call (906) 482-6616 or fill out our form for business phone, UCaaS, IT support, and networking solutions." />
|
||||
<meta property="og:title" content="Contact Queue North | Schedule a Consultation" />
|
||||
<meta property="og:description" content="Schedule a free consultation with Queue North Technologies. Business communications and IT solutions in Houghton, MI." />
|
||||
<meta property="og:url" content="https://queuenorth.com/contact" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:image" content="https://queuenorth.com/logo.svg" />
|
||||
<meta property="og:site_name" content="Queue North Technologies" />
|
||||
</Helmet>
|
||||
{/* Page Hero */}
|
||||
<section className="bg-background py-16 lg:py-24">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
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'
|
||||
|
|
@ -16,8 +17,71 @@ const industryIcons = {
|
|||
const Home = () => {
|
||||
const navigate = useNavigate()
|
||||
|
||||
const organizationLd = {
|
||||
'@context': 'https://schema.org',
|
||||
'@type': 'Organization',
|
||||
name: 'Queue North Technologies',
|
||||
url: 'https://queuenorth.com',
|
||||
logo: 'https://queuenorth.com/logo.svg',
|
||||
description: 'Business communications and IT partner — Houghton, MI. 8x8 Certified Partner, Veteran Owned, 25+ years of service.',
|
||||
address: {
|
||||
'@type': 'PostalAddress',
|
||||
addressLocality: 'Houghton',
|
||||
addressRegion: 'MI',
|
||||
addressCountry: 'US',
|
||||
},
|
||||
contactPoint: {
|
||||
'@type': 'ContactPoint',
|
||||
telephone: '+1-906-482-6616',
|
||||
contactType: 'customer service',
|
||||
areaServed: 'US',
|
||||
},
|
||||
sameAs: [],
|
||||
}
|
||||
|
||||
const localBusinessLd = {
|
||||
'@context': 'https://schema.org',
|
||||
'@type': 'LocalBusiness',
|
||||
'@id': 'https://queuenorth.com/#business',
|
||||
name: 'Queue North Technologies',
|
||||
image: 'https://queuenorth.com/logo.svg',
|
||||
url: 'https://queuenorth.com',
|
||||
telephone: '+1-906-482-6616',
|
||||
email: 'info@queuenorth.com',
|
||||
address: {
|
||||
'@type': 'PostalAddress',
|
||||
streetAddress: 'Houghton',
|
||||
addressLocality: 'Houghton',
|
||||
addressRegion: 'MI',
|
||||
addressCountry: 'US',
|
||||
},
|
||||
areaServed: {
|
||||
'@type': 'Place',
|
||||
name: 'Upper Peninsula, Michigan',
|
||||
},
|
||||
priceRange: '$$',
|
||||
openingHoursSpecification: {
|
||||
'@type': 'OpeningHoursSpecification',
|
||||
dayOfWeek: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'],
|
||||
opens: '08:00',
|
||||
closes: '18:00',
|
||||
},
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Helmet>
|
||||
<title>Queue North Technologies | Business Communications & IT Partner — Houghton, MI</title>
|
||||
<meta name="description" content="Queue North Technologies is a veteran-owned 8x8 Certified Partner providing business phone systems, UCaaS, contact center, IT support, and networking solutions in Houghton, MI and the Upper Peninsula. 25+ years of proven reliability." />
|
||||
<meta property="og:title" content="Queue North Technologies | Business Communications & IT Partner — Houghton, MI" />
|
||||
<meta property="og:description" content="Veteran-owned 8x8 Certified Partner. Business phone, UCaaS, contact center, IT support, and networking solutions. 25+ years serving Houghton, MI and the Upper Peninsula." />
|
||||
<meta property="og:url" content="https://queuenorth.com" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:image" content="https://queuenorth.com/logo.svg" />
|
||||
<meta property="og:site_name" content="Queue North Technologies" />
|
||||
<script type="application/ld+json">{JSON.stringify(organizationLd)}</script>
|
||||
<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">
|
||||
|
|
@ -39,7 +103,7 @@ const Home = () => {
|
|||
</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" className="h-5 w-5" />
|
||||
<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">
|
||||
|
|
@ -59,7 +123,7 @@ const Home = () => {
|
|||
<div className="relative rounded-xl overflow-hidden shadow-2xl">
|
||||
<img
|
||||
src="/assets/hero-tech.png"
|
||||
alt="Communications Infrastructure"
|
||||
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" />
|
||||
|
|
@ -78,7 +142,7 @@ const Home = () => {
|
|||
</div>
|
||||
<div className="flex flex-wrap justify-center items-center gap-8 md:gap-16 opacity-70">
|
||||
<div className="flex items-center gap-3">
|
||||
<img src="/assets/8x8_Logo_White.svg" alt="8x8" className="h-8" />
|
||||
<img src="/assets/8x8_Logo_White.svg" alt="8x8 Certified Partner logo" className="h-8" />
|
||||
<span className="font-medium">8x8 Certified Partner</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-3">
|
||||
|
|
@ -102,7 +166,7 @@ const Home = () => {
|
|||
<div className="flex-1">
|
||||
<img
|
||||
src="/assets/JointLogoWhite.png"
|
||||
alt="Joint Logo White - 8x8 and Cisco Partner"
|
||||
alt="8x8 and Cisco Certified Partner logo for Queue North Technologies"
|
||||
className="max-h-32 w-auto object-contain mx-auto"
|
||||
/>
|
||||
</div>
|
||||
|
|
@ -141,7 +205,7 @@ const Home = () => {
|
|||
<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" className="h-8 w-auto" />
|
||||
<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>
|
||||
|
|
|
|||
|
|
@ -1,9 +1,20 @@
|
|||
import { Helmet } from 'react-helmet-async'
|
||||
import { industries } from '@/data/industries'
|
||||
import { Link } from 'react-router-dom'
|
||||
|
||||
const Industries = () => {
|
||||
return (
|
||||
<>
|
||||
<Helmet>
|
||||
<title>Industries We Serve | Queue North Technologies</title>
|
||||
<meta name="description" content="Queue North Technologies serves healthcare, retail, manufacturing, education, and finance industries with tailored communications and IT solutions in Houghton, MI and the Upper Peninsula." />
|
||||
<meta property="og:title" content="Industries We Serve | Queue North Technologies" />
|
||||
<meta property="og:description" content="Tailored communications and IT solutions for healthcare, retail, manufacturing, education, and finance." />
|
||||
<meta property="og:url" content="https://queuenorth.com/industries" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:image" content="https://queuenorth.com/logo.svg" />
|
||||
<meta property="og:site_name" content="Queue North Technologies" />
|
||||
</Helmet>
|
||||
{/* Page Hero */}
|
||||
<section className="bg-background py-16 md:py-24">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
|
|
@ -30,14 +41,14 @@ const Industries = () => {
|
|||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4" />
|
||||
</svg>
|
||||
</div>
|
||||
<h3 className="text-xl font-semibold text-primary-navy group-hover:text-primary-navy-dark transition-colors">
|
||||
<h2 className="text-xl font-semibold text-primary-navy group-hover:text-primary-navy-dark transition-colors">
|
||||
{industry.name}
|
||||
</h3>
|
||||
</h2>
|
||||
</div>
|
||||
<p className="text-soft-text mb-4">{industry.shortDesc}</p>
|
||||
|
||||
<div className="mb-4">
|
||||
<h4 className="text-sm font-semibold text-text mb-2">Pain Points We Solve</h4>
|
||||
<h3 className="text-sm font-semibold text-text mb-2">Pain Points We Solve</h3>
|
||||
<div className="space-y-2">
|
||||
{industry.painPoints.slice(0, 2).map((painPoint, index) => (
|
||||
<div key={index} className="flex items-start gap-2 text-sm text-soft-text">
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { Helmet } from 'react-helmet-async'
|
||||
import { useParams } from 'react-router-dom'
|
||||
import { industries } from '@/data/industries'
|
||||
import { Link } from 'react-router-dom'
|
||||
|
|
@ -10,6 +11,10 @@ const IndustryDetail = () => {
|
|||
if (!industry) {
|
||||
return (
|
||||
<section className="bg-background py-16 md:py-24">
|
||||
<Helmet>
|
||||
<title>Industry Not Found | Queue North Technologies</title>
|
||||
<meta name="description" content="The industry page you are looking for does not exist." />
|
||||
</Helmet>
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="text-center">
|
||||
<h1 className="text-3xl font-bold text-primary-navy mb-4">Industry Not Found</h1>
|
||||
|
|
@ -23,8 +28,22 @@ const IndustryDetail = () => {
|
|||
)
|
||||
}
|
||||
|
||||
const industryTitle = `${industry.name} | Queue North Technologies`
|
||||
const industryDesc = industry.shortDesc || `Learn about Queue North Technologies solutions for the ${industry.name} industry in Houghton, MI and the Upper Peninsula.`
|
||||
const industryUrl = `https://queuenorth.com/industries/${industry.id}`
|
||||
|
||||
return (
|
||||
<>
|
||||
<Helmet>
|
||||
<title>{industryTitle}</title>
|
||||
<meta name="description" content={industryDesc} />
|
||||
<meta property="og:title" content={industryTitle} />
|
||||
<meta property="og:description" content={industryDesc} />
|
||||
<meta property="og:url" content={industryUrl} />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:image" content="https://queuenorth.com/logo.svg" />
|
||||
<meta property="og:site_name" content="Queue North Technologies" />
|
||||
</Helmet>
|
||||
{/* Page Hero */}
|
||||
<section className="bg-background py-16 md:py-24">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
|
|
@ -89,7 +108,7 @@ const IndustryDetail = () => {
|
|||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
<div>
|
||||
<h4 className="font-semibold text-text mb-2">Industry</h4>
|
||||
<h3 className="font-semibold text-text mb-2">Industry</h3>
|
||||
<p className="text-soft-text">{industry.name}</p>
|
||||
</div>
|
||||
<div className="pt-4 border-t border-border">
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { Helmet } from 'react-helmet-async'
|
||||
import { useParams } from 'react-router-dom'
|
||||
import { services } from '@/data/services'
|
||||
import { Link } from 'react-router-dom'
|
||||
|
|
@ -10,6 +11,10 @@ const ServiceDetail = () => {
|
|||
if (!service) {
|
||||
return (
|
||||
<section className="bg-background py-16 md:py-24">
|
||||
<Helmet>
|
||||
<title>Service Not Found | Queue North Technologies</title>
|
||||
<meta name="description" content="The service page you are looking for does not exist." />
|
||||
</Helmet>
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="text-center">
|
||||
<h1 className="text-3xl font-bold text-primary-navy mb-4">Service Not Found</h1>
|
||||
|
|
@ -23,8 +28,39 @@ const ServiceDetail = () => {
|
|||
)
|
||||
}
|
||||
|
||||
const serviceTitle = `${service.name} | Queue North Technologies`
|
||||
const serviceDesc = service.shortDesc || `Learn about ${service.name} from Queue North Technologies — serving Houghton, MI and the Upper Peninsula.`
|
||||
const serviceUrl = `https://queuenorth.com/services/${service.id}`
|
||||
|
||||
const serviceDetailLd = {
|
||||
'@context': 'https://schema.org',
|
||||
'@type': 'Service',
|
||||
name: service.name,
|
||||
description: service.shortDesc,
|
||||
provider: {
|
||||
'@type': 'Organization',
|
||||
name: 'Queue North Technologies',
|
||||
url: 'https://queuenorth.com',
|
||||
},
|
||||
areaServed: {
|
||||
'@type': 'Place',
|
||||
name: 'Houghton, MI / Upper Peninsula',
|
||||
},
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Helmet>
|
||||
<title>{serviceTitle}</title>
|
||||
<meta name="description" content={serviceDesc} />
|
||||
<meta property="og:title" content={serviceTitle} />
|
||||
<meta property="og:description" content={serviceDesc} />
|
||||
<meta property="og:url" content={serviceUrl} />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:image" content="https://queuenorth.com/logo.svg" />
|
||||
<meta property="og:site_name" content="Queue North Technologies" />
|
||||
<script type="application/ld+json">{JSON.stringify(serviceDetailLd)}</script>
|
||||
</Helmet>
|
||||
{/* Page Hero */}
|
||||
<section className="bg-background py-16 md:py-24">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
|
|
@ -101,11 +137,11 @@ const ServiceDetail = () => {
|
|||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
<div>
|
||||
<h4 className="font-semibold text-text mb-2">Service</h4>
|
||||
<h3 className="font-semibold text-text mb-2">Service</h3>
|
||||
<p className="text-soft-text">{service.name}</p>
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="font-semibold text-text mb-2">Category</h4>
|
||||
<h3 className="font-semibold text-text mb-2">Category</h3>
|
||||
<p className="text-soft-text capitalize">{service.id.replace('-', ' ')}</p>
|
||||
</div>
|
||||
<div className="pt-4 border-t border-border">
|
||||
|
|
|
|||
|
|
@ -1,10 +1,37 @@
|
|||
import { Helmet } from 'react-helmet-async'
|
||||
import { services } from '@/data/services'
|
||||
import { MessageCircle, Users, LifeBuoy, GraduationCap, Link as LinkIcon, Wifi, Network } from 'lucide-react'
|
||||
import { Link } from 'react-router-dom'
|
||||
|
||||
const serviceLd = {
|
||||
'@context': 'https://schema.org',
|
||||
'@type': 'Service',
|
||||
serviceType: 'Business Communications and IT Services',
|
||||
provider: {
|
||||
'@type': 'Organization',
|
||||
name: 'Queue North Technologies',
|
||||
url: 'https://queuenorth.com',
|
||||
},
|
||||
areaServed: {
|
||||
'@type': 'Place',
|
||||
name: 'Houghton, MI / Upper Peninsula',
|
||||
},
|
||||
}
|
||||
|
||||
const Services = () => {
|
||||
return (
|
||||
<>
|
||||
<Helmet>
|
||||
<title>Business Phone, UCaaS & IT Services | Queue North Technologies</title>
|
||||
<meta name="description" content="Explore Queue North Technologies services: unified communications, contact center, managed IT support, consulting & training, infrastructure cabling, wireless access, and local networking." />
|
||||
<meta property="og:title" content="Business Phone, UCaaS & IT Services | Queue North Technologies" />
|
||||
<meta property="og:description" content="Unified communications, contact center, managed IT support, consulting, cabling, wireless, and networking solutions." />
|
||||
<meta property="og:url" content="https://queuenorth.com/services" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:image" content="https://queuenorth.com/logo.svg" />
|
||||
<meta property="og:site_name" content="Queue North Technologies" />
|
||||
<script type="application/ld+json">{JSON.stringify(serviceLd)}</script>
|
||||
</Helmet>
|
||||
{/* Page Hero */}
|
||||
<section className="bg-background py-16 lg:py-24">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
|
|
@ -35,9 +62,9 @@ const Services = () => {
|
|||
{service.icon === 'wifi' && <Wifi className="h-6 w-6 text-primary-navy" />}
|
||||
{service.icon === 'network' && <Network className="h-6 w-6 text-primary-navy" />}
|
||||
</div>
|
||||
<h3 className="text-xl font-semibold text-primary-navy group-hover:text-primary-navy-dark transition-colors">
|
||||
<h2 className="text-xl font-semibold text-primary-navy group-hover:text-primary-navy-dark transition-colors">
|
||||
{service.name}
|
||||
</h3>
|
||||
</h2>
|
||||
</div>
|
||||
<p className="text-soft-text mb-4">{service.shortDesc}</p>
|
||||
<div className="space-y-2 mb-4">
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { Helmet } from 'react-helmet-async'
|
||||
import { useState } from 'react'
|
||||
import { useMutation } from '@tanstack/react-query'
|
||||
import { toast } from 'sonner'
|
||||
|
|
@ -105,6 +106,16 @@ const Support = () => {
|
|||
|
||||
return (
|
||||
<>
|
||||
<Helmet>
|
||||
<title>IT Support & Help Desk | Queue North Technologies</title>
|
||||
<meta name="description" content="Get IT support and help desk services from Queue North Technologies. 24/7 monitoring, rapid response SLAs, and dedicated support engineers for your business." />
|
||||
<meta property="og:title" content="IT Support & Help Desk | Queue North Technologies" />
|
||||
<meta property="og:description" content="24/7 IT support and help desk services. Rapid response SLAs, dedicated support engineers." />
|
||||
<meta property="og:url" content="https://queuenorth.com/support" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:image" content="https://queuenorth.com/logo.svg" />
|
||||
<meta property="og:site_name" content="Queue North Technologies" />
|
||||
</Helmet>
|
||||
{/* Page Hero */}
|
||||
<section className="bg-background py-16 md:py-24">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
|
|
|
|||
Loading…
Reference in New Issue