"use client"; import { ChevronRight, ExternalLink, FileText, type LucideIcon, MoreHorizontal, Plus, RefreshCw, Share, Trash2, Eye, } from "lucide-react"; import { useRouter } from "next/navigation"; import { useTranslations } from "next-intl"; import { useCallback, useState } from "react"; import { Collapsible, CollapsibleContent, CollapsibleTrigger, } from "@/components/ui/collapsible"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; import { SidebarGroup, SidebarGroupContent, SidebarGroupLabel, SidebarMenu, SidebarMenuAction, SidebarMenuButton, SidebarMenuItem, useSidebar, } from "@/components/ui/sidebar"; // Map of icon names to their components const actionIconMap: Record = { ExternalLink, FileText, Share, Trash2, MoreHorizontal, RefreshCw, }; interface NoteAction { name: string; icon: string; onClick: () => void; } interface NoteItem { name: string; url: string; icon: LucideIcon; id?: number; search_space_id?: number; actions?: NoteAction[]; } interface NavNotesProps { notes: NoteItem[]; onAddNote?: () => void; defaultOpen?: boolean; } export function NavNotes({ notes, onAddNote, defaultOpen = true }: NavNotesProps) { const t = useTranslations("sidebar"); const { isMobile } = useSidebar(); const router = useRouter(); const [isDeleting, setIsDeleting] = useState(null); const [isOpen, setIsOpen] = useState(defaultOpen); // Handle note deletion with loading state const handleDeleteNote = useCallback(async (noteId: number, deleteAction: () => void) => { setIsDeleting(noteId); try { await deleteAction(); } finally { setIsDeleting(null); } }, []); // Enhanced note item component const NoteItemComponent = useCallback( ({ note }: { note: NoteItem }) => { const isDeletingNote = isDeleting === note.id; return ( router.push(note.url)} disabled={isDeletingNote} className={`group/item relative ${isDeletingNote ? "opacity-50" : ""}`} size="sm" > {note.name} {note.actions && note.actions.length > 0 && ( More {note.actions.map((action, actionIndex) => { const ActionIcon = actionIconMap[action.icon] || FileText; const isDeleteAction = action.name.toLowerCase().includes("delete"); return ( { if (isDeleteAction) { handleDeleteNote(note.id || 0, action.onClick); } else { action.onClick(); } }} disabled={isDeletingNote} className={isDeleteAction ? "text-destructive" : ""} > {isDeletingNote && isDeleteAction ? "Deleting..." : action.name} ); })} )} ); }, [isDeleting, router, isMobile, handleDeleteNote] ); return (
{t("notes") || "Notes"}
{onAddNote && ( )}
{/* Note Items */} {notes.length > 0 ? ( notes.map((note) => ) ) : ( /* Empty state with create button */ {onAddNote ? ( {t("create_new_note") || "Create a new note"} ) : ( {t("no_notes") || "No notes yet"} )} )}
); }