import { forwardRef, useRef, useEffect } from "react" import { cn } from "../../utils/cn" import { Button } from "../ui/button" import { ChatPlusIcon, ChatsIcon } from "../icons-v2-generated" import { Chevron02RightIcon } from "../icons-v2-generated" import { ChatSidebarSkeleton, DialogListItemSkeleton } from "./chat-sidebar-skeleton" import type { ChatSidebarProps, DialogListItemProps } from "./types" const DialogListItem = forwardRef( ({ className, dialog, isActive, onDialogSelect, onClick, ...props }, ref) => { const handleClick = (e: React.MouseEvent) => { onDialogSelect?.(dialog.id) onClick?.(e) } const formatTimestamp = (timestamp?: Date | string) => { if (!timestamp) return '' const date = typeof timestamp === 'string' ? new Date(timestamp) : timestamp return date.toLocaleDateString('en-US', { year: 'numeric', month: '2-digit', day: '2-digit' }) + ', ' + date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', hour12: false }) } return (
{/* Content area */}

{dialog.title || 'Untitled Chat'}

{dialog.timestamp && (

{formatTimestamp(dialog.timestamp)}

)}
{/* Right side indicator - always visible */}
{dialog.unreadMessagesCount && dialog.unreadMessagesCount > 0 ? (
{dialog.unreadMessagesCount > 99 ? '99+' : dialog.unreadMessagesCount}
) : ( )}
) } ) DialogListItem.displayName = "DialogListItem" const ChatSidebar = forwardRef( ({ className, onNewChat, onDialogSelect, dialogs = [], activeDialogId, isLoading, isCreatingDialog, children, hasNextPage, isFetchingNextPage, onLoadMore, ...props }, ref) => { const showEmptyState = dialogs.length === 0 && !children const scrollContainerRef = useRef(null) const loadMoreRef = useRef(null) const onLoadMoreRef = useRef(onLoadMore) onLoadMoreRef.current = onLoadMore const isFetchingRef = useRef(isFetchingNextPage) isFetchingRef.current = isFetchingNextPage useEffect(() => { const scrollContainer = scrollContainerRef.current const loadMoreElement = loadMoreRef.current if (!scrollContainer || !loadMoreElement || !hasNextPage) return const observer = new IntersectionObserver( (entries) => { const [entry] = entries if (entry.isIntersecting && !isFetchingRef.current) { onLoadMoreRef.current?.() } }, { root: scrollContainer, rootMargin: '100px', threshold: 0.1 } ) observer.observe(loadMoreElement) return () => observer.disconnect() }, [hasNextPage]) if (isLoading && dialogs.length === 0 && !children) { return ( ) } return (
{/* Start New Chat Button */}
{/* Dialogs List or Content Area */}
{showEmptyState ? ( /* Empty State */

No Current Chats

Previous Mingo sessions will show here

) : children ? ( /* Custom children content */
{children}
) : ( /* Dialogs List */
{dialogs.map((dialog) => ( ))} {/* Infinite scroll loading indicator and intersection target */} {hasNextPage && (
{isFetchingNextPage && ( <> )}
)}
)}
) } ) ChatSidebar.displayName = "ChatSidebar" export { ChatSidebar, DialogListItem }