"use client"; import type { Team } from "@stackframe/stack"; import { Brain, ChevronLeft, ChevronRight, CircleDollarSign, Database, FileText, HelpCircle, Home, Key, Megaphone, MessageSquare, Phone, Star, TrendingUp, Workflow, Wrench, Zap, } from "lucide-react"; import Link from "next/link"; import { usePathname, useRouter } from "next/navigation"; import React from "react"; import ThemeToggle from "@/components/ThemeSwitcher"; import { Button } from "@/components/ui/button"; import { Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupLabel, SidebarHeader, SidebarMenu, SidebarMenuButton, SidebarMenuItem, SidebarRail, SidebarTrigger, useSidebar, } from "@/components/ui/sidebar"; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from "@/components/ui/tooltip"; import { useAppConfig } from "@/context/AppConfigContext"; import { useAuth } from "@/lib/auth"; import { cn } from "@/lib/utils"; // Conditionally load Stack components only when using Stack auth const StackUserButton = React.lazy(() => import("@stackframe/stack").then((mod) => ({ default: mod.UserButton })) ); // Lazy load SelectedTeamSwitcher - we'll pass selectedTeam from our context const StackTeamSwitcher = React.lazy(() => import("@stackframe/stack").then((mod) => ({ default: mod.SelectedTeamSwitcher, })) ); export function AppSidebar() { const pathname = usePathname(); const router = useRouter(); const { state } = useSidebar(); const { provider, getSelectedTeam } = useAuth(); const { config } = useAppConfig(); // Get selected team for Stack auth (cast to Team type from Stack) const selectedTeam = provider === "stack" && getSelectedTeam ? getSelectedTeam() as Team | null : null; // Version info from app config context const versionInfo = config ? { ui: config.uiVersion, api: config.apiVersion } : null; const isActive = (path: string) => { return pathname.startsWith(path); }; // Organize navigation into sections const overviewSection = [ { title: "Overview", url: "/overview", icon: Home, }, ]; const buildSection = [ { title: "Voice Agents", url: "/workflow", icon: Workflow, }, { title: "Campaigns", url: "/campaigns", icon: Megaphone, }, { title: "Automation", url: "/automation", icon: Zap, }, { title: "Models", url: "/model-configurations", icon: Brain, }, { title: "Telephony", url: "/telephony-configurations", icon: Phone, }, { title: "Tools", url: "/tools", icon: Wrench, }, { title: "Files", url: "/files", icon: Database, }, // { // title: "Integrations", // url: "/integrations", // icon: Plug, // }, { title: "Developers", url: "/api-keys", icon: Key, }, ]; const observeSection = [ { title: "Usage", url: "/usage", icon: TrendingUp, }, { title: "Reports", url: "/reports", icon: FileText, }, { title: "LoopTalk", url: "/looptalk", icon: MessageSquare, }, ]; const SidebarLink = ({ item }: { item: typeof overviewSection[0] }) => { const isItemActive = isActive(item.url); const Icon = item.icon; if (state === "collapsed") { return ( {item.title} {item.title} ); } return ( {item.title} ); }; return ( {/* Logo - only show when expanded */} {state === "expanded" && ( Dograh {versionInfo && ( v{versionInfo.ui} )} )} {/* Toggle button - center it when collapsed */} {state === "expanded" ? ( ) : ( )} {/* Team Switcher for Stack Auth - at the top */} {provider === "stack" && state === "expanded" && ( } > { router.refresh(); }} /> )} {/* Star us on GitHub for OSS mode - at the top */} {provider !== "stack" && ( {state === "collapsed" ? ( Star us on GitHub Star us on GitHub ) : ( Star us on GitHub )} )} {/* Overview Section */} {overviewSection.map((item) => ( ))} {/* BUILD Section */} {buildSection.length > 0 && ( {state === "expanded" && ( BUILD )} {buildSection.map((item) => ( ))} )} {/* OBSERVE Section */} {state === "expanded" && ( OBSERVE )} {observeSection.map((item) => ( ))} {/* Bottom Actions */} {/* Get Help - for OSS mode */} {provider !== "stack" && ( <> {state === "collapsed" ? ( Get Help Get Help ) : ( Get Help )} > )} {/* User Button for Stack Auth - at the bottom */} {provider === "stack" && ( } > , onClick: () => router.push("/usage"), }, ]} /> )} {/* Theme Toggle - at the very bottom */} {state === "collapsed" ? ( Toggle theme ) : ( )} ); }
{item.title}
Star us on GitHub
Get Help
Toggle theme