import { useState, useRef, useEffect } from 'preact/hooks'; import { streamChat } from './api'; import type { ChatMessage } from './types'; const QUICK_ACTIONS = [ 'Doctor availability', 'Clinic timings', 'Book appointment', 'Health packages', ]; export const Chat = () => { const [messages, setMessages] = useState([]); const [input, setInput] = useState(''); const [loading, setLoading] = useState(false); const scrollRef = useRef(null); useEffect(() => { if (scrollRef.current) { scrollRef.current.scrollTop = scrollRef.current.scrollHeight; } }, [messages]); const sendMessage = async (text: string) => { if (!text.trim() || loading) return; const userMsg: ChatMessage = { role: 'user', content: text.trim() }; const updated = [...messages, userMsg]; setMessages(updated); setInput(''); setLoading(true); try { const stream = await streamChat(updated); const reader = stream.getReader(); const decoder = new TextDecoder(); let assistantText = ''; setMessages([...updated, { role: 'assistant', content: '' }]); while (true) { const { done, value } = await reader.read(); if (done) break; assistantText += decoder.decode(value, { stream: true }); setMessages([...updated, { role: 'assistant', content: assistantText }]); } } catch { setMessages([...updated, { role: 'assistant', content: 'Sorry, I encountered an error. Please try again.' }]); } finally { setLoading(false); } }; return (
{messages.length === 0 && (
👋
How can we help you?
Ask about doctors, clinics, packages, or book an appointment.
{QUICK_ACTIONS.map(q => ( ))}
)} {messages.map((msg, i) => (
{msg.content || '...'}
))}
setInput(e.target.value)} onKeyDown={(e: any) => e.key === 'Enter' && sendMessage(input)} disabled={loading} />
); };