"use client"; import type { Team } from "@stackframe/stack"; import { Brain, ChevronLeft, ChevronRight, CircleDollarSign, Database, FileText, HelpCircle, Home, Key, LogOut, Megaphone, MessageSquare, Phone, Settings, 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 { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; 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"; // 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, logout, user } = 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 - at the bottom */} {provider === "stack" && ( {(user?.displayName || (user as { primaryEmail?: string })?.primaryEmail || "") .split(/[\s@]/) .filter(Boolean) .slice(0, 2) .map((s: string) => s[0]?.toUpperCase()) .join("") || "U"} {user?.displayName && ( {user.displayName} )} {(user as { primaryEmail?: string })?.primaryEmail && ( {(user as { primaryEmail?: string }).primaryEmail} )} router.push("/handler/account-settings")} className="cursor-pointer"> Account settings router.push("/usage")} className="cursor-pointer"> Usage logout()} className="cursor-pointer"> Sign out )} {/* Theme Toggle - at the very bottom */} {state === "collapsed" ? ( Toggle theme ) : ( )} ); }
{item.title}
Star us on GitHub
Get Help
{user.displayName}
{(user as { primaryEmail?: string }).primaryEmail}
Toggle theme