feat: allow path params for verse navigation

This commit is contained in:
gosangam
2026-04-15 13:41:34 +05:30
parent c0a00d4c04
commit abb7cc49d0
19 changed files with 1462 additions and 261 deletions
@@ -0,0 +1,81 @@
import Link from "next/link";
import { PageHeader } from "@/components/page-header";
import { notFound } from "next/navigation";
import { getBookMeta, getSingleVerse, getChapterVerseIndex } from "@/lib/api";
import { ChapterViewer } from "@/app/books/chapter-viewer";
type Sb1962Meta = {
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("sb1962");
if (!meta) notFound();
const sb1962Meta = meta as unknown as Sb1962Meta;
const chapterInfo = sb1962Meta.chapters?.find(
(c) => c.number === parseInt(chapter),
);
if (!chapterInfo?.title) notFound();
const title: string = chapterInfo.title;
const verseIndex = await getChapterVerseIndex(
"sb1962",
null,
parseInt(chapter),
);
if (verseIndex.length === 0) notFound();
const requestedVerse = parseInt(verseParam);
const verse = await getSingleVerse(
"sb1962",
null,
parseInt(chapter),
requestedVerse,
);
if (!verse) notFound();
return (
<div className="min-h-screen bg-background">
<PageHeader sticky wide>
<Link
href="/books/sb1962"
className="text-sm text-muted-foreground hover:text-foreground"
>
&larr; Śrīmad-Bhāgavatam (1962)
</Link>
<h1 className="mt-2 text-2xl font-bold text-foreground">
Chapter {chapter}: {title}
</h1>
</PageHeader>
<div className="w-full md:max-w-7xl mx-auto flex">
<ChapterViewer
initialVerse={verse}
initialVerseNum={requestedVerse}
verseIndex={verseIndex.map((v) => ({
verse: v.verse,
verseEnd: v.verseEnd ?? undefined,
reference: v.reference,
}))}
book="sb1962"
division={null}
chapter={parseInt(chapter)}
basePath={`/books/sb1962/${chapter}`}
showBengali={false}
/>
</div>
</div>
);
}
+20
View File
@@ -0,0 +1,20 @@
import { redirect } from "next/navigation";
import { notFound } from "next/navigation";
import { getChapterVerseIndex } from "@/lib/api";
export default async function ChapterPage({
params,
}: {
params: Promise<{ chapter: string }>;
}) {
const { chapter } = await params;
const verseIndex = await getChapterVerseIndex(
"sb1962",
null,
parseInt(chapter),
);
if (verseIndex.length === 0) {
notFound();
}
redirect(`/books/sb1962/${chapter}/${verseIndex[0].verse}`);
}
+69
View File
@@ -0,0 +1,69 @@
import Link from "next/link";
import { notFound } from "next/navigation";
import { getBookMeta } from "@/lib/api";
import { PageHeader } from "@/components/page-header";
import { Card, CardContent } from "@/components/ui/card";
import { ExtractedVerseCount } from "../extracted-verse-count";
type ChapterInfo = {
number: number;
title: string;
totalVerses: number;
};
export default async function Sb1962Page() {
const meta = await getBookMeta("sb1962");
if (!meta) notFound();
const intro = meta as unknown as {
book: string;
title: string;
author: string;
description?: string;
totalChapters: number;
chapters: ChapterInfo[];
};
return (
<div className="min-h-screen bg-background">
<PageHeader>
<Link
href="/books"
className="text-sm text-muted-foreground hover:text-foreground transition-colors"
>
&larr; Books
</Link>
<h1 className="mt-3 text-3xl font-bold text-foreground">
{intro.title}
</h1>
<p className="mt-1 text-muted-foreground">{intro.author}</p>
</PageHeader>
<main className="max-w-3xl mx-auto px-6 py-8">
<Card className="divide-y divide-border py-0">
<CardContent className="p-0">
<ul className="divide-y divide-border">
{intro.chapters.map((ch) => (
<li key={ch.number}>
<Link
href={`/books/sb1962/${ch.number}`}
className="flex items-center justify-between px-5 py-4 hover:bg-muted transition-colors"
>
<div>
<span className="text-sm text-primary font-medium">
Chapter {ch.number}
</span>
<p className="font-medium text-foreground">{ch.title}</p>
</div>
<span className="text-sm text-muted-foreground shrink-0 ml-4">
<ExtractedVerseCount count={ch.totalVerses} />
</span>
</Link>
</li>
))}
</ul>
</CardContent>
</Card>
</main>
</div>
);
}