Spaces:
Build error
Build error
| 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> | |
| ); | |
| }; | |