an app to share curated trails sidetrail.app
1

Configure Feed

Select the types of activity you want to include in your feed.

at main 1.9 kB View raw
1"use client"; 2 3import { usePathname } from "next/navigation"; 4import Link from "next/link"; 5import * as DropdownMenu from "@radix-ui/react-dropdown-menu"; 6import { useLoginModal } from "@/app/LoginModalContext"; 7import { logout } from "@/auth/actions"; 8import "./UserMenu.css"; 9import { Suspense } from "react"; 10 11interface UserMenuClientProps { 12 user: { 13 handle: string; 14 avatar?: string; 15 } | null; 16} 17 18export function UserMenuClient({ user }: UserMenuClientProps) { 19 const { openLoginModal } = useLoginModal(); 20 21 if (!user) { 22 return ( 23 <button onClick={openLoginModal} className="UserMenu-loginButton"> 24 log in 25 </button> 26 ); 27 } 28 29 return ( 30 <DropdownMenu.Root> 31 <DropdownMenu.Trigger asChild> 32 <button className="UserMenu-trigger" aria-label="User menu"> 33 {user.avatar ? ( 34 <img src={user.avatar} alt={user.handle} className="UserMenu-avatar" /> 35 ) : ( 36 <span className="UserMenu-avatarFallback">{user.handle[0].toUpperCase()}</span> 37 )} 38 </button> 39 </DropdownMenu.Trigger> 40 <Suspense fallback={null}> 41 <UserMenuDropdown handle={user.handle} /> 42 </Suspense> 43 </DropdownMenu.Root> 44 ); 45} 46 47function UserMenuDropdown({ handle }: { handle: string }) { 48 const pathname = usePathname(); 49 return ( 50 <DropdownMenu.Portal> 51 <DropdownMenu.Content className="UserMenu-content" align="end" sideOffset={8}> 52 <DropdownMenu.Item asChild> 53 <Link href={`/@${handle}`} className="UserMenu-item"> 54 profile 55 </Link> 56 </DropdownMenu.Item> 57 58 <DropdownMenu.Separator className="UserMenu-separator" /> 59 60 <DropdownMenu.Item className="UserMenu-item" onSelect={() => logout(pathname)}> 61 log out 62 </DropdownMenu.Item> 63 </DropdownMenu.Content> 64 </DropdownMenu.Portal> 65 ); 66}