Trial Expiry Card
billingsdk/trial-expiry-cardFreeBlock
A card component that displays trial expiration countdown with progress indicator and feature list
Install it
npx shadcn@latest add https://billingsdk.com/r/trial-expiry-card.jsonSource
1"use client";23import { useState, useEffect } from "react";4import { Button } from "@/components/ui/button";5import { Badge } from "@/components/ui/badge";6import {7 Card,8 CardContent,9 CardDescription,10 CardHeader,11 CardTitle,12} from "@/components/ui/card";13import { cn } from "@/lib/utils";14import { Check } from "lucide-react";1516export interface TrialExpiryCardProps {17 trialEndDate?: Date | string | number;18 daysRemaining?: number;19 onUpgrade?: () => void | Promise<void>;20 className?: string;21 title?: string;22 description?: string;23 upgradeButtonText?: string;24 features?: string[];25}2627interface TimeRemaining {28 days: number;29 hours: number;30 minutes: number;31 seconds: number;32}3334const calculateTimeRemaining = (35 endDate: Date | string | number,36): TimeRemaining => {37 try {38 let end: Date;39 if (typeof endDate === "string") {40 end = new Date(endDate);41 } else if (typeof endDate === "number") {42 end = new Date(endDate);43 } else if (endDate instanceof Date) {44 end = endDate;45 } else {46 // Fallback for any other type47 return { days: 0, hours: 0, minutes: 0, seconds: 0 };48 }4950 // Validate that we have a valid date51 if (isNaN(end.getTime())) {52 return { days: 0, hours: 0, minutes: 0, seconds: 0 };53 }5455 const now = new Date();56 const diff = end.getTime() - now.getTime();5758 if (diff <= 0) {59 return { days: 0, hours: 0, minutes: 0, seconds: 0 };60 }6162 return {63 days: Math.floor(diff / (1000 * 60 * 60 * 24)),64 hours: Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)),65 minutes: Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60)),66 seconds: Math.floor((diff % (1000 * 60)) / 1000),67 };68 } catch (error) {69 console.error("Error calculating time remaining:", error);70 return { days: 0, hours: 0, minutes: 0, seconds: 0 };71 }72};7374export function TrialExpiryCard({75 trialEndDate,76 daysRemaining: propDaysRemaining,77 onUpgrade,78 className,79 title = "Trial Period",80 description,81 upgradeButtonText = "Upgrade Now",82 features = [83 "Unlimited projects",84 "Priority support",85 "Advanced analytics",86 "Custom integrations",87 ],88}: TrialExpiryCardProps) {89 const [isLoading, setIsLoading] = useState(false);90 const [timeRemaining, setTimeRemaining] = useState<TimeRemaining>(() => {91 if (trialEndDate) {92 return calculateTimeRemaining(trialEndDate);93 }94// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from billingsdk
All 35 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| All Componentsall | billingsdk | Blocks | Free | no deps | |
| Top Bannerbanner | billingsdk | Blocks | Free | 2 deps · 2 files | |
| Billing Screenbilling-screen | billingsdk | Blocks | Free | 2 deps · 2 files | |
| Billing Settingsbilling-settings | billingsdk | Blocks | Free | 2 deps · 2 files | |
| Billing Settings 2billing-settings-2 | billingsdk | Blocks | Free | 1 dep · 2 files | |
| Cancel Subscription Cardcancel-subscription-card | billingsdk | Blocks | Free | 1 dep · 3 files | |
| Cancel Subscription Dialogcancel-subscription-dialog | billingsdk | Blocks | Free | 1 dep · 3 files | |
| Detailed Usage Tabledetailed-usage-table | billingsdk | Blocks | Free | no deps · 2 files |
