"use client"; import { Archive, ArrowDownUp, BookText, Bot, ClipboardCheck, Compass, FolderTree, Image as ImageIcon, LogOut, Network, Settings, Sparkles, UserPlus, Users, } from "lucide-react"; import Link from "next/link"; import { usePathname, useRouter } from "next/navigation"; import { useEffect, useRef, useState } from "react"; import { api } from "@/lib/api/client"; import { cn } from "@/lib/utils"; import { ThemeToggle } from "@/components/theme-toggle"; export function AppSidebar({ onNavigate }: { onNavigate?: () => void }) { const pathname = usePathname(); const router = useRouter(); const segs = pathname.split("/").filter(Boolean); // ["trees", "", ...] const treeId = segs[0] === "trees" && segs[1] ? segs[1] : null; const [treeName, setTreeName] = useState(null); const [me, setMe] = useState<{ display_name: string | null; email: string } | null>(null); const [menuOpen, setMenuOpen] = useState(false); const menuRef = useRef(null); useEffect(() => { if (!treeId) { setTreeName(null); return; } api .GET("/api/v1/trees/{tree_id}", { params: { path: { tree_id: treeId } } }) .then((r) => setTreeName(r.data?.name ?? null)); }, [treeId]); useEffect(() => { api.GET("/api/v1/users/me").then((r) => setMe(r.data ?? null)); }, []); useEffect(() => { function onDoc(e: MouseEvent) { if (menuRef.current && !menuRef.current.contains(e.target as Node)) setMenuOpen(false); } document.addEventListener("mousedown", onDoc); return () => document.removeEventListener("mousedown", onDoc); }, []); async function logout() { onNavigate?.(); await api.POST("/api/v1/auth/logout"); router.push("/login"); } const Item = ({ href, label, icon: Icon, active, }: { href: string; label: string; icon: typeof Users; active: boolean; }) => ( {label} ); return ( ); }