Staaarter

Billing Invoice List

A billing history table listing past invoices with an ID, date, status badge, and amount per row, plus a download link on the right of each row. Built for customer billing portals and account settings screens where someone needs to scan past charges and pull a PDF without leaving the page.

By Staaarter Team
Billing
Updated March 14, 2026
Docs
Live preview

Docs

Installation

A real shadcn registry command, not a copy-paste stand-in: it fetches this block plus its badge dependencies and any missing npm packages, and installs them straight into your project.

npx shadcn add https://staaarter.com/r/billing-invoice-list.json

Prefer not to use the CLI? Copy the source from the Code toggle above into src/components/blocks/billing/billing1.tsx instead.

Usage

The file also exports billing1Demo, the exact props behind the preview above. Spread it to get a working section in one line, then replace it with your own data.

import { Billing1, billing1Demo } from "@/components/blocks/billing/billing1";

export default function Page() {
  return <Billing1 {...billing1Demo} />;
}

Props

PropTypeDefaultDescription
titlestring"Billing history"Heading shown above the table.
descriptionstringnoneOptional one-line note under the heading, omitted if not passed.
invoicesInvoiceRow[]noneRows rendered in the order given; the component does not sort them.
classNamestringnoneExtra classes for the outer container.

Types

interface InvoiceRow {
  id: string;
  date: string;
  amount: string;
  status: "Paid" | "Pending" | "Failed";
  downloadHref: string;
}

Behavior notes

  • The invoices array is rendered as-is, in the order it's passed. Sort or filter it before handing it to the component if you need newest-first or a status filter.
  • Status uses a fixed 3-value union (Paid, Pending, Failed) mapped to color classes in STATUS_STYLES. Add a new status by extending both the type and that map.
  • Each row's download action is a next/link, not a button, so it works with a direct file URL out of the box; wire it to an onClick handler instead if you need to fetch a signed URL first.
  • The amount column is a plain string, not a number, so currency formatting and symbol placement are entirely up to the caller.
  • The table scrolls horizontally on narrow viewports via overflow-x-auto rather than reflowing into cards, so all five columns stay aligned at any width.

Frequently asked questions