SEO
This commit is contained in:
@@ -11,7 +11,19 @@ interface BreadcrumbProps {
|
||||
}
|
||||
|
||||
const Breadcrumb: React.FC<BreadcrumbProps> = ({ items }) => {
|
||||
const breadcrumbSchema = {
|
||||
'@context': 'https://schema.org',
|
||||
'@type': 'BreadcrumbList',
|
||||
itemListElement: items.map((item, index) => ({
|
||||
'@type': 'ListItem',
|
||||
position: index + 1,
|
||||
name: item.label,
|
||||
...(item.to ? { item: `https://bayareait.services${item.to}` } : {}),
|
||||
})),
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<nav aria-label="breadcrumb" className="text-sm text-gray-500 dark:text-gray-400 flex items-center gap-1.5">
|
||||
{items.map((item, i) => (
|
||||
<React.Fragment key={i}>
|
||||
@@ -29,6 +41,11 @@ const Breadcrumb: React.FC<BreadcrumbProps> = ({ items }) => {
|
||||
</React.Fragment>
|
||||
))}
|
||||
</nav>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{ __html: JSON.stringify(breadcrumbSchema) }}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -24,6 +24,20 @@ const BlogPostPage: React.FC<BlogPostPageProps> = ({ data }) => {
|
||||
? 'Local Services'
|
||||
: 'IT Insights';
|
||||
|
||||
const schema = {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "BlogPosting",
|
||||
"headline": data.h1,
|
||||
"description": data.description,
|
||||
"url": `https://bayareait.services/${data.slug}`,
|
||||
"image": data.image ? `https://bayareait.services${data.image}` : "https://bayareait.services/logo.svg",
|
||||
"publisher": {
|
||||
"@type": "Organization",
|
||||
"name": "Bay Area IT",
|
||||
"url": "https://bayareait.services"
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<SEO
|
||||
@@ -31,6 +45,7 @@ const BlogPostPage: React.FC<BlogPostPageProps> = ({ data }) => {
|
||||
description={data.description}
|
||||
keywords={data.keywords}
|
||||
canonicalUrl={`https://bayareait.services/${data.slug}`}
|
||||
schema={schema}
|
||||
/>
|
||||
|
||||
<div className="min-h-screen bg-background-light dark:bg-background-dark relative overflow-x-hidden pt-32 pb-16">
|
||||
|
||||
@@ -1,12 +1,42 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { motion } from 'framer-motion';
|
||||
import SEO from '../../components/SEO';
|
||||
|
||||
const ContactPage: React.FC = () => {
|
||||
const [isSubmitted, setIsSubmitted] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
window.scrollTo(0, 0);
|
||||
}, []);
|
||||
|
||||
const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
|
||||
event.preventDefault();
|
||||
|
||||
const formData = new FormData(event.currentTarget);
|
||||
const name = String(formData.get('name') || '').trim();
|
||||
const phone = String(formData.get('phone') || '').trim();
|
||||
const email = String(formData.get('email') || '').trim();
|
||||
const company = String(formData.get('company') || '').trim();
|
||||
const message = String(formData.get('message') || '').trim();
|
||||
|
||||
const subject = encodeURIComponent(`Website inquiry from ${name || 'Bay Area IT visitor'}`);
|
||||
const body = encodeURIComponent(
|
||||
[
|
||||
`Name: ${name || 'Not provided'}`,
|
||||
`Phone: ${phone || 'Not provided'}`,
|
||||
`Email: ${email || 'Not provided'}`,
|
||||
`Company: ${company || 'Not provided'}`,
|
||||
'',
|
||||
'Message:',
|
||||
message || 'No message provided',
|
||||
].join('\n'),
|
||||
);
|
||||
|
||||
window.location.href = `mailto:info@bayareaaffiliates.com?subject=${subject}&body=${body}`;
|
||||
setIsSubmitted(true);
|
||||
event.currentTarget.reset();
|
||||
};
|
||||
|
||||
const faqs = [
|
||||
{ q: 'How quickly can you start?', a: 'Most assessments can begin within 48 hours of contact. Emergency support is available 24/7.' },
|
||||
{ q: 'How do you price services?', a: 'Transparent monthly pricing based on devices and services needed. No hidden fees or surprise charges.' },
|
||||
@@ -44,32 +74,37 @@ const ContactPage: React.FC = () => {
|
||||
className="bg-white/5 backdrop-blur-sm p-8 md:p-10 rounded-3xl shadow-xl border border-white/10"
|
||||
>
|
||||
<h3 className="text-2xl font-bold mb-8 text-white">Send us a message</h3>
|
||||
<form className="space-y-6">
|
||||
<form className="space-y-6" onSubmit={handleSubmit}>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<div>
|
||||
<label htmlFor="name" className="block text-sm font-medium text-gray-300 mb-2">Name *</label>
|
||||
<input type="text" id="name" required className="w-full px-4 py-3 rounded-xl bg-black/20 border border-white/10 focus:border-white/30 focus:ring-1 focus:ring-white/30 outline-none transition-all text-white placeholder-gray-600" placeholder="John Doe" />
|
||||
<input type="text" id="name" name="name" required className="w-full px-4 py-3 rounded-xl bg-black/20 border border-white/10 focus:border-white/30 focus:ring-1 focus:ring-white/30 outline-none transition-all text-white placeholder-gray-600" placeholder="John Doe" />
|
||||
</div>
|
||||
<div>
|
||||
<label htmlFor="phone" className="block text-sm font-medium text-gray-300 mb-2">Phone</label>
|
||||
<input type="tel" id="phone" className="w-full px-4 py-3 rounded-xl bg-black/20 border border-white/10 focus:border-white/30 focus:ring-1 focus:ring-white/30 outline-none transition-all text-white placeholder-gray-600" placeholder="(555) 000-0000" />
|
||||
<input type="tel" id="phone" name="phone" className="w-full px-4 py-3 rounded-xl bg-black/20 border border-white/10 focus:border-white/30 focus:ring-1 focus:ring-white/30 outline-none transition-all text-white placeholder-gray-600" placeholder="(555) 000-0000" />
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label htmlFor="email" className="block text-sm font-medium text-gray-300 mb-2">Email *</label>
|
||||
<input type="email" id="email" required className="w-full px-4 py-3 rounded-xl bg-black/20 border border-white/10 focus:border-white/30 focus:ring-1 focus:ring-white/30 outline-none transition-all text-white placeholder-gray-600" placeholder="john@company.com" />
|
||||
<input type="email" id="email" name="email" required className="w-full px-4 py-3 rounded-xl bg-black/20 border border-white/10 focus:border-white/30 focus:ring-1 focus:ring-white/30 outline-none transition-all text-white placeholder-gray-600" placeholder="john@company.com" />
|
||||
</div>
|
||||
<div>
|
||||
<label htmlFor="company" className="block text-sm font-medium text-gray-300 mb-2">Company</label>
|
||||
<input type="text" id="company" className="w-full px-4 py-3 rounded-xl bg-black/20 border border-white/10 focus:border-white/30 focus:ring-1 focus:ring-white/30 outline-none transition-all text-white placeholder-gray-600" placeholder="Acme Inc." />
|
||||
<input type="text" id="company" name="company" className="w-full px-4 py-3 rounded-xl bg-black/20 border border-white/10 focus:border-white/30 focus:ring-1 focus:ring-white/30 outline-none transition-all text-white placeholder-gray-600" placeholder="Acme Inc." />
|
||||
</div>
|
||||
<div>
|
||||
<label htmlFor="message" className="block text-sm font-medium text-gray-300 mb-2">Message *</label>
|
||||
<textarea id="message" rows={4} required className="w-full px-4 py-3 rounded-xl bg-black/20 border border-white/10 focus:border-white/30 focus:ring-1 focus:ring-white/30 outline-none transition-all text-white placeholder-gray-600 resize-none" placeholder="How can we help you?"></textarea>
|
||||
<textarea id="message" name="message" rows={4} required className="w-full px-4 py-3 rounded-xl bg-black/20 border border-white/10 focus:border-white/30 focus:ring-1 focus:ring-white/30 outline-none transition-all text-white placeholder-gray-600 resize-none" placeholder="How can we help you?"></textarea>
|
||||
</div>
|
||||
<button type="submit" className="w-full py-4 bg-white text-black font-bold rounded-xl transition-all hover:bg-gray-200 hover:scale-[1.02] shadow-[0_0_20px_rgba(255,255,255,0.1)]">
|
||||
Send Message
|
||||
</button>
|
||||
{isSubmitted && (
|
||||
<p className="text-sm text-gray-400">
|
||||
Your mail client should open with the message prefilled. If it does not, email us at info@bayareaaffiliates.com.
|
||||
</p>
|
||||
)}
|
||||
</form>
|
||||
</motion.div>
|
||||
|
||||
|
||||
@@ -89,6 +89,23 @@ const ServicePage: React.FC<ServicePageProps> = ({ data }) => {
|
||||
window.scrollTo(0, 0);
|
||||
}, []);
|
||||
|
||||
const schema = {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "Service",
|
||||
"name": data.h1,
|
||||
"description": data.description,
|
||||
"url": `https://bayareait.services/${data.slug}`,
|
||||
"provider": {
|
||||
"@type": "Organization",
|
||||
"name": "Bay Area IT",
|
||||
"url": "https://bayareait.services"
|
||||
},
|
||||
"areaServed": {
|
||||
"@type": "AdministrativeArea",
|
||||
"name": "Corpus Christi and the Coastal Bend"
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<SEO
|
||||
@@ -96,6 +113,7 @@ const ServicePage: React.FC<ServicePageProps> = ({ data }) => {
|
||||
description={data.description}
|
||||
keywords={data.keywords}
|
||||
canonicalUrl={`https://bayareait.services/${data.slug}`}
|
||||
schema={schema}
|
||||
/>
|
||||
|
||||
<div className="min-h-screen bg-background-light dark:bg-background-dark relative overflow-x-hidden">
|
||||
|
||||
Reference in New Issue
Block a user