Billing Trial Countdown
A trial countdown block that shows how much trial time is left, switching from a neutral tone to amber and then red as the deadline approaches, plus an optional usage breakdown for premium features used during the trial. Time remaining is passed in as plain numbers rather than computed from the current clock, so it renders identically on the server and after hydration.
Docs
Installation
A real shadcn registry command, not a copy-paste stand-in: it fetches this block plus its button dependencies and any missing npm packages, and installs them straight into your project.
npx shadcn add https://staaarter.com/r/billing-trial-countdown.jsonPrefer not to use the CLI? Copy the source from the Code toggle above into src/components/blocks/billing/billing143.tsx instead.
Usage
The file also exports billing143Demo, 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 { Billing143, billing143Demo } from "@/components/blocks/billing/billing143"; export default function Page() { return <Billing143 {...billing143Demo} />; }
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| heading | string | "Your trial" | Heading shown next to the status icon. |
| description | string | none | Optional supporting text under the heading. |
| daysRemaining | number | none | Whole days left in the trial. Pass 0 on the final day and rely on hoursRemaining. |
| hoursRemaining | number | none | Hours left within the current day, shown alongside daysRemaining. |
| trialEndLabel | string | none | Human-readable end date, e.g. "May 10, 2026", shown under the countdown. |
| usageItems | TrialUsageItem[] | none | Optional list of premium features used during the trial, each rendered with a small progress bar. |
| expired | boolean | false | When true, switches the block into its expired state regardless of daysRemaining. |
| upgradeHref | string | "#" | Link target for the call-to-action button. |
| upgradeLabel | string | "Unlock full access" / "Reactivate your account" | Button label; defaults differ based on whether the trial is expired. |
| className | string | none | Extra classes for the outer container. |
Types
interface TrialUsageItem { label: string; used: number; total: number; }
Behavior notes
- Time remaining is entirely prop-driven: the component does not call Date.now() or set up a timer. Recompute daysRemaining/hoursRemaining on the server (or in a parent client component) and pass fresh values down; this keeps the block SSR-safe and avoids hydration mismatches.
- Urgency is derived purely from daysRemaining and the expired flag: normal above 2 days, amber at 2 days or fewer, red at 1 day or fewer or once expired.
- When daysRemaining is 0, the headline switches to showing only hoursRemaining instead of "0 days".
- The usage section and its progress bars only render when usageItems is a non-empty array.
- In the expired state, the button label defaults to "Reactivate your account" instead of "Unlock full access", and the description below the countdown reads "ended" instead of "ends".
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.