// Implements: T036-T043 // Phase III - AI-Powered Todo Chatbot // ChatInterface Component - Full implementation with API integration import React, { useState, useRef, useEffect } from 'react'; interface Message { role: 'user' | 'assistant'; content: string; timestamp: Date; tool_calls?: any[]; } interface ChatResponse { reply: string; conversation_id: string; tool_calls?: any[]; } interface ChatInterfaceProps { jwtToken: string; apiBaseUrl?: string; } const ChatInterface: React.FC = ({ jwtToken, apiBaseUrl = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8000' }) => { const [messages, setMessages] = useState([]); const [inputMessage, setInputMessage] = useState(''); const [isLoading, setIsLoading] = useState(false); const [conversationId, setConversationId] = useState(null); const [error, setError] = useState(null); const messagesEndRef = useRef(null); const inputRef = useRef(null); // Auto-scroll to bottom when new messages arrive useEffect(() => { messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' }); }, [messages]); // Focus input on mount useEffect(() => { inputRef.current?.focus(); }, []); const detectLanguage = (text: string): 'en' | 'ur' => { // Urdu Unicode range const urduPattern = /[\u0600-\u06FF]/; return urduPattern.test(text) ? 'ur' : 'en'; }; const handleSendMessage = async () => { if (!inputMessage.trim() || isLoading) { return; } const userMessage: Message = { role: 'user', content: inputMessage.trim(), timestamp: new Date(), }; // Add user message to chat setMessages((prev) => [...prev, userMessage]); setInputMessage(''); setIsLoading(true); setError(null); inputRef.current?.focus(); try { // Call Phase III backend API const response = await fetch(`${apiBaseUrl}/api/chat/`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${jwtToken}`, }, body: JSON.stringify({ message: userMessage.content, conversation_id: conversationId }), }); if (!response.ok) { const errorData = await response.json(); throw new Error(errorData.detail || 'Failed to send message'); } const data: ChatResponse = await response.json(); const assistantMessage: Message = { role: 'assistant', content: data.reply, timestamp: new Date(), tool_calls: data.tool_calls }; setMessages((prev) => [...prev, assistantMessage]); setConversationId(data.conversation_id); // Log tool calls for debugging if (data.tool_calls && data.tool_calls.length > 0) { console.log('Tool calls executed:', data.tool_calls); } } catch (err) { const errorMessage = err instanceof Error ? err.message : 'Failed to send message'; setError(errorMessage); console.error('Error sending message:', err); // Add error message to chat const errorMessageObj: Message = { role: 'assistant', content: `❌ Error: ${errorMessage}`, timestamp: new Date(), }; setMessages((prev) => [...prev, errorMessageObj]); } finally { setIsLoading(false); } }; const handleKeyPress = (e: React.KeyboardEvent) => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); handleSendMessage(); } }; return (

AI Task Assistant

Manage tasks in English or Urdu

{messages.length === 0 && (

Start a conversation...

Try: "Add a task to buy milk" or "دودھ لینے کا ٹاسک شامل کرو"

)} {messages.map((msg, index) => (
{msg.content}
{msg.timestamp.toLocaleTimeString()}
))} {isLoading && (
Thinking...
)} {error && (

{error}

)}
setInputMessage(e.target.value)} onKeyPress={handleKeyPress} placeholder={ detectLanguage(inputMessage) === 'ur' ? 'اپنا میسج ٹائپ کریں...' : 'Type your message...' } disabled={isLoading} maxLength={1000} />
); }; export default ChatInterface;