'use client'; import { useState, useEffect } from 'react'; import { Plus, X, Edit, Trash2, Check, Users, AlertTriangle } from 'lucide-react'; interface Plan { id: string; name: string; slug: string; priceMonthly: number; priceYearly: number; maxProfessionals: number; maxServices: number; features: string[]; active: boolean; subscribers: number; } const emptyPlan: Partial = { name: '', slug: '', priceMonthly: 0, priceYearly: 0, maxProfessionals: 1, maxServices: 10, features: [], active: true }; export default function Plans() { const [plans, setPlans] = useState([]); const [showModal, setShowModal] = useState(false); const [editing, setEditing] = useState(null); const [form, setForm] = useState>(emptyPlan); const [featureInput, setFeatureInput] = useState(''); const [deleteConfirm, setDeleteConfirm] = useState(null); const [loading, setLoading] = useState(true); const fetchPlans = async () => { try { const res = await fetch('/api/plans'); if (res.ok) { const data = await res.json(); if (Array.isArray(data)) { setPlans(data); } } } catch (e) { console.error(e); } finally { setLoading(false); } }; useEffect(() => { fetchPlans(); }, []); const openAdd = () => { setEditing(null); setForm({ ...emptyPlan, features: [] }); setShowModal(true); }; const openEdit = (p: Plan) => { setEditing(p); setForm({ ...p, features: p.features || [] }); setShowModal(true); }; const handleSave = async () => { if (!form.name?.trim()) return; const method = editing ? 'PUT' : 'POST'; try { const res = await fetch('/api/plans', { method, headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(form) }); if (res.ok) { fetchPlans(); setShowModal(false); } } catch (e) { console.error(e); } }; const handleDelete = async (id: string) => { try { await fetch(`/api/plans?id=${id}`, { method: 'DELETE' }); setPlans(prev => prev.filter(p => p.id !== id)); setDeleteConfirm(null); } catch (e) { console.error(e); } }; const addFeature = () => { if (featureInput.trim()) { setForm(p => ({ ...p, features: [...(p.features || []), featureInput.trim()] })); setFeatureInput(''); } }; const removeFeature = (idx: number) => { setForm(p => ({ ...p, features: (p.features || []).filter((_, i) => i !== idx) })); }; const colors = ['#3b82f6', '#6C63FF', '#a855f7', '#f59e0b']; if (loading) return
Carregando planos...
; return (

{plans.length} planos configurados

{plans.map((p, idx) => (
{deleteConfirm === p.id && (

Excluir plano {p.name}?

{p.subscribers} assinantes serão afetados

)}

{p.name}

R$ {Number(p.priceMonthly || 0).toFixed(2).replace('.', ',')} /mês
ou R$ {Number(p.priceYearly || 0).toFixed(2).replace('.', ',')} /ano
{p.maxProfessionals >= 999 ? '∞' : p.maxProfessionals}
Profissionais
{p.maxServices >= 999 ? '∞' : p.maxServices}
Serviços
    {(p.features || []).map((f, i) => (
  • {f}
  • ))}
))}
{plans.length === 0 && (
Nenhum plano cadastrado.
)} {showModal && (
setShowModal(false)}>
e.stopPropagation()}>

{editing ? 'Editar Plano' : 'Novo Plano'}

{ const val = e.target.value; setForm(p => ({ ...p, name: val, slug: editing ? p.slug : val.toLowerCase().replace(/[^a-z0-9]/g, '-') })); }} />
setForm(p => ({ ...p, slug: e.target.value }))} disabled={!!editing} />
{ const val = Number(e.target.value); setForm(p => ({ ...p, priceMonthly: val, priceYearly: p.priceYearly || val * 10 })); }} />
setForm(p => ({ ...p, priceYearly: Number(e.target.value) }))} />
setForm(p => ({ ...p, maxProfessionals: Number(e.target.value) }))} />
setForm(p => ({ ...p, maxServices: Number(e.target.value) }))} />
setFeatureInput(e.target.value)} onKeyDown={e => { if (e.key === 'Enter') { e.preventDefault(); addFeature(); } }} />
{(form.features || []).map((f, i) => (
{f}
))}
)}
); }