"use client"; import { useMemo, useState } from "react"; import { SearchIcon } from "lucide-react"; import type { GameNpc } from "@/payload-types"; import { Badge } from "@/components/ui/badge"; import { Card, CardContent } from "@/components/ui/card"; import { Checkbox } from "@/components/ui/checkbox"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { cn } from "@/lib/utils"; import { NpcCard } from "@/components/frontend/personnel/NpcCard"; interface NpcDirectoryProps { readonly npcs: GameNpc[]; } export function NpcDirectory({ npcs }: NpcDirectoryProps) { const [search, setSearch] = useState(""); const [inGameOnly, setInGameOnly] = useState(false); const [vendorsOnly, setVendorsOnly] = useState(false); const filteredNpcs = useMemo(() => { const query = search.trim().toLowerCase(); return [...npcs] .filter((npc) => { if (inGameOnly && npc.isInGame !== true) return false; if (vendorsOnly && npc.vendor?.enabled !== true) return false; if ( query && !`${npc.name} ${npc.occupation ?? ""}`.toLowerCase().includes(query) ) { return false; } return true; }) .sort((left, right) => left.name.localeCompare(right.name)); }, [inGameOnly, npcs, search, vendorsOnly]); const hasFilters = Boolean(search.trim()) || inGameOnly || vendorsOnly; return (
setSearch(event.target.value)} />
Contact filters
setInGameOnly(checked === true)} />
setVendorsOnly(checked === true)} />
{filteredNpcs.length} of {npcs.length}
{filteredNpcs.length === 0 ? (

{npcs.length === 0 ? "No contacts have been added." : hasFilters ? "No contacts match those filters." : "No contacts found."}

{npcs.length === 0 ? "NPC records will appear here as the theater develops." : "Try a different search or clear one of the filters."}

) : (
{filteredNpcs.map((npc) => ( ))}
)}
); }