Phase 4: pricing, about, area, Windows 10 and business pages

- /pricing: full price list, no-fix-no-fee terms, travel and payments
- /about: first-person page from confirmed facts, links to area pages
- /areas/[suburb]: Te Atatū Peninsula, Te Atatū South, Henderson and
  Massey, generated from src/lib/areas.js with suburb-specific copy
- /windows-10: options page with free Windows 11 check; October 2028
  used for business Extended Security Updates
- /business: $65/month plan (2 hours, no lock-in, no rollover)
- Nav gains Pricing/About and Business/Windows 10 links; footer rebuilt
  with address, hours and links; homepage links areas, /business and
  a Windows 10 banner; sitemap includes all new routes
- Mobile menu hides by its own height (fixes overflow with more links);
  hamburger now used below 900px so the link row never overlaps

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
asownerytandClaude Opus 5.5 committed 2026-09-30 20:47:06 +13:00
1 parent 40d3a08050
commit 9f5cf387dc
13 files changed
+862 -57

No files matched your search

+131
View File
@@ -0,0 +1,131 @@
import Link from "next/link";
import { notFound } from "next/navigation";
import { ArrowRight, MessageSquare, Phone } from "lucide-react";
import HeaderSm from "../../components/HeaderSm";
import Button from "../../components/Button";
import CtaBand from "../../components/CtaBand";
import FaqList from "../../components/FaqList";
import JsonLd from "../../components/JsonLd";
import { areas, getArea } from "@/lib/areas";
import { services } from "@/lib/services";
import { business, links, pageMetadata, serviceSchema } from "@/lib/site";
export const dynamicParams = false;
export function generateStaticParams() {
return areas.map(({ slug }) => ({ suburb: slug }));
}
export async function generateMetadata({ params }) {
const area = getArea((await params).suburb);
return pageMetadata({
title: `Computer Repair ${area.name} | Te Atatu Computers`,
description: `Laptop & PC repairs, upgrades, virus removal and IT support in ${area.name}. $35 diagnosis, no fix no fee. Call or text ${business.phone}.`,
path: `/areas/${area.slug}`,
});
}
export default async function AreaPage({ params }) {
const area = getArea((await params).suburb);
if (!area) notFound();
const faqs = [
area.faq,
{
question: "How much will it cost?",
answer:
"A diagnosis is $35, and if I can't fix it you don't pay it. Labour is $35 an hour and parts are extra. I'll tell you the cost before I start.",
},
];
return (
<div>
<JsonLd
data={serviceSchema({
name: `Computer repair in ${area.name}`,
description: area.intro,
path: `/areas/${area.slug}`,
areas: [area.name],
})}
/>
<HeaderSm text={`Computer & Laptop Repair in ${area.name}`} />
<section className="container mx-auto max-w-3xl mb-16">
<p className="text-lg mb-6">{area.intro}</p>
<div className="flex flex-col sm:flex-row gap-3">
<Button href={links.tel} variant="primary">
<Phone aria-hidden="true" />
Call {business.phone}
</Button>
<Button href={links.sms} variant="outlineDark">
<MessageSquare aria-hidden="true" />
Text me
</Button>
</div>
</section>
<section className="container mx-auto max-w-3xl mb-16">
<h2 className="text-3xl font-bold mb-4">
Getting your computer to me
</h2>
<p className="mb-4">{area.gettingThere}</p>
<p>
I work Monday to Friday, 9am to 6pm, and weekends by appointment.
Most repairs are done within 24–48 hours, although this isn&apos;t
guaranteed.
</p>
</section>
<section className="container mx-auto max-w-3xl mb-16">
<h2 className="text-3xl font-bold mb-4">
What I can help with in {area.name}
</h2>
<ul className="space-y-2 mb-4">
{Object.entries(services).map(([slug, service]) => (
<li key={slug}>
<Link
href={`/services/${slug}`}
className="inline-flex items-center gap-1 font-bold text-sky-800 hover:underline"
>
{service.name}
<ArrowRight aria-hidden="true" className="size-4" />
</Link>
</li>
))}
</ul>
<p>
See all prices on the{" "}
<Link href="/pricing" className="text-sky-800 underline">
pricing page
</Link>
. I don&apos;t repair Apple devices.
</p>
</section>
<section className="container mx-auto max-w-3xl mb-16">
<h2 className="text-3xl font-bold mb-4">Questions</h2>
<FaqList faqs={faqs} />
</section>
<CtaBand />
<section className="container mx-auto max-w-3xl py-16">
<h2 className="text-2xl font-bold mb-4">Other areas I serve</h2>
<ul className="flex flex-wrap gap-x-6 gap-y-2">
{areas
.filter(({ slug }) => slug !== area.slug)
.map(({ slug, name }) => (
<li key={slug}>
<Link
href={`/areas/${slug}`}
className="text-sky-800 hover:underline"
>
{name}
</Link>
</li>
))}
</ul>
</section>
</div>
);
}