diff --git a/src/components/wpp/AppWPP.jsx b/src/components/wpp/AppWPP.jsx index 688a698..ce7722c 100644 --- a/src/components/wpp/AppWPP.jsx +++ b/src/components/wpp/AppWPP.jsx @@ -74,9 +74,12 @@ export default function AppWPP() { }, []); // Salva no localStorage sempre que `servers` mudar - const updateServersState = (updatedList) => { - setServers(updatedList); - saveServers(updatedList); + const updateServersState = (updater) => { + setServers((prevServers) => { + const next = typeof updater === 'function' ? updater(prevServers) : updater; + saveServers(next); + return next; + }); }; const showToast = (message, type = 'info') => { @@ -91,79 +94,97 @@ export default function AppWPP() { // Servidor CRUD const handleSaveServer = (serverData) => { - let updated; - const exists = servers.some((s) => s.id === serverData.id); - if (exists) { - updated = servers.map((s) => (s.id === serverData.id ? { ...s, ...serverData } : s)); - showToast(`Servidor "${serverData.name}" atualizado!`, 'success'); - } else { - updated = [...servers, serverData]; - setActiveServerId(serverData.id); - showToast(`Servidor "${serverData.name}" adicionado com sucesso!`, 'success'); - } - updateServersState(updated); + updateServersState((prevServers) => { + const exists = prevServers.some((s) => s.id === serverData.id); + let updated; + if (exists) { + updated = prevServers.map((s) => (s.id === serverData.id ? { ...s, ...serverData } : s)); + } else { + updated = [...prevServers, serverData]; + setActiveServerId(serverData.id); + } + return updated; + }); + showToast(`Servidor "${serverData.name}" salvo com sucesso!`, 'success'); }; const handleRemoveServer = () => { - if (!activeServer) return; + if (!activeServerId) return; + const currentName = activeServer?.name || 'Servidor'; setConfirmModal({ isOpen: true, title: 'Remover Servidor', - message: `Tem certeza que deseja remover o servidor "${activeServer.name}"?`, + message: `Tem certeza que deseja remover o servidor "${currentName}"?`, description: 'Todas as sessões cadastradas para este servidor deixarão de ser exibidas na listagem.', confirmText: 'Remover Servidor', type: 'danger', onConfirm: () => { - const updated = servers.filter((s) => s.id !== activeServer.id); - updateServersState(updated); - setActiveServerId(updated.length > 0 ? updated[0].id : null); - showToast(`Servidor "${activeServer.name}" removido.`, 'info'); + updateServersState((prevServers) => { + const updated = prevServers.filter((s) => s.id !== activeServerId); + setActiveServerId(updated.length > 0 ? updated[0].id : null); + return updated; + }); + showToast(`Servidor "${currentName}" removido.`, 'info'); } }); }; // Sessão CRUD const handleSaveSession = async (sessionData, originalName) => { - if (!activeServer) return; + if (!activeServerId) return; - let updatedSessions = [...(activeServer.sessions || [])]; - if (originalName) { - updatedSessions = updatedSessions.map((s) => (s.name === originalName ? sessionData : s)); - showToast(`Sessão "${sessionData.name}" atualizada!`, 'success'); - } else { - if (updatedSessions.some((s) => s.name === sessionData.name)) { - showToast('Já existe uma sessão com este nome.', 'error'); - return; + let isDuplicate = false; + + updateServersState((prevServers) => { + const srv = prevServers.find((s) => s.id === activeServerId); + if (!srv) return prevServers; + + const currentSessions = [...(srv.sessions || [])]; + let updatedSessions; + + if (originalName) { + updatedSessions = currentSessions.map((s) => (s.name === originalName ? sessionData : s)); + } else { + if (currentSessions.some((s) => s.name === sessionData.name)) { + isDuplicate = true; + return prevServers; + } + updatedSessions = [...currentSessions, sessionData]; } - updatedSessions.push(sessionData); - showToast(`Sessão "${sessionData.name}" criada!`, 'success'); + + return prevServers.map((s) => (s.id === activeServerId ? { ...s, sessions: updatedSessions } : s)); + }); + + if (isDuplicate) { + showToast('Já existe uma sessão com este nome.', 'error'); + return; } - const updatedServer = { ...activeServer, sessions: updatedSessions }; - const updatedServers = servers.map((s) => (s.id === activeServer.id ? updatedServer : s)); - updateServersState(updatedServers); + if (originalName) { + showToast(`Sessão "${sessionData.name}" atualizada!`, 'success'); + } else { + showToast(`Sessão "${sessionData.name}" criada com sucesso!`, 'success'); - // Se for nova sessão, tenta gerar token e iniciar - if (!originalName) { - try { - const token = await generateToken(activeServer, sessionData.name); - if (token) { - sessionData.token = token; - updateServersState( - servers.map((s) => - s.id === activeServer.id - ? { ...s, sessions: updatedSessions.map((x) => (x.name === sessionData.name ? { ...x, token } : x)) } - : s - ) - ); + // Se for nova sessão, tenta gerar token e iniciar no servidor WPP + const currentServer = servers.find((s) => s.id === activeServerId) || activeServer; + if (currentServer) { + if (!sessionData.token) { + try { + const token = await generateToken(currentServer, sessionData.name); + if (token) { + updateSessionProperty(sessionData.name, { token }); + } + } catch (e) { + console.warn('Erro ao gerar token automático:', e); + } } - } catch (e) {} - handleStartSession(sessionData.name, true); + handleStartSession(sessionData.name, true); + } } }; const handleRemoveSession = (sessionName) => { - if (!activeServer) return; + if (!activeServerId) return; setConfirmModal({ isOpen: true, title: 'Excluir Sessão', @@ -172,11 +193,13 @@ export default function AppWPP() { confirmText: 'Excluir Sessão', type: 'danger', onConfirm: () => { - const updatedSessions = activeServer.sessions.filter((s) => s.name !== sessionName); - const updatedServers = servers.map((s) => - s.id === activeServer.id ? { ...s, sessions: updatedSessions } : s + updateServersState((prevServers) => + prevServers.map((s) => { + if (s.id !== activeServerId) return s; + const updatedSessions = (s.sessions || []).filter((sess) => sess.name !== sessionName); + return { ...s, sessions: updatedSessions }; + }) ); - updateServersState(updatedServers); showToast(`Sessão "${sessionName}" removida.`, 'info'); } }); @@ -284,14 +307,18 @@ export default function AppWPP() { }; const updateSessionProperty = (sessionName, props) => { - if (!activeServer) return; - const updatedSessions = activeServer.sessions.map((s) => - s.name === sessionName ? { ...s, ...props } : s + if (!activeServerId) return; + updateServersState((prevServers) => + prevServers.map((srv) => { + if (srv.id !== activeServerId) return srv; + const currentSessions = srv.sessions || []; + const exists = currentSessions.some((s) => s.name === sessionName); + const updatedSessions = exists + ? currentSessions.map((s) => (s.name === sessionName ? { ...s, ...props } : s)) + : [...currentSessions, { name: sessionName, ...props }]; + return { ...srv, sessions: updatedSessions }; + }) ); - const updatedServers = servers.map((srv) => - srv.id === activeServer.id ? { ...srv, sessions: updatedSessions } : srv - ); - updateServersState(updatedServers); }; // Filtro de sessões @@ -469,8 +496,20 @@ export default function AppWPP() {

