'use client' import { useState, useEffect } from 'react' import { useChat } from '@ai-sdk/react' import { DefaultChatTransport, type UIMessage } from 'ai' import { Button } from '~/components/ui/button' import { Textarea } from '~/components/ui/textarea' import { useGsapContext, } from '~/app/_providers/GsapProvicer'; import Messages from './Messages' import { DeleteIcon } from 'lucide-react'; import { trpc } from '~/app/_trpc/Client' import { Spinner } from '~/components/ui/spinner'; interface DBMessage { id: string role: 'user' | 'assistant' content: string } interface ChatInterfaceProps { sessionId?: string // initialMessages: DBMessage[] } function toUIMessages(dbMessages: DBMessage[]): UIMessage[] { return dbMessages.map((m) => ({ id: m.id, role: m.role, parts: [{ type: 'text' as const, text: m.content }], })) } export default function ChatInterface({ sessionId }: ChatInterfaceProps) { const utils = trpc.useUtils(); const { data: dbMessages, refetch: refetchMessages } = trpc.chat.getMessages.useQuery(sessionId ? sessionId : "") const [messages, setMessages] = useState([]); function addMessage(newMessage: UIMessage) { setMessages(prev => [...prev, newMessage]); } useEffect(() => { setMessages(toUIMessages(dbMessages ?? [])); }, [dbMessages]); if (messages.at(0)?.id != 'init') { messages.unshift({ id: "init", role: 'assistant', parts: [{ type: 'text', text: "Hi im gregors ai assistant,you can ask me to provide general information or to schedule a meeting." }], }) } const [input, setInput] = useState('') const { sendMessage, status, error, clearError } = useChat({ transport: new DefaultChatTransport({ api: '/api/chat', body: { sessionId }, }), messages: messages, }) const handleSend = () => { const text = input.trim() if (!text || status != 'ready') return setInput('') sendMessage({ text }) addMessage({ id: "", role: "user", parts: [ { type: 'text', text } ] }) addMessage({ id: "", role: "assistant", parts: [ { type: 'text', text: "Thinking..." } ] }) } const clearChatMutation = trpc.chat.clearChat.useMutation() const handleClear = () => { clearChatMutation.mutate(undefined, { onSuccess: () => { utils.chat.getMessages.invalidate() refetchMessages() } }) } const gsapContext = useGsapContext() useEffect(() => { console.log(status) if (status == 'ready') { utils.chat.getMessages.invalidate(); refetchMessages() } }, [status]) useEffect(() => { let scroller = gsapContext?.getScroller() if (scroller instanceof Window) { return; } console.log(scroller?.scrollHeight) scroller?.scrollTo({ behavior: 'smooth', top: scroller.scrollHeight }) }, [messages]) return (
{messages && } {error && (
{error.message.includes('quota') || error.message.includes('429') ? 'OpenAI quota exceeded. Please try again later.' : `Error: ${error.message}`}
)}