import React, { useState, useEffect, useRef } from 'react'; import { Mail, MessageSquare, BookOpen, Send, User, Reply, CheckCircle2, AlertCircle, Smartphone, Save, Smile, Megaphone, Clock } from 'lucide-react'; import CustomModal from './CustomModal'; interface SupportTicket { id: string; content: string; status: string; createdAt: string; user: { id: string; name: string; email: string; avatarUrl: string | null; whatsapp: string | null; }; } interface Note { id: string; content: string; createdAt: string; user: { id: string; name: string; email: string; avatarUrl: string | null; whatsapp: string | null; }; lesson: { title: string; module: { course: { title: string; } } }; } // Simple emoji picker groups const EMOJI_LIST = [ '😊','😁','🎉','🙏','💪','🚀','❤️','✅','⭐','🔥','💡','📚','🎓','👏','🤝', '💰','💳','🛒','📱','📧','🌟','🏆','✨','🎯','📢','👋','😀','🥳','💎','🌈' ]; // Default template texts const DEFAULT_TEMPLATES: Record = { whatsappTemplatePayment: `Olá, *{nome}*! 🎉 Recebemos a confirmação do seu pagamento com sucesso! 💰 *Valor:* {valor} 📦 *Plano/Curso:* {plano}{curso} Seu acesso já está liberado na plataforma. Qualquer dúvida, estamos à disposição. Muito obrigado pela sua confiança! 🙏 _Equipe MicrotecFlix_`, whatsappTemplateWelcome: `Olá, *{nome}*! 👋 Seja muito bem-vindo(a) à *MicrotecFlix*! 🎓🚀 Estamos felizes em ter você conosco. Agora você tem acesso à nossa plataforma de cursos de informática e pacote Office. Acesse: https://estudo.microtecinformaticacurso.com.br Se tiver qualquer dúvida, é só chamar. 😊 _Equipe MicrotecFlix_`, whatsappTemplateNewContent: `Oi, *{nome}*! 🎬 Temos uma novidade imperdível para você na plataforma! ⭐ *Novo conteúdo disponível:* Acabamos de publicar um novo curso/módulo/aula. Acesse agora mesmo e aproveite: https://estudo.microtecinformaticacurso.com.br Bons estudos! 💪 _Equipe MicrotecFlix_`, whatsappTemplatePromo: `Oi, *{nome}*! 🌟 Temos uma oferta especial para você hoje! 🎯 Aproveite nossa promoção exclusiva e acelere seus estudos de informática e pacote Office. Não perca essa oportunidade única! Acesse agora: https://estudo.microtecinformaticacurso.com.br Qualquer dúvida, estamos aqui. 🙏 _Equipe MicrotecFlix_` }; export default function AdminMessagesView() { const [activeTab, setActiveTab] = useState<'tickets' | 'notes' | 'whatsapp_templates'>('tickets'); const [tickets, setTickets] = useState([]); const [notes, setNotes] = useState([]); const [isLoading, setIsLoading] = useState(true); const [replyText, setReplyText] = useState(''); const [replyingTo, setReplyingTo] = useState(null); const [isSending, setIsSending] = useState(false); const [alertModal, setAlertModal] = useState<{isOpen: boolean, title: string, message: string, isError?: boolean}>({isOpen: false, title: '', message: ''}); // WhatsApp Templates State const [settings, setSettings] = useState(null); const [activeTemplateModal, setActiveTemplateModal] = useState(null); const [currentTemplateText, setCurrentTemplateText] = useState(''); const [isSavingTemplate, setIsSavingTemplate] = useState(false); const [isTestingTemplate, setIsTestingTemplate] = useState(null); const [showEmojiPicker, setShowEmojiPicker] = useState(false); const textareaRef = useRef(null); // Broadcast state const [broadcastText, setBroadcastText] = useState(''); const [broadcastDelay, setBroadcastDelay] = useState(10); const [isBroadcasting, setIsBroadcasting] = useState(false); const [showBroadcastEmojiPicker, setShowBroadcastEmojiPicker] = useState(false); const broadcastRef = useRef(null); useEffect(() => { fetchData(); }, []); const fetchData = async () => { setIsLoading(true); try { const token = localStorage.getItem('admin_token'); const [msgRes, settingsRes] = await Promise.all([ fetch('/api/admin/messages', { headers: { 'Authorization': `Bearer ${token}` } }), fetch('/api/admin/settings', { headers: { 'Authorization': `Bearer ${token}` } }) ]); if (msgRes.ok) { const data = await msgRes.json(); setTickets(data.tickets); setNotes(data.notes); } if (settingsRes.ok) { const data = await settingsRes.json(); setSettings(data); // Pre-fill broadcast from template if (data.whatsappTemplatePromo) { setBroadcastText(data.whatsappTemplatePromo); } } } catch (error) { console.error('Error fetching data:', error); } finally { setIsLoading(false); } }; const handleReply = async (userId: string, ticketId?: string) => { if (!replyText.trim()) return; setIsSending(true); try { const token = localStorage.getItem('admin_token'); const res = await fetch('/api/admin/reply-message', { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ userId, message: replyText, ticketId }) }); if (res.ok) { setReplyText(''); setReplyingTo(null); fetchData(); setAlertModal({isOpen: true, title: 'Sucesso', message: 'Resposta enviada com sucesso!'}); } else { setAlertModal({isOpen: true, title: 'Erro', message: 'Erro ao enviar resposta.', isError: true}); } } catch (error) { console.error('Error replying:', error); setAlertModal({isOpen: true, title: 'Erro', message: 'Erro interno ao enviar resposta.', isError: true}); } finally { setIsSending(false); } }; const handleSaveTemplate = async (field: string) => { setIsSavingTemplate(true); try { const token = localStorage.getItem('admin_token'); const res = await fetch('/api/admin/settings', { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ [field]: currentTemplateText }) }); if (res.ok) { setSettings({...settings, [field]: currentTemplateText}); setActiveTemplateModal(null); setAlertModal({isOpen: true, title: 'Sucesso', message: 'Template salvo com sucesso! O envio automático já está ativado.'}); } else { setAlertModal({isOpen: true, title: 'Erro', message: 'Erro ao salvar template.', isError: true}); } } catch (error) { console.error('Error saving template:', error); setAlertModal({isOpen: true, title: 'Erro', message: 'Erro interno ao salvar template.', isError: true}); } finally { setIsSavingTemplate(false); } }; const handleTestTemplate = async (templateId: string, e: React.MouseEvent) => { e.stopPropagation(); setIsTestingTemplate(templateId); try { const token = localStorage.getItem('admin_token'); const res = await fetch('/api/admin/whatsapp/test-template', { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ templateId }) }); const data = await res.json(); if (res.ok) { setAlertModal({isOpen: true, title: 'Enviado! 📱', message: data.message}); } else { setAlertModal({isOpen: true, title: 'Erro no Teste', message: data.error, isError: true}); } } catch (error) { console.error('Error testing template:', error); setAlertModal({isOpen: true, title: 'Erro', message: 'Erro interno ao testar template.', isError: true}); } finally { setIsTestingTemplate(null); } }; const insertEmoji = (emoji: string, isForBroadcast = false) => { const ref = isForBroadcast ? broadcastRef : textareaRef; const setter = isForBroadcast ? setBroadcastText : setCurrentTemplateText; const current = isForBroadcast ? broadcastText : currentTemplateText; if (ref.current) { const start = ref.current.selectionStart; const end = ref.current.selectionEnd; const newText = current.substring(0, start) + emoji + current.substring(end); setter(newText); setTimeout(() => { if (ref.current) { ref.current.focus(); ref.current.setSelectionRange(start + emoji.length, start + emoji.length); } }, 0); } else { setter(current + emoji); } if (isForBroadcast) setShowBroadcastEmojiPicker(false); else setShowEmojiPicker(false); }; const handleBroadcast = async () => { if (!broadcastText.trim()) return; setIsBroadcasting(true); try { const token = localStorage.getItem('admin_token'); const res = await fetch('/api/admin/whatsapp/broadcast', { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ message: broadcastText, delaySeconds: broadcastDelay }) }); const data = await res.json(); if (res.ok) { setAlertModal({isOpen: true, title: 'Envio Iniciado! 🚀', message: data.message || 'Broadcast iniciado com sucesso!'}); } else { setAlertModal({isOpen: true, title: 'Erro', message: data.error || 'Erro ao iniciar broadcast.', isError: true}); } } catch (error) { console.error('Error broadcasting:', error); setAlertModal({isOpen: true, title: 'Erro', message: 'Erro interno ao enviar.', isError: true}); } finally { setIsBroadcasting(false); } }; const whatsappTemplates = [ { id: 'whatsappTemplatePayment', title: 'Pagamento Confirmado', desc: 'Enviada automaticamente quando o aluno paga um plano ou curso.', icon: '💰', tags: ['{nome}', '{valor}', '{plano}', '{curso}'] }, { id: 'whatsappTemplateWelcome', title: 'Boas-Vindas (Nova Conta)', desc: 'Enviada automaticamente quando o aluno cria uma conta.', icon: '👋', tags: ['{nome}'] }, { id: 'whatsappTemplateNewContent', title: 'Novo Conteúdo (Carrossel)', desc: 'Enviada manualmente ao postar curso/módulo/aula.', icon: '🎬', tags: ['{nome}'] }, ]; return (

Mensagens e Comunicações

Gerencie dúvidas, anotações e configure as mensagens automáticas do WhatsApp.

{isLoading ? (
) : (
{activeTab === 'tickets' && ( tickets.length === 0 ? (
Nenhum comentário recebido.
) : ( tickets.map(ticket => (
{ticket.status === 'REPLIED' && (
Respondido
)}
{ticket.user.avatarUrl ? ( {ticket.user.name} ) : ( )}

{ticket.user.name}

{ticket.user.email} {ticket.user.whatsapp && `• WA: ${ticket.user.whatsapp}`}

{new Date(ticket.createdAt).toLocaleString('pt-BR')}

{ticket.content}
{replyingTo === ticket.id ? (