From eb902aa52aed8df0919a98bc8ff4cb4adaa05390 Mon Sep 17 00:00:00 2001 From: Matthew Meszaros Date: Sat, 23 May 2026 10:40:32 +0000 Subject: [PATCH] =?UTF-8?q?refactor(web):=20UserNav=20menu=20onto=20Popove?= =?UTF-8?q?rMenu=20=E2=80=94=20last=20shadcn=20dropdown=20is=20gone?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Was still using the shadcn DropdownMenu — different border + shadow, different open animation, different item heights. Stood out against every other popover in the dashboard now that OrgSwitcher moved over. Switched to PopoverMenu with side="top" (sidebar lives at the bottom, menu has to rise) and align="start". Identity block (name + email) becomes a short header inside the popover with the same hairline + shadow as the rest. Settings / Billing / Team use PopoverMenuItem with 12px icons; Log out is the danger variant so it reads as a destructive action (red text on hover) without needing its own treatment. That's the whole dashboard on one popover primitive now — folders, sort, accounts, schedule, org switcher, user menu — same micro- animation, same surface. --- web/src/components/layout/UserNav.tsx | 107 +++++++++++++++----------- 1 file changed, 60 insertions(+), 47 deletions(-) diff --git a/web/src/components/layout/UserNav.tsx b/web/src/components/layout/UserNav.tsx index 9d2dd42f..70ff7353 100644 --- a/web/src/components/layout/UserNav.tsx +++ b/web/src/components/layout/UserNav.tsx @@ -1,23 +1,27 @@ -// User menu — sits at the very bottom of the sidebar on the sky chrome. -// Styled for the dark background; the dropdown itself is light because -// it overlays the content area. +// User menu — bottom of the sidebar. +// +// Moved off the shadcn DropdownMenu onto the same PopoverMenu primitive +// every other dropdown in the dashboard uses (folders, sort, accounts, +// org switcher). One animation curve, one surface, one set of styles. +// +// Opens upward (side="top") from the trigger so the popover settles up +// from the bottom of the sidebar instead of falling off-screen. -import { Link, useNavigate } from "react-router-dom"; +import { useNavigate } from "react-router-dom"; import { CreditCardIcon, LogOutIcon, SettingsIcon, UsersIcon, } from "lucide-react"; -import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuGroup, - DropdownMenuItem, - DropdownMenuSeparator, - DropdownMenuTrigger, -} from "@/components/ui/dropdown-menu"; import { useAppStore } from "@/stores"; +import { + PopoverMenu, + PopoverMenuContent, + PopoverMenuItem, + PopoverMenuSeparator, + PopoverMenuTrigger, +} from "@/components/ui/popover-menu"; export function UserNav() { const navigate = useNavigate(); @@ -39,8 +43,8 @@ export function UserNav() { : user.email; return ( - - + + - - -
-
{displayName}
-
{user.email}
+ + + + {/* Identity block — same name/email row but inside the + PopoverMenu chrome so it inherits the consistent + hairline border + shadow. */} +
+
+ {displayName} +
+
+ {user.email} +
- - - - - - Settings - - - - - - Billing - - - - - - Team - - - - - - - Log out - - - + + navigate("/app/settings")} + icon={} + > + Settings + + navigate("/app/billing")} + icon={} + > + Billing + + navigate("/app/team")} + icon={} + > + Team + + + } + danger + > + Log out + +
+ ); }