OrderHistory
Pure presentation of the order history. It never fetches; the
caller passes the resolved orders page (via useOrders) and owns
pagination. Compose children for a bespoke layout, or omit children (plus
orders + renderItem) for the standard card list.
import { OrderHistory } from "@evolve-storefront/feature-order/order-history";Renders inside OrderProvider.
Preview
Usage
The filtered history, which is the whole composition a consumer writes.
// A Server Component. `page`, `search`, `status` and the dates all come// from searchParams, so the filtered list is a shareable URL.const { createdFrom, createdUntil } = orderDateRange({ from: query.from, until: query.until, timeZone: shopperTimeZone,});
const orders = await gqlClient(GetBusinessOrders, { businessUnitId, page, pageSize: PAGE_SIZE, searchTerm: query.search, status: query.status ? [query.status] : undefined, createdFrom, createdUntil,}).then((response) => response.data?.businessUnit?.orders);
<> <OrderHistoryFilters searchTerm={query.search} createdFrom={query.from} createdUntil={query.until} /> <OrderHistoryStatusFilter status={query.status} renderLink={({ status, children }) => ( <Link href={ordersHref({ ...query, status, page: undefined })}> {children} </Link> )} /> {/* Only the list waits — the filters render immediately. */} <Suspense key={`${page}:${query.search ?? ""}`} fallback={<OrderHistorySkeleton />}> <OrderHistory orders={orders?.items ?? []} pagination={orders?.pagination} renderLink={pageLink(query)} noResults={Boolean(query.search)} renderItem={renderItem} /> </Suspense></>;Props
No props of its own.
Change the layout
Pass children to OrderHistory to arrange its parts yourself. Every part is exported from @evolve-storefront/feature-order/order-history.
// A Server Component. `page`, `search`, `status` and the dates all come// from searchParams, so the filtered list is a shareable URL.const { createdFrom, createdUntil } = orderDateRange({ from: query.from, until: query.until, timeZone: shopperTimeZone,});
const orders = await gqlClient(GetBusinessOrders, { businessUnitId, page, pageSize: PAGE_SIZE, searchTerm: query.search, status: query.status ? [query.status] : undefined, createdFrom, createdUntil,}).then((response) => response.data?.businessUnit?.orders);
<> <OrderHistoryFilters searchTerm={query.search} createdFrom={query.from} createdUntil={query.until} /> <OrderHistoryStatusFilter status={query.status} renderLink={({ status, children }) => ( <Link href={ordersHref({ ...query, status, page: undefined })}> {children} </Link> )} /> {/* Only the list waits — the filters render immediately. */} <Suspense key={`${page}:${query.search ?? ""}`} fallback={<OrderHistorySkeleton />}> <OrderHistory orders={orders?.items ?? []} pagination={orders?.pagination} renderLink={pageLink(query)} noResults={Boolean(query.search)} renderItem={renderItem} /> </Suspense></>;OrderCardSummary card for one order: number, date, status, total and a few product thumbnails.
| Prop | Type | Description |
|---|---|---|
order | OrderSummary | |
actions? | ReactNode | Per-card action (e.g. a "View order" link) — composed by the caller. |
Any other props go to the root element, like on a plain HTML element.
OrderHistoryFiltersSearch and date-range filters for the order history: a GET form of named fields, with no handlers, so a Server Component can render it.
Render it outside the boundary that suspends on the orders — a field inside it is
blanked by its own submission. The dates are yyyy-mm-dd days; pass them through
orderDateRange before useOrders, which takes instants. What the search matches,
and why the placeholder ships here: README, "Filtering the history".
| Prop | Type | Description |
|---|---|---|
searchTerm? | string | The term currently applied, echoed back into the field. |
createdFrom? | string | The applied lower bound as |
createdUntil? | string | The applied upper bound as |
names? | OrderHistoryFilterNames | Override the field names to match the page's search params. |
dates? | boolean | Offer the date range. Defaults to true; a consumer store with few orders turns it off. |
purchaseOrders? | boolean | Name purchase order numbers in the search placeholder. Defaults to true; consumers have none. |
children? | ReactNode | Extra controls, rendered after the built-in ones and before the submit. |
Any other props go to the root element, like on a plain HTML element.
OrderHistoryItemsThe order list plus its pager.
Pass renderLink to page by navigation and keep the whole subtree
server-rendered, or onPageChange to page from client state. Neither renders
no pager; both is a type error.
No props of its own.
OrderHistoryResultCount"12 results": how many orders match the current search and filters.
| Prop | Type | Description |
|---|---|---|
pagination? | Pagination | The list query's |
Any other props go to the root element, like on a plain HTML element.
OrderHistoryStatusFilterState filter for the order history.
The "all orders" tab omits the filter, which leaves cancelled orders out — so
CANCELLED is its own tab rather than a row inside the first one. One tab is one
state and the query argument is a list, so a caller wraps:
status: status ? [status] : undefined.
No props of its own.
OrderHistoryTableThe order history as a table, for buyers who compare and search: date, number, purchase order reference, who ordered, status and the total excluding VAT.
No props of its own.
Loading and empty states
Render these while the data loads or when there is nothing to show, so the page does not jump when it arrives.
| Loading | OrderCardSkeleton | Loading state for OrderCard. |
| Empty | OrderHistoryEmpty | Empty state — a friendly message with a shopping call to action. |
| Loading | OrderHistorySkeleton | Loading state for OrderHistory — the same flex flex-col gap-4 list of cards. |

