import React, { useState, useEffect } from 'react'; import { RefreshCw, Save, Plus, Trash2, Edit, CheckCircle2, AlertTriangle, BookOpen, Layers, DollarSign } from 'lucide-react'; import { Course, Plan } from '../types'; interface AdminPricingManagerProps { courses: Course[]; fetchCourses: () => void; } function CoursePricingCard({ course, saveLoading, onSave }: { course: Course, saveLoading: string | null, onSave: (id: string, locked: boolean, price: number) => void }) { const [localPrice, setLocalPrice] = useState(course.price || 0); const [localLocked, setLocalLocked] = useState(course.isLocked || false); useEffect(() => { setLocalPrice(course.price || 0); setLocalLocked(course.isLocked || false); }, [course.price, course.isLocked]); const isChanged = localPrice !== (course.price || 0) || localLocked !== (course.isLocked || false); return (

{course.title}

{course.category}

Acesso
{localLocked && (
setLocalPrice(parseFloat(e.target.value) || 0)} className="w-full bg-black/40 border border-white/10 rounded-lg pl-9 pr-3 py-2 text-sm text-white focus:outline-none focus:border-red-500 transition-colors" />
)}
); } export const AdminPricingManager: React.FC = ({ courses, fetchCourses }) => { const [plans, setPlans] = useState([]); const [loading, setLoading] = useState(true); const [saveLoading, setSaveLoading] = useState(null); // Modal state for Plans const [showPlanModal, setShowPlanModal] = useState(false); const [planForm, setPlanForm] = useState>({ cycle: 'LIFETIME', active: true, includedCourses: [] }); const token = localStorage.getItem('devflix_token'); const fetchPlans = async () => { setLoading(true); try { const res = await fetch('/api/admin/plans', { headers: { 'Authorization': `Bearer ${token}` } }); if (res.ok) { const data = await res.json(); setPlans(data); } } catch (err) { console.error(err); } finally { setLoading(false); } }; useEffect(() => { fetchPlans(); }, []); const handleUpdateCoursePrice = async (courseId: string, isLocked: boolean, price: number) => { setSaveLoading(`course_${courseId}`); try { await fetch(`/api/admin/courses/${courseId}/price`, { method: 'PUT', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` }, body: JSON.stringify({ isLocked, price }) }); fetchCourses(); } catch (err) { console.error(err); } finally { setSaveLoading(null); } }; const handleSavePlan = async (e: React.FormEvent) => { e.preventDefault(); setSaveLoading('plan_save'); try { const url = planForm.id ? `/api/admin/plans/${planForm.id}` : '/api/admin/plans'; const method = planForm.id ? 'PUT' : 'POST'; await fetch(url, { method, headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` }, body: JSON.stringify(planForm) }); await fetchPlans(); setShowPlanModal(false); } catch (err) { console.error(err); } finally { setSaveLoading(null); } }; const handleDeletePlan = async (planId: string) => { if (!window.confirm('Tem certeza que deseja excluir este plano?')) return; try { await fetch(`/api/admin/plans/${planId}`, { method: 'DELETE', headers: { 'Authorization': `Bearer ${token}` } }); fetchPlans(); } catch (err) { console.error(err); } }; const toggleCourseInPlan = (courseId: string) => { const current = planForm.includedCourses || []; if (current.includes(courseId)) { setPlanForm({ ...planForm, includedCourses: current.filter(id => id !== courseId) }); } else { setPlanForm({ ...planForm, includedCourses: [...current, courseId] }); } }; return (
{/* SEÇÃO 1: Precificação Avulsa */}

Cursos Individuais (Venda Avulsa)

Configure quais cursos são pagos e defina o preço unitário vitalício.

{courses.map(course => ( ))}
{/* SEÇÃO 2: Planos e Combos */}

Combos & Planos de Assinatura

Crie pacotes agrupando cursos ou assinaturas globais mensais/anuais.

{loading ? (
) : plans.length === 0 ? (

Nenhum plano ou combo criado.

Crie pacotes para oferecer descontos na compra de vários cursos juntos.

) : (
{plans.map(plan => (
{!plan.active && (
Inativo
)}
{plan.cycle === 'MONTHLY' ? 'Assinatura Mensal' : plan.cycle === 'YEARLY' ? 'Assinatura Anual' : 'Pagamento Único (Combo)'}

{plan.title}

{plan.description}

R$ {plan.price.toFixed(2).replace('.', ',')} {plan.cycle !== 'LIFETIME' && / {plan.cycle === 'MONTHLY' ? 'mês' : 'ano'}}
Cursos Inclusos: {plan.includedCourses.length === 0 ? (
Acesso Global (Tudo)
) : (
    {plan.includedCourses.slice(0, 3).map(cId => { const c = courses.find(cx => cx.id === cId); return c ?
  • {c.title}
  • : null; })} {plan.includedCourses.length > 3 && (
  • + {plan.includedCourses.length - 3} outros cursos
  • )}
)}
))}
)}
{/* Plan Form Modal */} {showPlanModal && (

{planForm.id ? 'Editar Plano / Combo' : 'Criar Novo Plano / Combo'}

setPlanForm({...planForm, title: e.target.value})} className="w-full bg-black/40 border border-white/10 rounded-lg p-3 text-sm text-white focus:outline-none focus:border-purple-500 transition-colors" placeholder="Ex: Combo Master Office" />