Invoice List
Display invoice history with status badges, amounts, dates, and download/view actions. Includes loading skeleton and empty state.
Preview
States
Loading
Features
- Custom card container with header icon (Receipt)
- Invoice count displayed in header
- Colored status badges with icons: CheckCircle (paid), Clock (pending), XCircle (failed), RotateCcw (refunded), Ban (void)
- FileText icon for each invoice row
- View and download action buttons with hover states
- Static loading skeleton (no animations)
- Enhanced empty state with larger icon container
- Responsive horizontal scroll on mobile
Install Summary
This kit will add the following files and dependencies to your project. Download the bundle and extract it into your project root.
Component Files
| File | Path |
|---|---|
| invoice-list.tsx | components/billing/invoice-list/invoice-list.tsx |
| invoice-row.tsx | components/billing/invoice-list/invoice-row.tsx |
| types.ts | components/billing/invoice-list/types.ts |
| index.ts | components/billing/invoice-list/index.ts |
Utility Files
| File | Path |
|---|---|
| format.ts | lib/format.ts |
| design-tokens.ts | lib/design-tokens.ts |
Dependencies
Install these dependencies before using the component:
Terminal
bash
npx shadcn@latest add buttonTerminal
bash
npm install @phosphor-icons/reactInstallation
Download the complete bundle as a ZIP file, or copy the text bundle to your clipboard:
Component Files
The component consists of the following files:
1. invoice-list.tsx
invoice-list.tsx
tsx
"use client";
import { FileText, Receipt } from "@phosphor-icons/react";
import { cn } from "@/lib/utils";
import { InvoiceRow, InvoiceCard } from "./invoice-row";2. invoice-row.tsx
invoice-row.tsx
tsx
"use client";
import {
ArrowLineDown as Download,
Export as ExternalLink,3. types.ts
types.ts
tsx
export type InvoiceStatus = "paid" | "pending" | "failed" | "refunded" | "void";
export interface Invoice {
id: string;
number: string;4. index.ts
index.ts
tsx
export { InvoiceList } from "./invoice-list";
export { InvoiceRow } from "./invoice-row";
export type {
InvoiceStatus,
Invoice,
InvoiceListProps,
InvoiceRowProps,
} from "./types";
Shared Utilities
This component uses shared utility functions. These are included in the bundle above:
format.ts
format.ts
tsx
export function formatDate(date: Date): string {
return date.toLocaleDateString("en-US", {
month: "short",
day: "numeric",
year: "numeric",
});
}
export function formatRelativeTime(date: Date, now: Date = new Date()): string {
const diff = now.getTime() - date.getTime();
const minutes = Math.floor(diff / 60000);
if (minutes < 1) return "Just now";
if (minutes < 60) return `${minutes}m ago`;
const hours = Math.floor(minutes / 60);
if (hours < 24) return `${hours}h ago`;
const days = Math.floor(hours / 24);
if (days < 7) return `${days}d ago`;
return formatDate(date);
}
export function formatPrice(amount: number, currency = "USD"): string {
return new Intl.NumberFormat("en-US", {
style: "currency",
currency,
minimumFractionDigits: 0,
maximumFractionDigits: 2,
}).format(amount);
}
export function formatNumber(num: number): string {
if (num >= 1_000_000) return `${(num / 1_000_000).toFixed(1)}M`;
if (num >= 1_000) return `${(num / 1_000).toFixed(1)}K`;
return num.toString();
}
design-tokens.ts
design-tokens.ts
tsx
// Border radius
export const radius = {
card: "rounded-xl",
badge: "rounded-full",
button: "rounded-lg",Usage
app/billing/page.tsx
tsx
"use client";
import { InvoiceList, type Invoice } from "@/components/billing";
const invoices: Invoice[] = [Props
| Prop | Type | Default |
|---|---|---|
| invoices | Invoice[] | Required |
| onDownload | (invoice) => void | - |
| onView | (invoice) => void | - |
| isLoading | boolean | false |
| emptyMessage | string | "No invoices yet" |
| className | string | - |
Invoice Status
| Status | Description | Badge |
|---|---|---|
| paid | Payment completed | CheckCircle2 + Emerald (green) |
| pending | Awaiting payment | Clock + Yellow |
| failed | Payment failed | XCircle + Red |
| refunded | Payment refunded | RotateCcw + Blue |
| void | Invoice voided | Ban + Gray |
Accessibility
- Semantic table structure with proper headers
- Action buttons have aria-labels
- Hover states for row highlighting
- Responsive with horizontal scroll