| 'use client'; |
| import React, { useState, useEffect, useRef } from 'react'; |
| import { api } from '../../services/api'; |
|
|
| export default function AIChatPanel({ sessionId }) { |
| const [messages, setMessages] = useState([]); |
| const [input, setInput] = useState(''); |
| const [loading, setLoading] = useState(false); |
| const chatEndRef = useRef(null); |
|
|
| useEffect(() => { |
| if (sessionId) { |
| loadHistory(); |
| } |
| }, [sessionId]); |
|
|
| const loadHistory = async () => { |
| try { |
| const history = await api.getChatHistory(sessionId); |
| if (Array.isArray(history)) setMessages(history); |
| } catch (err) { |
| console.error("Failed to load chat history:", err); |
| } |
| }; |
|
|
| const handleSend = async (e) => { |
| e.preventDefault(); |
| if (!input.trim() || !sessionId || loading) return; |
|
|
| const userMessage = { role: 'user', content: input }; |
| setMessages((prev) => [...prev, userMessage]); |
| const currentPrompt = input; |
| setInput(''); |
| setLoading(true); |
|
|
| try { |
| const res = await api.sendChatMessage(sessionId, 'user', currentPrompt); |
| if (res && res.content) { |
| setMessages((prev) => [...prev, { role: 'assistant', content: res.content }]); |
| } |
| } catch (err) { |
| setMessages((prev) => [...prev, { role: 'assistant', content: "Error communicating with AI agent." }]); |
| } finally { |
| setLoading(false); |
| chatEndRef.current?.scrollIntoView({ behavior: 'smooth' }); |
| } |
| }; |
|
|
| return ( |
| <div className="w-80 bg-slate-900 border-l border-slate-800 flex flex-col h-full text-slate-200"> |
| <div className="p-3 border-b border-slate-800 font-semibold text-xs uppercase tracking-wider text-slate-400"> |
| AI Workspace Assistant |
| </div> |
| |
| <div className="flex-1 overflow-y-auto p-3 space-y-3 text-sm"> |
| {messages.map((msg, idx) => ( |
| <div |
| key={idx} |
| className={`p-3 rounded-lg max-w-[90%] whitespace-pre-wrap ${ |
| msg.role === 'user' |
| ? 'bg-blue-600 text-white ml-auto' |
| : 'bg-slate-800 border border-slate-700 text-slate-200' |
| }`} |
| > |
| <div className="text-[10px] opacity-60 mb-1 uppercase font-bold">{msg.role}</div> |
| {msg.content} |
| </div> |
| ))} |
| {loading && ( |
| <div className="bg-slate-800 text-slate-400 p-3 rounded-lg text-xs animate-pulse"> |
| AI is thinking & generating code... |
| </div> |
| )} |
| <div ref={chatEndRef} /> |
| </div> |
| |
| <form onSubmit={handleSend} className="p-3 border-t border-slate-800 flex gap-2"> |
| <input |
| type="text" |
| value={input} |
| onChange={(e) => setInput(e.target.value)} |
| placeholder="Ask AI to generate code..." |
| className="flex-1 bg-slate-800 border border-slate-700 rounded px-3 py-1.5 text-xs text-white focus:outline-none focus:border-blue-500" |
| /> |
| <button |
| type="submit" |
| disabled={loading} |
| className="bg-blue-600 hover:bg-blue-500 text-white px-3 py-1.5 rounded text-xs font-medium disabled:opacity-50" |
| > |
| Send |
| </button> |
| </form> |
| </div> |
| ); |
| } |
|
|