114 lines
3.6 KiB
TypeScript
114 lines
3.6 KiB
TypeScript
export const dynamic = "force-dynamic";
|
|
|
|
import type { Metadata } from "next";
|
|
import Link from "next/link";
|
|
import { redirect, notFound } from "next/navigation";
|
|
import { ChevronRight } from "lucide-react";
|
|
import { getBookMeta, getProseChapter, getChapterVerseIndex } from "@/lib/api";
|
|
import { CC_LILAS } from "@/lib/constants";
|
|
import { buildOgMeta } from "@/lib/og";
|
|
import { PageHeader } from "@/components/layout/page-header";
|
|
import { Card, CardContent } from "@/components/ui/card";
|
|
import { buttonVariants } from "@/components/ui/button";
|
|
import { FindInPage } from "@/components/layout/find-in-page";
|
|
import { cn } from "@/lib/utils";
|
|
|
|
type ChapterInfo = { number: number; title: string; totalVerses: number };
|
|
type LilaInfo = {
|
|
key: string;
|
|
name: string;
|
|
totalChapters: number;
|
|
totalVerses: number;
|
|
chapters: ChapterInfo[];
|
|
};
|
|
|
|
export async function generateMetadata({
|
|
params,
|
|
}: {
|
|
params: Promise<{ lila: string; chapter: string }>;
|
|
}): Promise<Metadata> {
|
|
const { lila, chapter } = await params;
|
|
const lilaName = CC_LILAS[lila] || lila;
|
|
return buildOgMeta({
|
|
title: "Śrī Caitanya-caritāmṛta",
|
|
detail: `${lilaName}, Chapter ${chapter}`,
|
|
});
|
|
}
|
|
|
|
export default async function CcChapterPage({
|
|
params,
|
|
}: {
|
|
params: Promise<{ lila: string; chapter: string }>;
|
|
}) {
|
|
const { lila, chapter } = await params;
|
|
const chapterNum = parseInt(chapter);
|
|
|
|
const [meta, summary, verseIndex] = await Promise.all([
|
|
getBookMeta("cc"),
|
|
getProseChapter("cc", 0, `${lila}-${chapterNum}`),
|
|
getChapterVerseIndex("cc", lila, chapterNum),
|
|
]);
|
|
|
|
if (!meta) notFound();
|
|
const lilaInfo = (meta.lilas as LilaInfo[] | undefined)?.find(
|
|
(l) => l.key === lila,
|
|
);
|
|
if (!lilaInfo) notFound();
|
|
const chapterInfo = lilaInfo.chapters.find((ch) => ch.number === chapterNum);
|
|
if (!chapterInfo) notFound();
|
|
if (verseIndex.length === 0) notFound();
|
|
|
|
const firstVerse = verseIndex[0].verse;
|
|
|
|
// Chapters without a summary (e.g. Ādi 7) go straight to the verses.
|
|
if (!summary || summary.paragraphs.length === 0) {
|
|
redirect(`/books/cc/${lila}/${chapterNum}/${firstVerse}`);
|
|
}
|
|
|
|
return (
|
|
<div className="min-h-screen bg-background">
|
|
<PageHeader sticky>
|
|
<Link
|
|
href={`/books/cc/${lila}`}
|
|
className="text-sm text-muted-foreground hover:text-foreground transition-colors"
|
|
>
|
|
← {lilaInfo.name}
|
|
</Link>
|
|
<div className="mt-3 flex items-start justify-between gap-3">
|
|
<h1 className="text-2xl font-bold text-foreground">
|
|
Chapter {chapterNum}: {chapterInfo.title}
|
|
</h1>
|
|
<FindInPage targetId="book-content" className="shrink-0 mt-0.5" />
|
|
</div>
|
|
</PageHeader>
|
|
|
|
<main className="max-w-5xl mx-auto px-6 py-8 space-y-6">
|
|
<p className="text-sm font-bold uppercase tracking-wider text-muted-foreground">
|
|
Chapter Summary
|
|
</p>
|
|
<Card id="book-content">
|
|
<CardContent className="py-8 px-6 sm:px-8">
|
|
<div className="space-y-4">
|
|
{summary.paragraphs.map((paragraph, i) => (
|
|
<div
|
|
key={i}
|
|
className="text-base text-foreground leading-relaxed"
|
|
dangerouslySetInnerHTML={{ __html: paragraph }}
|
|
/>
|
|
))}
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
|
|
<Link
|
|
href={`/books/cc/${lila}/${chapterNum}/${firstVerse}`}
|
|
className={cn(buttonVariants({ size: "lg" }), "gap-2")}
|
|
>
|
|
Read the chapter
|
|
<ChevronRight className="size-4" />
|
|
</Link>
|
|
</main>
|
|
</div>
|
|
);
|
|
}
|