{searchQuery ? 'Nenhuma sessão corresponde à busca informada.' - : 'Clique em "+ Nova Sessão" acima para cadastrar sua primeira sessão do WhatsApp.'} + : 'Clique no botão abaixo para cadastrar uma nova sessão do WhatsApp.'}

+ )} diff --git a/src/components/wpp/ModalSession.jsx b/src/components/wpp/ModalSession.jsx index 4077634..a0fcc48 100644 --- a/src/components/wpp/ModalSession.jsx +++ b/src/components/wpp/ModalSession.jsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from 'react'; +import React, { useState, useEffect, useRef } from 'react'; import { X, MessageSquare, Key, Globe, Shield } from 'lucide-react'; export default function ModalSession({ isOpen, onClose, onSave, sessionToEdit }) { @@ -7,6 +7,7 @@ export default function ModalSession({ isOpen, onClose, onSave, sessionToEdit }) const [webhook, setWebhook] = useState(''); const [waitQrCode, setWaitQrCode] = useState(false); const [proxyUrl, setProxyUrl] = useState(''); + const inputRef = useRef(null); useEffect(() => { if (sessionToEdit) { @@ -22,19 +23,23 @@ export default function ModalSession({ isOpen, onClose, onSave, sessionToEdit }) setWaitQrCode(false); setProxyUrl(''); } + if (isOpen) { + setTimeout(() => inputRef.current?.focus(), 100); + } }, [sessionToEdit, isOpen]); if (!isOpen) return null; const handleSubmit = (e) => { e.preventDefault(); - if (!name.trim()) { + const cleanName = name.trim().replace(/\s+/g, '_'); + if (!cleanName) { alert('Informe o nome da sessão.'); return; } onSave({ - name: name.trim(), + name: cleanName, token: token.trim(), webhook: webhook.trim(), waitQrCode, @@ -47,14 +52,14 @@ export default function ModalSession({ isOpen, onClose, onSave, sessionToEdit }) }; return ( -
-
e.stopPropagation()} style={{ maxWidth: '520px' }}> +
+

{sessionToEdit ? 'Editar Sessão' : 'Nova Sessão WhatsApp'}

-
@@ -64,13 +69,17 @@ export default function ModalSession({ isOpen, onClose, onSave, sessionToEdit })
setName(e.target.value)} required /> + + Nome de identificação único para a rota da API (espaços serão convertidos em "_"). +
@@ -78,7 +87,7 @@ export default function ModalSession({ isOpen, onClose, onSave, sessionToEdit }) setToken(e.target.value)} />