'use client'; import { Menu, MenuButton, MenuItem, MenuItems, Transition } from '@headlessui/react'; import { Fragment, useRef, type CSSProperties, type ReactNode } from 'react'; import { useDrop } from 'react-dnd'; import type { Folder, SidebarFilter } from '@/types/documents'; import { PDFIcon, EPUBIcon, FileIcon, DotsHorizontalIcon } from '@/components/icons/Icons'; import { FolderIcon, HomeIcon, ClockIcon, FolderPlusIcon } from './finderIcons'; import { DND_DOCUMENT, type DocumentDragItem } from '../dnd/dndTypes'; interface FinderSidebarProps { filter: SidebarFilter; onFilterChange: (filter: SidebarFilter) => void; folders: Folder[]; counts: { all: number; pdf: number; epub: number; html: number }; onDeleteFolder: (folderId: string) => void; onNewFolder: () => void; onClearFolders: () => void; /** When dragging onto a folder row, move dropped docs into that folder. */ onDropOnFolder: (folderId: string, item: DocumentDragItem) => void; /** Width controls (desktop only). */ width: number; onWidthChange: (px: number) => void; topSlot?: ReactNode; bottomSlot?: ReactNode; /** Fired for explicit row/button actions (used to close mobile drawer). */ onRowAction?: () => void; } const MIN_WIDTH = 168; const MAX_WIDTH = 320; interface SidebarRowProps { active: boolean; onClick: () => void; icon: ReactNode; label: string; count?: number; countClassName?: string; trailing?: ReactNode; isDropTarget?: boolean; } function SidebarRow({ active, onClick, icon, label, count, countClassName, trailing, isDropTarget, }: SidebarRowProps) { return ( ); } function FolderRow({ folder, active, onClick, onDelete, onDropOnFolder, }: { folder: Folder; active: boolean; onClick: () => void; onDelete: () => void; onDropOnFolder: (folderId: string, item: DocumentDragItem) => void; }) { const [{ isOver, canDrop }, dropRef] = useDrop< DocumentDragItem, void, { isOver: boolean; canDrop: boolean } >(() => ({ accept: DND_DOCUMENT, drop: (item) => { onDropOnFolder(folder.id, item); }, canDrop: (item) => { // Don't accept if all items are already in this folder. return item.docs.some((d) => d.folderId !== folder.id); }, collect: (monitor) => ({ isOver: monitor.isOver({ shallow: true }), canDrop: monitor.canDrop(), }), }), [folder.id, onDropOnFolder]); const isDropTarget = isOver && canDrop; return (