ADD Dropdown component for user actions
This commit is contained in:
65
frontend/src/components/Dropdown.tsx
Normal file
65
frontend/src/components/Dropdown.tsx
Normal 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 };
|
||||
@@ -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>
|
||||
) :
|
||||
(
|
||||
|
||||
Reference in New Issue
Block a user