"use client"; import { useState, useMemo } from "react"; import Link from "next/link"; import { Card, CardHeader, CardTitle, CardDescription, 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 OtherDocumentInfo = { slug: string; title: string; description: string; year: number | null; totalChapters: number; 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, "") ); } export function OtherDocumentsGrid({ items, }: { items: OtherDocumentInfo[]; }) { const [query, setQuery] = useState(""); const normalizedItems = useMemo( () => items.map((item) => ({ item, searchText: normalize( `${item.title} ${item.description} ${item.slug}`, ), })), [items], ); const filtered = useMemo(() => { if (!query.trim()) return items; const q = normalize(query.trim()); return normalizedItems .filter((entry) => entry.searchText.includes(q)) .map((entry) => entry.item); }, [items, normalizedItems, query]); return (
{filtered.length === 0 ? "No documents found" : `${filtered.length} document${filtered.length === 1 ? "" : "s"} found`}
)} {/* Grid */}