Spaces:
Runtime error
Runtime error
"use client"; | |
import React from "react"; | |
import { DialogClose } from "@radix-ui/react-dialog"; | |
import { ChatBubbleIcon, GearIcon, TrashIcon } from "@radix-ui/react-icons"; | |
import * as Tabs from "@radix-ui/react-tabs"; | |
import { Message } from "ai/react"; | |
import Link from "next/link"; | |
import { buttonVariants } from "@/components/ui/button"; | |
import { cn } from "@/lib/utils"; | |
import { ChatOptions } from "./chat/chat-options"; | |
import Settings from "./settings"; | |
import SidebarSkeleton from "./sidebar-skeleton"; | |
import { | |
Dialog, | |
DialogContent, | |
DialogDescription, | |
DialogHeader, | |
DialogTitle, | |
DialogTrigger, | |
} from "./ui/dialog"; | |
interface Chats { | |
[key: string]: { chatId: string; messages: Message[] }[]; | |
} | |
interface SidebarTabsProps { | |
isLoading: boolean; | |
localChats: Chats; | |
selectedChatId: string; | |
chatOptions: ChatOptions; | |
setChatOptions: React.Dispatch<React.SetStateAction<ChatOptions>>; | |
handleDeleteChat: (chatId: string) => void; | |
} | |
const SidebarTabs = ({ | |
localChats, | |
selectedChatId, | |
isLoading, | |
chatOptions, | |
setChatOptions, | |
handleDeleteChat, | |
}: SidebarTabsProps) => ( | |
<Tabs.Root | |
className="overflow-hidden h-full bg-accent/20 dark:bg-card/35" | |
defaultValue="chats" | |
> | |
<div className=" text-sm o h-full"> | |
<Tabs.Content className="h-screen overflow-y-auto" value="chats"> | |
<div className="h-full mb-28"> | |
{Object.keys(localChats).length > 0 && ( | |
<> | |
{Object.keys(localChats).map((group, index) => ( | |
<div key={index} className="flex flex-col py-2 pl-3 pr-1 gap-2 mb-8"> | |
<p className="px-2 text-xs font-medium text-muted-foreground"> | |
{group} | |
</p> | |
<ol> | |
{localChats[group].map( | |
({ chatId, messages }, chatIndex) => { | |
const isSelected = | |
chatId.substring(5) === selectedChatId; | |
return ( | |
<li | |
className="flex w-full items-center relative" | |
key={chatIndex} | |
> | |
<div className="flex-col w-full truncate"> | |
<Link | |
href={`/chats/${chatId.substring(5)}`} | |
className={cn( | |
{ | |
[buttonVariants({ | |
variant: "secondaryLink", | |
})]: isSelected, | |
[buttonVariants({ variant: "ghost" })]: | |
!isSelected, | |
}, | |
"flex gap-2 p-2 justify-start" | |
)} | |
> | |
<span className="text-sm font-normal max-w-[184px] truncate"> | |
{messages.length > 0 | |
? messages[0].content | |
: ""} | |
</span> | |
</Link> | |
</div> | |
<div className="absolute right-0 rounded-xs"> | |
<Dialog> | |
<DialogTrigger | |
className={ | |
"items-center whitespace-nowrap font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 h-8 rounded-sm px-3 text-xs justify-start gap-2 w-full hover:text-red-500 hover:bg-card dark:hover:bg-accent" + | |
(isSelected | |
? " bg-accent dark:bg-card" | |
: " ") | |
} | |
> | |
<TrashIcon className="w-4 h-4" /> | |
</DialogTrigger> | |
<DialogContent> | |
<DialogHeader className="space-y-4"> | |
<DialogTitle>Delete chat?</DialogTitle> | |
<DialogDescription> | |
Are you sure you want to delete this chat? | |
This action cannot be undone. | |
</DialogDescription> | |
<div className="flex justify-end gap-2"> | |
<DialogClose className="border border-input bg-background hover:bg-accent hover:text-accent-foreground px-4 py-2 rounded-sm"> | |
Cancel | |
</DialogClose> | |
<DialogClose | |
className="bg-destructive text-destructive-foreground hover:bg-destructive/90 px-4 py-2 rounded-sm" | |
onClick={() => handleDeleteChat(chatId)} | |
> | |
Delete | |
</DialogClose> | |
</div> | |
</DialogHeader> | |
</DialogContent> | |
</Dialog> | |
</div> | |
</li> | |
); | |
} | |
)} | |
</ol> | |
</div> | |
))} | |
</> | |
)} | |
{isLoading && <SidebarSkeleton />} | |
</div> | |
</Tabs.Content> | |
<Tabs.Content className="h-screen overflow-y-auto" value="settings"> | |
<div className="h-full mb-16 pl-2"> | |
<Settings chatOptions={chatOptions} setChatOptions={setChatOptions} /> | |
</div> | |
</Tabs.Content> | |
</div> | |
<div className="sticky left-0 right-0 bottom-0 z-20 m-0 overflow-hidden"> | |
<Tabs.List | |
className="flex flex-wrap -mb-px py-2 text-sm font-medium text-center justify-center gap-2 bg-accent dark:bg-card" | |
aria-label="Navigation" | |
> | |
<Tabs.Trigger | |
className="inline-flex items-center justify-center p-0.5 rounded-sm data-[state=active]:bg-gray-200 dark:data-[state=active]:bg-gray-700 h-10 w-10" | |
value="chats" | |
> | |
<ChatBubbleIcon className="w-5 h-5" /> | |
{/* <span className="text-xs">Chats</span> */} | |
</Tabs.Trigger> | |
<Tabs.Trigger | |
className="inline-flex items-center justify-center p-0.5 rounded-sm data-[state=active]:bg-gray-200 dark:data-[state=active]:bg-gray-700 h-10 w-10" | |
value="settings" | |
> | |
<GearIcon className="w-5 h-5" /> | |
{/* <span className="text-xs">Settings</span> */} | |
</Tabs.Trigger> | |
</Tabs.List> | |
</div> | |
</Tabs.Root> | |
); | |
export default SidebarTabs; | |