pageparse.ai / frontend /src /components /ChatPanel.tsx
Varun2007's picture
initial clean deployment commit with compilers
8c3e275
Raw
History Blame Contribute Delete
2.76 kB
import { useState, useRef, useEffect } from 'react';
import { Send, Loader2, Bot, User } from 'lucide-react';
import { API_BASE_URL } from '../services/api';
export const ChatPanel = () => {
const [messages, setMessages] = useState<{ sender: 'bot' | 'user'; text: string }[]>([
{ sender: 'bot', text: 'Ask me anything about your notes, tasks, and transcripts.' }
]);
const [input, setInput] = useState('');
const [loading, setLoading] = useState(false);
const messagesEndRef = useRef<HTMLDivElement>(null);
useEffect(() => {
messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
}, [messages]);
const handleSend = async (e: React.FormEvent) => {
e.preventDefault();
if (!input.trim() || loading) return;
const userMessage = input;
setInput('');
setMessages(prev => [...prev, { sender: 'user', text: userMessage }]);
setLoading(true);
try {
const response = await fetch(`${API_BASE_URL}/chat`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ prompt: userMessage }),
});
if (!response.ok) throw new Error('Chat failed');
const data = await response.json();
setMessages(prev => [...prev, { sender: 'bot', text: data.response || 'No response.' }]);
} catch (err) {
setTimeout(() => {
setMessages(prev => [...prev, {
sender: 'bot',
text: `[Offline] Found 3 items related to "${userMessage}" in local records.`
}]);
}, 800);
} finally {
setLoading(false);
}
};
return (
<div className="chat-panel">
<div className="chat-messages">
{messages.map((m, idx) => (
<div key={idx} className={`chat-msg ${m.sender}`}>
{m.sender === 'bot' ? <Bot size={14} style={{ flexShrink: 0, marginTop: 2, color: 'var(--purple)' }} /> : <User size={14} style={{ flexShrink: 0, marginTop: 2, color: 'var(--accent)' }} />}
<span>{m.text}</span>
</div>
))}
{loading && (
<div className="flex items-center gap-2 text-xs text-tertiary" style={{ padding: 8 }}>
<Loader2 size={14} className="animate-spin" /> AI reading context...
</div>
)}
<div ref={messagesEndRef} />
</div>
<form className="chat-input-row" onSubmit={handleSend}>
<input
type="text"
value={input}
onChange={e => setInput(e.target.value)}
placeholder="Ask about notes/tasks..."
className="input"
disabled={loading}
/>
<button type="submit" className="btn btn-primary btn-sm" disabled={loading}>
<Send size={14} />
</button>
</form>
</div>
);
};