113 lines
3.2 KiB
TypeScript
113 lines
3.2 KiB
TypeScript
export const dynamic = "force-dynamic";
|
||
|
||
import type { Metadata } from "next";
|
||
import Link from "next/link";
|
||
import { PageHeader } from "@/components/page-header";
|
||
import { ogForDisciples } from "@/lib/og";
|
||
import {
|
||
getTotalDiscipleCount,
|
||
getFilteredDisciples,
|
||
getDiscipleLetterCounts,
|
||
getDisciplePlaces,
|
||
getDiscipleYears,
|
||
getDiscipleSuffixCounts,
|
||
getFilteredDiscipleCount,
|
||
} from "@/lib/disciples";
|
||
import type { SuffixFilter } from "@/lib/disciples";
|
||
import { DisciplesBrowser } from "./disciples-browser";
|
||
|
||
export async function generateMetadata(): Promise<Metadata> {
|
||
return ogForDisciples();
|
||
}
|
||
|
||
const VALID_SUFFIXES: SuffixFilter[] = ["all", "Dasa", "Devi Dasi"];
|
||
|
||
function parseSuffix(raw: string | undefined): SuffixFilter {
|
||
if (!raw) return "all";
|
||
// Handle URL-encoded "Devi Dasi" → "Devi+Dasi" or "Devi%20Dasi"
|
||
const decoded = decodeURIComponent(raw.replace(/\+/g, " "));
|
||
if (VALID_SUFFIXES.includes(decoded as SuffixFilter)) {
|
||
return decoded as SuffixFilter;
|
||
}
|
||
return "all";
|
||
}
|
||
|
||
function parseLetter(raw: string | undefined): string {
|
||
if (!raw) return "A";
|
||
const cleaned = raw.trim();
|
||
if (cleaned.toLowerCase() === "all") return "All";
|
||
// Single uppercase letter
|
||
const ch = cleaned.charAt(0).toUpperCase();
|
||
if (ch >= "A" && ch <= "Z") return ch;
|
||
return "A";
|
||
}
|
||
|
||
export default async function DisciplesPage({
|
||
searchParams,
|
||
}: {
|
||
searchParams: Promise<{ letter?: string; suffix?: string }>;
|
||
}) {
|
||
const params = await searchParams;
|
||
const activeLetter = parseLetter(params.letter);
|
||
const activeSuffix = parseSuffix(params.suffix);
|
||
|
||
// letter=null means "All" — no letter filter
|
||
const letterFilter = activeLetter === "All" ? null : activeLetter;
|
||
|
||
const [
|
||
totalCount,
|
||
disciples,
|
||
filteredCount,
|
||
letterCounts,
|
||
places,
|
||
years,
|
||
suffixCounts,
|
||
] = await Promise.all([
|
||
getTotalDiscipleCount(),
|
||
getFilteredDisciples(letterFilter, activeSuffix),
|
||
getFilteredDiscipleCount(letterFilter, activeSuffix),
|
||
getDiscipleLetterCounts(),
|
||
getDisciplePlaces(),
|
||
getDiscipleYears(),
|
||
getDiscipleSuffixCounts(),
|
||
]);
|
||
|
||
// Serialize dates to ISO strings for the client component
|
||
const serializedDisciples = disciples.map((d) => ({
|
||
...d,
|
||
initiationDate: d.initiationDate ? d.initiationDate.toISOString() : null,
|
||
}));
|
||
|
||
return (
|
||
<div className="min-h-screen bg-background">
|
||
<PageHeader>
|
||
<Link
|
||
href="/"
|
||
className="text-sm text-muted-foreground hover:text-foreground transition-colors"
|
||
>
|
||
← Home
|
||
</Link>
|
||
<h1 className="mt-3 text-3xl font-bold text-foreground">Disciples</h1>
|
||
<p className="mt-1 text-muted-foreground">
|
||
{totalCount.toLocaleString()} disciples initiated by Śrīla Prabhupāda
|
||
(1966–1977)
|
||
</p>
|
||
</PageHeader>
|
||
|
||
<main className="max-w-5xl mx-auto px-6 py-8">
|
||
<DisciplesBrowser
|
||
initialDisciples={serializedDisciples}
|
||
initialLetter={activeLetter}
|
||
activeSuffix={activeSuffix}
|
||
letterCounts={letterCounts}
|
||
suffixCounts={suffixCounts}
|
||
places={places}
|
||
years={years}
|
||
totalCount={totalCount}
|
||
filteredCount={filteredCount}
|
||
/>
|
||
</main>
|
||
</div>
|
||
);
|
||
}
|