Files
computer-repair/src/app/page.js
T
asownerytandClaude Opus 5.5 f916f058fc Swap to shadcn components and polish the design
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]>
2026-09-30 21:25:07 +13:00

367 lines
12 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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&apos;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&apos;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&apos;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&apos;re talking to the person who will actually fix your
computer. There&apos;s no call centre and no being passed around.
</p>
<p className="text-lg">
I&apos;ll explain what&apos;s wrong in plain language and tell you
what it will cost before I start. If I can&apos;t fix it, you
don&apos;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">&ldquo;{quote}&rdquo;</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&apos;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>
);
}