Skip to content

InvoiceList

Pure presentation of the invoice list. It never fetches; the caller passes the resolved invoices page (via useInvoices) and owns pagination + the status/search filters. Compose InvoiceStatusTabs above it for status filtering.

import { InvoiceList } from "@evolve-storefront/feature-invoice/invoice-list";

Renders inside InvoiceProvider.

Preview

DefaultOpen in Storybook ↗

Usage

More invoices than fit on one page, so the pager renders below the list.

const { data } = useInvoices({ page });
<InvoiceList
invoices={data?.items}
total={data?.pagination.totalCount}
page={page}
onPageChange={setPage}
renderItem={(invoice) => <InvoiceCard invoice={invoice} actions={<ViewInvoiceLink invoice={invoice} />} />}
/>;

Props

No props of its own.

Change the layout

Pass children to InvoiceList to arrange its parts yourself. Every part is exported from @evolve-storefront/feature-invoice/invoice-list.

const { data } = useInvoices({ status: status ? [status] : undefined });
<InvoiceList>
<InvoiceStatusTabs status={status} onStatusChange={setStatus} />
<InvoiceListItems invoices={data?.items ?? []} renderItem={(invoice) => <InvoiceRow invoice={invoice} />} />
</InvoiceList>;
InvoiceCardSummary row for one invoice: number, dates, status, total and amount due, and the orders it bills.
PropTypeDescription
invoiceInvoiceSummary
actions?ReactNode

Per-row actions (download / pay / view) — composed by the caller.

Any other props go to the root element, like on a plain HTML element.

InvoiceListFiltersSearch and invoice-date filters for the invoice list: a GET form of named fields, with no handlers, so a Server Component can render it.
PropTypeDescription
searchTerm?string

The term currently applied, echoed back into the field.

invoiceDateFrom?string

The applied first day as yyyy-mm-dd, which is also what the query takes.

invoiceDateUntil?string

The applied last day as yyyy-mm-dd.

names?InvoiceListFilterNames

Override the field names to match the page's search params.

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.

InvoiceListItemsThe invoice list plus its pager.

No props of its own.

InvoiceListResultCount"12 results": how many invoices match the current search and filters.
PropTypeDescription
total?number | null

The list query's pagination.totalCount.

Any other props go to the root element, like on a plain HTML element.

InvoiceStatusTabsStatus filter tabs for the invoice list.

The default set leaves out PAYMENT_UNDERWAY and CREDITED. Both are real states a badge renders, but neither is a thing a buyer goes looking for a list of, and a tab per enum value is a row of tabs nobody scans. Pass statuses to change it.

PropTypeDescription
onStatusChange(status?: InvoiceStatus | undefined) => void

Requests a different filter, or undefined for "all". The caller owns status and feeds it back, so this is the controlled-state grammar rather than onClick — declining to update it is valid.

status?InvoiceStatus

The status filter currently applied, or undefined for "all".

counts?Partial<Record<InvoiceStatus, number>> | null

How many invoices each status holds, shown in its tab: useInvoiceStatusCounts's data. null or omitted shows none, as does a status the record leaves out.

statuses?InvoiceStatus[]

The statuses offered as tabs, in order.

Any other props go to the root element, like on a plain HTML element.

InvoiceTableThe invoices as a table: number, orders, due date, payment status, total, outstanding amount and reference, with a pay link and a PDF download per row, and the list's pager below.

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.

LoadingInvoiceCardSkeletonLoading state for InvoiceCard.
EmptyInvoiceListEmptyEmpty state.
LoadingInvoiceListSkeletonLoading state for InvoiceList.
LoadingInvoiceTableSkeletonPlaceholder rows for InvoiceTable, in its columns, while the page loads.