'use client'; import { isToday, isYesterday, subMonths, subWeeks } from 'date-fns'; import Link from 'next/link'; import { useParams, usePathname, useRouter } from 'next/navigation'; import { type User } from 'next-auth'; import { useEffect, useState } from 'react'; import { toast } from 'sonner'; import useSWR from 'swr'; import { MoreHorizontalIcon, TrashIcon } from '@/components/icons'; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, } from '@/components/ui/alert-dialog'; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from '@/components/ui/dropdown-menu'; import { SidebarGroup, SidebarGroupContent, SidebarMenu, SidebarMenuAction, SidebarMenuButton, SidebarMenuItem, useSidebar, } from '@/components/ui/sidebar'; import { Chat } from '@/lib/db/schema'; import { fetcher } from '@/lib/utils'; type GroupedChats = { today: Chat[]; yesterday: Chat[]; lastWeek: Chat[]; lastMonth: Chat[]; older: Chat[]; }; const ChatItem = ({ chat, isActive, onDelete, setOpenMobile, }: { chat: Chat; isActive: boolean; onDelete: (chatId: string) => void; setOpenMobile: (open: boolean) => void; }) => ( setOpenMobile(false)}> {chat.title} More onDelete(chat.id)} > Delete ); export function SidebarHistory({ user }: { user: User | undefined }) { const { setOpenMobile } = useSidebar(); const { id } = useParams(); const pathname = usePathname(); const { data: history, isLoading, mutate, } = useSWR>(user ? '/api/history' : null, fetcher, { fallbackData: [], }); useEffect(() => { mutate(); }, [pathname, mutate]); const [deleteId, setDeleteId] = useState(null); const [showDeleteDialog, setShowDeleteDialog] = useState(false); const router = useRouter(); const handleDelete = async () => { const deletePromise = fetch(`/api/chat?id=${deleteId}`, { method: 'DELETE', }); toast.promise(deletePromise, { loading: 'Deleting chat...', success: () => { mutate((history) => { if (history) { return history.filter((h) => h.id !== id); } }); return 'Chat deleted successfully'; }, error: 'Failed to delete chat', }); setShowDeleteDialog(false); if (deleteId === id) { router.push('/'); } }; if (!user) { return (
Login to save and revisit previous chats!
); } if (isLoading) { return (
Today
{[44, 32, 28, 64, 52].map((item) => (
))}
); } if (history?.length === 0) { return (
Your conversations will appear here once you start chatting!
); } const groupChatsByDate = (chats: Chat[]): GroupedChats => { const now = new Date(); const oneWeekAgo = subWeeks(now, 1); const oneMonthAgo = subMonths(now, 1); return chats.reduce( (groups, chat) => { const chatDate = new Date(chat.createdAt); if (isToday(chatDate)) { groups.today.push(chat); } else if (isYesterday(chatDate)) { groups.yesterday.push(chat); } else if (chatDate > oneWeekAgo) { groups.lastWeek.push(chat); } else if (chatDate > oneMonthAgo) { groups.lastMonth.push(chat); } else { groups.older.push(chat); } return groups; }, { today: [], yesterday: [], lastWeek: [], lastMonth: [], older: [], } as GroupedChats ); }; return ( <> {history && (() => { const groupedChats = groupChatsByDate(history); return ( <> {groupedChats.today.length > 0 && ( <>
Today
{groupedChats.today.map((chat) => ( { setDeleteId(chatId); setShowDeleteDialog(true); }} setOpenMobile={setOpenMobile} /> ))} )} {groupedChats.yesterday.length > 0 && ( <>
Yesterday
{groupedChats.yesterday.map((chat) => ( { setDeleteId(chatId); setShowDeleteDialog(true); }} setOpenMobile={setOpenMobile} /> ))} )} {groupedChats.lastWeek.length > 0 && ( <>
Last 7 days
{groupedChats.lastWeek.map((chat) => ( { setDeleteId(chatId); setShowDeleteDialog(true); }} setOpenMobile={setOpenMobile} /> ))} )} {groupedChats.lastMonth.length > 0 && ( <>
Last 30 days
{groupedChats.lastMonth.map((chat) => ( { setDeleteId(chatId); setShowDeleteDialog(true); }} setOpenMobile={setOpenMobile} /> ))} )} {groupedChats.older.length > 0 && ( <>
Older
{groupedChats.older.map((chat) => ( { setDeleteId(chatId); setShowDeleteDialog(true); }} setOpenMobile={setOpenMobile} /> ))} )} ); })()}
Are you absolutely sure? This action cannot be undone. This will permanently delete your chat and remove it from our servers. Cancel Continue ); }