import { type ReactNode } from 'react'; import { Unplug } from 'lucide-react'; import { useNodes } from '@/context/NodeContext'; import type { Capability } from '@/lib/capabilities'; import { isValidVersion } from '@/lib/version'; import { LockCard } from './ui/LockCard'; interface CapabilityGateProps { capability: Capability; featureName?: string; children: ReactNode; } /** * Renders children only when the active node advertises the required * capability. When it does not, returns a clean lock card explaining the * version mismatch instead of rendering the gated UI. * * Short-circuiting is load-bearing: callers wrap CapabilityGate around * lazy-loaded views, and rendering the gated children to "blur and * overlay" them would still trigger the chunk fetch (and ship the JSX * to anyone who opens DevTools). The lock card has no children * dependency and adds no chunk weight, so a node that lacks the * capability never downloads the gated module. */ export function CapabilityGate({ capability, featureName = 'This feature', children }: CapabilityGateProps) { const { hasCapability, activeNode, activeNodeMeta } = useNodes(); if (hasCapability(capability)) return <>{children}; const nodeName = activeNode?.name ?? 'this node'; const versionHint = isValidVersion(activeNodeMeta?.version) ? `${nodeName} is running v${activeNodeMeta.version}.` : `${nodeName} does not advertise this capability.`; return ( ); }