Spaces:
Paused
Paused
| import { Trash } from 'lucide-react'; | |
| import { | |
| Description, | |
| Dialog, | |
| DialogBackdrop, | |
| DialogPanel, | |
| DialogTitle, | |
| Transition, | |
| TransitionChild, | |
| } from '@headlessui/react'; | |
| import { Fragment, useState } from 'react'; | |
| import { toast } from 'sonner'; | |
| import { Chat } from '@/app/library/page'; | |
| const DeleteChat = ({ | |
| chatId, | |
| chats, | |
| setChats, | |
| redirect = false, | |
| }: { | |
| chatId: string; | |
| chats: Chat[]; | |
| setChats: (chats: Chat[]) => void; | |
| redirect?: boolean; | |
| }) => { | |
| const [confirmationDialogOpen, setConfirmationDialogOpen] = useState(false); | |
| const [loading, setLoading] = useState(false); | |
| const handleDelete = async () => { | |
| setLoading(true); | |
| try { | |
| const res = await fetch( | |
| `${process.env.NEXT_PUBLIC_API_URL}/chats/${chatId}`, | |
| { | |
| method: 'DELETE', | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| }, | |
| }, | |
| ); | |
| if (res.status != 200) { | |
| throw new Error('Failed to delete chat'); | |
| } | |
| const newChats = chats.filter((chat) => chat.id !== chatId); | |
| setChats(newChats); | |
| if (redirect) { | |
| window.location.href = '/'; | |
| } | |
| } catch (err: any) { | |
| toast.error(err.message); | |
| } finally { | |
| setConfirmationDialogOpen(false); | |
| setLoading(false); | |
| } | |
| }; | |
| return ( | |
| <> | |
| <button | |
| onClick={() => { | |
| setConfirmationDialogOpen(true); | |
| }} | |
| className="bg-transparent text-red-400 hover:scale-105 transition duration-200" | |
| > | |
| <Trash size={17} /> | |
| </button> | |
| <Transition appear show={confirmationDialogOpen} as={Fragment}> | |
| <Dialog | |
| as="div" | |
| className="relative z-50" | |
| onClose={() => { | |
| if (!loading) { | |
| setConfirmationDialogOpen(false); | |
| } | |
| }} | |
| > | |
| <DialogBackdrop className="fixed inset-0 bg-black/30" /> | |
| <div className="fixed inset-0 overflow-y-auto"> | |
| <div className="flex min-h-full items-center justify-center p-4 text-center"> | |
| <TransitionChild | |
| as={Fragment} | |
| enter="ease-out duration-200" | |
| enterFrom="opacity-0 scale-95" | |
| enterTo="opacity-100 scale-100" | |
| leave="ease-in duration-100" | |
| leaveFrom="opacity-100 scale-200" | |
| leaveTo="opacity-0 scale-95" | |
| > | |
| <DialogPanel className="w-full max-w-md transform rounded-2xl bg-light-secondary dark:bg-dark-secondary border border-light-200 dark:border-dark-200 p-6 text-left align-middle shadow-xl transition-all"> | |
| <DialogTitle className="text-lg font-medium leading-6 dark:text-white"> | |
| Delete Confirmation | |
| </DialogTitle> | |
| <Description className="text-sm dark:text-white/70 text-black/70"> | |
| Are you sure you want to delete this chat? | |
| </Description> | |
| <div className="flex flex-row items-end justify-end space-x-4 mt-6"> | |
| <button | |
| onClick={() => { | |
| if (!loading) { | |
| setConfirmationDialogOpen(false); | |
| } | |
| }} | |
| className="text-black/50 dark:text-white/50 text-sm hover:text-black/70 hover:dark:text-white/70 transition duration-200" | |
| > | |
| Cancel | |
| </button> | |
| <button | |
| onClick={handleDelete} | |
| className="text-red-400 text-sm hover:text-red-500 transition duration200" | |
| > | |
| Delete | |
| </button> | |
| </div> | |
| </DialogPanel> | |
| </TransitionChild> | |
| </div> | |
| </div> | |
| </Dialog> | |
| </Transition> | |
| </> | |
| ); | |
| }; | |
| export default DeleteChat; | |