import React, { useState, useEffect } from 'react'; import { useTranslation } from 'react-i18next'; import { Link } from 'react-router-dom'; import { Check, Star, Loader, Users, MapPin, Package } from 'lucide-react'; import { Button, Card } from '../ui'; import { subscriptionService, type PlanMetadata, type SubscriptionTier, SUBSCRIPTION_TIERS } from '../../api'; import { getRegisterUrl } from '../../utils/navigation'; type BillingCycle = 'monthly' | 'yearly'; type DisplayMode = 'landing' | 'settings' | 'selection'; interface SubscriptionPricingCardsProps { mode?: DisplayMode; selectedPlan?: string; onPlanSelect?: (planKey: string) => void; showPilotBanner?: boolean; pilotCouponCode?: string; pilotTrialMonths?: number; showComparison?: boolean; className?: string; } export const SubscriptionPricingCards: React.FC = ({ mode = 'landing', selectedPlan, onPlanSelect, showPilotBanner = false, pilotCouponCode, pilotTrialMonths = 3, showComparison = false, className = '' }) => { const { t } = useTranslation('subscription'); const [plans, setPlans] = useState | null>(null); const [billingCycle, setBillingCycle] = useState('monthly'); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { loadPlans(); }, []); const loadPlans = async () => { try { setLoading(true); setError(null); const availablePlans = await subscriptionService.fetchAvailablePlans(); setPlans(availablePlans.plans); } catch (err) { console.error('Failed to load plans:', err); setError(t('ui.error_loading')); } finally { setLoading(false); } }; const getPrice = (plan: PlanMetadata) => { return billingCycle === 'monthly' ? plan.monthly_price : plan.yearly_price; }; const getSavings = (plan: PlanMetadata) => { if (billingCycle === 'yearly') { return subscriptionService.calculateYearlySavings( plan.monthly_price, plan.yearly_price ); } return null; }; const formatFeatureName = (feature: string): string => { const translatedFeature = t(`features.${feature}`); return translatedFeature.startsWith('features.') ? feature.replace(/_/g, ' ') : translatedFeature; }; const handlePlanAction = (tier: string, plan: PlanMetadata) => { if ((mode === 'settings' || mode === 'selection') && onPlanSelect) { onPlanSelect(tier); } }; // Get top 3 benefits for each tier (business outcomes) const getTopBenefits = (tier: SubscriptionTier, plan: PlanMetadata): string[] => { // Use hero_features if available, otherwise use first 3 features return plan.hero_features?.slice(0, 3) || plan.features.slice(0, 3); }; // Format limit display with emoji and user-friendly text const formatLimit = (value: number | string | null | undefined, unlimitedKey: string): string => { if (!value || value === -1 || (typeof value === 'string' && value.toLowerCase() === 'unlimited')) { return t(unlimitedKey); } return value.toString(); }; if (loading) { return (
{t('ui.loading')}
); } if (error || !plans) { return (

{error}

); } return (
{/* Pilot Program Banner */} {showPilotBanner && pilotCouponCode && (

{t('ui.pilot_program_active')}

${pilotTrialMonths}`) .replace('20%', '20%') }} />

)} {/* Billing Cycle Toggle */}
{/* Simplified Plans Grid */}
{Object.entries(plans).map(([tier, plan]) => { const price = getPrice(plan); const savings = getSavings(plan); const isPopular = plan.popular; const tierKey = tier as SubscriptionTier; const topBenefits = getTopBenefits(tierKey, plan); const CardWrapper = mode === 'landing' ? Link : 'div'; const cardProps = mode === 'landing' ? { to: getRegisterUrl(tier) } : mode === 'selection' || mode === 'settings' ? { onClick: () => handlePlanAction(tier, plan) } : {}; const isSelected = mode === 'selection' && selectedPlan === tier; return ( {/* Selected Badge */} {isSelected && (
{t('ui.selected', 'Seleccionado')}
)} {/* Popular Badge */} {isPopular && !isSelected && (
{t('ui.most_popular')}
)} {/* Plan Header */}

{t(`plans.${tier}.name`, plan.name)}

{plan.tagline_key ? t(plan.tagline_key) : plan.tagline || ''}

{/* Price */}
{subscriptionService.formatPrice(price)} /{billingCycle === 'monthly' ? t('ui.per_month') : t('ui.per_year')}
{/* Trial Badge - Always Visible */}
{savings ? t('ui.save_amount', { amount: subscriptionService.formatPrice(savings.savingsAmount) }) : showPilotBanner ? t('billing.free_months', { count: pilotTrialMonths }) : t('billing.free_trial_days', { count: plan.trial_days }) }
{/* Perfect For */} {plan.recommended_for_key && (

{t(plan.recommended_for_key)}

)} {/* Feature Inheritance Indicator */} {tier === SUBSCRIPTION_TIERS.PROFESSIONAL && (

✓ {t('ui.feature_inheritance_professional')}

)} {tier === SUBSCRIPTION_TIERS.ENTERPRISE && (

✓ {t('ui.feature_inheritance_enterprise')}

)} {/* Top 3 Benefits + Key Limits */}
{/* Business Benefits */} {topBenefits.map((feature) => (
{formatFeatureName(feature)}
))} {/* Key Limits (Users, Locations, Products) */}
{formatLimit(plan.limits.users, 'limits.users_unlimited')} {t('limits.users_label', 'usuarios')}
{formatLimit(plan.limits.locations, 'limits.locations_unlimited')} {t('limits.locations_label', 'ubicaciones')}
{formatLimit(plan.limits.products, 'limits.products_unlimited')} {t('limits.products_label', 'productos')}
{/* CTA Button */} {/* Footer */}

{showPilotBanner ? t('ui.free_trial_footer', { months: pilotTrialMonths }) : t('ui.free_trial_footer', { months: 0 }) }

); })}
{/* Comparison Link */} {showComparison && mode === 'landing' && (
{t('ui.view_full_comparison', 'Ver comparación completa de características →')}
)}
); };