Files
agentlens/apps/web/src/app/docs/docs-sidebar.tsx
Vectry 5256bf005b feat: documentation pages and updated model pricing
- Add 13 documentation pages under /docs (getting-started, concepts, SDK refs, integrations, API reference, self-hosting, OpenCode plugin)
- Shared docs layout with collapsible sidebar navigation
- Update model pricing across all SDKs: add GPT-5.x, GPT-4.1, o3/o4-mini, Claude 4.5 series, claude-opus-4-6
- Update trace-analytics context window lookup with current models
2026-02-10 03:27:11 +00:00

122 lines
3.5 KiB
TypeScript

"use client";
import { useState } from "react";
interface NavItem {
title: string;
href: string;
}
interface NavSection {
heading: string;
items: NavItem[];
}
const navigation: NavSection[] = [
{
heading: "Overview",
items: [
{ title: "Introduction", href: "/docs" },
{ title: "Getting Started", href: "/docs/getting-started" },
{ title: "Core Concepts", href: "/docs/concepts" },
],
},
{
heading: "SDKs",
items: [
{ title: "Python SDK", href: "/docs/python-sdk" },
{ title: "TypeScript SDK", href: "/docs/typescript-sdk" },
],
},
{
heading: "Integrations",
items: [
{ title: "OpenAI", href: "/docs/integrations/openai" },
{ title: "Anthropic", href: "/docs/integrations/anthropic" },
{ title: "LangChain", href: "/docs/integrations/langchain" },
],
},
{
heading: "Tools",
items: [{ title: "OpenCode Plugin", href: "/docs/opencode-plugin" }],
},
{
heading: "Reference",
items: [
{ title: "REST API", href: "/docs/api-reference" },
{ title: "Self-Hosting", href: "/docs/self-hosting" },
],
},
];
function SidebarContent() {
return (
<nav className="space-y-6">
{navigation.map((section) => (
<div key={section.heading}>
<h4 className="text-xs font-semibold uppercase tracking-wider text-neutral-500 mb-2 px-3">
{section.heading}
</h4>
<ul className="space-y-0.5">
{section.items.map((item) => (
<li key={item.href}>
<a
href={item.href}
className="block px-3 py-1.5 text-sm text-neutral-400 hover:text-neutral-100 hover:bg-neutral-800/50 rounded-md transition-colors"
>
{item.title}
</a>
</li>
))}
</ul>
</div>
))}
</nav>
);
}
export function DocsSidebar() {
const [mobileOpen, setMobileOpen] = useState(false);
return (
<>
<button
type="button"
onClick={() => setMobileOpen(!mobileOpen)}
className="lg:hidden fixed bottom-4 right-4 z-50 w-12 h-12 rounded-full bg-emerald-500 text-neutral-950 shadow-lg shadow-emerald-500/25 flex items-center justify-center"
aria-label="Toggle navigation"
>
<svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
{mobileOpen ? (
<path strokeLinecap="round" strokeLinejoin="round" d="M6 18L18 6M6 6l12 12" />
) : (
<path strokeLinecap="round" strokeLinejoin="round" d="M4 6h16M4 12h16M4 18h16" />
)}
</svg>
</button>
{mobileOpen && (
<div className="lg:hidden fixed inset-0 z-40">
<div
className="absolute inset-0 bg-neutral-950/80 backdrop-blur-sm"
onClick={() => setMobileOpen(false)}
onKeyDown={(e) => {
if (e.key === "Escape") setMobileOpen(false);
}}
role="button"
tabIndex={0}
aria-label="Close navigation"
/>
<div className="absolute left-0 top-14 bottom-0 w-72 bg-neutral-950 border-r border-neutral-800/50 p-6 overflow-y-auto">
<SidebarContent />
</div>
</div>
)}
<aside className="hidden lg:block w-64 flex-shrink-0 border-r border-neutral-800/50 sticky top-14 h-[calc(100vh-3.5rem)] overflow-y-auto py-8 px-4">
<SidebarContent />
</aside>
</>
);
}