273 lines
12 KiB
TypeScript
273 lines
12 KiB
TypeScript
import type { Metadata } from "next"
|
|
import Link from "next/link"
|
|
import Image from "next/image"
|
|
import { getAllLocations } from "@/lib/location-data"
|
|
import { businessConfig } from "@/lib/seo-config"
|
|
import { MapPin, Phone, ArrowRight, Wrench, Clock } from "lucide-react"
|
|
import { Button } from "@/components/ui/button"
|
|
import { PublicInset, PublicPageHeader, PublicSurface } from "@/components/public-surface"
|
|
|
|
export const metadata: Metadata = {
|
|
title: "Service Areas | Vending Machines Across Utah | Rocky Mountain Vending",
|
|
description:
|
|
"Rocky Mountain Vending serves 20+ cities across Utah including Salt Lake City, Ogden, Provo, Sandy, and more. Free vending machine delivery and installation. View all service areas.",
|
|
keywords: [
|
|
"vending machines Utah",
|
|
"Utah vending service areas",
|
|
"vending machine supplier Utah",
|
|
"Salt Lake County vending",
|
|
"Davis County vending",
|
|
"Utah County vending",
|
|
],
|
|
openGraph: {
|
|
title: "Service Areas | Vending Machines Across Utah",
|
|
description:
|
|
"Rocky Mountain Vending serves 20+ cities across Utah. Free vending machine delivery and installation. View all service areas.",
|
|
url: `${businessConfig.website}/service-areas`,
|
|
type: "website",
|
|
},
|
|
alternates: {
|
|
canonical: `${businessConfig.website}/service-areas`,
|
|
},
|
|
}
|
|
|
|
function LocationCard({
|
|
city,
|
|
zipCode,
|
|
href,
|
|
neighborhoods,
|
|
}: {
|
|
city: string
|
|
zipCode: string
|
|
href: string
|
|
neighborhoods: string[]
|
|
}) {
|
|
return (
|
|
<Link href={href} className="group block h-full">
|
|
<PublicSurface className="h-full p-5 transition-all hover:-translate-y-0.5 hover:shadow-[0_26px_65px_rgba(0,0,0,0.12)] md:p-6">
|
|
<div className="flex items-start justify-between gap-4">
|
|
<div className="space-y-1">
|
|
<h3 className="text-xl font-semibold text-foreground transition-colors group-hover:text-primary">{city}</h3>
|
|
<p className="text-sm text-muted-foreground">{zipCode}</p>
|
|
</div>
|
|
<div className="rounded-full border border-border/60 bg-background/90 p-2 text-muted-foreground transition-all group-hover:border-primary/30 group-hover:text-primary group-hover:translate-x-0.5">
|
|
<ArrowRight className="h-4 w-4" />
|
|
</div>
|
|
</div>
|
|
<PublicInset className="mt-5">
|
|
<p className="text-xs font-semibold uppercase tracking-[0.18em] text-primary/75">Popular Areas</p>
|
|
<p className="mt-2 text-sm leading-relaxed text-muted-foreground">{neighborhoods.slice(0, 2).join(", ")}</p>
|
|
</PublicInset>
|
|
</PublicSurface>
|
|
</Link>
|
|
)
|
|
}
|
|
|
|
export default function ServiceAreasPage() {
|
|
const locations = getAllLocations()
|
|
const state = "Utah"
|
|
|
|
const saltLakeCounty = locations.filter((loc) =>
|
|
[
|
|
"salt-lake-city-utah",
|
|
"sandy-utah",
|
|
"draper-utah",
|
|
"murray-utah",
|
|
"midvale-utah",
|
|
"south-salt-lake-utah",
|
|
"west-valley-city-utah",
|
|
"west-jordan-utah",
|
|
"south-jordan-utah",
|
|
"riverton-utah",
|
|
"herriman-utah",
|
|
"holladay-utah",
|
|
"millcreek-utah",
|
|
"cottonwood-heights-utah",
|
|
].includes(loc.slug),
|
|
)
|
|
|
|
const davisCounty = locations.filter((loc) =>
|
|
["ogden-utah", "layton-utah", "clearfield-utah", "syracuse-utah", "clinton-utah"].includes(loc.slug),
|
|
)
|
|
|
|
const utahCounty = locations.filter((loc) => ["provo-utah"].includes(loc.slug))
|
|
|
|
return (
|
|
<div className="container mx-auto px-4 py-10 md:py-14">
|
|
<PublicPageHeader
|
|
align="center"
|
|
eyebrow="Service Coverage"
|
|
title="Utah locations we serve with vending, repairs, parts, and machine support."
|
|
description="Rocky Mountain Vending supports businesses and schools across Utah with free placement, dependable service, and fast local follow-up. Browse the cities we cover and reach out if your location is nearby but not listed yet."
|
|
/>
|
|
|
|
<div className="mt-10 grid gap-6 lg:grid-cols-[1.1fr_0.9fr]">
|
|
<PublicSurface>
|
|
<div className="relative aspect-[926/1024] overflow-hidden rounded-[1.5rem] bg-[radial-gradient(circle_at_top_left,rgba(196,154,52,0.16),transparent_55%),linear-gradient(180deg,rgba(247,244,236,0.7),rgba(255,255,255,0.96))]">
|
|
<Image
|
|
src="/images/rocky-mountain-vending-service-area-926x1024.webp"
|
|
alt="Rocky Mountain Vending service area map covering Salt Lake City, Ogden, Provo and surrounding Utah cities"
|
|
fill
|
|
className="object-cover"
|
|
/>
|
|
</div>
|
|
</PublicSurface>
|
|
|
|
<PublicSurface className="flex flex-col justify-between">
|
|
<div>
|
|
<p className="text-xs font-semibold uppercase tracking-[0.2em] text-primary/80">Need Coverage Confirmation?</p>
|
|
<h2 className="mt-3 text-3xl font-semibold tracking-tight text-balance text-foreground">
|
|
Don't see your city yet?
|
|
</h2>
|
|
<p className="mt-3 text-base leading-relaxed text-muted-foreground">
|
|
We may still be able to help. If you're near one of these service zones, call or send us a request and we'll confirm the best next step.
|
|
</p>
|
|
</div>
|
|
|
|
<div className="mt-6 space-y-4">
|
|
<PublicInset>
|
|
<a
|
|
href={businessConfig.phoneUrl}
|
|
className="flex items-center gap-3 text-base font-semibold text-foreground transition hover:text-primary"
|
|
>
|
|
<Phone className="h-5 w-5 text-primary" />
|
|
{businessConfig.phone}
|
|
</a>
|
|
<p className="mt-2 text-sm text-muted-foreground">We'll confirm delivery range, support availability, and the best intake path for your location.</p>
|
|
</PublicInset>
|
|
<Button asChild className="h-11 rounded-full px-5">
|
|
<Link href="/#request-machine">Request a Free Machine</Link>
|
|
</Button>
|
|
</div>
|
|
</PublicSurface>
|
|
</div>
|
|
|
|
<section className="mt-12">
|
|
<PublicSurface>
|
|
<div className="text-center">
|
|
<p className="text-xs font-semibold uppercase tracking-[0.2em] text-primary/80">Core Services</p>
|
|
<h2 className="mt-3 text-3xl font-semibold tracking-tight text-balance md:text-4xl">Our vending machine services across {state}</h2>
|
|
<p className="mx-auto mt-3 max-w-2xl text-base leading-relaxed text-muted-foreground">
|
|
From free placement and machine sales to repairs, moving, and parts help, we keep one consistent service experience across every city we serve.
|
|
</p>
|
|
</div>
|
|
|
|
<div className="mt-8 grid gap-5 md:grid-cols-3">
|
|
{[
|
|
{
|
|
icon: Wrench,
|
|
title: "Repairs",
|
|
body: "Expert repair and maintenance for snack, beverage, food, and combo machines.",
|
|
href: "/services/repairs",
|
|
cta: "Learn more",
|
|
},
|
|
{
|
|
icon: MapPin,
|
|
title: "Parts",
|
|
body: "Replacement parts, manuals, and support for major vending machine brands.",
|
|
href: "/services/parts",
|
|
cta: "Shop parts",
|
|
},
|
|
{
|
|
icon: Clock,
|
|
title: "Moving",
|
|
body: "Professional machine moving for vending machines and related equipment across Utah.",
|
|
href: "/services/moving",
|
|
cta: "Moving services",
|
|
},
|
|
].map((service) => (
|
|
<PublicInset key={service.title} className="h-full p-5 text-center">
|
|
<div className="mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-primary/10 text-primary">
|
|
<service.icon className="h-6 w-6" />
|
|
</div>
|
|
<h3 className="mt-4 text-xl font-semibold">{service.title}</h3>
|
|
<p className="mt-2 text-sm leading-relaxed text-muted-foreground">{service.body}</p>
|
|
<Link href={service.href} className="mt-5 inline-flex items-center gap-2 text-sm font-medium text-primary hover:underline">
|
|
{service.cta}
|
|
<ArrowRight className="h-4 w-4" />
|
|
</Link>
|
|
</PublicInset>
|
|
))}
|
|
</div>
|
|
</PublicSurface>
|
|
</section>
|
|
|
|
<section className="mt-12 space-y-12">
|
|
{[
|
|
{
|
|
title: "Salt Lake County",
|
|
description: "Serving the heart of Utah's business district with comprehensive vending solutions.",
|
|
items: saltLakeCounty,
|
|
},
|
|
{
|
|
title: "Davis County",
|
|
description: "Supporting businesses from Ogden to Layton with reliable vending service and repairs.",
|
|
items: davisCounty,
|
|
},
|
|
{
|
|
title: "Utah County",
|
|
description: "Delivering quality vending solutions to Provo and surrounding areas.",
|
|
items: utahCounty,
|
|
},
|
|
].map((section) => (
|
|
<div key={section.title} className="space-y-5">
|
|
<div>
|
|
<p className="text-xs font-semibold uppercase tracking-[0.2em] text-primary/80">Coverage Area</p>
|
|
<h2 className="mt-2 text-3xl font-semibold tracking-tight text-balance">{section.title}</h2>
|
|
<p className="mt-2 max-w-3xl text-base leading-relaxed text-muted-foreground">{section.description}</p>
|
|
</div>
|
|
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
|
|
{section.items.map((location) => (
|
|
<LocationCard
|
|
key={location.slug}
|
|
city={location.city}
|
|
zipCode={location.zipCode}
|
|
href={`/vending-machines-${location.slug}`}
|
|
neighborhoods={location.neighborhoods}
|
|
/>
|
|
))}
|
|
</div>
|
|
</div>
|
|
))}
|
|
</section>
|
|
|
|
<section className="mt-12 grid gap-6 lg:grid-cols-[1.15fr_0.85fr]">
|
|
<PublicSurface>
|
|
<h2 className="text-3xl font-semibold tracking-tight text-balance">Why businesses choose Rocky Mountain Vending</h2>
|
|
<div className="mt-6 grid gap-5 md:grid-cols-2">
|
|
{[
|
|
["FREE vending machines", "No upfront costs, hidden fees, or machine charges for qualifying businesses."],
|
|
["FREE delivery and installation", "Within range of our service areas, we handle setup and launch for you."],
|
|
["FREE maintenance and repairs", "We keep machines running smoothly so your team has fewer interruptions."],
|
|
["Healthy and traditional options", "We tailor product mix to the people using the machines every day."],
|
|
].map(([title, body]) => (
|
|
<PublicInset key={title}>
|
|
<h3 className="text-lg font-semibold text-foreground">{title}</h3>
|
|
<p className="mt-2 text-sm leading-relaxed text-muted-foreground">{body}</p>
|
|
</PublicInset>
|
|
))}
|
|
</div>
|
|
<Button asChild className="mt-6 h-11 rounded-full px-5">
|
|
<Link href="/#request-machine">Get Your Free Machine</Link>
|
|
</Button>
|
|
</PublicSurface>
|
|
|
|
<PublicSurface>
|
|
<h2 className="text-3xl font-semibold tracking-tight text-balance">What we support in every service area</h2>
|
|
<div className="mt-6 space-y-4">
|
|
{[
|
|
["For businesses", "Offices, warehouses, auto shops, and other workplaces that want reliable on-site vending."],
|
|
["For schools", "Healthy options for students and staff with a service plan that stays easy to manage."],
|
|
["For gyms and fitness spaces", "Protein bars, sports drinks, and post-workout options that match the location."],
|
|
].map(([title, body]) => (
|
|
<PublicInset key={title}>
|
|
<h3 className="text-lg font-semibold">{title}</h3>
|
|
<p className="mt-2 text-sm leading-relaxed text-muted-foreground">{body}</p>
|
|
</PublicInset>
|
|
))}
|
|
</div>
|
|
</PublicSurface>
|
|
</section>
|
|
</div>
|
|
)
|
|
}
|