"use client"; import { useEffect, useRef, useState } from "react"; import { Bookmark, ChevronDown, Gem, Star, MinusCircle, Package, Check } from "lucide-react"; import { cn } from "@/lib/utils"; import type { FilterCriteria, MarkOption } from "@/lib/filters"; const OPTIONS: Array<{ value: MarkOption; label: string; Icon: React.ComponentType<{ className?: string }>; tint: "cyan" | "amber" | "violet" | "muted"; }> = [ { value: "vip", label: "VIP", Icon: Gem, tint: "cyan" }, { value: "favorite", label: "Favorite", Icon: Star, tint: "amber" }, { value: "owned", label: "Owned", Icon: Package, tint: "violet" }, { value: "unmarked", label: "Unmarked", Icon: MinusCircle, tint: "muted" }, ]; export function MarkPopover({ criteria, onChange, }: { criteria: FilterCriteria; onChange: (next: FilterCriteria) => void; }) { const [open, setOpen] = useState(false); const wrapRef = useRef(null); const active = criteria.marks.length > 0; useEffect(() => { if (!open) return; const onDoc = (e: MouseEvent) => { if (!wrapRef.current?.contains(e.target as Node)) setOpen(false); }; document.addEventListener("mousedown", onDoc); return () => document.removeEventListener("mousedown", onDoc); }, [open]); useEffect(() => { if (!open) return; const onKey = (e: KeyboardEvent) => { if (e.key === "Escape") setOpen(false); }; window.addEventListener("keydown", onKey); return () => window.removeEventListener("keydown", onKey); }, [open]); function toggle(value: MarkOption) { const has = criteria.marks.includes(value); const next = has ? criteria.marks.filter((m) => m !== value) : [...criteria.marks, value]; onChange({ ...criteria, marks: next }); } function selectAll() { onChange({ ...criteria, marks: [] }); } return (
{open && (
e.stopPropagation()} >
{OPTIONS.map(({ value, label, Icon, tint }) => { const on = criteria.marks.includes(value); return ( ); })}
)}
); }