{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "sidebar-06",
  "type": "registry:block",
  "title": "Sidebar Replacement",
  "description": "A sidebar replacement block.",
  "author": "ephraim duncan <https://ephraimduncan.com>",
  "registryDependencies": [
    "avatar",
    "dropdown-menu",
    "sidebar"
  ],
  "dependencies": [
    "@tabler/icons-react",
    "lucide-react"
  ],
  "files": [
    {
      "path": "content/components/sidebar/sidebar-06/app-sidebar.tsx",
      "type": "registry:component",
      "target": "components/sidebar-06/app-sidebar.tsx",
      "content": "'use client';\n\nimport {\n  IconActivityHeartbeat,\n  IconArchive,\n  IconArrowLeft,\n  IconBackground,\n  IconBellRinging,\n  IconBrandGoogle,\n  IconBrandMeta,\n  IconBrandNpm,\n  IconBrandOpenai,\n  IconBug,\n  IconChartBar,\n  IconChevronRight,\n  IconCloud,\n  IconDatabase,\n  IconFileText,\n  IconFolder,\n  IconFolders,\n  IconGitCommit,\n  IconGitMerge,\n  IconGitPullRequest,\n  IconHome,\n  IconKey,\n  IconLockExclamation,\n  IconLockPassword,\n  IconLogout,\n  IconNorthStar,\n  IconPackageExport,\n  IconPackages,\n  IconPasswordFingerprint,\n  IconPlayerPlay,\n  IconScanEye,\n  IconSettings,\n  IconShieldLock,\n  IconStar,\n  IconTarget,\n  IconTerminal2,\n  IconUser,\n  IconUserPlus,\n  IconWebhook,\n} from '@tabler/icons-react';\nimport type React from 'react';\nimport { useState } from 'react';\nimport { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';\nimport {\n  Sidebar,\n  SidebarContent,\n  SidebarFooter,\n  SidebarGroup,\n  SidebarGroupContent,\n  SidebarHeader,\n  SidebarMenu,\n  SidebarMenuBadge,\n  SidebarMenuButton,\n  SidebarMenuItem,\n} from '@/components/ui/sidebar';\nimport { cn } from '@/lib/utils';\nimport { TeamSwitcher } from '@/components/sidebar-06/team-switcher';\n\nconst data = {\n  teams: [\n    {\n      name: 'OpenAI',\n      logo: IconBrandOpenai,\n      plan: 'Enterprise',\n    },\n    {\n      name: 'Anthropic',\n      logo: IconNorthStar,\n      plan: 'Pro',\n    },\n    {\n      name: 'Google',\n      logo: IconBrandGoogle,\n      plan: 'Free',\n    },\n    {\n      name: 'Meta',\n      logo: IconBrandMeta,\n      plan: 'Free',\n    },\n  ],\n};\n\ninterface SidebarItem {\n  id: string;\n  label: string;\n  icon: React.ComponentType<{ className?: string }>;\n  badge?: string;\n  hasSubItems?: boolean;\n  route?: string;\n  subItems?: {\n    id: string;\n    label: string;\n    icon: React.ComponentType<{ className?: string }>;\n    route?: string;\n  }[];\n}\n\nconst sidebarItems: SidebarItem[] = [\n  {\n    id: 'overview',\n    label: 'Overview',\n    icon: IconHome,\n    hasSubItems: true,\n    subItems: [\n      {\n        id: 'dashboard',\n        label: 'Dashboard',\n        icon: IconChartBar,\n        route: '/overview/dashboard',\n      },\n      {\n        id: 'activity',\n        label: 'Activity',\n        icon: IconActivityHeartbeat,\n        route: '/overview/activity',\n      },\n      {\n        id: 'insights',\n        label: 'Insights',\n        icon: IconTarget,\n        route: '/overview/insights',\n      },\n    ],\n  },\n  {\n    id: 'repositories',\n    label: 'Repositories',\n    icon: IconFolders,\n    badge: '12',\n    hasSubItems: true,\n    subItems: [\n      {\n        id: 'all-repos',\n        label: 'All Repositories',\n        icon: IconFolder,\n        route: '/repositories',\n      },\n      {\n        id: 'starred',\n        label: 'Starred',\n        icon: IconStar,\n        route: '/repositories/starred',\n      },\n      {\n        id: 'archived',\n        label: 'Archived',\n        icon: IconArchive,\n        route: '/repositories/archived',\n      },\n    ],\n  },\n  {\n    id: 'pull-requests',\n    label: 'Pull Requests',\n    icon: IconGitPullRequest,\n    badge: '3',\n    hasSubItems: true,\n    subItems: [\n      {\n        id: 'open-prs',\n        label: 'Open',\n        icon: IconGitPullRequest,\n        route: '/pull-requests/open',\n      },\n      {\n        id: 'review-requests',\n        label: 'Review Requests',\n        icon: IconScanEye,\n        route: '/pull-requests/review',\n      },\n      {\n        id: 'merged',\n        label: 'Merged',\n        icon: IconGitMerge,\n        route: '/pull-requests/merged',\n      },\n    ],\n  },\n  {\n    id: 'issues',\n    label: 'Issues',\n    icon: IconBug,\n    badge: '7',\n    hasSubItems: true,\n    subItems: [\n      {\n        id: 'open-issues',\n        label: 'Open Issues',\n        icon: IconBug,\n        route: '/issues/open',\n      },\n      {\n        id: 'assigned',\n        label: 'Assigned to Me',\n        icon: IconUserPlus,\n        route: '/issues/assigned',\n      },\n      {\n        id: 'created',\n        label: 'Created by Me',\n        icon: IconGitCommit,\n        route: '/issues/created',\n      },\n    ],\n  },\n  {\n    id: 'actions',\n    label: 'Actions',\n    icon: IconBackground,\n    hasSubItems: true,\n    subItems: [\n      {\n        id: 'workflows',\n        label: 'Workflows',\n        icon: IconPlayerPlay,\n        route: '/actions/workflows',\n      },\n      {\n        id: 'runners',\n        label: 'Runners',\n        icon: IconTerminal2,\n        route: '/actions/runners',\n      },\n      {\n        id: 'deployments',\n        label: 'Deployments',\n        icon: IconCloud,\n        route: '/actions/deployments',\n      },\n    ],\n  },\n  {\n    id: 'packages',\n    label: 'Packages',\n    icon: IconPackages,\n    hasSubItems: true,\n    subItems: [\n      {\n        id: 'published',\n        label: 'Published',\n        icon: IconPackageExport,\n        route: '/packages/published',\n      },\n      {\n        id: 'container-registry',\n        label: 'Container Registry',\n        icon: IconDatabase,\n        route: '/packages/containers',\n      },\n      {\n        id: 'npm-packages',\n        label: 'npm Packages',\n        icon: IconBrandNpm,\n        route: '/packages/npm',\n      },\n    ],\n  },\n  {\n    id: 'security',\n    label: 'Security',\n    icon: IconLockPassword,\n    badge: '2',\n    hasSubItems: true,\n    subItems: [\n      {\n        id: 'alerts',\n        label: 'Security Alerts',\n        icon: IconLockExclamation,\n        route: '/security/alerts',\n      },\n      {\n        id: 'advisories',\n        label: 'Advisories',\n        icon: IconShieldLock,\n        route: '/security/advisories',\n      },\n      {\n        id: 'secrets',\n        label: 'Secrets',\n        icon: IconPasswordFingerprint,\n        route: '/security/secrets',\n      },\n    ],\n  },\n  {\n    id: 'settings',\n    label: 'Settings',\n    icon: IconSettings,\n    hasSubItems: true,\n    subItems: [\n      {\n        id: 'profile',\n        label: 'Profile',\n        icon: IconUser,\n        route: '/settings/profile',\n      },\n      {\n        id: 'notifications',\n        label: 'Notifications',\n        icon: IconBellRinging,\n        route: '/settings/notifications',\n      },\n      {\n        id: 'webhooks',\n        label: 'Webhooks',\n        icon: IconWebhook,\n        route: '/settings/webhooks',\n      },\n      {\n        id: 'api-keys',\n        label: 'API Keys',\n        icon: IconKey,\n        route: '/settings/api-keys',\n      },\n    ],\n  },\n  {\n    id: 'docs',\n    label: 'Documentation',\n    icon: IconFileText,\n    hasSubItems: false,\n    route: '/docs',\n  },\n];\n\nexport function AppSidebar() {\n  const [activeItem, setActiveItem] = useState<string | null>(null);\n  const [selectedSubItem, setSelectedSubItem] = useState<string | null>(null);\n\n  const activeItemData = sidebarItems.find((item) => item.id === activeItem);\n\n  const handleItemClick = (item: SidebarItem) => {\n    if (item.hasSubItems) {\n      setActiveItem(item.id);\n      setSelectedSubItem(null);\n    } else {\n      console.log(`[v0] Navigating to: ${item.route}`);\n    }\n  };\n\n  const handleSubItemClick = (subItem: { id: string; route?: string }) => {\n    setSelectedSubItem(selectedSubItem === subItem.id ? null : subItem.id);\n    if (subItem.route) {\n      console.log(`[v0] Navigating to: ${subItem.route}`);\n    }\n  };\n\n  const handleBackToMain = () => {\n    setActiveItem(null);\n    setSelectedSubItem(null);\n  };\n\n  return (\n    <div className=\"flex h-dvh bg-background\">\n      <Sidebar\n        className=\"w-64 border-r\"\n        collapsible=\"none\"\n        side=\"left\"\n        variant=\"sidebar\"\n      >\n        {activeItem ? (\n          activeItemData?.subItems && (\n            <>\n              <SidebarHeader className=\"flex flex-row items-center justify-between border-b px-4\">\n                <button\n                  className=\"flex h-8 w-8 items-center justify-center rounded-md p-0 hover:bg-sidebar-accent\"\n                  onClick={handleBackToMain}\n                >\n                  <IconArrowLeft className=\"h-4 w-4\" />\n                </button>\n                <h3 className=\"flex-1 text-center font-medium\">\n                  {activeItemData.label}\n                </h3>\n                <div className=\"w-8\" />\n              </SidebarHeader>\n\n              <SidebarContent>\n                <SidebarGroup>\n                  <SidebarGroupContent>\n                    <SidebarMenu>\n                      {activeItemData.subItems.map((subItem) => {\n                        const SubIcon = subItem.icon;\n                        const isSelected = selectedSubItem === subItem.id;\n\n                        return (\n                          <SidebarMenuItem key={subItem.id}>\n                            <SidebarMenuButton\n                              className=\"h-10 w-full px-3\"\n                              isActive={isSelected}\n                              onClick={() => handleSubItemClick(subItem)}\n                            >\n                              <div className=\"flex min-w-0 flex-1 items-center gap-3\">\n                                <SubIcon className=\"h-4 w-4 shrink-0\" />\n                                <span className=\"truncate\">\n                                  {subItem.label}\n                                </span>\n                              </div>\n                            </SidebarMenuButton>\n                          </SidebarMenuItem>\n                        );\n                      })}\n                    </SidebarMenu>\n                  </SidebarGroupContent>\n                </SidebarGroup>\n              </SidebarContent>\n            </>\n          )\n        ) : (\n          <>\n            <SidebarHeader>\n              <TeamSwitcher teams={data.teams} />\n            </SidebarHeader>\n\n            <SidebarContent>\n              <SidebarGroup>\n                <SidebarGroupContent>\n                  <SidebarMenu>\n                    {sidebarItems.map((item) => {\n                      const Icon = item.icon;\n                      const chevronIndicator = (\n                        <IconChevronRight className=\"h-4 w-4 shrink-0 transition-transform\" />\n                      );\n\n                      return (\n                        <SidebarMenuItem key={item.id}>\n                          <SidebarMenuButton\n                            className=\"h-10 w-full px-3\"\n                            onClick={() => handleItemClick(item)}\n                          >\n                            <div className=\"flex min-w-0 flex-1 items-center gap-3\">\n                              <Icon className=\"h-4 w-4 shrink-0\" />\n                              <span className=\"truncate\">{item.label}</span>\n                            </div>\n                            <div className=\"ml-auto flex min-w-fit shrink-0 items-center gap-1\">\n                              {(item.badge || item.hasSubItems) &&\n                                (item.badge ? (\n                                  <SidebarMenuBadge\n                                    className={cn(\n                                      'min-w-fit',\n                                      item.hasSubItems && 'gap-x-3'\n                                    )}\n                                  >\n                                    {item.badge}\n                                    {item.hasSubItems && chevronIndicator}\n                                  </SidebarMenuBadge>\n                                ) : (\n                                  chevronIndicator\n                                ))}\n                            </div>\n                          </SidebarMenuButton>\n                        </SidebarMenuItem>\n                      );\n                    })}\n                  </SidebarMenu>\n                </SidebarGroupContent>\n              </SidebarGroup>\n            </SidebarContent>\n\n            <SidebarFooter>\n              <SidebarMenu>\n                <SidebarMenuItem>\n                  <SidebarMenuButton className=\"h-12 w-full px-3\">\n                    <div className=\"flex min-w-0 flex-1 items-center gap-3\">\n                      <Avatar className=\"h-8 w-8 rounded-full\">\n                        <AvatarImage alt=\"ephraim\" src=\"/avatar-01.png\" />\n                        <AvatarFallback className=\"rounded-full\">\n                          E\n                        </AvatarFallback>\n                      </Avatar>\n                      <div className=\"min-w-0 flex-1 text-left\">\n                        <div className=\"truncate font-medium text-sm\">\n                          ephraim\n                        </div>\n                        <div className=\"truncate text-muted-foreground text-xs\">\n                          ephraim@blocks.so\n                        </div>\n                      </div>\n                    </div>\n                    <IconLogout className=\"h-4 w-4 shrink-0\" />\n                  </SidebarMenuButton>\n                </SidebarMenuItem>\n              </SidebarMenu>\n            </SidebarFooter>\n          </>\n        )}\n      </Sidebar>\n    </div>\n  );\n}\n"
    },
    {
      "path": "content/components/sidebar/sidebar-06/app/page.tsx",
      "type": "registry:page",
      "target": "app/page.tsx",
      "content": "'use client';\n\nimport { SidebarProvider } from '@/components/ui/sidebar';\nimport { AppSidebar } from '@/components/sidebar-06/app-sidebar';\n\nexport default function Page() {\n  return (\n    <SidebarProvider>\n      <div className=\"flex h-dvh w-full\">\n        <AppSidebar />\n      </div>\n    </SidebarProvider>\n  );\n}\n"
    },
    {
      "path": "content/components/sidebar/sidebar-06/team-switcher.tsx",
      "type": "registry:component",
      "target": "components/sidebar-06/team-switcher.tsx",
      "content": "'use client';\n\nimport { ChevronsUpDown, Plus } from 'lucide-react';\nimport * as React from 'react';\n\nimport {\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuLabel,\n  DropdownMenuSeparator,\n  DropdownMenuShortcut,\n  DropdownMenuTrigger,\n} from '@/components/ui/dropdown-menu';\nimport {\n  SidebarMenu,\n  SidebarMenuButton,\n  SidebarMenuItem,\n  useSidebar,\n} from '@/components/ui/sidebar';\n\nexport function TeamSwitcher({\n  teams,\n}: {\n  teams: {\n    name: string;\n    logo: React.ElementType;\n    plan: string;\n  }[];\n}) {\n  const { isMobile } = useSidebar();\n  const [activeTeam, setActiveTeam] = React.useState(teams[0]);\n\n  if (!activeTeam) {\n    return null;\n  }\n\n  return (\n    <SidebarMenu>\n      <SidebarMenuItem>\n        <DropdownMenu>\n          <DropdownMenuTrigger\n            render={\n              <SidebarMenuButton\n                className=\"data-popup-open:bg-sidebar-accent data-popup-open:text-sidebar-accent-foreground\"\n                size=\"lg\"\n              />\n            }\n          >\n            <div className=\"flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-accent text-sidebar-accent-foreground\">\n              <activeTeam.logo className=\"size-4\" />\n            </div>\n            <div className=\"grid flex-1 text-left text-sm leading-tight\">\n              <span className=\"truncate font-medium\">{activeTeam.name}</span>\n              <span className=\"truncate text-xs\">{activeTeam.plan}</span>\n            </div>\n            <ChevronsUpDown className=\"ml-auto\" />\n          </DropdownMenuTrigger>\n          <DropdownMenuContent\n            align=\"start\"\n            className=\"w-(--anchor-width) min-w-56 rounded-lg\"\n            side={isMobile ? 'bottom' : 'right'}\n            sideOffset={4}\n          >\n            <DropdownMenuLabel className=\"text-muted-foreground text-xs\">\n              Teams\n            </DropdownMenuLabel>\n            {teams.map((team, index) => (\n              <DropdownMenuItem\n                className=\"gap-2 p-2\"\n                key={team.name}\n                onClick={() => setActiveTeam(team)}\n              >\n                <div className=\"flex size-6 items-center justify-center rounded-md border\">\n                  <team.logo className=\"size-3.5 shrink-0\" />\n                </div>\n                {team.name}\n                <DropdownMenuShortcut>⌘{index + 1}</DropdownMenuShortcut>\n              </DropdownMenuItem>\n            ))}\n            <DropdownMenuSeparator />\n            <DropdownMenuItem className=\"gap-2 p-2\">\n              <div className=\"flex size-6 items-center justify-center rounded-md border bg-transparent\">\n                <Plus className=\"size-4\" />\n              </div>\n              <div className=\"font-medium text-muted-foreground\">Add team</div>\n            </DropdownMenuItem>\n          </DropdownMenuContent>\n        </DropdownMenu>\n      </SidebarMenuItem>\n    </SidebarMenu>\n  );\n}\n"
    }
  ],
  "categories": [
    "sidebar"
  ]
}