"use client"; import { useEffect, useRef, useState, useTransition } from "react"; import { useRouter } from "next/navigation"; import { Plus, Minus, X, Loader2, Sparkles } from "lucide-react"; import { CategoryIcon } from "./CategoryIcon"; import { useActressSelection } from "./ActressSelectionProvider"; import { bulkAddCategory, bulkRemoveCategory, createActressCategory, } from "@/app/actions/actressCategories"; import type { ActressCategory } from "@/lib/db/queries"; const PALETTE = ["#fbbf24", "#22d3ee", "#a78bfa", "#f472b6", "#34d399", "#fb7185", "#f97316", "#60a5fa"]; export function ActressBulkBar({ categories }: { categories: ActressCategory[] }) { const sel = useActressSelection(); const router = useRouter(); const [, start] = useTransition(); const [busy, setBusy] = useState(false); const [openMenu, setOpenMenu] = useState<"add" | "remove" | null>(null); const [creating, setCreating] = useState(false); const [newName, setNewName] = useState(""); const [newColor, setNewColor] = useState(PALETTE[0]); const ref = useRef(null); // Click outside to close menus. useEffect(() => { const onDoc = (e: MouseEvent) => { if (ref.current && !ref.current.contains(e.target as Node)) { setOpenMenu(null); setCreating(false); } }; if (openMenu || creating) document.addEventListener("mousedown", onDoc); return () => document.removeEventListener("mousedown", onDoc); }, [openMenu, creating]); const empty = sel.ids.size === 0; const selectedIds = Array.from(sel.ids); function runAdd(categoryId: number) { setBusy(true); setOpenMenu(null); start(async () => { try { await bulkAddCategory(selectedIds, categoryId); router.refresh(); } finally { setBusy(false); } }); } function runRemove(categoryId: number) { setBusy(true); setOpenMenu(null); start(async () => { try { await bulkRemoveCategory(selectedIds, categoryId); router.refresh(); } finally { setBusy(false); } }); } async function createAndAdd() { if (busy) return; const name = newName.trim(); if (!name) return; setBusy(true); try { const created = await createActressCategory({ name, color: newColor, icon: "tag", priority: 50 }); if (created) { await bulkAddCategory(selectedIds, created.id); router.refresh(); } setCreating(false); setNewName(""); setOpenMenu(null); } catch (err) { console.error("[createAndAdd] failed:", err); } finally { setBusy(false); } } return (
{sel.ids.size} selected
{openMenu === "add" && ( {categories.map((c) => ( runAdd(c.id)} icon={} color={c.color}> {c.name} ))}
{creating ? (
setNewName(e.target.value)} onKeyDown={(e) => { if (e.key === "Enter") createAndAdd(); if (e.key === "Escape") setCreating(false); }} placeholder="Category name" maxLength={32} className="w-full glass rounded-md px-2 py-1.5 text-sm outline-none focus:border-[var(--color-cyan)]" />
{PALETTE.map((p) => (
) : ( )}
)}
{openMenu === "remove" && ( {categories.map((c) => ( runRemove(c.id)} icon={} color={c.color}> {c.name} ))} )}
); } function Menu({ children }: { children: React.ReactNode }) { return (
{children}
); } function MenuItem({ icon, color, children, onClick, }: { icon?: React.ReactNode; color?: string | null; children: React.ReactNode; onClick: () => void }) { return ( ); }