78 lines
3.4 KiB
TypeScript
78 lines
3.4 KiB
TypeScript
"use client";
|
|
|
|
import { useState, useRef, useEffect } from 'react';
|
|
import Link from 'next/link';
|
|
import { User, Settings, LogOut, ChevronDown } from 'lucide-react';
|
|
|
|
interface UserMenuProps {
|
|
email: string | undefined;
|
|
}
|
|
|
|
export default function UserMenu({ email }: UserMenuProps) {
|
|
const [isOpen, setIsOpen] = useState(false);
|
|
const menuRef = useRef<HTMLDivElement>(null);
|
|
|
|
// Close on click outside
|
|
useEffect(() => {
|
|
function handleClickOutside(event: MouseEvent) {
|
|
if (menuRef.current && !menuRef.current.contains(event.target as Node)) {
|
|
setIsOpen(false);
|
|
}
|
|
}
|
|
document.addEventListener("mousedown", handleClickOutside);
|
|
return () => {
|
|
document.removeEventListener("mousedown", handleClickOutside);
|
|
};
|
|
}, []);
|
|
|
|
return (
|
|
<div className="relative" ref={menuRef}>
|
|
<button
|
|
onClick={() => setIsOpen(!isOpen)}
|
|
className="flex items-center gap-3 focus:outline-none group cursor-pointer"
|
|
>
|
|
<div className="hidden sm:flex flex-col items-end mr-1">
|
|
<span className="text-sm text-white font-medium group-hover:text-primary transition-colors">{email?.split('@')[0]}</span>
|
|
</div>
|
|
<div className="h-9 w-9 rounded-full bg-gray-800 flex items-center justify-center text-gray-300 border border-gray-700 group-hover:border-primary group-hover:text-primary transition-all">
|
|
<User size={18} />
|
|
</div>
|
|
<ChevronDown size={14} className={`text-gray-500 group-hover:text-primary transition-all duration-200 ${isOpen ? 'rotate-180' : ''}`} />
|
|
</button>
|
|
|
|
{isOpen && (
|
|
<div className="absolute right-0 mt-2 w-56 bg-[#0B0F17] border border-gray-800 rounded-xl shadow-2xl py-1 z-50 animate-in fade-in zoom-in-95 duration-100 overflow-hidden ring-1 ring-white/5">
|
|
<div className="px-4 py-3 border-b border-gray-800 bg-gray-900/50 sm:hidden">
|
|
<p className="text-sm text-white font-medium truncate">{email}</p>
|
|
</div>
|
|
|
|
<div className="p-1">
|
|
<Link
|
|
href="/app/settings"
|
|
className="flex items-center gap-2 px-3 py-2 text-sm text-gray-300 hover:text-white hover:bg-gray-800 rounded-lg transition-colors"
|
|
onClick={() => setIsOpen(false)}
|
|
>
|
|
<Settings size={16} />
|
|
Settings
|
|
</Link>
|
|
</div>
|
|
|
|
<div className="h-px bg-gray-800 my-1 mx-1"></div>
|
|
|
|
<div className="p-1">
|
|
<form action="/auth/signout" method="post">
|
|
<button
|
|
type="submit"
|
|
className="w-full flex items-center gap-2 px-3 py-2 text-sm text-red-400 hover:text-red-300 hover:bg-red-900/20 rounded-lg transition-colors text-left"
|
|
>
|
|
<LogOut size={16} />
|
|
Sign Out
|
|
</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|