import React from "react"; import { formatTimeDelta } from "#/utils/format-time-delta"; import { ConversationRepoLink } from "./conversation-repo-link"; import { ProjectStatus, ConversationStateIndicator, } from "./conversation-state-indicator"; import { EllipsisButton } from "./ellipsis-button"; import { ConversationCardContextMenu } from "./conversation-card-context-menu"; import { cn } from "#/utils/utils"; interface ConversationCardProps { onClick?: () => void; onDelete?: () => void; onChangeTitle?: (title: string) => void; onDownloadWorkspace?: () => void; isActive?: boolean; title: string; selectedRepository: string | null; lastUpdatedAt: string; // ISO 8601 status?: ProjectStatus; variant?: "compact" | "default"; } export function ConversationCard({ onClick, onDelete, onChangeTitle, onDownloadWorkspace, isActive, title, selectedRepository, lastUpdatedAt, status = "STOPPED", variant = "default", }: ConversationCardProps) { const [contextMenuVisible, setContextMenuVisible] = React.useState(false); const [titleMode, setTitleMode] = React.useState<"view" | "edit">("view"); const inputRef = React.useRef(null); const handleBlur = () => { if (inputRef.current?.value) { const trimmed = inputRef.current.value.trim(); onChangeTitle?.(trimmed); inputRef.current!.value = trimmed; } else { // reset the value if it's empty inputRef.current!.value = title; } setTitleMode("view"); }; const handleKeyUp = (event: React.KeyboardEvent) => { if (event.key === "Enter") { event.currentTarget.blur(); } }; const handleInputClick = (event: React.MouseEvent) => { event.preventDefault(); event.stopPropagation(); }; const handleDelete = (event: React.MouseEvent) => { event.preventDefault(); event.stopPropagation(); onDelete?.(); }; const handleEdit = (event: React.MouseEvent) => { event.preventDefault(); event.stopPropagation(); setTitleMode("edit"); setContextMenuVisible(false); }; const handleDownload = (event: React.MouseEvent) => { event.stopPropagation(); onDownloadWorkspace?.(); }; React.useEffect(() => { if (titleMode === "edit") { inputRef.current?.focus(); } }, [titleMode]); const hasContextMenu = !!(onDelete || onChangeTitle || onDownloadWorkspace); return (
{isActive && }
{hasContextMenu && ( { event.preventDefault(); event.stopPropagation(); setContextMenuVisible((prev) => !prev); }} /> )} {contextMenuVisible && ( setContextMenuVisible(false)} onDelete={onDelete && handleDelete} onEdit={onChangeTitle && handleEdit} onDownload={onDownloadWorkspace && handleDownload} position={variant === "compact" ? "top" : "bottom"} /> )}
{selectedRepository && ( e.stopPropagation()} /> )}

); }