159 lines
4.7 KiB
TypeScript
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>
|
|
);
|
|
};
|