@@ -33,6 +33,7 @@ import { type FeedbackType } from "~/routes/resources.feedback";
33
33
import { cn } from "~/utils/cn" ;
34
34
import {
35
35
accountPath ,
36
+ adminPath ,
36
37
logoutPath ,
37
38
newOrganizationPath ,
38
39
newProjectPath ,
@@ -76,6 +77,7 @@ import { HelpAndFeedback } from "./HelpAndFeedbackPopover";
76
77
import { SideMenuHeader } from "./SideMenuHeader" ;
77
78
import { SideMenuItem } from "./SideMenuItem" ;
78
79
import { SideMenuSection } from "./SideMenuSection" ;
80
+ import { useHasAdminAccess } from "~/hooks/useUser" ;
79
81
80
82
type SideMenuUser = Pick < User , "email" | "admin" > & { isImpersonating : boolean } ;
81
83
export type SideMenuProject = Pick <
@@ -106,6 +108,7 @@ export function SideMenu({
106
108
const currentPlan = useCurrentPlan ( ) ;
107
109
const { isConnected } = useDevPresence ( ) ;
108
110
const isFreeUser = currentPlan ?. v3Subscription ?. isPaying === false ;
111
+ const isAdmin = useHasAdminAccess ( ) ;
109
112
110
113
useEffect ( ( ) => {
111
114
const handleScroll = ( ) => {
@@ -130,7 +133,8 @@ export function SideMenu({
130
133
< div
131
134
className = { cn (
132
135
"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"
134
138
) }
135
139
>
136
140
< ProjectSelector
@@ -139,6 +143,23 @@ export function SideMenu({
139
143
project = { project }
140
144
user = { user }
141
145
/>
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 /> }
142
163
</ div >
143
164
< div
144
165
className = "overflow-hidden overflow-y-auto pt-2 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-charcoal-600"
@@ -319,10 +340,7 @@ function ProjectSelector({
319
340
< PopoverArrowTrigger
320
341
isOpen = { isOrgMenuOpen }
321
342
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"
326
344
>
327
345
< span className = "flex items-center gap-1.5 overflow-hidden" >
328
346
< Avatar avatar = { organization . avatar } size = { 1.25 } orgName = { organization . title } />
@@ -406,19 +424,24 @@ function ProjectSelector({
406
424
< PopoverMenuItem to = { newProjectPath ( organization ) } title = "New project" icon = { PlusIcon } />
407
425
</ div >
408
426
< 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
+ ) }
410
437
</ div >
411
438
< div className = "border-t border-charcoal-700 p-1" >
412
439
< PopoverMenuItem
413
440
to = { accountPath ( ) }
414
441
title = "Account"
415
442
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"
420
444
/>
421
- { user . isImpersonating && < ImpersonationBanner /> }
422
445
</ div >
423
446
< div className = "border-t border-charcoal-700 p-1" >
424
447
< PopoverMenuItem
@@ -513,7 +536,7 @@ function SwitchOrganizations({
513
536
< div className = "border-t border-charcoal-700 p-1" >
514
537
< PopoverMenuItem
515
538
to = { newOrganizationPath ( ) }
516
- title = "New Organization "
539
+ title = "New organization "
517
540
icon = { PlusIcon }
518
541
leadingIconClassName = "text-text-dimmed"
519
542
/>
0 commit comments