| | |
| | import React, { useState, useRef, useEffect } from "react"; |
| |
|
| | export default function UserMenu({ name, email, onLogout }) { |
| | const [open, setOpen] = useState(false); |
| | const ref = useRef(null); |
| |
|
| | useEffect(() => { |
| | function handleClickOutside(e) { |
| | if (ref.current && !ref.current.contains(e.target)) { |
| | setOpen(false); |
| | } |
| | } |
| | document.addEventListener("mousedown", handleClickOutside); |
| | return () => document.removeEventListener("mousedown", handleClickOutside); |
| | }, []); |
| |
|
| | const initial = |
| | (name && name.trim().charAt(0).toUpperCase()) || |
| | (email && email.trim().charAt(0).toUpperCase()) || |
| | "?"; |
| |
|
| | return ( |
| | <div className="relative" ref={ref}> |
| | <button |
| | type="button" |
| | onClick={() => setOpen((v) => !v)} |
| | className="inline-flex items-center gap-2 rounded-full border border-slate-200 bg-white px-3 py-1.5 text-xs text-slate-700 hover:bg-slate-50" |
| | > |
| | <span className="inline-flex items-center justify-center h-6 w-6 rounded-full bg-slate-100 text-[11px] font-semibold text-slate-700"> |
| | {initial} |
| | </span> |
| | <span className="hidden sm:inline max-w-[120px] truncate"> |
| | {email || name || "Account"} |
| | </span> |
| | <span className="text-[10px] text-slate-400">▼</span> |
| | </button> |
| | |
| | {open && ( |
| | <div className="absolute right-0 mt-2 w-40 rounded-lg border border-slate-200 bg-white shadow-lg text-xs text-slate-800 z-50"> |
| | <div className="px-3 py-2 border-b border-slate-100"> |
| | <div className="font-semibold truncate"> |
| | {name || "User"} |
| | </div> |
| | {email && ( |
| | <div className="text-[11px] text-slate-500 truncate"> |
| | {email} |
| | </div> |
| | )} |
| | </div> |
| | {/* Extra nav items can be added here later */} |
| | <button |
| | type="button" |
| | onClick={() => { |
| | setOpen(false); |
| | onLogout && onLogout(); |
| | }} |
| | className="w-full text-left px-3 py-2 hover:bg-slate-50 text-[11px]" |
| | > |
| | Log out |
| | </button> |
| | </div> |
| | )} |
| | </div> |
| | ); |
| | } |
| |
|