Loading...
Loading...
> A pricing plan selection component for upgrade flows. Shows plan cards with features, popular badge, and selection state.
1import { PlanSelector } from "@/components/ui/billing-summary-card"
For individuals and small projects
For growing teams
For large organizations
1const plans = [2 {3 id: "starter",4 name: "Starter",5 price: 9,6 interval: "month",7 description: "For individuals",8 features: ["5 projects", "1GB storage", "Email support"],9 },10 {11 id: "pro",12 name: "Pro",13 price: 29,14 interval: "month",15 description: "For growing teams",16 features: ["Unlimited projects", "10GB storage", "Priority support"],17 popular: true,18 },19 {20 id: "enterprise",21 name: "Enterprise",22 price: 99,23 interval: "month",24 description: "For large organizations",25 features: ["Unlimited everything", "100GB storage", "24/7 support"],26 },27];2829<PlanSelector30 plans={plans}31 selectedPlanId="pro"32 onSelectPlan={(id) => handleSelectPlan(id)}33/>
For individuals and small projects
For growing teams
For large organizations
1<PlanSelector2 plans={[3 { ...starterPlan, current: true },4 proPlan,5 enterprisePlan,6 ]}7 onSelectPlan={handleSelectPlan}8/>
| Prop | Type | Default | Description |
|---|---|---|---|
| plans* | PlanOption[] | - | Array of available plans. |
| selectedPlanId | string | - | Currently selected plan ID. |
| onSelectPlan | (planId: string) => void | - | Plan selection handler. |
Complete example showing plan selection with Stripe checkout:
1'use client';23import { useState } from 'react';4import { PlanSelector } from '@/components/ui/billing-summary-card';5import { useRouter } from 'next/navigation';67const plans = [8 {9 id: 'starter',10 name: 'Starter',11 price: 9,12 interval: 'month' as const,13 description: 'For individuals',14 features: ['1,000 credits/month', '5 projects', 'Email support'],15 },16 {17 id: 'pro',18 name: 'Pro',19 price: 29,20 interval: 'month' as const,21 description: 'For growing teams',22 features: ['10,000 credits/month', 'Unlimited projects', 'Priority support'],23 popular: true,24 },25];2627export default function UpgradePage() {28 const router = useRouter();29 const [selectedPlan, setSelectedPlan] = useState('pro');30 const [loading, setLoading] = useState(false);3132 const handleSelectPlan = async (planId: string) => {33 setSelectedPlan(planId);34 setLoading(true);3536 // Create Stripe checkout session37 const res = await fetch('/api/stripe/checkout', {38 method: 'POST',39 headers: { 'Content-Type': 'application/json' },40 body: JSON.stringify({ priceId: planId }),41 });4243 const { url } = await res.json();44 router.push(url); // Redirect to Stripe45 };4647 return (48 <PlanSelector49 plans={plans}50 selectedPlanId={selectedPlan}51 onSelectPlan={handleSelectPlan}52 />53 );54}
Show which plan the user is currently on (disables that plan's button):
1const plans = [2 { id: 'free', name: 'Free', price: 0, interval: 'month',3 features: ['100 credits/month'], current: true },4 { id: 'starter', name: 'Starter', price: 9, interval: 'month',5 features: ['1,000 credits/month'] },6 { id: 'pro', name: 'Pro', price: 29, interval: 'month',7 features: ['10,000 credits/month'], popular: true },8];910<PlanSelector plans={plans} onSelectPlan={handleUpgrade} />
Complete TypeScript interface for plan data:
1interface PlanOption {2 id: string; // Unique plan ID3 name: string; // Display name4 price: number; // Monthly price in dollars5 interval: "month" | "year";6 description?: string; // Short description7 features: string[]; // Feature list8 popular?: boolean; // Shows "POPULAR" badge9 current?: boolean; // Shows "CURRENT" badge, disables button10}
Load plans dynamically from your backend:
1'use client';23import { useEffect, useState } from 'react';4import { PlanSelector } from '@/components/ui/billing-summary-card';56export function PricingPage() {7 const [plans, setPlans] = useState([]);8 const [currentPlan, setCurrentPlan] = useState(null);910 useEffect(() => {11 // Fetch available plans12 fetch('/api/billing/plans')13 .then(r => r.json())14 .then(data => {15 setPlans(data.plans);16 setCurrentPlan(data.currentPlanId);17 });18 }, []);1920 return (21 <PlanSelector22 plans={plans}23 selectedPlanId={currentPlan}24 onSelectPlan={(id) => handleUpgrade(id)}25 />26 );27}