mirror of
https://git.v0id.ovh/n3wt-innov/n3wt-school.git
synced 2026-01-29 07:53:23 +00:00
81 lines
2.3 KiB
JavaScript
81 lines
2.3 KiB
JavaScript
// Composant générique pour les menus dropdown
|
|
import { useRouter } from 'next/navigation';
|
|
import React, { useState, useEffect, useRef } from 'react';
|
|
|
|
const DropdownMenu = ({
|
|
buttonContent,
|
|
items,
|
|
buttonClassName,
|
|
menuClassName,
|
|
dropdownOpen: propDropdownOpen,
|
|
setDropdownOpen: propSetDropdownOpen,
|
|
}) => {
|
|
const [dropdownOpen, setDropdownOpen] = useState(false);
|
|
const menuRef = useRef(null);
|
|
const router = useRouter();
|
|
const isControlled =
|
|
propDropdownOpen !== undefined && propSetDropdownOpen !== undefined;
|
|
const actualDropdownOpen = isControlled ? propDropdownOpen : dropdownOpen;
|
|
const actualSetDropdownOpen = isControlled
|
|
? propSetDropdownOpen
|
|
: setDropdownOpen;
|
|
|
|
const handleClickOutside = (event) => {
|
|
if (menuRef.current && !menuRef.current.contains(event.target)) {
|
|
actualSetDropdownOpen(false);
|
|
}
|
|
};
|
|
|
|
useEffect(() => {
|
|
document.addEventListener('mousedown', handleClickOutside);
|
|
return () => {
|
|
document.removeEventListener('mousedown', handleClickOutside);
|
|
};
|
|
}, []);
|
|
|
|
const renderMenuItem = (item, index) => {
|
|
// Si l'élément est de type 'info', afficher simplement le contenu
|
|
if (item.type === 'info') {
|
|
return <div key={index}>{item.content}</div>;
|
|
}
|
|
|
|
// Si l'élément est de type 'separator', afficher le séparateur
|
|
if (item.type === 'separator') {
|
|
return <div key={index}>{item.content}</div>;
|
|
}
|
|
|
|
// Par défaut ou si l'élément est de type 'item', afficher un bouton cliquable
|
|
return (
|
|
<button
|
|
key={index}
|
|
className="block w-full px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 flex items-center gap-2"
|
|
onClick={() => {
|
|
item.onClick();
|
|
actualSetDropdownOpen(false);
|
|
}}
|
|
>
|
|
{item.icon && <item.icon className="w-4 h-4" />}
|
|
<span className="flex items-center justify-center">{item.label}</span>
|
|
</button>
|
|
);
|
|
};
|
|
|
|
return (
|
|
<div className="relative" ref={menuRef}>
|
|
<button
|
|
className={buttonClassName}
|
|
onClick={() => actualSetDropdownOpen(!actualDropdownOpen)}
|
|
>
|
|
{buttonContent}
|
|
</button>
|
|
{actualDropdownOpen && (
|
|
<div className={menuClassName}>
|
|
{items.map((item, index) => renderMenuItem(item, index))}
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default DropdownMenu;
|