"use client"; import { useQuery, useQueryClient } from "@tanstack/react-query"; import { Loader2, MessageCircleMore, MoreHorizontal, Search, Trash2, X } from "lucide-react"; import { useRouter } from "next/navigation"; import { useTranslations } from "next-intl"; import { useCallback, useMemo, useState } from "react"; import { toast } from "sonner"; import { Button } from "@/components/ui/button"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; import { Input } from "@/components/ui/input"; import { ScrollArea } from "@/components/ui/scroll-area"; import { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle, } from "@/components/ui/sheet"; import { useDebouncedValue } from "@/hooks/use-debounced-value"; import { chatsApiService } from "@/lib/apis/chats-api.service"; import { cn } from "@/lib/utils"; interface AllChatsSidebarProps { open: boolean; onOpenChange: (open: boolean) => void; searchSpaceId: string; } export function AllChatsSidebar({ open, onOpenChange, searchSpaceId, }: AllChatsSidebarProps) { const t = useTranslations("sidebar"); const router = useRouter(); const queryClient = useQueryClient(); const [deletingChatId, setDeletingChatId] = useState(null); const [searchQuery, setSearchQuery] = useState(""); const debouncedSearchQuery = useDebouncedValue(searchQuery, 300); // Fetch all chats const { data: chatsData, error: chatsError, isLoading: isLoadingChats, } = useQuery({ queryKey: ["all-chats", searchSpaceId], queryFn: () => chatsApiService.getChats({ queryParams: { search_space_id: Number(searchSpaceId), }, }), enabled: !!searchSpaceId && open, }); // Handle chat navigation const handleChatClick = useCallback( (chatId: number, chatSearchSpaceId: number) => { router.push(`/dashboard/${chatSearchSpaceId}/researcher/${chatId}`); onOpenChange(false); }, [router, onOpenChange] ); // Handle chat deletion const handleDeleteChat = useCallback( async (chatId: number) => { setDeletingChatId(chatId); try { await chatsApiService.deleteChat({ id: chatId }); toast.success(t("chat_deleted") || "Chat deleted successfully"); // Invalidate queries to refresh the list queryClient.invalidateQueries({ queryKey: ["all-chats", searchSpaceId] }); queryClient.invalidateQueries({ queryKey: ["chats"] }); } catch (error) { console.error("Error deleting chat:", error); toast.error(t("error_deleting_chat") || "Failed to delete chat"); } finally { setDeletingChatId(null); } }, [queryClient, searchSpaceId, t] ); // Clear search const handleClearSearch = useCallback(() => { setSearchQuery(""); }, []); // Filter chats based on search query (client-side filtering) const chats = useMemo(() => { const allChats = chatsData ?? []; if (!debouncedSearchQuery) { return allChats; } const query = debouncedSearchQuery.toLowerCase(); return allChats.filter((chat) => chat.title.toLowerCase().includes(query) ); }, [chatsData, debouncedSearchQuery]); const isSearchMode = !!debouncedSearchQuery; return ( {t("all_chats") || "All Chats"} {t("all_chats_description") || "Browse and manage all your chats"} {/* Search Input */}
setSearchQuery(e.target.value)} className="pl-9 pr-8 h-9" /> {searchQuery && ( )}
{isLoadingChats ? (
) : chatsError ? (
{t("error_loading_chats") || "Error loading chats"}
) : chats.length > 0 ? (
{chats.map((chat) => { const isDeleting = deletingChatId === chat.id; return (
{/* Main clickable area for navigation */} {/* Actions dropdown - separate from main click area */} handleDeleteChat(chat.id)} className="text-destructive focus:text-destructive" > Delete
); })}
) : isSearchMode ? (

{t("no_chats_found") || "No chats found"}

{t("try_different_search") || "Try a different search term"}

) : (

{t("no_chats") || "No chats yet"}

{t("start_new_chat_hint") || "Start a new chat from the researcher"}

)}
); }