- Backend: faq_questions table (schema + migration), CRUD + reorder API, Swagger docs - Admin: FAQ page with create/edit, enable/disable, show on homepage, drag reorder - Public /faq page fetches enabled FAQs from API; layout builds dynamic JSON-LD - Homepage: FAQ section under Stay updated (homepage-enabled only) with See full FAQ link - llms.txt: FAQ section uses homepage FAQs from API - i18n: home.faq title/seeFull, admin FAQ nav Co-authored-by: Cursor <cursoragent@cursor.com>
58 lines
1.6 KiB
TypeScript
58 lines
1.6 KiB
TypeScript
import type { Metadata } from 'next';
|
||
|
||
const apiUrl = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3001';
|
||
|
||
async function getFaqForSchema(): Promise<{ question: string; answer: string }[]> {
|
||
try {
|
||
const res = await fetch(`${apiUrl}/api/faq`, { next: { revalidate: 60 } });
|
||
if (!res.ok) return [];
|
||
const data = await res.json();
|
||
const faqs = data.faqs || [];
|
||
return faqs.map((f: { question: string; questionEs?: string | null; answer: string; answerEs?: string | null }) => ({
|
||
question: f.question,
|
||
answer: f.answer || '',
|
||
}));
|
||
} catch {
|
||
return [];
|
||
}
|
||
}
|
||
|
||
export const metadata: Metadata = {
|
||
title: 'Frequently Asked Questions',
|
||
description: 'Find answers to common questions about Spanglish language exchange events in Asunción. Learn about how events work, who can attend, and more.',
|
||
openGraph: {
|
||
title: 'Frequently Asked Questions – Spanglish',
|
||
description: 'Find answers to common questions about Spanglish language exchange events in Asunción.',
|
||
},
|
||
};
|
||
|
||
export default async function FAQLayout({
|
||
children,
|
||
}: {
|
||
children: React.ReactNode;
|
||
}) {
|
||
const faqList = await getFaqForSchema();
|
||
const faqSchema = {
|
||
'@context': 'https://schema.org',
|
||
'@type': 'FAQPage',
|
||
mainEntity: faqList.map(({ question, answer }) => ({
|
||
'@type': 'Question',
|
||
name: question,
|
||
acceptedAnswer: {
|
||
'@type': 'Answer',
|
||
text: answer,
|
||
},
|
||
})),
|
||
};
|
||
|
||
return (
|
||
<>
|
||
<script
|
||
type="application/ld+json"
|
||
dangerouslySetInnerHTML={{ __html: JSON.stringify(faqSchema) }}
|
||
/>
|
||
{children}
|
||
</>
|
||
);
|
||
}
|