134 lines
3.8 KiB
TypeScript
134 lines
3.8 KiB
TypeScript
import type { Metadata } from "next";
|
||
import Link from "next/link";
|
||
import { PageHeader } from "@/components/layout/page-header";
|
||
import { FindInPage } from "@/components/layout/find-in-page";
|
||
import { notFound } from "next/navigation";
|
||
import { getBookMeta, getSingleVerse, getChapterVerseIndex } from "@/lib/api";
|
||
import { ChapterViewer } from "@/app/(app)/books/chapter-viewer";
|
||
import type { MobileNavGroup } from "@/components/layout/mobile-nav";
|
||
import { ogForVerse, extractQuoteFromHl, buildOgMeta } from "@/lib/og";
|
||
|
||
export const dynamic = "force-dynamic";
|
||
|
||
export async function generateMetadata({
|
||
params,
|
||
searchParams,
|
||
}: {
|
||
params: Promise<{ chapter: string; verse: string }>;
|
||
searchParams: Promise<Record<string, string | string[] | undefined>>;
|
||
}): Promise<Metadata> {
|
||
const { chapter, verse } = await params;
|
||
const sp = await searchParams;
|
||
const v = await getSingleVerse(
|
||
"bg",
|
||
null,
|
||
parseInt(chapter),
|
||
parseInt(verse),
|
||
);
|
||
const paragraphs = v ? [v.translation, ...v.purport] : undefined;
|
||
const quote = extractQuoteFromHl(sp, paragraphs);
|
||
if (quote) {
|
||
return buildOgMeta({
|
||
title: "Bhagavad-gītā As It Is",
|
||
detail: `Chapter ${chapter}, Verse ${verse}`,
|
||
quote,
|
||
});
|
||
}
|
||
return ogForVerse("bg", {
|
||
chapter: parseInt(chapter),
|
||
verse: parseInt(verse),
|
||
});
|
||
}
|
||
|
||
type BgMeta = {
|
||
book: string;
|
||
title: string;
|
||
author: string;
|
||
totalChapters: number;
|
||
chapters: { number: number; title: string; totalVerses: number }[];
|
||
};
|
||
|
||
export default async function VersePage({
|
||
params,
|
||
}: {
|
||
params: Promise<{ chapter: string; verse: string }>;
|
||
}) {
|
||
const { chapter, verse: verseParam } = await params;
|
||
|
||
const meta = await getBookMeta("bg");
|
||
if (!meta) notFound();
|
||
|
||
const bgMeta = meta as unknown as BgMeta;
|
||
const chapterInfo = bgMeta.chapters?.find(
|
||
(c) => c.number === parseInt(chapter),
|
||
);
|
||
if (!chapterInfo?.title) notFound();
|
||
|
||
const title: string = chapterInfo.title;
|
||
|
||
const verseIndex = await getChapterVerseIndex("bg", null, parseInt(chapter));
|
||
if (verseIndex.length === 0) notFound();
|
||
|
||
const requestedVerse = parseInt(verseParam);
|
||
const verse = await getSingleVerse(
|
||
"bg",
|
||
null,
|
||
parseInt(chapter),
|
||
requestedVerse,
|
||
);
|
||
if (!verse) notFound();
|
||
|
||
// Build mobile nav groups — verses for the current chapter
|
||
const mobileNavGroups: MobileNavGroup[] = [
|
||
{
|
||
title: "Verses",
|
||
items: verseIndex.map((v) => ({
|
||
slug: String(v.verse),
|
||
label: v.verseEnd
|
||
? `Verse ${chapter}.${v.verse}–${v.verseEnd}`
|
||
: `Verse ${chapter}.${v.verse}`,
|
||
href: `/books/bg/${chapter}/${v.verse}`,
|
||
type: "verse",
|
||
})),
|
||
},
|
||
];
|
||
|
||
return (
|
||
<div className="min-h-screen bg-background">
|
||
<PageHeader sticky>
|
||
<Link
|
||
href="/books/bg"
|
||
className="text-sm text-muted-foreground hover:text-foreground"
|
||
>
|
||
← Bhagavad-gītā
|
||
</Link>
|
||
<div className="mt-2 flex items-start justify-between gap-3">
|
||
<h1 className="text-2xl font-bold text-foreground">
|
||
Chapter {chapter}: {title}
|
||
</h1>
|
||
<FindInPage targetId="book-content" className="shrink-0 mt-0.5" />
|
||
</div>
|
||
</PageHeader>
|
||
|
||
<div className="max-w-5xl mx-auto flex">
|
||
<ChapterViewer
|
||
initialVerse={verse}
|
||
initialVerseNum={requestedVerse}
|
||
verseIndex={verseIndex.map((v) => ({
|
||
verse: v.verse,
|
||
verseEnd: v.verseEnd ?? undefined,
|
||
reference: v.reference,
|
||
}))}
|
||
book="bg"
|
||
division={null}
|
||
chapter={parseInt(chapter)}
|
||
basePath={`/books/bg/${chapter}`}
|
||
showBengali={false}
|
||
mobileNavGroups={mobileNavGroups}
|
||
mobileNavBookTitle={`Chapter ${chapter}: ${title}`}
|
||
/>
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|