Billing Purchase Approval Workflow
An internal approval workflow for subscription upgrades or license purchases, showing each approver in order with their current status. The approver whose turn it is can leave an optional comment and approve or reject, which updates that step and, on approval, unlocks the next one in the chain.
Docs
Installation
A real shadcn registry command, not a copy-paste stand-in: it fetches this block plus its button, textarea dependencies and any missing npm packages, and installs them straight into your project.
npx shadcn add https://staaarter.com/r/billing-purchase-approval-workflow.jsonPrefer not to use the CLI? Copy the source from the Code toggle above into src/components/blocks/billing/billing104.tsx instead.
Usage
The file also exports billing104Demo, 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 { Billing104, billing104Demo } from "@/components/blocks/billing/billing104"; export default function Page() { return <Billing104 {...billing104Demo} />; }
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| title | string | "Purchase approval" | Heading at the top of the card. |
| requestSummary | string | none | One-line description of what's being requested, for example a plan upgrade and seat count. |
| requestedBy | string | none | Name and, optionally, team of the person who submitted the request. |
| amount | string | none | Formatted spend amount shown top-right, for example "$4,500/year". |
| steps | ApprovalStep[] | none | The approval chain in order. Exactly one step should start as "pending" (the active step); later steps should start as "waiting". |
| approveLabel | string | "Approve" | Label on the approve button for the active step. |
| rejectLabel | string | "Reject" | Label on the reject button for the active step. |
| className | string | none | Extra classes for the outer card. |
Types
type ApprovalStepStatus = "approved" | "rejected" | "pending" | "waiting"; interface ApprovalStep { id: string; approverName: string; approverRole: string; status: ApprovalStepStatus; comment?: string; decidedAt?: string; }
Behavior notes
- The steps array is copied into local state on mount, so approve/reject decisions only change what's rendered in the browser, they don't call any API. Wire the actual mutation into your own onClick handler if you fork this component.
- Only the step whose status is "pending" shows the comment box and action buttons; every other step is read-only.
- Approving the active step marks it "approved" and, if the next step's status is "waiting", flips that next step to "pending" so it becomes the new active step.
- Rejecting the active step marks it "rejected" and stops the chain there. Any steps still marked "waiting" stay waiting rather than auto-advancing, since the request is dead.
- A comment typed into the textarea is attached to whichever step gets decided next and then cleared; it's not saved if you navigate away without approving or rejecting.
- A banner appears above the step list once every step is approved, or as soon as any step is rejected, summarizing the outcome.
Frequently asked questions
More Billing Blocks
View all →Billing Invoice List
Invoice history table with status badges, formatted amounts, and a per-row download link, built with shadcn/ui and Tailwind CSS.
Billing Failed Payment Alert
High-contrast failed-payment alert with a message, a retry button, and an optional update-payment-method button, built with shadcn/ui and Tailwind CSS.
Billing Credit Balance
Compact credit balance card with a large total, an optional purchased-versus-promotional breakdown, a low-balance notice, and a top-up button.
Billing Payment Methods
A saved payment method list for React and Next.js with brand icons, a default badge, near-expiry warnings, and remove/set-default actions per row.
Billing Add Card
A card entry form for React and Next.js with auto-formatted fields, internal brand detection, and per-field validation feedback built with shadcn/ui and Tailwind CSS.
Billing Coupon Code
An inline promo code input for React and Next.js with a simulated loading state, an applied summary showing the discount amount, and an invalid-code message.