"use client"; import { useEffect } from "react"; import { Plus, Pencil, Trash2, Check, X } from "lucide-react"; import { cn } from "@/lib/utils"; import { useLocale } from "@/lib/i18n/provider"; import { useConversationList } from "./use-conversation-list"; import type { Conversation } from "./conversation-menu"; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, } from "@/components/ui/alert-dialog"; /** * Persistent conversation list for the desktop-fullscreen chat layout — * ChatGPT/Claude-style, always visible rather than a dropdown (that's * ConversationMenu, used in the drawer/mobile layout instead). Shares its * fetch/rename/delete logic with ConversationMenu via useConversationList. */ export function ConversationSidebar({ activeId, onSelect, onCreated, onDeletedActive, className, }: { activeId: string | null; onSelect: (id: string) => void; onCreated: (conversation: Conversation) => void; onDeletedActive: () => void; className?: string; }) { const { locale } = useLocale(); const { t, conversations, loading, load, create, renamingId, renameValue, setRenameValue, startRename, cancelRename, submitRename, deleteTargetId, setDeleteTargetId, confirmDelete, } = useConversationList(onDeletedActive, activeId); useEffect(() => { void load(); // eslint-disable-next-line react-hooks/exhaustive-deps -- load() is idempotent (guarded by its own `loaded` flag), only needs to run once on mount }, []); async function handleCreate() { const created = await create(); if (created) onCreated(created); } return (
{t("loading")}
} {!loading && conversations.length === 0 && ({t("empty")}
)} {!loading && conversations.map((c) => (