Aegis / web /src /components /ChatPanel.jsx
Phani
Aegis: initial deploy
478302a
Raw History Blame Contribute Delete
2.82 kB
import { useEffect, useRef, useState } from 'react'
import DomainButtons from './DomainButtons'
import MessageBubble from './MessageBubble'
export default function ChatPanel({
conversation,
categories,
loading,
onSend,
}) {
const [draft, setDraft] = useState('')
const messagesEndRef = useRef(null)
const textareaRef = useRef(null)
const messages = conversation?.messages || []
useEffect(() => {
messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' })
}, [messages.length, loading])
function handleSubmit(event) {
event.preventDefault()
const trimmed = draft.trim()
if (!trimmed || loading) return
onSend(trimmed)
setDraft('')
}
function handleKeyDown(event) {
if (event.key === 'Enter' && !event.shiftKey) {
event.preventDefault()
handleSubmit(event)
}
}
function handlePick(question) {
setDraft(question)
textareaRef.current?.focus()
}
return (
<div className="chat-panel">
<div className="chat-header">
<h1>{conversation ? conversation.title : 'Aegis'}</h1>
<p className="chat-subtitle">
Local instruction-tuned model &middot; LOS + Guidewire + Duck Creek
+ general insurance &middot; retrieval augmented
</p>
</div>
<div className="messages">
{messages.length === 0 && (
<div className="welcome">
<div className="welcome-icon">Æ</div>
<h2>Ask Aegis something</h2>
<p>
Pick a domain below or type your own question. Experimental
model — do not rely on it for real loan, underwriting, claims,
or financial decisions.
</p>
</div>
)}
{messages.map((message, index) => (
<MessageBubble key={index} message={message} />
))}
{loading && (
<div className="message-row">
<div className="bubble bubble--assistant bubble--typing">
<span className="dot" />
<span className="dot" />
<span className="dot" />
</div>
</div>
)}
<div ref={messagesEndRef} />
</div>
<div className="composer">
<DomainButtons categories={categories} onPick={handlePick} />
<form className="composer-form" onSubmit={handleSubmit}>
<textarea
ref={textareaRef}
value={draft}
onChange={(event) => setDraft(event.target.value)}
onKeyDown={handleKeyDown}
placeholder="Ask about LOS, Guidewire, Duck Creek, or general insurance..."
rows={1}
/>
<button type="submit" disabled={loading || !draft.trim()}>
Send
</button>
</form>
</div>
</div>
)
}