"use client"; import React, { useState, useRef, useEffect } from "react"; import { ChatbotPayload } from "@/interface/chatbot"; import { apiChatbot } from "@/service/chatbotService"; type Message = { id: string; sender: "user" | "bot"; text: string; }; export default function ChatbotWidget({ projectId = "", }: { projectId?: string; }) { const [isOpen, setIsOpen] = useState(false); const [messages, setMessages] = useState([ { id: "init", sender: "bot", text: "Xin chào! Tôi là trợ lý lịch sử thân thiện. Tôi có thể giúp gì cho bạn?", }, ]); const [input, setInput] = useState(""); const [isLoading, setIsLoading] = useState(false); const messagesEndRef = useRef(null); const scrollToBottom = () => { messagesEndRef.current?.scrollIntoView({ behavior: "smooth" }); }; useEffect(() => { if (isOpen) { scrollToBottom(); } }, [messages, isOpen]); const handleSend = async () => { if (!input.trim()) return; const userMessage: Message = { id: Date.now().toString(), sender: "user", text: input.trim(), }; setMessages((prev) => [...prev, userMessage]); setInput(""); setIsLoading(true); try { const payload: ChatbotPayload = { project_id: projectId, question: userMessage.text, }; const res = await apiChatbot(payload); const botMessage: Message = { id: (Date.now() + 1).toString(), sender: "bot", text: res?.status ? res?.data : "Xin lỗi, tôi không thể trả lời lúc này.", }; setMessages((prev) => [...prev, botMessage]); } catch (error: any) { const errorMessage: Message = { id: (Date.now() + 1).toString(), sender: "bot", text: error?.response?.data?.message || "Có lỗi xảy ra khi kết nối. Vui lòng thử lại sau.", }; setMessages((prev) => [...prev, errorMessage]); } finally { setIsLoading(false); } }; const handleKeyDown = (e: React.KeyboardEvent) => { if (e.key === "Enter") { handleSend(); } }; return (
{!isOpen && ( )} {/* Khung Chat */} {isOpen && (
{/* Header */}
Trợ lý lịch sử.
{/* Nội dung Chat */}
{messages.map((msg) => (
{msg.text}
))} {isLoading && (
)}
{/* Khu vực Nhập Input */}
setInput(e.target.value)} onKeyDown={handleKeyDown} disabled={isLoading} className="flex-1 bg-gray-100 dark:bg-gray-800 border-transparent focus:border-brand-500 focus:bg-white dark:focus:bg-gray-900 focus:ring-1 focus:ring-brand-500/20 rounded-full px-4 py-2.5 text-sm outline-none transition-all" />
)}
); }