@@ -33,6 +33,7 @@ import { type FeedbackType } from "~/routes/resources.feedback";
3333import { cn } from "~/utils/cn" ;
3434import {
3535 accountPath ,
36+ adminPath ,
3637 logoutPath ,
3738 newOrganizationPath ,
3839 newProjectPath ,
@@ -76,6 +77,7 @@ import { HelpAndFeedback } from "./HelpAndFeedbackPopover";
7677import { SideMenuHeader } from "./SideMenuHeader" ;
7778import { SideMenuItem } from "./SideMenuItem" ;
7879import { SideMenuSection } from "./SideMenuSection" ;
80+ import { useHasAdminAccess } from "~/hooks/useUser" ;
7981
8082type SideMenuUser = Pick < User , "email" | "admin" > & { isImpersonating : boolean } ;
8183export type SideMenuProject = Pick <
@@ -106,6 +108,7 @@ export function SideMenu({
106108 const currentPlan = useCurrentPlan ( ) ;
107109 const { isConnected } = useDevPresence ( ) ;
108110 const isFreeUser = currentPlan ?. v3Subscription ?. isPaying === false ;
111+ const isAdmin = useHasAdminAccess ( ) ;
109112
110113 useEffect ( ( ) => {
111114 const handleScroll = ( ) => {
@@ -130,7 +133,8 @@ export function SideMenu({
130133 < div
131134 className = { cn (
132135 "flex items-center justify-between overflow-hidden border-b px-1 py-1 transition duration-300" ,
133- showHeaderDivider ? "border-grid-bright" : "border-transparent"
136+ showHeaderDivider ? "border-grid-bright" : "border-transparent" ,
137+ user . isImpersonating && "rounded-md border border-dashed border-amber-400"
134138 ) }
135139 >
136140 < ProjectSelector
@@ -139,6 +143,23 @@ export function SideMenu({
139143 project = { project }
140144 user = { user }
141145 />
146+ { isAdmin && (
147+ < TooltipProvider disableHoverableContent = { true } >
148+ < Tooltip >
149+ < TooltipTrigger >
150+ < LinkButton
151+ variant = "minimal/medium"
152+ to = { adminPath ( ) }
153+ TrailingIcon = { Cog8ToothIcon }
154+ />
155+ </ TooltipTrigger >
156+ < TooltipContent side = "bottom" className = { "text-xs" } >
157+ Admin dashboard
158+ </ TooltipContent >
159+ </ Tooltip >
160+ </ TooltipProvider >
161+ ) }
162+ { user . isImpersonating && < ImpersonationBanner /> }
142163 </ div >
143164 < div
144165 className = "overflow-hidden overflow-y-auto pt-2 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-charcoal-600"
@@ -319,10 +340,7 @@ function ProjectSelector({
319340 < PopoverArrowTrigger
320341 isOpen = { isOrgMenuOpen }
321342 overflowHidden
322- className = { cn (
323- "h-8 w-full justify-between py-1 pl-1.5" ,
324- user . isImpersonating && "border border-dashed border-amber-400"
325- ) }
343+ className = "h-8 w-full justify-between py-1 pl-1.5"
326344 >
327345 < span className = "flex items-center gap-1.5 overflow-hidden" >
328346 < Avatar avatar = { organization . avatar } size = { 1.25 } orgName = { organization . title } />
@@ -406,19 +424,24 @@ function ProjectSelector({
406424 < PopoverMenuItem to = { newProjectPath ( organization ) } title = "New project" icon = { PlusIcon } />
407425 </ div >
408426 < div className = "border-t border-charcoal-700 p-1" >
409- < SwitchOrganizations organizations = { organizations } organization = { organization } />
427+ { organizations . length > 1 ? (
428+ < SwitchOrganizations organizations = { organizations } organization = { organization } />
429+ ) : (
430+ < PopoverMenuItem
431+ to = { newOrganizationPath ( ) }
432+ title = "New organization"
433+ icon = { PlusIcon }
434+ leadingIconClassName = "text-text-dimmed"
435+ />
436+ ) }
410437 </ div >
411438 < div className = "border-t border-charcoal-700 p-1" >
412439 < PopoverMenuItem
413440 to = { accountPath ( ) }
414441 title = "Account"
415442 icon = { UserProfilePhoto }
416- leadingIconClassName = { cn (
417- "text-text-dimmed rounded-full border border-transparent" ,
418- user . isImpersonating && "rounded-full border-yellow-500"
419- ) }
443+ leadingIconClassName = "text-text-dimmed rounded-full border border-transparent"
420444 />
421- { user . isImpersonating && < ImpersonationBanner /> }
422445 </ div >
423446 < div className = "border-t border-charcoal-700 p-1" >
424447 < PopoverMenuItem
@@ -513,7 +536,7 @@ function SwitchOrganizations({
513536 < div className = "border-t border-charcoal-700 p-1" >
514537 < PopoverMenuItem
515538 to = { newOrganizationPath ( ) }
516- title = "New Organization "
539+ title = "New organization "
517540 icon = { PlusIcon }
518541 leadingIconClassName = "text-text-dimmed"
519542 />
0 commit comments