export const dynamic = "force-dynamic"; import type { Metadata } from "next"; import Link from "next/link"; import { notFound } from "next/navigation"; import { ogForEssay, extractQuoteFromHl, buildOgMeta } from "@/lib/og"; import { PageHeader } from "@/components/layout/page-header"; import { JsonLd } from "@/components/seo/json-ld"; import { articleJsonLd } from "@/lib/jsonld"; import { Card, CardContent } from "@/components/ui/card"; import { buttonVariants } from "@/components/ui/button"; import { ChevronLeft, ChevronRight } from "lucide-react"; import { cn } from "@/lib/utils"; import { MobileNav, type MobileNavGroup } from "@/components/layout/mobile-nav"; import { bff, bffList } from "@/lib/bff"; // --------------------------------------------------------------------------- // HTML sanitisation (same pattern used across all readers) // --------------------------------------------------------------------------- function sanitizeHtml(html: string): string { let clean = html.replace(/][\s\S]*?<\/script>/gi, ""); clean = clean.replace(/][\s\S]*?<\/style>/gi, ""); clean = clean.replace(/][\s\S]*?<\/iframe>/gi, ""); clean = clean.replace( /<\/?(?:script|style|iframe|object|embed|form|input|textarea|select|button)[^>]*>/gi, "", ); clean = clean.replace(/\s+on\w+\s*=\s*(?:"[^"]*"|'[^']*'|[^\s>]+)/gi, ""); clean = clean.replace(/href\s*=\s*"javascript:[^"]*"/gi, 'href=""'); clean = clean.replace(/href\s*=\s*'javascript:[^']*'/gi, "href=''"); return clean; } // --------------------------------------------------------------------------- // Data fetching // --------------------------------------------------------------------------- type EssayData = { slug: string; title: string; author: string; year: number | null; group: string | null; paragraphs: string[]; }; type SidebarItem = { slug: string; title: string; }; async function getEssay(slug: string): Promise { const doc = await bff<{ slug: string; title: string; author: string; year: number | null; group: string | null; paragraphs: string[]; }>(`/essays/${slug}`); if (!doc) return null; return { slug: doc.slug, title: doc.title, author: doc.author, year: doc.year, group: doc.group, paragraphs: (doc.paragraphs ?? []).map(sanitizeHtml), }; } async function getEssaySidebar(): Promise { return bffList("/essays"); } // --------------------------------------------------------------------------- // Page // --------------------------------------------------------------------------- export async function generateMetadata({ params, searchParams, }: { params: Promise<{ slug: string }>; searchParams: Promise>; }): Promise { const { slug } = await params; const sp = await searchParams; const essay = await getEssay(slug); if (!essay) return {}; const hlQuote = extractQuoteFromHl(sp, essay.paragraphs); if (hlQuote) { return buildOgMeta({ title: essay.title, detail: "Essay by Śrīla Prabhupāda", quote: hlQuote, }); } return ogForEssay(essay.title); } export default async function EssayPage({ params, }: { params: Promise<{ slug: string }>; }) { const { slug } = await params; const essay = await getEssay(slug); if (!essay) notFound(); const allEssays = await getEssaySidebar(); const currentIdx = allEssays.findIndex((item) => item.slug === slug); const prev = currentIdx > 0 ? allEssays[currentIdx - 1] : null; const next = currentIdx < allEssays.length - 1 ? allEssays[currentIdx + 1] : null; return (
← Essays

{essay.title}

{/* Left sidebar */} {/* Main content */}
{/* Top navigation */} {/* Content */}
{essay.paragraphs.map((paragraph, i) => (
))}
{/* Bottom navigation */}
); } // --------------------------------------------------------------------------- // Sidebar // --------------------------------------------------------------------------- function EssaySidebar({ items, currentSlug, }: { items: SidebarItem[]; currentSlug: string; }) { return ( ); } // --------------------------------------------------------------------------- // Prev / Next navigation // --------------------------------------------------------------------------- function EssayNav({ prev, next, allEssays, currentSlug, }: { prev: SidebarItem | null; next: SidebarItem | null; allEssays: SidebarItem[]; currentSlug: string; }) { const mobileNavGroups: MobileNavGroup[] = []; if (allEssays.length > 0) { mobileNavGroups.push({ title: "Essays", items: allEssays.map((i) => ({ slug: i.slug, label: i.title, href: `/essays/${i.slug}`, type: "chapter", })), }); } return (
{prev ? ( {prev.title} Previous ) : (
)}
{next ? ( {next.title} Next ) : (
)}
); }