feat: add ssr

This commit is contained in:
gosangam
2026-04-17 22:51:58 +05:30
parent d88ababd76
commit 0aab1d23ec
97 changed files with 29891 additions and 68 deletions
+34 -62
View File
@@ -1,16 +1,7 @@
import Link from "next/link";
import { PageHeader } from "@/components/page-header";
import {
Card,
CardHeader,
CardTitle,
CardDescription,
CardContent,
} from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { cn } from "@/lib/utils";
import { ExtractedVerseCount } from "./extracted-verse-count";
import { getAllBooks, type BookMeta } from "@/lib/api";
import { BooksGrid, type BookInfo } from "./books-grid";
type ChapterEntry = { totalVerses: number };
type CantoEntry = { totalChapters: number; chapters: ChapterEntry[] };
@@ -21,12 +12,6 @@ interface ChapterBookMeta extends BookMeta {
chapters: ChapterEntry[];
}
interface KbMeta extends BookMeta {
totalChapters: number;
description: string;
volumes: { number: number; totalChapters: number }[];
}
interface SbMeta extends BookMeta {
totalCantos: number;
cantos: CantoEntry[];
@@ -37,15 +22,6 @@ interface CcMeta extends BookMeta {
lilas: LilaEntry[];
}
type BookInfo = {
slug: string;
title: string;
author: string;
description: string;
totalVerses: number;
href: string;
};
function buildBookList(allBooks: BookMeta[]): BookInfo[] {
const books: BookInfo[] = [];
@@ -65,6 +41,8 @@ function buildBookList(allBooks: BookMeta[]): BookInfo[] {
title,
author,
description: `${bg.totalChapters} chapters`,
contentDescription:
"The essence of Vedic knowledge — Lord Kṛṣṇa's teachings to Arjuna on the battlefield of Kurukṣetra.",
totalVerses,
href: "/books/bg",
});
@@ -79,6 +57,9 @@ function buildBookList(allBooks: BookMeta[]): BookInfo[] {
title,
author,
description: `${sb62.totalChapters} chapters · First Canto`,
contentDescription:
(data as { description?: string }).description ||
"The original 1962 Indian edition of the First Canto.",
totalVerses,
href: "/books/sb1962",
});
@@ -97,6 +78,8 @@ function buildBookList(allBooks: BookMeta[]): BookInfo[] {
title,
author,
description: `${sb.totalCantos} cantos, ${totalChapters} chapters`,
contentDescription:
"The ripened fruit of Vedic literature — the science of God in 18,000 verses.",
totalVerses,
href: "/books/sb",
});
@@ -115,18 +98,37 @@ function buildBookList(allBooks: BookMeta[]): BookInfo[] {
title,
author,
description: `${cc.totalLilas} līlās, ${totalChapters} chapters`,
contentDescription:
"The life and teachings of Lord Caitanya Mahāprabhu — the most complete theistic science.",
totalVerses,
href: "/books/cc",
});
} else if (slug === "kb") {
const kb = data as KbMeta;
} else {
// Generic handler for all other books — pulls description from metadata
const metaDesc = (data as { description?: string }).description || "";
const totalChapters = (data as { totalChapters?: number }).totalChapters;
const totalMantras = (data as { totalMantras?: number }).totalMantras;
const totalTexts = (data as { totalTexts?: number }).totalTexts;
const parts = (data as { parts?: unknown[] }).parts;
const volumes = (data as { volumes?: unknown[] }).volumes;
let badge = "";
if (totalMantras) badge = `${totalMantras} mantras`;
else if (totalTexts) badge = `${totalTexts} texts`;
else if (totalChapters && volumes)
badge = `${totalChapters} chapters · ${volumes.length} volumes`;
else if (totalChapters && parts)
badge = `${totalChapters} chapters · ${parts.length} parts`;
else if (totalChapters) badge = `${totalChapters} chapters`;
books.push({
slug,
title,
author,
description: `${kb.totalChapters} chapters · 2 volumes`,
description: badge,
contentDescription: metaDesc,
totalVerses: 0,
href: "/books/kb",
href: `/books/${slug}`,
});
}
}
@@ -149,42 +151,12 @@ export default async function BooksPage() {
</Link>
<h1 className="mt-3 text-3xl font-bold text-foreground">Books</h1>
<p className="mt-1 text-muted-foreground">
Structured verse-by-verse editions with Devanagari, transliteration,
synonyms, translation &amp; purports
Browse the books and teachings of Śrīla Prabhupāda
</p>
</PageHeader>
<main className="max-w-3xl mx-auto px-6 py-8">
<div className="grid gap-4">
{books.map((book) => (
<Link key={book.slug} href={book.href} className="block">
<Card
className={cn(
"transition-all hover:shadow-md hover:ring-foreground/20",
)}
>
<CardHeader>
<CardTitle className="text-xl font-bold">
{book.title}
</CardTitle>
<CardDescription>{book.author}</CardDescription>
</CardHeader>
<CardContent>
<div className="flex items-center gap-3 text-sm">
<Badge variant="secondary">{book.description}</Badge>
{book.totalVerses > 0 && (
<ExtractedVerseCount
count={book.totalVerses}
label="extracted verses"
className="text-muted-foreground"
/>
)}
</div>
</CardContent>
</Card>
</Link>
))}
</div>
<main className="max-w-6xl mx-auto px-6 py-8">
<BooksGrid books={books} />
</main>
</div>
);