import { useState, useEffect } from 'react'; import PageMeta from '../../components/common/PageMeta'; import { useToast } from '../../components/ui/toast/ToastContainer'; import { fetchAPI } from '../../services/api'; import { PricingTable, PricingPlan } from '../../components/ui/pricing-table'; interface Plan { id: number; name: string; slug: string; price: string | number; billing_cycle: string; is_active: boolean; max_users: number; max_sites: number; max_keywords: number; max_clusters: number; max_content_ideas: number; monthly_word_count_limit: number; monthly_ai_credit_limit: number; monthly_image_count: number; daily_content_tasks: number; daily_ai_request_limit: number; daily_image_generation_limit: number; included_credits: number; image_model_choices: string[]; features: string[]; } interface PlanResponse { count: number; next: string | null; previous: string | null; results: Plan[]; } // Helper function to format numbers with commas const formatNumber = (num: number): string => { return num.toLocaleString(); }; // Helper function to format word count const formatWordCount = (num: number): string => { if (num >= 1000000) { return `${(num / 1000000).toFixed(1)}M`; } if (num >= 1000) { return `${(num / 1000).toFixed(0)}K`; } return num.toString(); }; // Extract major features from plan data const extractFeatures = (plan: Plan): string[] => { const features: string[] = []; // Sites and Users features.push(`${plan.max_sites} ${plan.max_sites === 1 ? 'Site' : 'Sites'}`); features.push(`${plan.max_users} ${plan.max_users === 1 ? 'User' : 'Users'}`); // Planner features features.push(`${formatNumber(plan.max_keywords)} Keywords`); features.push(`${formatNumber(plan.max_clusters)} Clusters`); features.push(`${formatNumber(plan.max_content_ideas)} Content Ideas`); // Writer features features.push(`${formatWordCount(plan.monthly_word_count_limit)} Words/Month`); features.push(`${plan.daily_content_tasks} Daily Content Tasks`); // Image features features.push(`${plan.monthly_image_count} Images/Month`); if (plan.image_model_choices && plan.image_model_choices.length > 0) { const models = plan.image_model_choices.map((m: string) => m.toUpperCase()).join(', '); features.push(`${models} Image Models`); } // AI Credits features.push(`${formatNumber(plan.included_credits)} AI Credits Included`); features.push(`${formatNumber(plan.monthly_ai_credit_limit)} Monthly AI Credit Limit`); // Feature flags if (plan.features && Array.isArray(plan.features)) { if (plan.features.includes('ai_writer')) { features.push('AI Writer'); } if (plan.features.includes('image_gen')) { features.push('Image Generation'); } if (plan.features.includes('auto_publish')) { features.push('Auto Publish'); } if (plan.features.includes('custom_prompts')) { features.push('Custom Prompts'); } } return features; }; // Transform Plan to PricingPlan const transformPlanToPricingPlan = (plan: Plan, index: number, totalPlans: number): PricingPlan => { const monthlyPrice = typeof plan.price === 'number' ? plan.price : parseFloat(String(plan.price || 0)); // Only highlight Growth plan (by slug) const highlighted = plan.slug.toLowerCase() === 'growth'; return { id: plan.id, name: plan.name, monthlyPrice: monthlyPrice, price: monthlyPrice, // Will be calculated by component based on period period: '/month', description: getPlanDescription(plan), features: extractFeatures(plan), buttonText: 'Choose Plan', highlighted: highlighted, }; }; // Get plan description based on plan name or features const getPlanDescription = (plan: Plan): string => { const slug = plan.slug.toLowerCase(); if (slug.includes('free')) { return 'Perfect for getting started'; } else if (slug.includes('starter')) { return 'For solo designers & freelancers'; } else if (slug.includes('growth')) { return 'For growing businesses'; } else if (slug.includes('scale') || slug.includes('enterprise')) { return 'For teams and large organizations'; } return 'Choose the perfect plan for your needs'; }; export default function Plans() { const toast = useToast(); const [plans, setPlans] = useState([]); const [loading, setLoading] = useState(true); useEffect(() => { loadPlans(); }, []); const loadPlans = async () => { try { setLoading(true); const response: PlanResponse = await fetchAPI('/v1/auth/plans/'); // Filter only active plans and sort by price const activePlans = (response.results || []) .filter((plan) => plan.is_active) .sort((a, b) => { const priceA = typeof a.price === 'number' ? a.price : parseFloat(String(a.price || 0)); const priceB = typeof b.price === 'number' ? b.price : parseFloat(String(b.price || 0)); return priceA - priceB; }); setPlans(activePlans); } catch (error: any) { toast.error(`Failed to load plans: ${error.message}`); } finally { setLoading(false); } }; const handlePlanSelect = (plan: PricingPlan) => { console.log('Selected plan:', plan); // TODO: Implement plan selection/subscription logic toast.success(`Selected plan: ${plan.name}`); }; const pricingPlans: PricingPlan[] = plans.map((plan, index) => transformPlanToPricingPlan(plan, index, plans.length) ); return (

Plans

Choose the perfect plan for your needs. All plans include our core features.

{loading ? (
Loading plans...
) : pricingPlans.length === 0 ? (
No active plans available
) : ( <> {/* Future: Add "View All Features" section here */}

Need more details? View all features and limits for each plan.

{/* TODO: Add expandable feature list component */}
)}
); }