'use client' import { ChevronRight, Lock } from 'lucide-react' import Link, { LinkProps } from 'next/link' import { usePathname } from 'next/navigation' import React, { useEffect, useState } from 'react' import { Badge, cn } from 'ui' import { useMobileMenu } from '@/hooks/use-mobile-menu' import { SidebarNavItem } from '@/types/nav' // We extend: // 1. LinkProps - for Next.js Link component props (prefetch, etc) // 2. AnchorHTMLAttributes - for standard HTML anchor props (className, etc) // We omit href from both since we compute it internally from item.href interface NavigationItemProps extends Omit, Omit, 'href'> { item: SidebarNavItem onClick?: (e: React.MouseEvent) => void level?: number internalPaths?: string[] isLoggedIn?: boolean } const NavigationItem: React.FC = ({ item, onClick, level = 0, internalPaths, isLoggedIn = true, ...props }) => { const { setOpen } = useMobileMenu() const pathname = usePathname() const [isOpen, setIsOpen] = useState(false) const pathParts = pathname.split('/') const slug = pathParts[pathParts.length - 1] const hasChildren = item.items && item.items.length > 0 // Check if internal content exists for this item and user is logged in const hasInternal = item.href && internalPaths?.includes(item.href) && isLoggedIn // Auto-expand if any child is active useEffect(() => { if (hasChildren) { const hasActiveChild = item.items?.some((child) => { return pathname === child.href }) if (hasActiveChild) { setIsOpen(true) } } }, [hasChildren, item.items, pathname]) // Use item.href if available, otherwise build from slug let href = item.href if (!href && slug) { href = `/docs/${slug}` } // Determine if this link represents the current page const isActive = pathname === href const handleLinkClick = (e: React.MouseEvent) => { // Close the mobile menu when navigating setOpen(false) // Call the onClick prop if it exists if (onClick) { onClick(e) } } const handleButtonClick = (e: React.MouseEvent) => { e.preventDefault() setIsOpen(!isOpen) } const itemClasses = cn( 'flex text-sm rounded-md transition-colors', level === 0 ? 'px-3 py-2' : 'px-3 py-1.5', isActive ? 'bg-surface-200 text-foreground' : hasChildren && isOpen ? 'bg-surface-100 text-foreground' : 'text-foreground-lighter hover:bg-surface-100 hover:text-foreground' ) return (
  • {hasChildren ? ( <> {isOpen && (
      {item.items?.map((childItem, i) => ( ))}
    )} ) : ( <> {item.title} {item.new && ( NEW )} {hasInternal && ( {item.title} (Internal) )} )}
  • ) } NavigationItem.displayName = 'NavigationItem' export default NavigationItem