159 lines
6.4 KiB
TypeScript
159 lines
6.4 KiB
TypeScript
import React from 'react';
|
|
import type { Metadata } from 'next';
|
|
import Link from 'next/link';
|
|
import Breadcrumbs, { BreadcrumbItem } from '@/components/Breadcrumbs';
|
|
import SeoJsonLd from '@/components/SeoJsonLd';
|
|
import { breadcrumbSchema } from '@/lib/schema';
|
|
import { MarketingPageTracker, TrackedCtaLink } from '@/components/marketing/MarketingAnalytics';
|
|
import { Button } from '@/components/ui/Button';
|
|
import { Card } from '@/components/ui/Card';
|
|
|
|
export const metadata: Metadata = {
|
|
title: {
|
|
absolute: 'QR Platform Comparisons | QR Master',
|
|
},
|
|
description:
|
|
'Head-to-head QR platform comparisons. See where QR Master fits against Beaconstac / Uniqode on pricing, analytics, privacy, and enterprise requirements.',
|
|
alternates: {
|
|
canonical: 'https://www.qrmaster.net/vs',
|
|
},
|
|
openGraph: {
|
|
title: 'QR Platform Comparisons | QR Master',
|
|
description:
|
|
'Head-to-head QR platform comparisons focused on pricing, analytics, GDPR, bulk creation, and enterprise fit.',
|
|
url: 'https://www.qrmaster.net/vs',
|
|
type: 'website',
|
|
images: ['/og-image.png'],
|
|
},
|
|
twitter: {
|
|
title: 'QR Platform Comparisons | QR Master',
|
|
description:
|
|
'Compare QR Master head-to-head with Beaconstac / Uniqode.',
|
|
},
|
|
};
|
|
|
|
const breadcrumbItems: BreadcrumbItem[] = [
|
|
{ name: 'Home', url: '/' },
|
|
{ name: 'Comparisons', url: '/vs' },
|
|
];
|
|
|
|
const pageSchema = {
|
|
'@context': 'https://schema.org',
|
|
'@type': 'CollectionPage',
|
|
name: 'QR Platform Comparisons',
|
|
url: 'https://www.qrmaster.net/vs',
|
|
description: 'Head-to-head comparison pages for QR Master against competing QR platforms.',
|
|
};
|
|
|
|
const comparisons = [
|
|
{
|
|
href: '/vs/beaconstac',
|
|
eyebrow: 'Head-to-head',
|
|
title: 'QR Master vs Beaconstac / Uniqode',
|
|
description:
|
|
'A detailed comparison of pricing, GDPR handling, analytics depth, bulk creation, simplicity, and enterprise requirements.',
|
|
},
|
|
];
|
|
|
|
export default function ComparisonsHubPage() {
|
|
return (
|
|
<>
|
|
<SeoJsonLd data={[pageSchema, breadcrumbSchema(breadcrumbItems)]} />
|
|
<MarketingPageTracker pageType="commercial" cluster="competitor" />
|
|
<div className="min-h-screen" style={{ backgroundColor: '#F8F7F4', color: '#18181B' }}>
|
|
<section className="border-b bg-white" style={{ borderColor: '#E4E0D9' }}>
|
|
<div className="container mx-auto max-w-7xl px-4 pb-20 pt-10 sm:px-6 lg:px-8">
|
|
<div className="mb-10">
|
|
<Breadcrumbs items={breadcrumbItems} />
|
|
</div>
|
|
|
|
<div className="max-w-3xl">
|
|
<div
|
|
className="mb-6 inline-block rounded px-3 py-1.5 text-xs font-semibold uppercase tracking-widest"
|
|
style={{ backgroundColor: '#DCFCE7', color: '#166534', letterSpacing: '0.12em' }}
|
|
>
|
|
QR Master comparisons
|
|
</div>
|
|
<h1
|
|
className="mb-6 text-4xl font-extrabold leading-[1.08] tracking-tight sm:text-5xl"
|
|
style={{ color: '#111110' }}
|
|
>
|
|
Head-to-head comparisons for teams choosing the right QR platform.
|
|
</h1>
|
|
<p className="mb-8 text-lg leading-relaxed" style={{ color: '#52525B' }}>
|
|
These pages are for direct platform decisions, not broad alternative browsing. If you already have two
|
|
tools in mind and want the tradeoffs laid out clearly, start here.
|
|
</p>
|
|
|
|
<div className="flex flex-col gap-3 sm:flex-row">
|
|
<TrackedCtaLink
|
|
href="/vs/beaconstac"
|
|
ctaLabel="Open Comparison"
|
|
ctaLocation="hero_primary"
|
|
pageType="commercial"
|
|
cluster="competitor"
|
|
>
|
|
<Button size="lg" className="h-13 w-full px-8 text-base sm:w-auto">
|
|
Open Comparison
|
|
</Button>
|
|
</TrackedCtaLink>
|
|
<TrackedCtaLink
|
|
href="/alternatives"
|
|
ctaLabel="Browse Alternatives"
|
|
ctaLocation="hero_secondary"
|
|
pageType="commercial"
|
|
cluster="competitor"
|
|
>
|
|
<Button variant="outline" size="lg" className="h-13 w-full px-8 text-base sm:w-auto">
|
|
Browse Alternatives
|
|
</Button>
|
|
</TrackedCtaLink>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section className="py-24" style={{ backgroundColor: '#F8F7F4' }}>
|
|
<div className="container mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
|
|
<div className="mb-12 max-w-3xl">
|
|
<h2 className="mb-4 text-3xl font-bold tracking-tight sm:text-4xl" style={{ color: '#111110' }}>
|
|
Available Comparisons
|
|
</h2>
|
|
<p className="text-lg" style={{ color: '#71717A' }}>
|
|
Direct side-by-side analysis for pricing, privacy, analytics, and operational fit.
|
|
</p>
|
|
</div>
|
|
|
|
<div className="grid gap-6 md:grid-cols-2">
|
|
{comparisons.map((item) => (
|
|
<Link key={item.href} href={item.href} className="group block">
|
|
<Card
|
|
className="h-full rounded-xl border bg-white p-7 shadow-none transition-transform duration-150 group-hover:-translate-y-1"
|
|
style={{ borderColor: '#E4E0D9' }}
|
|
>
|
|
<p
|
|
className="mb-4 text-xs font-semibold uppercase tracking-widest"
|
|
style={{ color: '#71717A', letterSpacing: '0.12em' }}
|
|
>
|
|
{item.eyebrow}
|
|
</p>
|
|
<h3 className="mb-3 text-xl font-bold" style={{ color: '#18181B' }}>
|
|
{item.title}
|
|
</h3>
|
|
<p className="text-sm leading-relaxed" style={{ color: '#52525B' }}>
|
|
{item.description}
|
|
</p>
|
|
<p className="mt-6 text-sm font-semibold" style={{ color: '#166534' }}>
|
|
Read comparison
|
|
</p>
|
|
</Card>
|
|
</Link>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
</>
|
|
);
|
|
}
|