Components (added via the shadcn MCP/CLI): - Navbar: NavigationMenu on desktop, Sheet on mobile; drops Navbar.module.css and the hand-rolled slide-down menu - Buttons: shadcn Button via a shared ContactButtons component (replaces Button.js and its CSS module) - Card for price cards, testimonials, the business block and plan; Table for prices; Input/Textarea/Label/NativeSelect/RadioGroup and Alert in the quote form; Separator in the footer - Components import cn from @/lib/utils (not the new "cn" package); accordion moved to the unified radix-ui package Design tweaks: - Geist Sans is actually applied (font variables were on <body>, but Tailwind reads them on <html>, so the site fell back to system fonts) - Theme primary set to the existing brand blue; slightly smaller radius - Balanced, tighter heading tracking; muted secondary text - 44px contact buttons; 16px FAQ text; tighter homepage spacing - Full-width selects with 16px text on phones (no iOS zoom) Co-Authored-By: Claude Opus 5.5 <[email protected]>
367 lines
12 KiB
JavaScript
367 lines
12 KiB
JavaScript
import Image from "next/image";
|
||
import Link from "next/link";
|
||
import styles from "./page.module.css";
|
||
import bgimage from "./assets/header-bg.jpg";
|
||
import ContactButtons from "./components/ContactButtons";
|
||
import MapEmbed from "./components/MapEmbed";
|
||
import { Card, CardContent } from "@/components/ui/card";
|
||
import ContactForm from "./components/ContactForm";
|
||
import FaqList from "./components/FaqList";
|
||
import CtaBand from "./components/CtaBand";
|
||
import { pageMetadata, business, links } from "@/lib/site";
|
||
import { homeFaqs } from "@/lib/faqs";
|
||
import { areas } from "@/lib/areas";
|
||
import {
|
||
ArrowRight,
|
||
Briefcase,
|
||
Cpu,
|
||
FolderInput,
|
||
HardDrive,
|
||
Laptop,
|
||
MapPin,
|
||
Monitor,
|
||
MonitorCog,
|
||
Power,
|
||
ShieldAlert,
|
||
Star,
|
||
} from "lucide-react";
|
||
|
||
export const metadata = pageMetadata({
|
||
title: "Computer & Laptop Repair Te Atatū | Te Atatu Computers",
|
||
description:
|
||
"Local laptop & PC repairs, upgrades and virus removal in Te Atatū and West Auckland. $35 diagnosis, no fix no fee. Call or text 021 107 7483.",
|
||
path: "/",
|
||
});
|
||
|
||
const commonFixes = [
|
||
{
|
||
icon: Laptop,
|
||
title: "Cracked laptop screen",
|
||
price: "from $35",
|
||
href: "/services/computer-repair",
|
||
},
|
||
{
|
||
icon: Power,
|
||
title: "Won't turn on or won't boot",
|
||
price: "$35 diagnosis",
|
||
href: "/services/computer-repair",
|
||
},
|
||
{
|
||
icon: HardDrive,
|
||
title: "Slow computer? SSD upgrade",
|
||
price: "from $45 + the drive",
|
||
href: "/services/computer-upgrades",
|
||
},
|
||
{
|
||
icon: ShieldAlert,
|
||
title: "Viruses & scam pop-ups",
|
||
price: "from $35",
|
||
href: "/services/virus-removal",
|
||
},
|
||
{
|
||
icon: MonitorCog,
|
||
title: "Windows reinstall",
|
||
price: "from $45",
|
||
href: "/services/computer-upgrades",
|
||
},
|
||
{
|
||
icon: FolderInput,
|
||
title: "Move files to a new PC",
|
||
price: "from $45",
|
||
href: "/services/it-support",
|
||
},
|
||
{
|
||
icon: Monitor,
|
||
title: "New computer setup",
|
||
price: "from $35",
|
||
href: "/services/it-support",
|
||
},
|
||
{
|
||
icon: Cpu,
|
||
title: "Custom PC build",
|
||
price: "from $35",
|
||
href: "/contact",
|
||
},
|
||
];
|
||
|
||
const steps = [
|
||
{
|
||
title: "Get in touch",
|
||
text: "Call, text, WhatsApp or send the form. Tell me what's going on and I'll let you know the next step.",
|
||
},
|
||
{
|
||
title: "Get it to me",
|
||
text: "Drop it off at Graham Avenue by appointment, or I can pick it up or come to you (travel fee depends on distance). Many software problems can be fixed remotely.",
|
||
},
|
||
{
|
||
title: "Fixed and back to you",
|
||
text: "$35 diagnosis, and I'll tell you the cost before I start. Most repairs are done within 24–48 hours, although this isn't guaranteed.",
|
||
},
|
||
];
|
||
|
||
function SectionCta() {
|
||
return (
|
||
<p className="text-center mt-8">
|
||
<a href={links.tel} className="font-semibold text-primary hover:underline">
|
||
Call or text {business.phone}
|
||
</a>
|
||
</p>
|
||
);
|
||
}
|
||
|
||
export default function Home() {
|
||
return (
|
||
<div className={styles.page}>
|
||
<main className={styles.main}>
|
||
<section>
|
||
<div className={styles.header}>
|
||
<Image
|
||
src={bgimage}
|
||
alt=""
|
||
placeholder="blur"
|
||
fill
|
||
priority
|
||
sizes="100vw"
|
||
style={{
|
||
objectFit: "cover",
|
||
}}
|
||
/>
|
||
<div className={styles.textbox}>
|
||
<div className="container mx-auto">
|
||
<div className={styles.textboxInner}>
|
||
<h1 className="mb-4 text-4xl md:text-6xl font-bold">
|
||
Laptop & PC repairs in Te Atatū
|
||
</h1>
|
||
<p className={styles.p}>
|
||
<strong>No fix, no fee.</strong>{" "}A $35 diagnosis, then I'll
|
||
tell you what it costs before I start. Local, honest help
|
||
for West Auckland.
|
||
</p>
|
||
<ContactButtons onDark className="mb-6" />
|
||
<p className="flex flex-wrap items-center gap-x-2 gap-y-1 text-sm">
|
||
<Star
|
||
aria-hidden="true"
|
||
className="size-4 fill-yellow-400 text-yellow-400"
|
||
/>
|
||
<a
|
||
href={business.googleBusinessProfileUrl}
|
||
className="underline hover:no-underline"
|
||
>
|
||
{business.rating.value} from {business.rating.count}{" "}
|
||
Google reviews
|
||
</a>
|
||
<span aria-hidden="true">·</span>
|
||
<span>Local to Te Atatū</span>
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section className="container mx-auto mb-24">
|
||
<h2 className="text-center text-3xl font-bold mb-2">
|
||
Common fixes & prices
|
||
</h2>
|
||
<p className="text-center mb-8 text-muted-foreground">
|
||
Labour prices. Parts are extra, and I'll always quote before
|
||
starting.
|
||
</p>
|
||
<ul className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
|
||
{commonFixes.map(({ icon: Icon, title, price, href }) => (
|
||
<li key={title}>
|
||
<Link href={href} className="group block h-full rounded-xl">
|
||
<Card className="h-full flex-row items-center gap-4 p-4 shadow-none transition-colors group-hover:border-primary">
|
||
<Icon
|
||
aria-hidden="true"
|
||
className="size-7 shrink-0 text-primary"
|
||
strokeWidth={1.5}
|
||
/>
|
||
<span>
|
||
<span className="block font-semibold">{title}</span>
|
||
<span className="block text-sm text-muted-foreground">
|
||
{price}
|
||
</span>
|
||
</span>
|
||
</Card>
|
||
</Link>
|
||
</li>
|
||
))}
|
||
</ul>
|
||
<SectionCta />
|
||
<Link
|
||
href="/windows-10"
|
||
className="mt-8 flex items-center justify-between gap-4 rounded-lg bg-sky-900 p-4 text-white transition-colors hover:bg-primary"
|
||
>
|
||
<span>
|
||
<span className="block font-bold">Still on Windows 10?</span>
|
||
<span className="block text-sm">
|
||
See your options, with a free Windows 11 compatibility check.
|
||
</span>
|
||
</span>
|
||
<ArrowRight aria-hidden="true" className="size-5 shrink-0" />
|
||
</Link>
|
||
</section>
|
||
|
||
<section className="bg-slate-100 py-16 mb-24">
|
||
<div className="container mx-auto">
|
||
<h2 className="text-center text-3xl font-bold mb-8">
|
||
How it works
|
||
</h2>
|
||
<ol className="grid grid-cols-1 md:grid-cols-3 gap-8">
|
||
{steps.map(({ title, text }, i) => (
|
||
<li key={title} className="border-t border-slate-300 pt-4">
|
||
<span className="mb-3 flex size-8 items-center justify-center rounded-full bg-primary text-sm font-semibold text-primary-foreground">
|
||
{i + 1}
|
||
</span>
|
||
<h3 className="text-xl font-bold mb-2">{title}</h3>
|
||
<p>{text}</p>
|
||
</li>
|
||
))}
|
||
</ol>
|
||
<SectionCta />
|
||
</div>
|
||
</section>
|
||
|
||
<section className="container mx-auto mb-24 max-w-3xl text-center">
|
||
<h2 className="text-3xl font-bold mb-4">
|
||
Hi, I'm {business.ownerName}
|
||
</h2>
|
||
<p className="text-lg mb-4">
|
||
I run Te Atatu Computers from Te Atatū Peninsula. When you call or
|
||
text, you're talking to the person who will actually fix your
|
||
computer. There's no call centre and no being passed around.
|
||
</p>
|
||
<p className="text-lg">
|
||
I'll explain what's wrong in plain language and tell you
|
||
what it will cost before I start. If I can't fix it, you
|
||
don't pay the diagnosis fee.
|
||
</p>
|
||
<SectionCta />
|
||
</section>
|
||
|
||
<section className="container mx-auto mb-24">
|
||
<h2 className="text-center text-3xl font-bold mb-8">
|
||
What customers say
|
||
</h2>
|
||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6 max-w-4xl mx-auto">
|
||
{business.testimonials.map(({ name, quote }) => (
|
||
<Card key={name} className="shadow-none">
|
||
<CardContent>
|
||
<figure>
|
||
<blockquote className="mb-3">“{quote}”</blockquote>
|
||
<figcaption className="font-semibold">{name}</figcaption>
|
||
</figure>
|
||
</CardContent>
|
||
</Card>
|
||
))}
|
||
</div>
|
||
<p className="text-center mt-8">
|
||
<a
|
||
href={business.googleBusinessProfileUrl}
|
||
className="inline-flex items-center gap-1 font-semibold text-primary hover:underline"
|
||
>
|
||
Read all reviews on Google
|
||
<ArrowRight aria-hidden="true" className="size-4" />
|
||
</a>
|
||
</p>
|
||
</section>
|
||
|
||
<section className="container mx-auto mb-24 flex flex-col gap-8 lg:flex-row">
|
||
<div className="w-full">
|
||
<h2 className="text-3xl font-bold mb-4">Areas I serve</h2>
|
||
<p className="mb-4 flex items-start gap-2">
|
||
<MapPin aria-hidden="true" className="size-5 shrink-0 mt-0.5" />
|
||
<span>
|
||
Based at {business.address.street}, {business.address.suburb}.
|
||
Drop-offs by appointment.
|
||
</span>
|
||
</p>
|
||
<p className="mb-4">
|
||
Onsite visits, pickup and return, and remote support across:
|
||
</p>
|
||
<ul className="grid grid-cols-2 gap-2 mb-6 list-disc pl-6">
|
||
{business.serviceArea.map((area) => {
|
||
const page = areas.find(({ name }) => name === area);
|
||
return (
|
||
<li key={area}>
|
||
{page ? (
|
||
<Link
|
||
href={`/areas/${page.slug}`}
|
||
className="text-primary hover:underline"
|
||
>
|
||
{area}
|
||
</Link>
|
||
) : (
|
||
area
|
||
)}
|
||
</li>
|
||
);
|
||
})}
|
||
</ul>
|
||
<p>
|
||
Not on the list? Get in touch and I'll let you know if I can
|
||
help.
|
||
</p>
|
||
<p className="mt-4">
|
||
<a
|
||
href={links.tel}
|
||
className="font-semibold text-primary hover:underline"
|
||
>
|
||
Call or text {business.phone}
|
||
</a>
|
||
</p>
|
||
</div>
|
||
<div className="w-full">
|
||
<MapEmbed />
|
||
</div>
|
||
</section>
|
||
|
||
<section className="container mx-auto mb-24">
|
||
<Card className="flex-col gap-6 p-6 shadow-none md:flex-row md:items-center md:p-8">
|
||
<Briefcase
|
||
aria-hidden="true"
|
||
className="size-12 shrink-0 text-primary"
|
||
strokeWidth={1.5}
|
||
/>
|
||
<div className="flex-1">
|
||
<h2 className="text-2xl font-bold mb-2">For local businesses</h2>
|
||
<p>
|
||
IT support for small businesses: Wi-Fi and networks, email,
|
||
backups, security and new PC setup. Onsite or remote, $35 an
|
||
hour, or $65 a month for 2 hours of support.
|
||
</p>
|
||
</div>
|
||
<Link
|
||
href="/business"
|
||
className="inline-flex items-center gap-1 font-semibold text-primary hover:underline"
|
||
>
|
||
Business IT plans
|
||
<ArrowRight aria-hidden="true" className="size-4" />
|
||
</Link>
|
||
</Card>
|
||
</section>
|
||
|
||
<section
|
||
className="container mx-auto max-w-3xl mb-24 scroll-mt-20"
|
||
id="faq"
|
||
>
|
||
<h2 className="text-center text-3xl font-bold mb-8">
|
||
Frequently asked questions
|
||
</h2>
|
||
<FaqList faqs={homeFaqs} />
|
||
<SectionCta />
|
||
</section>
|
||
|
||
<CtaBand quoteHref="#quote" />
|
||
<section
|
||
id="quote"
|
||
className="container mx-auto max-w-2xl py-16 scroll-mt-20"
|
||
>
|
||
<ContactForm />
|
||
</section>
|
||
</main>
|
||
</div>
|
||
);
|
||
}
|