import { createRef, MouseEventHandler, useEffect, useState } from "react"; import { useSession } from "./Session"; import { User } from "./api"; interface ContextMenuItem { label: string; onClick: () => void; } const UserInfo = (user: User) => { return (
username:
{user?.username}
display name:
{user?.display_name}
number:
{user?.number ? user?.number : "-"}
email:
{user?.email ? user?.email : "-"}
); }; export default function Avatar() { const { user, onLogout } = useSession(); const [contextMenu, setContextMenu] = useState<{ open: boolean; allowOpen: boolean; mouseX: number; mouseY: number; }>({ open: false, allowOpen: true, mouseX: 0, mouseY: 0 }); const contextMenuRef = createRef(); const avatarRef = createRef(); const contextMenuItems: ContextMenuItem[] = [ { label: "View Profile", onClick: handleViewProfile }, { label: "Logout", onClick: onLogout }, ]; const handleMenuClick: MouseEventHandler = (event) => { if (!contextMenu.allowOpen) return; event.preventDefault(); setContextMenu({ open: !contextMenu.open, allowOpen: contextMenu.allowOpen, mouseX: event.clientX + 4, mouseY: event.clientY + 2, }); }; useEffect(() => { if (contextMenu.open) { document.addEventListener("click", handleCloseContextMenuOutside); } return () => { document.removeEventListener("click", handleCloseContextMenuOutside); }; }, [contextMenu.open]); const handleMenuClose = () => { setContextMenu({ ...contextMenu, open: false }); setContextMenu((prevContextMenu) => ({ ...prevContextMenu, allowOpen: false, })); setTimeout(() => { setContextMenu((prevContextMenu) => ({ ...prevContextMenu, allowOpen: true, })); }, 100); }; const handleCloseContextMenuOutside: (event: MouseEvent) => void = (ev) => { if ( !( contextMenuRef.current?.contains(ev.target as Node) || avatarRef.current?.contains(ev.target as Node) ) ) handleMenuClose(); }; const [dialog, setDialog] = useState(<>); const dialogRef = createRef(); function handleViewProfile() { handleMenuClose(); if (user) { dialogRef.current?.showModal(); setDialog(UserInfo(user)); } } return (
{ if (contextMenu.open && event.target === avatarRef.current) { handleMenuClose(); } else { handleMenuClick(event); } }} ref={avatarRef} > 👤 {user?.username} {contextMenu.open && (
    {contextMenuItems.map((item, index) => (
  • { item.onClick(); handleMenuClose(); }} > {item.label}
  • ))}
)} { event.stopPropagation(); event.currentTarget.close(); }} > {dialog}
); }