From 7c46cbd87bdf93bdfcce1a9371d95a08f4e4c057 Mon Sep 17 00:00:00 2001 From: adilallo <39313955+adilallo@users.noreply.github.com> Date: Mon, 18 May 2026 16:50:44 -0600 Subject: [PATCH] Create use cases pages --- app/(marketing)/use-cases/[slug]/page.tsx | 149 ++++++++++++++++++ app/(marketing)/use-cases/page.tsx | 54 +++++-- app/(marketing)/use-cases/use-cases.css | 35 ++++ app/components/cards/Rule/Rule.container.tsx | 2 + app/components/cards/Rule/Rule.types.ts | 3 + app/components/cards/Rule/Rule.view.tsx | 26 +-- .../ContentContainer.container.tsx | 29 +++- .../ContentContainer.types.ts | 11 ++ .../ContentContainer.view.tsx | 20 +-- .../AskOrganizer/AskOrganizer.container.tsx | 16 +- .../AskOrganizer/AskOrganizer.types.ts | 3 +- .../AskOrganizer/AskOrganizer.view.tsx | 19 ++- .../ContentBanner/ContentBanner.container.tsx | 4 + .../ContentBanner/ContentBanner.types.ts | 20 ++- .../ContentBanner/ContentBanner.view.tsx | 82 ++++++++++ .../ContentLockup/ContentLockup.container.tsx | 6 +- lib/useCaseSyntheticPost.ts | 61 +++++++ messages/en/index.ts | 2 + messages/en/metadata.json | 17 ++ messages/en/pages/useCases.json | 16 +- messages/en/pages/useCasesDetail.json | 92 +++++++++++ stories/sections/AskOrganizer.stories.js | 22 ++- stories/sections/ContentBanner.stories.js | 34 +++- tests/components/AskOrganizer.test.tsx | 17 ++ tests/components/ContentBanner.test.tsx | 26 ++- tests/pages/use-cases-detail.test.jsx | 85 ++++++++++ tests/pages/use-cases.test.jsx | 35 ++++ tests/unit/Rule.test.jsx | 8 + 28 files changed, 836 insertions(+), 58 deletions(-) create mode 100644 app/(marketing)/use-cases/[slug]/page.tsx create mode 100644 app/(marketing)/use-cases/use-cases.css create mode 100644 lib/useCaseSyntheticPost.ts create mode 100644 messages/en/pages/useCasesDetail.json create mode 100644 tests/pages/use-cases-detail.test.jsx create mode 100644 tests/pages/use-cases.test.jsx 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 ( + <> +