import { useState } from 'react'; export interface PricingPlan { id?: number; name: string; price: string | number; // Current displayed price (will be calculated based on period) monthlyPrice?: string | number; // Base monthly price (used for annual discount calculation) annualDiscountPercent?: number; // Annual discount percentage from backend (default 15%) originalPrice?: string | number; period?: string; // "/month", "/year", "/Lifetime" description?: string; features: string[]; buttonText?: string; highlighted?: boolean; // For featured/popular plan icon?: React.ReactNode; disabled?: boolean; recommended?: boolean; // For "Recommended" badge } export interface PricingTableProps { variant?: '1' | '2' | '3'; // Three different table styles title?: string; subtitle?: string; plans: PricingPlan[]; showToggle?: boolean; // Monthly/Annually toggle onPlanSelect?: (plan: PricingPlan) => void; className?: string; } // Checkmark SVG Icon const CheckIcon = () => ( ); // X Icon for excluded features const XIcon = () => ( ); export default function PricingTable({ variant = '1', title, subtitle, plans, showToggle = false, onPlanSelect, className = '', }: PricingTableProps) { const [billingPeriod, setBillingPeriod] = useState<'monthly' | 'annually'>('monthly'); const handlePlanClick = (plan: PricingPlan) => { if (plan.disabled) return; onPlanSelect?.(plan); }; const formatPrice = (price: string | number) => { if (typeof price === 'number') { return price.toFixed(2); } return price; }; // Calculate price based on billing period with discount from backend const getDisplayPrice = (plan: PricingPlan): { price: number; originalPrice?: number } => { const monthlyPrice = typeof plan.monthlyPrice === 'number' ? plan.monthlyPrice : typeof plan.price === 'number' ? plan.price : parseFloat(String(plan.price || 0)); if (billingPeriod === 'annually' && showToggle) { // Get discount percentage from plan (default 15%) const discountPercent = plan.annualDiscountPercent || 15; const discountMultiplier = (100 - discountPercent) / 100; // Annual price: monthly * 12 * discount multiplier const annualPrice = monthlyPrice * 12 * discountMultiplier; const originalAnnualPrice = monthlyPrice * 12; return { price: annualPrice, originalPrice: originalAnnualPrice }; } // Monthly price return { price: monthlyPrice }; }; // Variant 1: With toggle and highlighted center card if (variant === '1') { return (
{title && (

{title}

)} {showToggle && (
{billingPeriod === 'annually' && (
Save 15% with annual billing
)}
)}
{plans.map((plan, index) => { const isHighlighted = plan.highlighted || false; // Use explicit highlighted prop const displayPrice = getDisplayPrice(plan); const period = billingPeriod === 'annually' && showToggle ? '/year' : (plan.period || '/month'); return (
{plan.name}

${formatPrice(displayPrice.price)}

{period}
{(displayPrice.originalPrice || plan.originalPrice) && ( ${formatPrice(displayPrice.originalPrice || plan.originalPrice || 0)} )}
{plan.description && (

{plan.description}

)}
    {plan.features.map((feature, idx) => { const isExcluded = feature.startsWith('!'); const featureText = isExcluded ? feature.substring(1) : feature; return (
  • {isExcluded ? : } {featureText}
  • ); })}
); })}
); } // Variant 2: With icons and border highlight if (variant === '2') { return (
{plans.map((plan, index) => { const isHighlighted = plan.highlighted || index === 1; return (
{plan.name} {plan.icon && ( {plan.icon} )}

${formatPrice(plan.price)}

{plan.period || ' / Lifetime'}
{plan.description && (

{plan.description}

)}
    {plan.features.map((feature, idx) => { const isExcluded = feature.startsWith('!'); const featureText = isExcluded ? feature.substring(1) : feature; return (
  • {isExcluded ? : } {featureText}
  • ); })}
); })}
); } // Variant 3: Compact with recommended badge if (variant === '3') { return (
{plans.map((plan, index) => { const isRecommended = plan.recommended || index === 2; return (
{isRecommended && (
Recommended
)} {plan.name} {plan.description && (

{plan.description}

)}

{typeof plan.price === 'string' && plan.price.toLowerCase() === 'free' ? 'Free' : `$${formatPrice(plan.price)}`}

{plan.period || 'For a Lifetime'}
    {plan.features.map((feature, idx) => { const isExcluded = feature.startsWith('!'); const featureText = isExcluded ? feature.substring(1) : feature; return (
  • {isExcluded ? ( ) : ( )} {featureText}
  • ); })}
); })}
); } return null; }