'use client'; import DeleteChat from '@/components/DeleteChat'; import BatchDeleteChats from '@/components/BatchDeleteChats'; import { cn, formatTimeDifference } from '@/lib/utils'; import { BookOpenText, Check, ClockIcon, Delete, ScanEye, Search, X } from 'lucide-react'; import Link from 'next/link'; import { useEffect, useState } from 'react'; import { toast } from 'sonner'; export interface Chat { id: string; title: string; createdAt: string; focusMode: string; } const Page = () => { const [chats, setChats] = useState([]); const [filteredChats, setFilteredChats] = useState([]); const [loading, setLoading] = useState(true); const [searchQuery, setSearchQuery] = useState(''); const [selectionMode, setSelectionMode] = useState(false); const [selectedChats, setSelectedChats] = useState([]); const [hoveredChatId, setHoveredChatId] = useState(null); const [isDeleteDialogOpen, setIsDeleteDialogOpen] = useState(false); useEffect(() => { const fetchChats = async () => { setLoading(true); const res = await fetch(`/api/chats`, { method: 'GET', headers: { 'Content-Type': 'application/json', }, }); const data = await res.json(); setChats(data.chats); setFilteredChats(data.chats); setLoading(false); }; fetchChats(); }, []); useEffect(() => { if (searchQuery.trim() === '') { setFilteredChats(chats); } else { const filtered = chats.filter((chat) => chat.title.toLowerCase().includes(searchQuery.toLowerCase()) ); setFilteredChats(filtered); } }, [searchQuery, chats]); const handleSearchChange = (e: React.ChangeEvent) => { setSearchQuery(e.target.value); }; const clearSearch = () => { setSearchQuery(''); }; const toggleSelectionMode = () => { setSelectionMode(!selectionMode); setSelectedChats([]); }; const toggleChatSelection = (chatId: string) => { if (selectedChats.includes(chatId)) { setSelectedChats(selectedChats.filter(id => id !== chatId)); } else { setSelectedChats([...selectedChats, chatId]); } }; const selectAllChats = () => { if (selectedChats.length === filteredChats.length) { setSelectedChats([]); } else { setSelectedChats(filteredChats.map(chat => chat.id)); } }; const deleteSelectedChats = () => { if (selectedChats.length === 0) return; setIsDeleteDialogOpen(true); }; const handleBatchDeleteComplete = () => { setSelectedChats([]); setSelectionMode(false); }; const updateChatsAfterDelete = (newChats: Chat[]) => { setChats(newChats); setFilteredChats(newChats.filter(chat => searchQuery.trim() === '' || chat.title.toLowerCase().includes(searchQuery.toLowerCase()) )); }; return loading ? (
) : (

Library


{/* Search Box */}
{searchQuery && ( )}
{/* Thread Count and Selection Controls */}
{!selectionMode ? (
You have {chats.length} threads in Perplexica
) : (
{selectedChats.length} selected thread{selectedChats.length !== 1 ? 's' : ''}
)}
{filteredChats.length === 0 && (

{searchQuery ? 'No threads found matching your search.' : 'No threads found.'}

)} {filteredChats.length > 0 && (
{filteredChats.map((chat, i) => (
setHoveredChatId(chat.id)} onMouseLeave={() => setHoveredChatId(null)} >
{/* Checkbox - visible when in selection mode or when hovering */} {(selectionMode || hoveredChatId === chat.id) && (
{ e.preventDefault(); if (!selectionMode) setSelectionMode(true); toggleChatSelection(chat.id); }} >
{selectedChats.includes(chat.id) && ( )}
)} {/* Chat Title */} { if (selectionMode) { e.preventDefault(); toggleChatSelection(chat.id); } }} > {chat.title}

{formatTimeDifference(new Date(), chat.createdAt)} Ago

{/* Delete button - only visible when not in selection mode */} {!selectionMode && ( )}
))}
)} {/* Batch Delete Confirmation Dialog */}
); }; export default Page;