"use client"; import { aiChatListQueryKey, useAiChatListQuery, useAiChatQuery, useCreateAiChatMutation, } from "@saas/ai/lib/api"; import { SidebarContentLayout } from "@saas/shared/components/SidebarContentLayout"; import { useQueryClient } from "@tanstack/react-query"; import { Button } from "@ui/components/button"; import { Textarea } from "@ui/components/textarea"; import { cn } from "@ui/lib"; import { type Message, useChat } from "ai/react"; import { EllipsisIcon, PlusIcon, SendIcon } from "lucide-react"; import { useFormatter } from "next-intl"; import { useQueryState } from "nuqs"; import { useCallback, useEffect, useMemo } from "react"; export function AiChat({ organizationId }: { organizationId?: string }) { const formatter = useFormatter(); const queryClient = useQueryClient(); const { data: chats, status: chatsStatus } = useAiChatListQuery(organizationId); const [chatId, setChatId] = useQueryState("chatId"); const { data: currentChat } = useAiChatQuery(chatId ?? "new"); const createChatMutation = useCreateAiChatMutation(); const { messages, input, handleInputChange, handleSubmit, isLoading, setMessages, } = useChat({ api: `/api/ai/chats/${chatId}/messages`, credentials: "include", initialMessages: [], }); useEffect(() => { if (currentChat?.messages?.length) { setMessages(currentChat.messages as unknown as Message[]); } }, [currentChat]); const createNewChat = useCallback(async () => { const newChat = await createChatMutation.mutateAsync({ organizationId, }); await queryClient.invalidateQueries({ queryKey: aiChatListQueryKey(organizationId), }); setChatId(newChat.id); }, [createChatMutation]); useEffect(() => { (async () => { if (chatId || chatsStatus !== "success") { return; } if (chats?.length) { setChatId(chats[0].id); } else { await createNewChat(); setMessages([]); } })(); }, [chatsStatus]); const hasChat = chatsStatus === "success" && !!chats?.length && !!currentChat?.id; const sortedChats = useMemo(() => { return ( chats?.sort( (a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime(), ) ?? [] ); }, [chats]); return ( {sortedChats.map((chat) => (
))} } >
{messages.map((message, index) => (
{message.content}
))} {isLoading && (
)}