Spaces:
Running
Running
File size: 2,884 Bytes
6c62075 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | import type { ChatSession } from '../../lib/contracts';
import { conversationPreview } from '../../lib/conversations';
interface ConversationListProps {
conversations: ChatSession[];
activeConversationId: string;
onNewConversation: () => void;
onOpenConversation: (conversationId: string) => void;
onOpenConversationSettings: (conversationId: string) => void;
onDeleteConversation: (conversationId: string) => void;
}
export function ConversationList({
conversations,
activeConversationId,
onNewConversation,
onOpenConversation,
onOpenConversationSettings,
onDeleteConversation,
}: ConversationListProps) {
return (
<main className="chat-surface conversation-library">
<header className="chat-header conversation-list-header">
<div>
<h2>Chats</h2>
<p>Saved only in this browser</p>
</div>
<button className="new-chat-button" type="button" onClick={onNewConversation}>New chat</button>
</header>
<section className="conversation-list" aria-label="Saved chats">
{conversations.length === 0 ? (
<div className="conversation-list-empty">
<h3>No saved chats</h3>
<p>Your first prompt creates a local session automatically.</p>
<button type="button" onClick={onNewConversation}>Start a chat</button>
</div>
) : conversations.map((conversation) => (
<article className={`conversation-row${conversation.id === activeConversationId ? ' is-current' : ''}`} key={conversation.id}>
<button className="conversation-open" type="button" onClick={() => onOpenConversation(conversation.id)}>
<span className="conversation-title-line">
<strong>{conversation.title}</strong>
{conversation.id === activeConversationId && <small>Current</small>}
</span>
<span>{conversationPreview(conversation.messages)}</span>
<small>{conversation.modelId.replace('bonsai-', 'Bonsai ')} · {formatConversationTime(conversation.updatedAt)}</small>
</button>
<div className="conversation-actions">
<button type="button" onClick={() => onOpenConversationSettings(conversation.id)}>Settings</button>
<button
className="conversation-delete"
type="button"
aria-label={`Delete chat: ${conversation.title}`}
onClick={() => onDeleteConversation(conversation.id)}
>
Delete
</button>
</div>
</article>
))}
</section>
</main>
);
}
function formatConversationTime(timestamp: number): string {
return new Intl.DateTimeFormat('en', {
month: 'short',
day: 'numeric',
hour: '2-digit',
minute: '2-digit',
}).format(new Date(timestamp));
}
|