Sage100/src/components/DropdownMenu.tsx
2026-01-20 11:05:50 +03:00

159 lines
4.7 KiB
TypeScript

import { useState, useEffect, useRef } from 'react';
import { Edit, Download, FileSignature, MoreVertical, Trash2, CircleDot, Copy } from 'lucide-react';
export const DropdownMenuTable = ({
row,
onEdit,
onStatus,
onESign,
onDownload,
onDelete,
onDulipcate
}: {
row: any;
onEdit?: () => void;
onStatus?: () => void;
onESign?: () => void;
onDownload?: () => void;
onDelete?: () => void;
onDulipcate?: () => void;
}) => {
const [isOpen, setIsOpen] = useState(false);
const dropdownRef = useRef<HTMLDivElement>(null);
// Fermer le menu quand on clique à l'extérieur
useEffect(() => {
const handleClickOutside = (event: MouseEvent) => {
if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {
setIsOpen(false);
}
};
if (isOpen) {
document.addEventListener('mousedown', handleClickOutside);
}
return () => {
document.removeEventListener('mousedown', handleClickOutside);
};
}, [isOpen]);
return (
<div className="relative bg" ref={dropdownRef}>
<button
onClick={(e) => {
e.stopPropagation();
setIsOpen(!isOpen);
}}
className="p-2 hover:bg-gray-100 dark:hover:bg-gray-800 rounded-lg transition-colors text-gray-600 dark:text-gray-400"
>
<MoreVertical className="w-4 h-4" />
</button>
{isOpen && (
<div className="absolute right-0 mt-2 w-56 bg-white dark:bg-gray-950 rounded-xl shadow-xl border border-gray-200 dark:border-gray-800 z-[9999] p-1">
{
onEdit && (
<button
onClick={(e) => {
e.stopPropagation();
onEdit?.();
setIsOpen(false);
}}
className="w-full text-left px-3 py-2 text-sm hover:bg-gray-50 dark:hover:bg-gray-900 rounded-lg flex items-center gap-2 transition-colors"
>
<Edit className="w-4 h-4" /> Modifier
</button>
)
}
{
onDulipcate && (
<button
onClick={(e) => {
e.stopPropagation();
onDulipcate?.();
setIsOpen(false);
}}
className="w-full text-left px-3 py-2 text-sm hover:bg-gray-50 dark:hover:bg-gray-900 rounded-lg flex items-center gap-2 transition-colors"
>
<Copy className="w-4 h-4" /> Dupliquer
</button>
)
}
{
onStatus && (
<button
onClick={(e) => {
e.stopPropagation();
onStatus?.();
setIsOpen(false);
}}
className="w-full text-left px-3 py-2 text-sm hover:bg-gray-50 dark:hover:bg-gray-900 rounded-lg flex items-center gap-2 transition-colors"
>
<CircleDot className="w-4 h-4" /> Changer le status
</button>
)
}
{
onESign && (
<button
onClick={(e) => {
e.stopPropagation();
onESign?.();
setIsOpen(false);
}}
className="w-full text-left px-3 py-2 text-sm hover:bg-gray-50 dark:hover:bg-gray-900 rounded-lg flex items-center gap-2 text-blue-600 transition-colors"
>
<FileSignature className="w-4 h-4" /> Signature Électronique
</button>
)
}
{
onDownload && (
<button
onClick={(e) => {
e.stopPropagation();
onDownload?.();
setIsOpen(false);
}}
className="w-full text-left px-3 py-2 text-sm hover:bg-gray-50 dark:hover:bg-gray-900 rounded-lg flex items-center gap-2 transition-colors"
>
<Download className="w-4 h-4" /> Télécharger PDF
</button>
)
}
{
onDelete && (
<>
<div className="h-px bg-gray-100 dark:bg-gray-800 my-1" />
<button
onClick={(e) => {
e.stopPropagation();
onDelete?.();
setIsOpen(false);
}}
className="w-full text-left px-3 py-2 text-sm hover:bg-red-50 dark:hover:bg-red-900/20 text-red-600 rounded-lg flex items-center gap-2 transition-colors"
>
<Trash2 className="w-4 h-4" /> Supprimer
</button>
</>
)
}
</div>
)}
</div>
);
};