"use client"; import { useEffect, useMemo, useState } from "react"; import { Crosshair, Layers, Package, Palette, SearchIcon } from "lucide-react"; import type { Asset, Loadout } from "@/payload-types"; import { Button } from "@/components/ui/button"; import { CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, } from "@/components/ui/command"; import { getAssetTypeLabel, type LockerGridItem } from "@/lib/locker"; import { buildSearchEntries, type LockerSearchEntry, type LockerSearchLocationKind, } from "@/lib/locker/search"; import { getAssetIcon } from "./LockerGrid"; function locationIcon(kind: LockerSearchLocationKind) { switch (kind) { case "locker": return ; case "attached": return ; case "skin": return ; case "loadout": return ; } } function entrySearchText(entry: LockerSearchEntry): string { return [ entry.displayName, entry.asset.name, getAssetTypeLabel(entry.assetType), ...entry.locations.map((l) => l.text), ] .join(" ") .toLowerCase(); } interface LockerSearchProps { items: LockerGridItem[]; loadouts: Loadout[]; onSelect: (entry: LockerSearchEntry) => void; } export function LockerSearch({ items, loadouts, onSelect }: LockerSearchProps) { const [open, setOpen] = useState(false); useEffect(() => { const onKey = (e: KeyboardEvent) => { if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "k") { e.preventDefault(); setOpen((v) => !v); } }; window.addEventListener("keydown", onKey); return () => window.removeEventListener("keydown", onKey); }, []); const entries = useMemo(() => buildSearchEntries(items, loadouts), [items, loadouts]); const groups = useMemo(() => { const byType = new Map(); for (const entry of entries) { const list = byType.get(entry.assetType) ?? []; list.push(entry); byType.set(entry.assetType, list); } return [...byType.entries()].sort((a, b) => getAssetTypeLabel(a[0]).localeCompare(getAssetTypeLabel(b[0])), ); }, [entries]); return ( <> No items found. {groups.map(([assetType, typeEntries]) => ( {typeEntries.map((entry) => ( { setOpen(false); onSelect(entry); }} className="items-start py-2.5" > {getAssetIcon(entry.assetType, "size-4")}
{entry.displayName} {entry.quantity > 0 && ( {entry.quantity.toLocaleString()}× )}
{entry.stats.length > 0 && (
{entry.stats.map((s) => `${s.label}: ${s.value}`).join(" · ")}
)} {entry.locations.length > 0 && (
{entry.locations.map((loc) => ( {locationIcon(loc.kind)} {loc.text} ))}
)}
))}
))}
); }