feat: implement SEO-optimized landing pages, sitemap, and updated footer for enhanced site navigation and search visibility.
This commit is contained in:
177
greenlns-landing/components/SeoCategoryPage.tsx
Normal file
177
greenlns-landing/components/SeoCategoryPage.tsx
Normal file
@@ -0,0 +1,177 @@
|
||||
import Link from 'next/link'
|
||||
import Navbar from '@/components/Navbar'
|
||||
import CTA from '@/components/CTA'
|
||||
import Footer from '@/components/Footer'
|
||||
import type { SeoPageProfile } from '@/lib/seoPages'
|
||||
import { siteConfig, hasIosStoreUrl } from '@/lib/site'
|
||||
|
||||
interface SeoCategoryPageProps {
|
||||
profile: SeoPageProfile
|
||||
}
|
||||
|
||||
export default function SeoCategoryPage({ profile }: SeoCategoryPageProps) {
|
||||
const faqSchema = {
|
||||
'@context': 'https://schema.org',
|
||||
'@type': 'FAQPage',
|
||||
mainEntity: profile.faqs.map((item) => ({
|
||||
'@type': 'Question',
|
||||
name: item.question,
|
||||
acceptedAnswer: {
|
||||
'@type': 'Answer',
|
||||
text: item.answer,
|
||||
},
|
||||
})),
|
||||
}
|
||||
|
||||
const appSchema = profile.includeAppSchema
|
||||
? {
|
||||
'@context': 'https://schema.org',
|
||||
'@type': 'SoftwareApplication',
|
||||
name: siteConfig.name,
|
||||
operatingSystem: 'iOS, Android',
|
||||
applicationCategory: 'LifestyleApplication',
|
||||
description: profile.directAnswer,
|
||||
...(hasIosStoreUrl && { downloadUrl: siteConfig.iosAppStoreUrl }),
|
||||
offers: {
|
||||
'@type': 'Offer',
|
||||
price: '0',
|
||||
priceCurrency: 'EUR',
|
||||
},
|
||||
}
|
||||
: null
|
||||
|
||||
return (
|
||||
<>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{ __html: JSON.stringify(faqSchema) }}
|
||||
/>
|
||||
{appSchema && (
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{ __html: JSON.stringify(appSchema) }}
|
||||
/>
|
||||
)}
|
||||
<Navbar />
|
||||
<main className="comparison-page">
|
||||
{/* Hero */}
|
||||
<section className="comparison-hero">
|
||||
<div className="container comparison-hero-grid">
|
||||
<div className="comparison-hero-copy">
|
||||
<p className="tag">GreenLens</p>
|
||||
<h1>{profile.h1}</h1>
|
||||
<p className="comparison-lead">{profile.tagline}</p>
|
||||
<p>{profile.directAnswer}</p>
|
||||
<div className="comparison-actions">
|
||||
<a href="#cta" className="btn-primary">Try GreenLens</a>
|
||||
<a href="#feature-table" className="btn-outline">See full comparison</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<aside className="comparison-hero-card">
|
||||
<p className="comparison-card-label">Definition</p>
|
||||
<p>{profile.definitionBlock}</p>
|
||||
<p className="comparison-verified">Last updated: {profile.lastUpdated}</p>
|
||||
</aside>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Feature table */}
|
||||
<section className="comparison-table-section" id="feature-table">
|
||||
<div className="container">
|
||||
<div className="comparison-section-head">
|
||||
<p className="tag">At a glance</p>
|
||||
<h2>{profile.featureTable.title}</h2>
|
||||
</div>
|
||||
|
||||
<div className="comparison-table">
|
||||
<div className="comparison-table-header">
|
||||
<span>Feature</span>
|
||||
<span>GreenLens</span>
|
||||
<span>{profile.featureTable.alternativeLabel}</span>
|
||||
</div>
|
||||
|
||||
{profile.featureTable.rows.map((row) => (
|
||||
<article key={row.feature} className="comparison-row">
|
||||
<div className="comparison-row-title">{row.feature}</div>
|
||||
<div className="comparison-cell comparison-cell--greenlens">{row.greenlens}</div>
|
||||
<div className="comparison-cell comparison-cell--competitor">{row.alternative}</div>
|
||||
</article>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Fit cards */}
|
||||
<section className="comparison-fit">
|
||||
<div className="container comparison-fit-grid">
|
||||
<article className="comparison-fit-card comparison-fit-card--greenlens">
|
||||
<p className="tag">Best fit</p>
|
||||
<h2>Choose GreenLens if:</h2>
|
||||
<ul className="comparison-bullet-list comparison-bullet-list--dark">
|
||||
{profile.greenLensIf.map((item) => (
|
||||
<li key={item}>{item}</li>
|
||||
))}
|
||||
</ul>
|
||||
</article>
|
||||
|
||||
<article className="comparison-fit-card">
|
||||
<p className="tag">Not the best fit</p>
|
||||
<h2>GreenLens is not the right tool if:</h2>
|
||||
<ul className="comparison-bullet-list comparison-bullet-list--dark">
|
||||
{profile.notBestIf.map((item) => (
|
||||
<li key={item}>{item}</li>
|
||||
))}
|
||||
</ul>
|
||||
</article>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* FAQ */}
|
||||
<section className="comparison-faq">
|
||||
<div className="container">
|
||||
<div className="comparison-section-head">
|
||||
<p className="tag">FAQ</p>
|
||||
<h2>Common questions answered directly.</h2>
|
||||
</div>
|
||||
|
||||
<div className="comparison-faq-grid">
|
||||
{profile.faqs.map((item) => (
|
||||
<article key={item.question} className="comparison-faq-card">
|
||||
<h3>{item.question}</h3>
|
||||
<p>{item.answer}</p>
|
||||
</article>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Related links */}
|
||||
{profile.relatedLinks.length > 0 && (
|
||||
<section className="comparison-links">
|
||||
<div className="container comparison-links-grid">
|
||||
{profile.relatedLinks.map((link) => (
|
||||
<Link key={link.href} href={link.href} className="comparison-link-card">
|
||||
<p className="comparison-mini-label">Related</p>
|
||||
<h3>{link.label}</h3>
|
||||
<p>{link.description}</p>
|
||||
</Link>
|
||||
))}
|
||||
|
||||
<Link href="/support" className="comparison-link-card comparison-link-card--support">
|
||||
<p className="comparison-mini-label">Need help?</p>
|
||||
<h3>Talk to GreenLens support</h3>
|
||||
<p>
|
||||
Questions about scans, care plans, billing, or features? Use the support page.
|
||||
</p>
|
||||
</Link>
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
|
||||
<CTA />
|
||||
</main>
|
||||
<Footer />
|
||||
</>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user