{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "use-product-recommendations",
  "title": "useProductRecommendations",
  "description": "Lazily fetches similar products when the section scrolls into view, via an injected fetcher, so it never blocks the PDP.",
  "dependencies": [
    "@channel3/sdk",
    "@tanstack/react-query"
  ],
  "registryDependencies": [
    "https://ui.trychannel3.com/r/use-in-viewport.json"
  ],
  "files": [
    {
      "path": "registry/default/hooks/use-product-recommendations.ts",
      "content": "import * as React from \"react\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport type { Product, SearchFilters } from \"@channel3/sdk/resources\";\n\nimport { useInViewport } from \"@/registry/default/hooks/use-in-viewport\";\n\nexport interface SimilarFetchInput {\n  productId: string;\n  limit: number;\n  filters?: SearchFilters;\n}\n\n/**\n * Fetches products similar to `productId`. Implement on the consumer side so\n * the Channel3 API key stays on your server: call\n * `client.products.findSimilar({ product_id, limit, filters })` and return its\n * `.products`.\n */\nexport type SimilarFetcher = (input: SimilarFetchInput) => Promise<Product[]>;\n\nexport interface UseProductRecommendationsOptions {\n  productId: string | undefined;\n  fetchSimilar: SimilarFetcher;\n  limit?: number;\n  filters?: SearchFilters;\n  eager?: boolean;\n  enabled?: boolean;\n}\n\nexport interface UseProductRecommendationsResult {\n  ref: (node: Element | null) => void;\n  products: Product[];\n  isLoading: boolean;\n  error: unknown;\n  hasLoaded: boolean;\n}\n\nconst EMPTY: Product[] = [];\n\nexport function useProductRecommendations({\n  productId,\n  fetchSimilar,\n  limit = 12,\n  filters,\n  eager = false,\n  enabled = true,\n}: UseProductRecommendationsOptions): UseProductRecommendationsResult {\n  const [inView, setInView] = React.useState(eager);\n  const [node, setNode] = React.useState<Element | null>(null);\n  const ref = React.useCallback((next: Element | null) => setNode(next), []);\n\n  React.useEffect(() => {\n    setInView(eager);\n  }, [productId, eager]);\n\n  useInViewport(node, () => setInView(true), { enabled: !eager && !inView, once: true });\n\n  const query = useQuery({\n    queryKey: [\"channel3-similar\", productId, limit, filters],\n    queryFn: () => fetchSimilar({ productId: productId!, limit, filters }),\n    enabled: Boolean(enabled && inView && productId),\n  });\n\n  return {\n    ref,\n    products: query.data ?? EMPTY,\n    isLoading: query.isFetching,\n    error: query.error,\n    hasLoaded: query.isSuccess,\n  };\n}\n",
      "type": "registry:hook"
    }
  ],
  "type": "registry:hook"
}
