'use client'; import { useState } from 'react'; import { Plus, Edit, Trash2, X, Check, AlertCircle, Zap } from 'lucide-react'; import { createPlan, updatePlan, deletePlan, grantMonthlyCredits, type SubscriptionPlan } from '@/services/subscription-service'; interface PlanManagementClientProps { initialPlans: SubscriptionPlan[]; } export default function PlanManagementClient({ initialPlans }: PlanManagementClientProps) { const [plans, setPlans] = useState(initialPlans); const [editingPlan, setEditingPlan] = useState(null); const [isCreating, setIsCreating] = useState(false); const [formData, setFormData] = useState({ name: '', display_name: '', monthly_credits: 0, price: 0, description: '', is_active: true, sort_order: 0 }); const [loading, setLoading] = useState(false); const [message, setMessage] = useState<{ type: 'success' | 'error'; text: string } | null>(null); const handleEdit = (plan: SubscriptionPlan) => { setEditingPlan(plan); setFormData({ name: plan.name, display_name: plan.display_name, monthly_credits: plan.monthly_credits, price: plan.price, description: plan.description || '', is_active: plan.is_active, sort_order: plan.sort_order }); setIsCreating(false); setMessage(null); }; const handleCreate = () => { setEditingPlan(null); setFormData({ name: '', display_name: '', monthly_credits: 0, price: 0, description: '', is_active: true, sort_order: plans.length + 1 }); setIsCreating(true); setMessage(null); }; const handleSave = async () => { if (!formData.name || !formData.display_name || formData.monthly_credits <= 0) { setMessage({ type: 'error', text: 'Please fill in all required fields' }); return; } setLoading(true); setMessage(null); if (isCreating) { const result = await createPlan(formData); if (result.success && result.plan) { setPlans([...plans, result.plan]); setMessage({ type: 'success', text: 'Plan created successfully' }); setIsCreating(false); } else { setMessage({ type: 'error', text: result.error || 'Failed to create plan' }); } } else if (editingPlan) { const result = await updatePlan(editingPlan.id, formData); if (result.success) { setPlans(plans.map(p => p.id === editingPlan.id ? { ...p, ...formData } : p)); setMessage({ type: 'success', text: 'Plan updated successfully' }); setEditingPlan(null); } else { setMessage({ type: 'error', text: result.error || 'Failed to update plan' }); } } setLoading(false); }; const handleDelete = async (planId: string) => { if (!confirm('Are you sure you want to delete this plan? Users on this plan will be unassigned.')) { return; } setLoading(true); const result = await deletePlan(planId); if (result.success) { setPlans(plans.filter(p => p.id !== planId)); setMessage({ type: 'success', text: 'Plan deleted successfully' }); } else { setMessage({ type: 'error', text: result.error || 'Failed to delete plan' }); } setLoading(false); }; const handleGrantCredits = async () => { if (!confirm('Grant monthly credits to all users based on their subscription plan?')) { return; } setLoading(true); setMessage(null); const result = await grantMonthlyCredits(); if (result.success) { setMessage({ type: 'success', text: `Credits granted! Processed: ${result.processed}, Failed: ${result.failed}` }); } else { setMessage({ type: 'error', text: result.error || 'Failed to grant credits' }); } setLoading(false); }; return (
{/* Actions Bar */}
{message && (
{message.type === 'success' ? : } {message.text}
)} {/* Plans Grid */}
{plans.map((plan) => (
{!plan.is_active && (
Inactive
)}

{plan.display_name}

{plan.name}

{plan.monthly_credits}
Credits/Month
€{plan.price.toFixed(2)}
per month
{plan.description && (

{plan.description}

)}
))}
{/* Edit/Create Modal */} {(editingPlan || isCreating) && (

{isCreating ? 'Create Plan' : 'Edit Plan'}

setFormData({ ...formData, name: e.target.value })} placeholder="e.g. starter" className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-amber-500/50" />
setFormData({ ...formData, display_name: e.target.value })} placeholder="e.g. Starter" className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-amber-500/50" />
setFormData({ ...formData, monthly_credits: parseInt(e.target.value) || 0 })} className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-amber-500/50" />
setFormData({ ...formData, price: parseFloat(e.target.value) || 0 })} className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-amber-500/50" />