export const dynamic = "force-dynamic"; import type { Metadata } from "next"; import fs from "fs"; import path from "path"; 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, type VerseIndexEntry, type VerseRecord, } from "@/lib/api"; import { ogForVerse, extractQuoteFromHl, buildOgMeta } from "@/lib/og"; import { ChapterViewer } from "@/app/(app)/(reader)/books/chapter-viewer"; import type { MobileNavGroup } from "@/components/layout/mobile-nav"; type NbsMeta = { book: string; title: string; author: string; totalChapters: number; chapters: { number: number; title: string; totalVerses: number }[]; }; const NBS_JSON_DIR = path.join(process.cwd(), "lib", "jsons", "books", "nbs"); // Fallback functions that read from local JSON when DB is empty async function getMetaWithFallback() { const meta = await getBookMeta("nbs"); if (meta) return meta as unknown as NbsMeta; const introPath = path.join(NBS_JSON_DIR, "intro.json"); if (!fs.existsSync(introPath)) return null; try { return JSON.parse(fs.readFileSync(introPath, "utf-8")) as NbsMeta; } catch { return null; } } async function getVerseIndexWithFallback( chapter: number, ): Promise { const index = await getChapterVerseIndex("nbs", null, chapter); if (index.length > 0) return index; // Fallback: read verse files from local JSON const versesDir = path.join( NBS_JSON_DIR, "chapters", String(chapter).padStart(2, "0"), "verses", ); if (!fs.existsSync(versesDir)) return [] as VerseIndexEntry[]; const files = fs .readdirSync(versesDir) .filter((f) => f.endsWith(".json")) .sort(); return files.map((f): VerseIndexEntry => { const v = JSON.parse(fs.readFileSync(path.join(versesDir, f), "utf-8")); return { verse: v.verse, verseEnd: v.verse_end || null, reference: v.reference, }; }); } async function getVerseWithFallback( chapter: number, verse: number, ): Promise { const v = await getSingleVerse("nbs", null, chapter, verse); if (v) return v; // Fallback: read from local JSON const versesDir = path.join( NBS_JSON_DIR, "chapters", String(chapter).padStart(2, "0"), "verses", ); if (!fs.existsSync(versesDir)) return null; const files = fs .readdirSync(versesDir) .filter((f) => f.endsWith(".json")) .sort(); for (const f of files) { const data = JSON.parse(fs.readFileSync(path.join(versesDir, f), "utf-8")); if (data.verse === verse) { return { id: `nbs-${chapter}-${verse}`, book: "nbs", division: null, chapter: data.chapter, verse: data.verse, verseEnd: data.verse_end || null, reference: data.reference, bookTitle: data.book_title, devanagari: data.devanagari, bengali: null, transliteration: data.transliteration, synonyms: data.synonyms, translation: data.translation, purport: data.purport, }; } } return null; } export async function generateMetadata({ params, searchParams, }: { params: Promise<{ chapter: string; verse: string }>; searchParams: Promise>; }): Promise { const { chapter, verse } = await params; const sp = await searchParams; const v = await getSingleVerse( "nbs", null, parseInt(chapter), parseInt(verse), ); const paragraphs = v ? [v.translation, ...v.purport] : undefined; const quote = extractQuoteFromHl(sp, paragraphs); if (quote) { return buildOgMeta({ title: "Nārada-bhakti-sūtra", detail: `Chapter ${chapter}, Verse ${verse}`, quote, }); } return ogForVerse("nbs", { chapter: parseInt(chapter), verse: parseInt(verse), }); } export default async function VersePage({ params, }: { params: Promise<{ chapter: string; verse: string }>; }) { const { chapter, verse: verseParam } = await params; const nbsMeta = await getMetaWithFallback(); if (!nbsMeta) notFound(); const chapterInfo = nbsMeta.chapters?.find( (c) => c.number === parseInt(chapter), ); if (!chapterInfo?.title) notFound(); const title: string = chapterInfo.title; const verseIndex = await getVerseIndexWithFallback(parseInt(chapter)); if (verseIndex.length === 0) notFound(); const requestedVerse = parseInt(verseParam); const verse = await getVerseWithFallback(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/nbs/${chapter}/${v.verse}`, type: "verse", })), }, ]; return (
← Nārada-bhakti-sūtra

Chapter {chapter}: {title}

({ verse: v.verse, verseEnd: v.verseEnd ?? undefined, reference: v.reference, }))} book="nbs" division={null} chapter={parseInt(chapter)} basePath={`/books/nbs/${chapter}`} showBengali={false} mobileNavGroups={mobileNavGroups} mobileNavBookTitle={`Chapter ${chapter}: ${title}`} />
); }