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>
113 lines
3.3 KiB
TypeScript
113 lines
3.3 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 { FAQSchema } from '@/components/faq-schema';
|
|
import { FAQSection } from '@/components/faq-section';
|
|
import type { Metadata } from 'next';
|
|
|
|
const WORDPRESS_SLUG = 'faqs';
|
|
|
|
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 || 'FAQs',
|
|
description: page.seoDescription || page.excerpt || '',
|
|
excerpt: page.excerpt,
|
|
date: page.date,
|
|
modified: page.modified,
|
|
image: page.images?.[0]?.localPath,
|
|
});
|
|
}
|
|
|
|
export default async function FAQsPage() {
|
|
try {
|
|
const page = getPageBySlug(WORDPRESS_SLUG);
|
|
|
|
if (!page) {
|
|
notFound();
|
|
}
|
|
|
|
// Extract FAQs from content
|
|
const faqs: Array<{ question: string; answer: string }> = [];
|
|
if (page.content) {
|
|
const contentStr = String(page.content);
|
|
// Extract FAQ items from accordion structure
|
|
const questionMatches = contentStr.matchAll(/<span class="ekit-accordion-title">([^<]+)<\/span>/g);
|
|
// Extract full answer content
|
|
const answerMatches = contentStr.matchAll(/<div class="elementskit-card-body ekit-accordion--content">([\s\S]*?)<\/div>\s*<\/div>\s*<!-- \.elementskit-card END -->/g);
|
|
|
|
const questions = Array.from(questionMatches).map(m => m[1].trim());
|
|
const answers = Array.from(answerMatches).map(m => {
|
|
let answer = m[1].trim();
|
|
answer = answer.replace(/\n\s*\n/g, '\n').replace(/>\s+</g, '><').trim();
|
|
return answer;
|
|
});
|
|
|
|
// Match questions with answers
|
|
questions.forEach((question, index) => {
|
|
if (answers[index]) {
|
|
faqs.push({ question, answer: answers[index] });
|
|
}
|
|
});
|
|
}
|
|
|
|
let structuredData;
|
|
try {
|
|
structuredData = generateStructuredData({
|
|
title: page.title || 'FAQs',
|
|
description: page.seoDescription || page.excerpt || '',
|
|
url: page.link || page.urlPath || `https://rockymountainvending.com/about/faqs/`,
|
|
datePublished: page.date,
|
|
dateModified: page.modified || page.date,
|
|
type: 'WebPage',
|
|
});
|
|
} catch (e) {
|
|
structuredData = {
|
|
'@context': 'https://schema.org',
|
|
'@type': 'WebPage',
|
|
headline: page.title || 'FAQs',
|
|
description: page.seoDescription || '',
|
|
url: `https://rockymountainvending.com/about/faqs/`,
|
|
};
|
|
}
|
|
|
|
return (
|
|
<>
|
|
<script
|
|
type="application/ld+json"
|
|
dangerouslySetInnerHTML={{ __html: JSON.stringify(structuredData) }}
|
|
/>
|
|
{faqs.length > 0 && (
|
|
<>
|
|
<FAQSchema
|
|
faqs={faqs}
|
|
pageUrl={page.link || page.urlPath || `https://rockymountainvending.com/about/faqs/`}
|
|
/>
|
|
<FAQSection faqs={faqs} />
|
|
</>
|
|
)}
|
|
</>
|
|
);
|
|
} catch (error) {
|
|
if (process.env.NODE_ENV === 'development') {
|
|
console.error('Error rendering FAQs page:', error);
|
|
}
|
|
notFound();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|