import { t } from "@lingui/core/macro"; import { useEffect, useRef } from "react"; import { HiLink, HiOutlineCalendar, HiOutlineDocumentDuplicate, HiOutlineTag, HiOutlineTrash, HiOutlineUserGroup, HiOutlineArrowRightCircle, } from "react-icons/hi2"; export type CardContextMenuAction = | "members" | "move" | "labels" | "dueDate" | "copyLink" | "duplicate" | "delete"; interface CardContextMenuProps { x: number; y: number; onClose: () => void; onAction: (action: CardContextMenuAction) => void; canEdit: boolean; } const MENU_ITEMS: { action: CardContextMenuAction; label: string; icon: React.ReactNode; requiresEdit: boolean; }[] = [ { action: "members", label: t`Manage members`, icon: , requiresEdit: true, }, { action: "move", label: t`Move to another list`, icon: , requiresEdit: true, }, { action: "labels", label: t`Add / edit label`, icon: , requiresEdit: true, }, { action: "dueDate", label: t`Set due date`, icon: , requiresEdit: true, }, { action: "copyLink", label: t`Copy link to card`, icon: , requiresEdit: false, }, { action: "duplicate", label: t`Duplicate card`, icon: , requiresEdit: true, }, { action: "delete", label: t`Delete card`, icon: , requiresEdit: true, }, ]; export function CardContextMenu({ x, y, onClose, onAction, canEdit, }: CardContextMenuProps) { const menuRef = useRef(null); useEffect(() => { const handleClickOutside = (e: MouseEvent) => { if (menuRef.current && !menuRef.current.contains(e.target as Node)) { onClose(); } }; const handleEscape = (e: KeyboardEvent) => { if (e.key === "Escape") onClose(); }; document.addEventListener("mousedown", handleClickOutside); document.addEventListener("keydown", handleEscape); return () => { document.removeEventListener("mousedown", handleClickOutside); document.removeEventListener("keydown", handleEscape); }; }, [onClose]); const items = MENU_ITEMS.filter((item) => !item.requiresEdit || canEdit); return (
{items.map(({ action, label, icon }) => ( ))}
); }