"use client"; import Image from "next/image"; import NextLink from "next/link"; import { BookOpen, FileText, Folder, GraduationCap, MessageCircle, Plus, Settings, Upload, User, Video } from "lucide-react"; import { useBackendHealth } from "@/hooks/useBackendHealth"; import type { ChatSessionOut } from "@/lib/api/chatHistory"; import type { ApiDocument } from "@/lib/api/types"; import { cn } from "@/lib/utils"; import { WorkspaceSearch } from "./WorkspacePanelPrimitives"; function dateGroupLabel(date: Date): string | null { const now = new Date(); const today = new Date(now.getFullYear(), now.getMonth(), now.getDate()); const yesterday = new Date(today); yesterday.setDate(yesterday.getDate() - 1); const dateStart = new Date(date.getFullYear(), date.getMonth(), date.getDate()); if (dateStart.getTime() === today.getTime()) return "Today"; if (dateStart.getTime() === yesterday.getTime()) return "Yesterday"; return null; // Older — no label needed, just an "Older" header } function groupSessionsByDate(sessions: ChatSessionOut[]): [string, ChatSessionOut[]][] { const groups: Map = new Map(); for (const session of sessions) { const d = new Date(session.updated_at); const label = dateGroupLabel(d) ?? "Older"; const list = groups.get(label); if (list) list.push(session); else groups.set(label, [session]); } const order = ["Today", "Yesterday", "Older"]; return order.filter((key) => groups.has(key)).map((key) => [key, groups.get(key)!]); } type LeftWorkspaceRailProps = { documents: ApiDocument[]; sessions: ChatSessionOut[]; selectedSourceIds: string[]; search: string; onSearchChange: (value: string) => void; onNewChat: () => void; onOpenSession: (sessionId: string) => void; onToggleSource: (id: string) => void; onUpload: () => void; isHistoryLoading: boolean; }; export function LeftWorkspaceRail({ documents, sessions, selectedSourceIds, search, onSearchChange, onNewChat, onOpenSession, onToggleSource, onUpload, isHistoryLoading, }: LeftWorkspaceRailProps) { const { health } = useBackendHealth(); const query = search.trim().toLowerCase(); const isSearching = query.length > 0; const filteredSessions = isSearching ? sessions.filter((session) => session.title.toLowerCase().includes(query) || session.subject.toLowerCase().includes(query)) : sessions; // The search box promises "chats OR sources" — actually filter sources too. const recentSources = isSearching ? documents.filter( (document) => document.title.toLowerCase().includes(query) || (document.subject ?? "").toLowerCase().includes(query), ) : documents.slice(0, 5); const noSearchResults = isSearching && filteredSessions.length === 0 && recentSources.length === 0; return ( ); }