'use client'; import { Fragment, useState } from 'react'; import { Dialog, Transition, Tab } from '@headlessui/react'; import { XMarkIcon, SparklesIcon, PlusIcon, MinusIcon, } from '@heroicons/react/24/outline'; interface CreatePlanModalProps { isOpen: boolean; onClose: () => void; onSuccess: (plan: any) => void; } interface CreatePlanForm { name: string; slug: string; description: string; min_users: number; max_users: number; monthly_price: string; annual_price: string; discount_months: number; features: string; differentiators: string; storage_gb: number; is_active: boolean; } export default function CreatePlanModal({ isOpen, onClose, onSuccess }: CreatePlanModalProps) { const [loading, setLoading] = useState(false); const [error, setError] = useState(''); const [formData, setFormData] = useState({ name: '', slug: '', description: '', min_users: 1, max_users: 30, monthly_price: '', annual_price: '', discount_months: 2, features: '', differentiators: '', storage_gb: 10, is_active: true, }); const handleChange = (e: React.ChangeEvent) => { const { name, value, type } = e.target; if (type === 'checkbox') { setFormData(prev => ({ ...prev, [name]: (e.target as HTMLInputElement).checked, })); } else if (type === 'number') { const numValue = parseFloat(value) || 0; setFormData(prev => { const newData = { ...prev, [name]: numValue, }; // Calcular preço anual automaticamente quando mensal ou discount_months muda if ((name === 'monthly_price' || name === 'discount_months')) { const monthlyPrice = name === 'monthly_price' ? numValue : parseFloat(prev.monthly_price) || 0; const discountMonths = name === 'discount_months' ? numValue : prev.discount_months; if (monthlyPrice > 0 && discountMonths >= 0) { // Calcula: (12 meses - meses de desconto) * preço mensal const monthsToPay = Math.max(0, 12 - discountMonths); const annualWithDiscount = (monthlyPrice * monthsToPay).toFixed(2); newData.annual_price = annualWithDiscount; } } return newData; }); } else { setFormData(prev => ({ ...prev, [name]: value, })); } }; const incrementValue = (field: 'min_users' | 'max_users' | 'storage_gb' | 'discount_months', step: number = 1) => { setFormData(prev => { const newValue = prev[field] + step; const newData = { ...prev, [field]: newValue, }; // Recalcular preço anual se mudou discount_months if (field === 'discount_months') { const monthlyPrice = parseFloat(prev.monthly_price) || 0; if (monthlyPrice > 0 && newValue >= 0) { const monthsToPay = Math.max(0, 12 - newValue); newData.annual_price = (monthlyPrice * monthsToPay).toFixed(2); } } return newData; }); }; const decrementValue = (field: 'min_users' | 'max_users' | 'storage_gb' | 'discount_months', step: number = 1, min: number = 0) => { setFormData(prev => { const newValue = Math.max(min, prev[field] - step); const newData = { ...prev, [field]: newValue, }; // Recalcular preço anual se mudou discount_months if (field === 'discount_months') { const monthlyPrice = parseFloat(prev.monthly_price) || 0; if (monthlyPrice > 0 && newValue >= 0) { const monthsToPay = Math.max(0, 12 - newValue); newData.annual_price = (monthlyPrice * monthsToPay).toFixed(2); } } return newData; }); }; const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); setLoading(true); setError(''); try { if (!formData.name || !formData.slug) { setError('Nome e Slug são obrigatórios'); setLoading(false); return; } const token = localStorage.getItem('token'); const features = formData.features .split(',') .map(f => f.trim()) .filter(f => f.length > 0); const differentiators = formData.differentiators .split(',') .map(d => d.trim()) .filter(d => d.length > 0); const payload = { name: formData.name, slug: formData.slug, description: formData.description, min_users: formData.min_users, max_users: formData.max_users, monthly_price: formData.monthly_price ? parseFloat(formData.monthly_price) : null, annual_price: formData.annual_price ? parseFloat(formData.annual_price) : null, features, differentiators, storage_gb: formData.storage_gb, is_active: formData.is_active, }; console.log('Enviando payload:', payload); const response = await fetch('/api/admin/plans', { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json', }, body: JSON.stringify(payload), }); if (!response.ok) { const errorData = await response.json(); console.error('Erro da API:', errorData); throw new Error(errorData.message || 'Erro ao criar plano'); } const data = await response.json(); console.log('Plano criado:', data); onSuccess(data.plan); handleClose(); } catch (err: any) { console.error('Erro ao criar plano:', err); setError(err.message || 'Erro desconhecido ao criar plano'); } finally { setLoading(false); } }; const handleClose = () => { if (!loading) { setError(''); setFormData({ name: '', slug: '', description: '', min_users: 1, max_users: 30, monthly_price: '', annual_price: '', discount_months: 2, features: '', differentiators: '', storage_gb: 10, is_active: true, }); onClose(); } }; return (
{/* Header */}
Criar Novo Plano

Configure um novo plano de assinatura para as agências.

{/* Error Message */} {error && (

{error}

)}
{['Dados Básicos', 'Usuários', 'Preços', 'Avançado'].map((tab) => ( `flex-1 px-4 py-2.5 text-sm font-medium rounded-lg transition-all focus:outline-none ${selected ? 'bg-white dark:bg-zinc-900 text-zinc-900 dark:text-white shadow-sm' : 'text-zinc-600 dark:text-zinc-400 hover:text-zinc-900 dark:hover:text-white' }` } > {tab} ))} {/* Tab 1: Dados Básicos */}