import React from "react"; import { motion, AnimatePresence } from "framer-motion"; import { MessageSquare, Plus, Trash2, Moon, Sun, Bot, History, FlaskConical } from "lucide-react"; import { clsx } from "clsx"; import { twMerge } from "tailwind-merge"; function cn(...inputs) { return twMerge(clsx(inputs)); } export default function ChatSidebar({ open, setOpen, models, selectedModelId, onSelectModel, isModelsLoading, modelsError, modelsIssues, onReloadModels, mode, modes, onModeChange, onNewChat, onClearHistory, historyList, activeSessionId, onSelectSession, isSessionLocked = false, theme, onToggleTheme, activeView = "chat", onNavigateToLabs, onNavigateToChat, }) { const selectedModel = models?.find((item) => item.id === selectedModelId); const uploadsStatus = selectedModel?.features?.status || "unknown"; const uploadsEnabled = Boolean(selectedModel?.features?.uploads); const historyScrollRef = React.useRef(null); React.useEffect(() => { const el = historyScrollRef.current; if (!el) return; let timeoutId = null; const onScroll = () => { el.classList.add("scrolling"); if (timeoutId) clearTimeout(timeoutId); timeoutId = setTimeout(() => el.classList.remove("scrolling"), 150); }; el.addEventListener("scroll", onScroll, { passive: true }); return () => { el.removeEventListener("scroll", onScroll); if (timeoutId) clearTimeout(timeoutId); }; }, []); return ( {open && ( <> setOpen?.(false)} aria-label="Close sidebar overlay" /> {/* Header & Logo */}

Vector

{/* View Navigation */}
Navigate
{/* New Chat Button - only in chat view */} {activeView === "chat" && ( )} {/* Models Selection - only in chat view */} {activeView === "chat" && (
{isSessionLocked ? "Model (Locked)" : "Model"}
{selectedModel && (
{uploadsStatus === "ok" ? uploadsEnabled ? "Uploads enabled" : "Uploads off" : "Uploads unknown"}
)} {(modelsError || (modelsIssues && modelsIssues.length > 0) || (!isModelsLoading && !models?.length)) && (
{modelsError &&
{modelsError}
} {!modelsError && !isModelsLoading && !models?.length && (
Add MODEL_1_NAME / MODEL_1_ID / MODEL_1_HOST to your environment.
)} {modelsIssues?.slice(0, 3).map((issue) => (
{issue}
))}
)}
)} {/* History List - only in chat view */} {activeView === "chat" && (
Recent
{historyList.length === 0 ? (
No history yet
) : ( historyList.map((session, i) => ( )) )}
)} {/* Spacer for Labs view */} {activeView === "labs" &&
} {/* Footer Actions */}
{activeView === "chat" && ( )}
)} ); }