diff --git a/app/(marketing)/use-cases/[slug]/page.tsx b/app/(marketing)/use-cases/[slug]/page.tsx new file mode 100644 index 0000000..dd94ce6 --- /dev/null +++ b/app/(marketing)/use-cases/[slug]/page.tsx @@ -0,0 +1,149 @@ +/** + * Figma: use case detail (22015:42619) + * https://www.figma.com/design/agv0VBLiBlcnSAaiAORgPR/Community-Rule-System?node-id=22015-42619 + */ +import type { Metadata } from "next"; +import { notFound } from "next/navigation"; +import messages from "../../../../messages/en/index"; +import { + buildUseCaseSyntheticPost, + getUseCaseDetailEntry, + isUseCaseDetailSlug, + USE_CASE_DETAIL_SLUGS, + useCaseContentKeyForSlug, +} from "../../../../lib/useCaseSyntheticPost"; +import ContentBanner from "../../../components/sections/ContentBanner"; +import AskOrganizer from "../../../components/sections/AskOrganizer"; +import type { AskOrganizerVariant } from "../../../components/sections/AskOrganizer/AskOrganizer.types"; +import "../use-cases.css"; + +type PageProps = { + params: Promise<{ slug: string }>; +}; + +export function generateStaticParams() { + return USE_CASE_DETAIL_SLUGS.map((slug) => ({ slug })); +} + +export async function generateMetadata({ params }: PageProps): Promise { + const { slug } = await params; + if (!isUseCaseDetailSlug(slug)) { + return {}; + } + + const contentKey = useCaseContentKeyForSlug(slug); + const meta = messages.metadata.useCasesDetail[contentKey]; + + return { + title: meta.title, + description: meta.description, + keywords: meta.keywords, + openGraph: { + title: meta.title, + description: meta.description, + type: "website", + siteName: "CommunityRule", + }, + }; +} + +export default async function UseCaseDetailPage({ params }: PageProps) { + const { slug } = await params; + if (!isUseCaseDetailSlug(slug)) { + notFound(); + } + + const detail = messages.pages.useCasesDetail; + const entry = getUseCaseDetailEntry(slug, detail); + const syntheticPost = buildUseCaseSyntheticPost(slug, detail); + const { ruleCard, askOrganizer } = entry; + + const askVariant = (askOrganizer.variant ?? "use-case-detail") as AskOrganizerVariant; + + const structuredData = { + "@context": "https://schema.org", + "@type": "WebPage", + name: entry.banner.title, + description: entry.banner.description, + url: `https://communityrule.com/use-cases/${slug}`, + publisher: { + "@type": "Organization", + name: "CommunityRule", + url: "https://communityrule.com", + }, + }; + + const breadcrumbData = { + "@context": "https://schema.org", + "@type": "BreadcrumbList", + itemListElement: [ + { + "@type": "ListItem", + position: 1, + name: "Home", + item: "https://communityrule.com", + }, + { + "@type": "ListItem", + position: 2, + name: "Use cases", + item: "https://communityrule.com/use-cases", + }, + { + "@type": "ListItem", + position: 3, + name: entry.banner.title, + item: `https://communityrule.com/use-cases/${slug}`, + }, + ], + }; + + return ( + <> +