ADD Dropdown component for user actions

This commit is contained in:
2025-06-24 22:52:24 +02:00
parent d3dce9ec25
commit 38f3778a6b
8 changed files with 503 additions and 36 deletions

View File

@@ -0,0 +1,65 @@
import React, {useEffect, useRef} from "react";
import clsx from "clsx";
type DropdownItemProps = {
item: string;
onClick: (item: string) => void;
className?: string;
}
const DropdownItem = ({ item, onClick, className }: DropdownItemProps) => {
return (
<li className={clsx(className, "cursor-pointer hover:bg-gray-100 px-4 py-2 align-middle")} onClick={() => onClick(item)}>
{item}
</li>
);
}
type DropdownProps = {
label: string;
children: React.ReactNode;
className?: string;
}
const Dropdown = ({ label, children, className }: DropdownProps) => {
const [isOpen, setIsOpen] = React.useState(false);
const ref = useRef<HTMLDivElement>(null);
const toggleDropdown = () => {
setIsOpen(!isOpen);
};
useEffect(() => {
function handleClickOutside(event: { target: any; }) {
if (ref.current && !ref.current.contains(event.target)) {
setIsOpen(false);
}
}
document.addEventListener('mousedown', handleClickOutside);
return () => {
document.removeEventListener('mousedown', handleClickOutside);
};
}, []);
return (
<div className={clsx(className, "relative inline-block text-left")}
ref={ref}>
<button
onClick={toggleDropdown}
className="inline-flex justify-between w-full rounded-xl border border-gray-300 shadow-sm px-4 py-2 bg-white text-sm font-medium text-gray-600 hover:bg-gray-50"
>
{label}
</button>
{isOpen && (
<ul className="absolute w-48 origin-top-right rounded-md bg-white shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none">
{children}
</ul>
)}
</div>
);
};
export { Dropdown, DropdownItem };

View File

@@ -2,6 +2,7 @@ import { Menu, X } from 'lucide-react';
import MenuButton from "./buttons/MenuButton.tsx";
import clsx from "clsx";
import type {User} from "../utils/types.ts";
import { Dropdown, DropdownItem } from "./Dropdown.tsx";
type props = {
sidebarToggled: boolean;
@@ -23,13 +24,22 @@ const Topbar = ({sidebarToggled, setSidebarToggled, user, className}: props) =>
{ user ? (
<div>
<MenuButton className={"w-40 text-gray-600"}>
{user.name}
</MenuButton>
<MenuButton className={"w-20 text-gray-600"}
onClick={() => globalThis.location.href = logoutUrl}>
Logout
</MenuButton>
<img
className={"w-8 h-8 rounded-full inline-block mr-2"}
src={user.profilePicture}
referrerPolicy="no-referrer"
/>
<Dropdown label={user.name}>
<DropdownItem item="Logout" onClick={() => globalThis.location.href = logoutUrl} className="text-red-600" />
</Dropdown>
{/*<Dropdown label={user.name}>*/}
{/* <DropdownItem>*/}
{/* <a href={logoutUrl}>Logout</a>*/}
{/* </DropdownItem>*/}
{/*</Dropdown>*/}
</div>
) :
(