The hook mirrors the SDK client method fetchOfferDetails: it waits until the provider is ready, then loads details and exposes offerDetailsState (LOADING, ERROR, or CONTENT).When the user picks an offer from the grid, keep that offer in React state and pass offer.id — TypeScript then matches the branded id type the hook expects.
"use client";import type { ComponentProps } from "react";import { useState } from "react";import { OffersGrid } from "@coinlist-co/react/client/components";import { useCoinListOfferDetails } from "@coinlist-co/react/client/hooks";type OfferFromGrid = Parameters< NonNullable<ComponentProps<typeof OffersGrid>["onOfferClick"]>>[0];function OfferDetailPanel({ offer }: { offer: OfferFromGrid }) { const { offerDetailsState } = useCoinListOfferDetails(offer.id); if (offerDetailsState.type === "LOADING") return <p>Loading details…</p>; if (offerDetailsState.type === "ERROR") return <p>Unable to load this offer.</p>; const detail = offerDetailsState.offerDetail; return ( <section> <h1>{detail.name}</h1> {/* Render options, terms, milestones from detail — see API reference for fields */} </section> );}export function OfferBrowseAndDetail() { const [selected, setSelected] = useState<OfferFromGrid | null>(null); return ( <> <OffersGrid onOfferClick={(offer) => setSelected(offer)} /> {selected ? <OfferDetailPanel offer={selected} /> : null} </> );}