import React, { useState, useEffect, useRef } from "react"; import { Send } from "lucide-react"; import MessageBubble from "./MessageBubble"; import { useChat } from "@ai-sdk/react"; import { TextStreamChatTransport } from "ai"; import { generateChatId, getTextMessagesFromParts } from "@/lib/chat"; import { CHAT_STATUS } from "@/constants/chat"; import { useRouter, useSearchParams } from "next/navigation"; import useChatStore from "@/store/chatStore"; import EmptyChat from "./EmptyChat"; const ChatInterface = () => { const router = useRouter(); const searchParams = useSearchParams(); const chatParam = searchParams.get("chat"); const chatId = chatParam || generateChatId(); const initialMessages = useChatStore((state) => state.messages[chatId]); const saveChat = useChatStore((state) => state.addMessages); const [newMessage, setNewMessage] = useState(""); const messagesEndRef = useRef(null); const containerRef = useRef(null); const [autoScroll, setAutoScroll] = useState(true); const [isLoading, setIsLoading] = useState(true); const { messages, sendMessage, status } = useChat({ id: chatId, messages: initialMessages, transport: new TextStreamChatTransport({ api: `${process.env.NEXT_PUBLIC_API_URL}/chat`, }), onFinish: (message) => { saveChat(chatId, message.messages); }, }); useEffect(() => { if (autoScroll && containerRef.current) { messagesEndRef.current?.scrollIntoView({ behavior: "smooth" }); } }, [messages, autoScroll]); useEffect(() => { const container = containerRef.current; if (!container) return; const handleScroll = () => { const isAtBottom = container.scrollTop + container.clientHeight >= container.scrollHeight; setAutoScroll(isAtBottom); }; container.addEventListener("scroll", handleScroll); return () => container.removeEventListener("scroll", handleScroll); }, []); useEffect(() => { if (newMessage.trim() === "") return; if (chatId) { router.replace(`?chat=${chatId}`); } }, [chatId, router, newMessage]); const handleSendMessage = (e: React.FormEvent) => { e.preventDefault(); if (newMessage.trim() === "") return; sendMessage({ text: newMessage, }); setNewMessage(""); setAutoScroll(true); }; const allMessages = getTextMessagesFromParts(messages); useEffect(() => { setIsLoading(false); }, []); return (
{!isLoading && allMessages.length === 0 && (
)} {allMessages.length > 0 && (
{allMessages.map((message) => ( ))} {status === CHAT_STATUS.SUBMITTED && ( )} {status === CHAT_STATUS.ERROR && ( )}
)}
setNewMessage(e.target.value)} className="block w-full p-6 md:ps-10 text-sm text-primary-700 border border-tertiary-200 bg-tertiary-200/10 rounded-xl focus:outline-primary-500 focus:ring-primary-500" placeholder="Ask me anything about cooking, recipes, or ingredients..." required />
); }; export default ChatInterface;