Next.js website for Rocky Mountain Vending company featuring: - Product catalog with Stripe integration - Service areas and parts pages - Admin dashboard with Clerk authentication - SEO optimized pages with JSON-LD structured data Co-authored-by: Cursor <cursoragent@cursor.com>
215 lines
12 KiB
TypeScript
215 lines
12 KiB
TypeScript
import { notFound } from 'next/navigation';
|
|
import { loadImageMapping } from '@/lib/wordpress-content';
|
|
import { generateSEOMetadata, generateStructuredData } from '@/lib/seo';
|
|
import { getPageBySlug } from '@/lib/wordpress-data-loader';
|
|
import { cleanWordPressContent } from '@/lib/clean-wordpress-content';
|
|
import { VendingMachinesShowcase } from '@/components/vending-machines-showcase';
|
|
import Image from 'next/image';
|
|
import type { Metadata } from 'next';
|
|
|
|
// This route maps to the main vending-machines WordPress page
|
|
const WORDPRESS_SLUG = 'vending-machines';
|
|
|
|
export async function generateMetadata(): Promise<Metadata> {
|
|
const page = getPageBySlug(WORDPRESS_SLUG);
|
|
|
|
if (!page) {
|
|
return {
|
|
title: 'Page Not Found | Rocky Mountain Vending',
|
|
};
|
|
}
|
|
|
|
return generateSEOMetadata({
|
|
title: page.title || 'Machines We Use',
|
|
description: page.seoDescription || page.excerpt || '',
|
|
excerpt: page.excerpt,
|
|
date: page.date,
|
|
modified: page.modified,
|
|
image: page.images?.[0]?.localPath,
|
|
});
|
|
}
|
|
|
|
export default async function MachinesWeUsePage() {
|
|
try {
|
|
const page = getPageBySlug(WORDPRESS_SLUG);
|
|
|
|
if (!page) {
|
|
notFound();
|
|
}
|
|
|
|
// Load image mapping (optional, won't break if it fails)
|
|
let imageMapping: any = {};
|
|
try {
|
|
imageMapping = loadImageMapping();
|
|
} catch (e) {
|
|
// Silently fail - image mapping is optional
|
|
if (process.env.NODE_ENV === 'development') {
|
|
console.warn('Could not load image mapping:', e);
|
|
}
|
|
imageMapping = {};
|
|
}
|
|
|
|
// Clean and render WordPress content as styled React components
|
|
const content = page.content ? (
|
|
cleanWordPressContent(String(page.content), {
|
|
imageMapping,
|
|
pageTitle: page.title // Pass page title to avoid duplicate headings
|
|
})
|
|
) : (
|
|
<p className="text-muted-foreground">No content available.</p>
|
|
);
|
|
|
|
// Generate structured data
|
|
let structuredData;
|
|
try {
|
|
structuredData = generateStructuredData({
|
|
title: page.title || 'Machines We Use',
|
|
description: page.seoDescription || page.excerpt || '',
|
|
url: page.link || page.urlPath || `https://rockymountainvending.com/vending-machines/machines-we-use/`,
|
|
datePublished: page.date,
|
|
dateModified: page.modified || page.date,
|
|
type: 'WebPage',
|
|
});
|
|
} catch (e) {
|
|
// Silently use fallback structured data in production
|
|
if (process.env.NODE_ENV === 'development') {
|
|
console.error('Error generating structured data:', e);
|
|
}
|
|
structuredData = {
|
|
'@context': 'https://schema.org',
|
|
'@type': 'WebPage',
|
|
headline: page.title || 'Machines We Use',
|
|
description: page.seoDescription || '',
|
|
url: `https://rockymountainvending.com/vending-machines/machines-we-use/`,
|
|
};
|
|
}
|
|
|
|
return (
|
|
<>
|
|
<script
|
|
type="application/ld+json"
|
|
dangerouslySetInnerHTML={{ __html: JSON.stringify(structuredData) }}
|
|
/>
|
|
<article className="container mx-auto px-4 py-8 md:py-12 max-w-6xl">
|
|
<header className="mb-12 text-center">
|
|
<h1 className="text-4xl md:text-5xl font-bold mb-4">{page.title || 'Vending Machines'}</h1>
|
|
<p className="text-lg text-muted-foreground max-w-2xl mx-auto">
|
|
Only The Best for Your Location
|
|
</p>
|
|
</header>
|
|
|
|
{/* Credit Card Readers Section */}
|
|
<section className="mb-16 max-w-4xl mx-auto">
|
|
<div className="flex flex-col items-center text-center">
|
|
<Image
|
|
src="https://rockymountainvending.com/wp-content/uploads/2024/01/Parlevel-Pay-Plus-247x300.jpg"
|
|
alt="Parlevel PayPlus credit card reader screen showing options for inserting, swiping, or tapping a card for payment."
|
|
width={247}
|
|
height={300}
|
|
className="rounded-lg shadow-lg mb-6 w-auto h-auto object-contain"
|
|
/>
|
|
<h3 className="text-xl md:text-2xl font-semibold mb-4">Credit Card Readers</h3>
|
|
<p className="text-muted-foreground leading-relaxed max-w-3xl">
|
|
<strong>Enhanced Payment Flexibility:</strong> Our vending machines are equipped with advanced NAYAX and Parlevel credit card readers, seamlessly integrated with Parlevel's Vending Management System (VMS). These cutting-edge readers use EMV chip technology to enhance transaction security, offering users greater peace of mind. Our system also streamlines inventory management, quickly resolves machine issues, and allows for the use of personalized pre-paid gift cards. Parlevel's VMS, backed by robust management tools and dependable hardware, is essential to our commitment to offering secure and varied payment options while maintaining the highest operational standards.
|
|
</p>
|
|
</div>
|
|
</section>
|
|
|
|
{/* Guaranteed Delivery Section */}
|
|
<section className="mb-16 max-w-4xl mx-auto">
|
|
<div className="flex flex-col items-center text-center">
|
|
<Image
|
|
src="https://rockymountainvending.com/wp-content/uploads/2024/10/Drop-Sensors-300x225.webp"
|
|
alt="Illustration of a vending machine drop sensor ensuring successful item delivery."
|
|
width={300}
|
|
height={225}
|
|
className="rounded-lg shadow-lg mb-6 w-auto h-auto object-contain"
|
|
/>
|
|
<h3 className="text-xl md:text-2xl font-semibold mb-4">Guaranteed Delivery</h3>
|
|
<p className="text-muted-foreground leading-relaxed max-w-3xl">
|
|
<strong>Purchase with Confidence:</strong> Our vending machines are equipped with highly sensitive sensors that ensure you receive the item you select. In the rare case that a product isn't dispensed, the machine is designed either to prevent the charge or to issue a prompt refund. This system demonstrates our commitment to providing a reliable and customer-friendly vending experience, ensuring you can shop with complete peace of mind.
|
|
</p>
|
|
</div>
|
|
</section>
|
|
|
|
{/* Cash and Coin Section */}
|
|
<section className="mb-16 max-w-4xl mx-auto">
|
|
<div className="flex flex-col items-center text-center">
|
|
<Image
|
|
src="https://rockymountainvending.com/wp-content/uploads/2024/10/Cash-and-Coins-Accepted-300x225.webp"
|
|
alt="Image showing U.S. dollar bills and coins, symbolizing cash and coin payments accepted by vending machines."
|
|
width={300}
|
|
height={225}
|
|
className="rounded-lg shadow-lg mb-6 w-auto h-auto object-contain"
|
|
/>
|
|
<h3 className="text-xl md:text-2xl font-semibold mb-4">Cash and Coin</h3>
|
|
<p className="text-muted-foreground leading-relaxed max-w-3xl">
|
|
<strong>Cash-Friendly Vending Options:</strong> Our vending machines are built to support both cash and coin payments, providing a convenient and flexible option for all customers. With the ability to accept multiple U.S. dollar denominations, they ensure smooth and hassle-free transactions. Whether you prefer using bills or coins, our vending machines are designed with your convenience in mind. This feature highlights our dedication to offering a user-friendly and accessible vending experience for everyone.
|
|
</p>
|
|
</div>
|
|
</section>
|
|
|
|
{/* Specialty Equipment Section */}
|
|
<section className="mb-16 max-w-4xl mx-auto">
|
|
<h2 className="text-2xl md:text-3xl font-semibold text-center mb-8">Specialty Equipment</h2>
|
|
<p className="text-muted-foreground text-center mb-12 leading-relaxed">
|
|
At Rocky Mountain Vending, we invest in high-quality equipment to deliver the best service with minimal interruptions. For locations that handle a lot of cash, we use bill recyclers to ensure customers can easily use $1, $2, $5, $10, or $20 bills without worry. This flexibility improves convenience and keeps transactions smooth. Additionally, we use commercial-grade steam cleaners to thoroughly sanitize our machines, a step many vendors overlook. Our commitment to using the best tools ensures a clean, efficient, and hassle-free vending experience.
|
|
</p>
|
|
|
|
<div className="grid md:grid-cols-2 gap-12">
|
|
{/* Bill Recycler Sub-section */}
|
|
<div className="flex flex-col items-center text-center">
|
|
<Image
|
|
src="https://rockymountainvending.com/wp-content/uploads/2024/10/Bill-Recycler-150x150.webp"
|
|
alt="Bill recycler on a vending machine, designed to accept and dispense U.S. dollar bills."
|
|
width={150}
|
|
height={150}
|
|
className="rounded-lg shadow-lg mb-6 object-contain"
|
|
/>
|
|
<h3 className="text-xl font-semibold mb-4">Bill Recycler</h3>
|
|
<p className="text-muted-foreground leading-relaxed">
|
|
The MEI Bill Recycler is an essential upgrade for high-cash locations, accepting $1, $2, $5, $10, and $20 bills while recycling $1 or $5 bills for future transactions. It features a bright, low-powered LED bezel that illuminates and clearly displays which bill denominations are currently accepted, improving user experience and ensuring efficient transactions. This reduces downtime by preventing cash shortages and minimizing machine jams. With tamper-evident sensors and high-capacity bill storage, it's ideal for businesses requiring reliable, hassle-free vending machine operations.
|
|
</p>
|
|
</div>
|
|
|
|
{/* Steam Cleaner Sub-section */}
|
|
<div className="flex flex-col items-center text-center">
|
|
<Image
|
|
src="https://rockymountainvending.com/wp-content/uploads/2024/10/Steam-Cleaner-150x150.jpg"
|
|
alt="Steam cleaner equipment used for sanitizing and deep cleaning vending machines."
|
|
width={150}
|
|
height={150}
|
|
className="rounded-lg shadow-lg mb-6 object-contain"
|
|
/>
|
|
<h3 className="text-xl font-semibold mb-4">Steam Cleaner</h3>
|
|
<p className="text-muted-foreground leading-relaxed">
|
|
We use a commercial-grade steam cleaner to ensure that our vending machines are not only visually appealing but also fully sanitized. Drink machines, in particular, can accumulate sticky residue from spills or explosions, making them hard to clean on-site. With powerful steam reaching temperatures of up to 310°F and operating at 75 PSI, this cleaner is ideal for deep cleaning, removing dirt, grease, and bacteria without harsh chemicals. Its continuous refill feature allows us to provide thorough cleanings quickly and efficiently, maintaining both hygiene and appearance.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
{/* Machines Showcase */}
|
|
<VendingMachinesShowcase />
|
|
</article>
|
|
</>
|
|
);
|
|
} catch (error) {
|
|
// Silently return error fallback in production
|
|
if (process.env.NODE_ENV === 'development') {
|
|
console.error('Error rendering Machines We Use page:', error);
|
|
}
|
|
return (
|
|
<div className="container mx-auto px-4 py-8 md:py-12">
|
|
<h1 className="text-4xl md:text-5xl font-bold mb-4">Error Loading Page</h1>
|
|
<p className="text-destructive mb-4">There was an error loading this page. Please try again later.</p>
|
|
{process.env.NODE_ENV === 'development' && (
|
|
<pre className="mt-4 p-4 bg-muted rounded text-sm overflow-auto">
|
|
{error instanceof Error ? error.message : String(error)}
|
|
</pre>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|
|
}
|
|
|