"use client"; import { useQuery, useQueryClient } from "@tanstack/react-query"; import { format } from "date-fns"; import { Loader2, MessageCircleMore, MoreHorizontal, Search, Trash2, X } from "lucide-react"; import { useRouter } from "next/navigation"; import { useTranslations } from "next-intl"; import { useCallback, 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 { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"; 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); const isSearchMode = !!debouncedSearchQuery.trim(); // Fetch all chats (when not searching) const { data: chatsData, error: chatsError, isLoading: isLoadingChats, } = useQuery({ queryKey: ["all-chats", searchSpaceId], queryFn: () => chatsApiService.getChats({ queryParams: { search_space_id: Number(searchSpaceId), }, }), enabled: !!searchSpaceId && open && !isSearchMode, }); // Search chats (when searching) const { data: searchData, error: searchError, isLoading: isLoadingSearch, } = useQuery({ queryKey: ["search-chats", searchSpaceId, debouncedSearchQuery], queryFn: () => chatsApiService.searchChats({ queryParams: { title: debouncedSearchQuery.trim(), search_space_id: Number(searchSpaceId), }, }), enabled: !!searchSpaceId && open && isSearchMode, }); // 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: ["search-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(""); }, []); // Determine which data source to use and loading/error states const chats = isSearchMode ? (searchData ?? []) : (chatsData ?? []); const isLoading = isSearchMode ? isLoadingSearch : isLoadingChats; const error = isSearchMode ? searchError : chatsError; 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 && ( )}
{isLoading ? (
) : error ? (
{t("error_loading_chats") || "Error loading chats"}
) : chats.length > 0 ? (
{chats.map((chat) => { const isDeleting = deletingChatId === chat.id; return (
{/* Main clickable area for navigation */}

{t("created") || "Created"}:{" "} {format(new Date(chat.created_at), "MMM d, yyyy 'at' h:mm a")}

{/* Actions dropdown - separate from main click area */} handleDeleteChat(chat.id)} className="text-destructive focus:text-destructive" > {t("delete") || "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"}

)}
); }