Spaces:
Sleeping
Sleeping
'use client'; | |
import { ChatWithMessages } from '@/lib/types'; | |
import React, { useEffect } from 'react'; | |
import ChatList from './chat/ChatList'; | |
import { Card } from './ui/Card'; | |
import { useAtom, useAtomValue } from 'jotai'; | |
import { selectedMessageId } from '@/state/chat'; | |
import CodeResultDisplay from './CodeResultDisplay'; | |
export interface ChatInterfaceProps { | |
chat: ChatWithMessages; | |
userId?: string | null; | |
} | |
const ChatInterface: React.FC<ChatInterfaceProps> = ({ chat, userId }) => { | |
const [messageId, setMessageId] = useAtom(selectedMessageId); | |
const messageCodeResult = chat.messages.find( | |
message => message.id === messageId, | |
)?.result; | |
useEffect(() => { | |
if (messageId) return; | |
const lastMessageWithResult = | |
chat.messages.findLast(message => !!message.result) ?? | |
chat.messages[chat.messages.length - 1]; | |
setMessageId(lastMessageWithResult?.id); | |
}, [messageId]); | |
return ( | |
<div className="relative flex overflow-hidden space-x-4 size-full"> | |
<div | |
data-state={messageCodeResult?.payload ? 'open' : 'closed'} | |
className="pl-4 peer absolute right-0 inset-y-0 hidden translate-x-full data-[state=open]:translate-x-0 z-30 duration-300 ease-in-out xl:flex flex-col items-start xl:w-1/2 h-full dark:bg-zinc-950 overflow-auto" | |
> | |
{messageCodeResult?.type === 'final_code' && | |
messageCodeResult.payload && ( | |
<Card className="size-full overflow-auto"> | |
<CodeResultDisplay codeResult={messageCodeResult.payload} /> | |
</Card> | |
)} | |
</div> | |
<div className="w-full flex justify-center pr-0 animate-in duration-300 ease-in-out peer-[[data-state=open]]:xl:pr-[50%]"> | |
<ChatList chat={chat} userId={userId} /> | |
</div> | |
</div> | |
); | |
}; | |
export default ChatInterface; | |