{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "messages-dropdown", "title": "Messages Dropdown", "description": "Navbar dropdown for displaying recent messages with avatar, name, text preview, and timestamp.", "registryDependencies": [ "https://raw.githubusercontent.com/dnachavez/adminlte-next/master/public/r/adminlte-theme.json", "https://raw.githubusercontent.com/dnachavez/adminlte-next/master/public/r/adminlte-dropdown.json", "https://raw.githubusercontent.com/dnachavez/adminlte-next/master/public/r/adminlte-badge.json" ], "files": [ { "path": "registry/new-york/messages-dropdown/components/messages-dropdown.tsx", "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"@/registry/new-york/adminlte-theme/lib/cn\"\n\ninterface Message {\n id: string | number\n name: string\n avatarUrl: string\n text: string\n time: string\n href?: string\n}\n\ninterface MessagesDropdownProps extends React.HTMLAttributes {\n messages: Message[]\n count?: number\n onSeeAll?: () => void\n}\n\nconst MessagesDropdown = React.forwardRef(\n ({ className, messages, count, onSeeAll, ...props }, ref) => {\n const [isOpen, setIsOpen] = React.useState(false)\n const containerRef = React.useRef(null)\n\n const displayCount = count ?? messages.length\n\n React.useEffect(() => {\n const handleClickOutside = (e: MouseEvent) => {\n if (\n containerRef.current &&\n !containerRef.current.contains(e.target as Node)\n ) {\n setIsOpen(false)\n }\n }\n if (isOpen) {\n document.addEventListener(\"mousedown\", handleClickOutside)\n }\n return () => document.removeEventListener(\"mousedown\", handleClickOutside)\n }, [isOpen])\n\n return (\n {\n ;(containerRef as React.MutableRefObject).current = node\n if (typeof ref === \"function\") ref(node)\n else if (ref) ref.current = node\n }}\n className={cn(\"relative inline-block\", className)}\n {...props}\n >\n setIsOpen(!isOpen)}\n className=\"relative flex items-center justify-center w-[50px] h-[50px] bg-transparent border-none text-[var(--adminlte-skin-navbar-color)] cursor-pointer hover:bg-black/10\"\n aria-label=\"Messages\"\n >\n {/* Mail icon */}\n \n \n \n {displayCount > 0 && (\n \n {displayCount}\n \n )}\n \n\n {isOpen && (\n
    \n
  • \n You have {displayCount} messages\n
  • \n {messages.map((message) => (\n
  • \n \n
    \n \n
    \n
    \n

    \n {message.name}\n

    \n

    \n {message.text}\n

    \n

    \n \n \n \n {message.time}\n

    \n
    \n \n
  • \n ))}\n
  • \n {\n e.preventDefault()\n onSeeAll?.()\n }}\n className=\"text-[14px] text-[#3c8dbc] no-underline hover:underline\"\n >\n See All Messages\n \n
  • \n
\n )}\n \n )\n }\n)\nMessagesDropdown.displayName = \"MessagesDropdown\"\n\nexport { MessagesDropdown }\nexport type { MessagesDropdownProps, Message }\n", "type": "registry:component" } ], "type": "registry:component" }