Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
140 changes: 77 additions & 63 deletions src/components/org-switcher.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"use client"

import * as React from "react"
import Link from "next/link"
import { useRouter } from "next/navigation"
import {
IconBuilding,
Expand Down Expand Up @@ -76,71 +77,84 @@ export function OrgSwitcher({
return (
<SidebarMenu>
<SidebarMenuItem>
<DropdownMenu>
<DropdownMenuTrigger asChild disabled={!hasOrgs}>
<SidebarMenuButton
size="lg"
className={cn(
"data-[state=open]:bg-sidebar-accent",
"data-[state=open]:text-sidebar-accent-foreground",
)}
>
<span
aria-label="Compass"
className="!size-5 shrink-0 block bg-current"
style={{
maskImage: "url(/logo-black.png)",
maskSize: "contain",
maskRepeat: "no-repeat",
WebkitMaskImage: "url(/logo-black.png)",
WebkitMaskSize: "contain",
WebkitMaskRepeat: "no-repeat",
}}
/>
<span className="truncate text-sm font-semibold">
{displayName}
</span>
{hasOrgs && (
<IconSelector
className="ml-auto size-4 shrink-0 opacity-50"
/>
)}
</SidebarMenuButton>
</DropdownMenuTrigger>
<DropdownMenuContent
className="w-(--radix-dropdown-menu-trigger-width) min-w-56 rounded-lg"
side={isMobile ? "bottom" : "right"}
align="start"
sideOffset={4}
<SidebarMenuButton
size="lg"
className="gap-0 px-0 hover:bg-transparent active:bg-transparent"
asChild={false}
>
<Link
href="/dashboard"
className="flex shrink-0 items-center justify-center size-8 rounded-md hover:bg-sidebar-accent transition-colors"
aria-label="Compass home"
>
{orgs.map((org, i) => {
const isActive = org.id === activeOrgId
const OrgIcon =
org.type === "personal" ? IconUser : IconBuilding
<span
className="!size-5 block bg-current"
style={{
maskImage: "url(/logo-black.png)",
maskSize: "contain",
maskRepeat: "no-repeat",
WebkitMaskImage: "url(/logo-black.png)",
WebkitMaskSize: "contain",
WebkitMaskRepeat: "no-repeat",
}}
/>
</Link>
<DropdownMenu>
<DropdownMenuTrigger asChild disabled={!hasOrgs}>
<button
className={cn(
"flex min-w-0 flex-1 items-center gap-1 rounded-md px-2 py-1 text-left",
"hover:bg-sidebar-accent transition-colors",
"data-[state=open]:bg-sidebar-accent",
"data-[state=open]:text-sidebar-accent-foreground",
!hasOrgs && "cursor-default hover:bg-transparent",
)}
>
<span className="truncate text-sm font-semibold">
{displayName}
</span>
{hasOrgs && (
<IconSelector
className="size-4 shrink-0 opacity-50"
/>
)}
</button>
</DropdownMenuTrigger>
<DropdownMenuContent
className="w-(--radix-dropdown-menu-trigger-width) min-w-56 rounded-lg"
side={isMobile ? "bottom" : "right"}
align="start"
sideOffset={4}
>
{orgs.map((org, i) => {
const isActive = org.id === activeOrgId
const OrgIcon =
org.type === "personal" ? IconUser : IconBuilding

return (
<React.Fragment key={org.id}>
{i > 0 && <DropdownMenuSeparator />}
<DropdownMenuItem
onClick={() => void handleOrgSwitch(org.id)}
disabled={isLoading}
className="gap-2 px-2 py-1.5"
>
<OrgIcon className="size-4 shrink-0 opacity-60" />
<span className="truncate font-medium">
{org.name}
</span>
{isActive && (
<IconCheck
className="ml-auto size-4 shrink-0 text-primary"
/>
)}
</DropdownMenuItem>
</React.Fragment>
)
})}
</DropdownMenuContent>
</DropdownMenu>
return (
<React.Fragment key={org.id}>
{i > 0 && <DropdownMenuSeparator />}
<DropdownMenuItem
onClick={() => void handleOrgSwitch(org.id)}
disabled={isLoading}
className="gap-2 px-2 py-1.5"
>
<OrgIcon className="size-4 shrink-0 opacity-60" />
<span className="truncate font-medium">
{org.name}
</span>
{isActive && (
<IconCheck
className="ml-auto size-4 shrink-0 text-primary"
/>
)}
</DropdownMenuItem>
</React.Fragment>
)
})}
</DropdownMenuContent>
</DropdownMenu>
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenu>
)
Expand Down
Loading