"use client"; import { useState, useMemo } from "react"; import Link from "next/link"; import { Card, CardHeader, CardTitle, CardContent, } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; import { Input } from "@/components/ui/input"; import { cn } from "@/lib/utils"; import { Search } from "lucide-react"; export type EssayInfo = { slug: string; title: string; year: number | null; group: string | null; href: string; }; /** * Strip diacritics / accents so that "Krsna" matches "Kṛṣṇa", * "Gita" matches "Gītā", "Srimad" matches "Śrīmad", etc. */ function normalize(text: string): string { return ( text .toLowerCase() .replace(/ṛ/g, "r") .replace(/ṝ/g, "r") .replace(/ṣ/g, "s") .replace(/ś/g, "s") .replace(/ṭ/g, "t") .replace(/ḍ/g, "d") .replace(/ṇ/g, "n") .replace(/ñ/g, "n") .replace(/ṅ/g, "n") .replace(/ḥ/g, "h") .replace(/ṁ/g, "m") .replace(/ṃ/g, "m") .replace(/ḷ/g, "l") .normalize("NFD") .replace(/[\u0300-\u036f]/g, "") ); } /** Human-readable group labels */ const GROUP_LABELS: Record = { "cc-essays": "Śrī Caitanya-caritāmṛta Essays", "pre-1977-essays": "Pre-1977 Essays", "two-essays": "Two Essays (1966)", reviews: "Reviews", standalone: "Standalone", "typed-transcripts": "Typed Transcripts", }; function groupLabel(group: string | null): string { if (!group) return "Other"; return GROUP_LABELS[group] ?? group; } export function EssaysGrid({ essays }: { essays: EssayInfo[] }) { const [query, setQuery] = useState(""); const normalizedEssays = useMemo( () => essays.map((essay) => ({ essay, searchText: normalize( `${essay.title} ${essay.group ?? ""} ${essay.slug}`, ), })), [essays], ); const filtered = useMemo(() => { if (!query.trim()) return essays; const q = normalize(query.trim()); return normalizedEssays .filter((entry) => entry.searchText.includes(q)) .map((entry) => entry.essay); }, [essays, normalizedEssays, query]); return (
{/* Search input */}
setQuery(e.target.value)} className="pl-9" />
{/* Results count when searching */} {query.trim() && (

{filtered.length === 0 ? "No essays found" : `${filtered.length} essay${filtered.length === 1 ? "" : "s"} found`}

)} {/* Grid */}
{filtered.map((essay) => ( {essay.title}
{essay.year && ( {essay.year} )} {essay.group && ( {groupLabel(essay.group)} )}
))}
); }