"use client"; import { ChevronRight, History, KeyRound, LayoutGrid } from "lucide-react"; import Link from "next/link"; import { usePathname } from "next/navigation"; import { useEffect, useMemo, useState } from "react"; import { Separator } from "@/components/ui/separator"; import { PLAYGROUND_PLATFORMS } from "@/lib/playground/catalog"; import { cn } from "@/lib/utils"; import type { RoutedSectionGroup, RoutedSectionItem } from "../RoutedSectionShell"; interface PlaygroundSidebarProps { workspaceId: string; className?: string; } export function getPlaygroundNavItems(base: string): RoutedSectionItem[] { return [ { value: "overview", label: "Overview", href: base, icon: , }, { value: "runs", label: "API Runs", href: `${base}/runs`, icon: , }, { value: "api-keys", label: "API Keys", href: `${base}/api-keys`, icon: , }, ]; } export function getPlaygroundNavGroups(base: string): RoutedSectionGroup[] { return PLAYGROUND_PLATFORMS.map((platform) => { const Icon = platform.icon; return { value: platform.id, label: platform.label, icon: , items: platform.verbs.map((verb) => ({ value: `${platform.id}/${verb.verb}`, label: verb.label, href: `${base}/${platform.id}/${verb.verb}`, })), }; }); } export function getPlaygroundActiveValue( pathname: string | null, base: string, items: RoutedSectionItem[] ): string { if (!pathname?.startsWith(base)) return ""; const rest = pathname.slice(base.length).replace(/^\/+/, ""); if (!rest) return "overview"; const [first, second] = rest.split("/"); if (second) return `${first}/${second}`; if (items.some((item) => item.value === first)) return first; return "overview"; } export function getPlaygroundSelectedLabel( activeValue: string, items: RoutedSectionItem[], groups: RoutedSectionGroup[] ): string { const topLevelItem = items.find((item) => item.value === activeValue); if (topLevelItem) return topLevelItem.label; const group = groups.find((item) => item.items.some((child) => child.value === activeValue)); const child = group?.items.find((item) => item.value === activeValue); if (group && child) return `${group.label}: ${child.label}`; return "API Playground"; } function findActiveGroupValue(groups: RoutedSectionGroup[], activeValue: string): string | null { return ( groups.find((group) => group.items.some((item) => item.value === activeValue))?.value ?? null ); } function PlaygroundNavLink({ item, activeValue, }: { item: RoutedSectionItem; activeValue: string; }) { const isActive = activeValue === item.value; return ( {item.icon} {item.label} ); } function PlaygroundNavGroup({ group, activeValue, isExpanded, onToggle, }: { group: RoutedSectionGroup; activeValue: string; isExpanded: boolean; onToggle: () => void; }) { return (
{group.items.map((item) => ( ))}
); } export function PlaygroundSidebar({ workspaceId, className }: PlaygroundSidebarProps) { const pathname = usePathname(); const base = `/dashboard/${workspaceId}/playground`; const items = useMemo(() => getPlaygroundNavItems(base), [base]); const groups = useMemo(() => getPlaygroundNavGroups(base), [base]); const activeValue = getPlaygroundActiveValue(pathname, base, items); const [expandedGroup, setExpandedGroup] = useState(() => findActiveGroupValue(groups, activeValue) ); useEffect(() => { const activeGroup = findActiveGroupValue(groups, activeValue); if (activeGroup) { setExpandedGroup(activeGroup); } }, [activeValue, groups]); return ( ); }