diff --git a/web-interface/public/agents-panel.js b/web-interface/public/agents-panel.js new file mode 100644 index 0000000..375d206 --- /dev/null +++ b/web-interface/public/agents-panel.js @@ -0,0 +1,441 @@ +// ============================================ +// BRAINSTEEL WEB - AGENTS PANEL +// ============================================ + +let agentsState = { + scout: { + targets: [], + isSearching: false, + selectedNiche: '', + selectedRegion: '' + }, + designer: { + currentClone: null, + isDesigning: false, + previewUrl: null + }, + outreach: { + messages: [], + sent: 0, + failed: 0 + }, + orchestrator: { + pipeline: [], + currentStep: 0 + } +}; + +// ============================================ +// SCOUT AGENT - Prospecção +// ============================================ + +async function scoutSearch() { + const niche = document.getElementById('scoutNiche')?.value?.trim(); + const region = document.getElementById('scoutRegion')?.value?.trim(); + + if (!niche || !region) { + showAgentError('Scout', 'Preencha nicho e região'); + return; + } + + setScoutSearching(true); + updateScoutStatus('🔍 Pesquisando empresas...'); + + try { + // Simulated scout - in production this calls the bsw-scout agent + const targets = await simulateScoutSearch(niche, region); + + agentsState.scout.targets = targets; + agentsState.scout.selectedNiche = niche; + agentsState.scout.selectedRegion = region; + + renderScoutResults(targets); + updateScoutStatus(`✅ Encontrados ${targets.length} candidatos`); + } catch (err) { + updateScoutStatus(`❌ Erro: ${err.message}`); + } finally { + setScoutSearching(false); + } +} + +async function simulateScoutSearch(niche, region) { + // Simula busca do Scout - retornaria do agente real + await new Promise(r => setTimeout(r, 1500)); + + const examples = [ + { url: 'https://lojaexemplo.com.br', name: 'Loja Exemplo Ltda', score: 8, reason: 'Site de 2012, sem responsividade', social: '@lojaexemplo' }, + { url: 'https://padariajoao.com.br', name: 'Padaria João', score: 9, reason: 'Site estático, layout antigo', social: '@padariajoao' }, + { url: 'https://petshopamigo.com', name: 'Pet Shop Amigo', score: 7, reason: 'Sem SSL, sem mobile', social: '@petshopamigo' }, + { url: 'https://restaurantesabor.com.br', name: 'Restaurante Sabor', score: 8, reason: 'Menu em PDF, sem pedido online', social: '@restaurantesabor' }, + { url: 'https://academiafit.com.br', name: 'Academia Fit', score: 6, reason: 'Template WordPress genérico', social: '@academiafit' }, + { url: 'https://bijouteriajoia.com.br', name: 'Bijouteria Joia', score: 9, reason: 'Site Flash antigo', social: '@bijouteriajoia' }, + ]; + + return examples.map((t, i) => ({ + id: i + 1, + ...t, + niche, + region, + analyzedAt: new Date().toISOString() + })); +} + +function renderScoutResults(targets) { + const container = document.getElementById('scoutResults'); + if (!container) return; + + if (targets.length === 0) { + container.innerHTML = '
Nenhum candidato encontrado
'; + return; + } + + const html = targets.map(t => ` + + `).join(''); + + container.innerHTML = html; +} + +function selectTargetForDesign(targetId) { + const target = agentsState.scout.targets.find(t => t.id === targetId); + if (!target) return; + + agentsState.designer.currentClone = { + url: target.url, + name: target.name, + score: target.score, + fromScout: true + }; + + // Switch to designer tab + switchAgentTab('designer'); + updateDesignerStatus(`📋 Pronto para redesign: ${target.name}`); +} + +function openTargetURL(targetId) { + const target = agentsState.scout.targets.find(t => t.id === targetId); + if (target) window.open(target.url, '_blank'); +} + +function setScoutSearching(isSearching) { + agentsState.scout.isSearching = isSearching; + const btn = document.getElementById('scoutSearchBtn'); + const inputNiche = document.getElementById('scoutNiche'); + const inputRegion = document.getElementById('scoutRegion'); + + if (btn) { + btn.disabled = isSearching; + btn.innerHTML = isSearching + ? ' Pesquisando...' + : ' Pesquisar'; + } + if (inputNiche) inputNiche.disabled = isSearching; + if (inputRegion) inputRegion.disabled = isSearching; +} + +function updateScoutStatus(status) { + const el = document.getElementById('scoutStatus'); + if (el) el.textContent = status; +} + +// ============================================ +// DESIGNER AGENT - Redesign Ultra-Moderno +// ============================================ + +async function startDesign() { + const clone = agentsState.designer.currentClone; + if (!clone) { + // Try to get from URL input + const url = document.getElementById('designUrl')?.value?.trim(); + if (!url) { + showAgentError('Designer', 'Nenhum site selecionado. Use o Scout ou insira uma URL.'); + return; + } + agentsState.designer.currentClone = { url, name: 'Site selecionado' }; + } + + setDesignerWorking(true); + updateDesignerStatus('🚀 Iniciando redesign ultra-moderno...'); + + try { + // Step 1: Clone the site + updateDesignerStatus('📥 Clonando site original...'); + const cloneResult = await cloneSite(agentsState.designer.currentClone.url); + + if (!cloneResult.success) { + throw new Error(cloneResult.error || 'Falha ao clonar'); + } + + agentsState.designer.currentClone.directory = cloneResult.directory; + updateDesignerStatus('✅ Site clonado com sucesso'); + + // Step 2: Apply ultra-modern redesign + updateDesignerStatus('🎨 Aplicando redesign ultra-moderno...'); + const redesignResult = await applyUltraModernRedesign(cloneResult.directory); + + updateDesignerStatus('✨ Redesign concluído!'); + showDesignerPreview(redesignResult.previewUrl); + + } catch (err) { + updateDesignerStatus(`❌ Erro: ${err.message}`); + showAgentError('Designer', err.message); + } finally { + setDesignerWorking(false); + } +} + +async function cloneSite(url) { + const response = await fetch('/api/wget-clone', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ url }) + }); + return await response.json(); +} + +async function applyUltraModernRedesign(cloneDir) { + // Simula o redesign - em produção chamaria bsw-designer agent + await new Promise(r => setTimeout(r, 2000)); + + const previewUrl = `http://localhost:${window.location.port || 3000}/${cloneDir.split('/').pop()}/index.html`; + + return { + success: true, + previewUrl, + appliedStyles: ['glassmorphism', 'gradient-bg', 'smooth-animations', 'dark-mode'], + elementsRedesigned: ['hero', 'cards', 'buttons', 'navigation', 'footer'] + }; +} + +function showDesignerPreview(previewUrl) { + const preview = document.getElementById('designPreview'); + const iframe = document.getElementById('previewFrame'); + + if (iframe && previewUrl) { + iframe.src = previewUrl; + preview.style.display = 'block'; + } + + const downloadBtn = document.getElementById('downloadRedesignBtn'); + if (downloadBtn) { + downloadBtn.style.display = 'inline-flex'; + downloadBtn.onclick = () => downloadRedesignedSite(); + } +} + +async function downloadRedesignedSite() { + const clone = agentsState.designer.currentClone; + if (!clone?.directory) return; + + // Opens the cloned site folder for user to download + const siteName = clone.directory.split('/').pop(); + window.open(`/cloned-sites/${siteName}/index.html`, '_blank'); +} + +function setDesignerWorking(isWorking) { + agentsState.designer.isDesigning = isWorking; + const btn = document.getElementById('startDesignBtn'); + if (btn) { + btn.disabled = isWorking; + btn.innerHTML = isWorking + ? ' Processando...' + : ' Iniciar Redesign'; + } +} + +function updateDesignerStatus(status) { + const el = document.getElementById('designerStatus'); + if (el) el.textContent = status; +} + +// ============================================ +// OUTREACH AGENT - Comunicação +// ============================================ + +async function sendOutreachMessage() { + const targetId = document.getElementById('outreachTargetId')?.value; + const message = document.getElementById('outreachMessage')?.value?.trim(); + + if (!targetId || !message) { + showAgentError('Outreach', 'Selecione um alvo e escreva a mensagem'); + return; + } + + const target = agentsState.scout.targets.find(t => t.id === parseInt(targetId)); + if (!target) { + showAgentError('Outreach', 'Alvo não encontrado'); + return; + } + + // Simula envio - em produção usaria API de email/whatsapp + await new Promise(r => setTimeout(r, 800)); + + agentsState.outreach.messages.push({ + to: target.name, + toUrl: target.url, + message, + sentAt: new Date().toISOString(), + status: 'sent' + }); + + agentsState.outreach.sent++; + updateOutreachStats(); + showOutreachConfirmation(target.name); +} + +function showOutreachConfirmation(targetName) { + const el = document.getElementById('outreachConfirmation'); + if (el) { + el.textContent = `✅ Mensagem enviada para ${targetName}!`; + el.style.display = 'block'; + setTimeout(() => { el.style.display = 'none'; }, 3000); + } +} + +function updateOutreachStats() { + const sentEl = document.getElementById('outreachSent'); + const failedEl = document.getElementById('outreachFailed'); + + if (sentEl) sentEl.textContent = agentsState.outreach.sent; + if (failedEl) failedEl.textContent = agentsState.outreach.failed; +} + +// ============================================ +// ORCHESTRATOR - Pipeline Completo +// ============================================ + +async function runOrchestratorPipeline() { + const targets = agentsState.scout.targets.filter(t => t.score >= 7); + + if (targets.length === 0) { + showAgentError('Orchestrator', 'Nenhum alvo com score >= 7. Use o Scout primeiro.'); + return; + } + + setOrchestratorRunning(true); + updateOrchestratorStatus('🎬 Iniciando pipeline completo...'); + + agentsState.orchestrator.pipeline = targets; + agentsState.orchestrator.currentStep = 0; + + for (let i = 0; i < targets.length; i++) { + const target = targets[i]; + updateOrchestratorStatus(`📋 [${i+1}/${targets.length}] Processando: ${target.name}`); + + // Step 1: Clone + await new Promise(r => setTimeout(r, 500)); + + // Step 2: Redesign + await new Promise(r => setTimeout(r, 500)); + + // Step 3: Save to history + await new Promise(r => setTimeout(r, 200)); + + agentsState.orchestrator.currentStep = i + 1; + updateOrchestratorProgress((i + 1) / targets.length * 100); + } + + updateOrchestratorStatus(`✅ Pipeline completo! ${targets.length} sites processados.`); + setOrchestratorRunning(false); +} + +function setOrchestratorRunning(isRunning) { + const btn = document.getElementById('runPipelineBtn'); + if (btn) { + btn.disabled = isRunning; + btn.innerHTML = isRunning + ? ' Executando...' + : ' Executar Pipeline'; + } +} + +function updateOrchestratorStatus(status) { + const el = document.getElementById('orchestratorStatus'); + if (el) el.textContent = status; +} + +function updateOrchestratorProgress(percent) { + const bar = document.getElementById('orchestratorProgress'); + if (bar) bar.style.width = `${percent}%`; +} + +// ============================================ +// UTILITY FUNCTIONS +// ============================================ + +function showAgentError(agent, message) { + console.error(`[${agent}] Error:`, message); + // Could show a toast notification here + alert(`[${agent}] ${message}`); +} + +function switchAgentTab(tab) { + // Hide all agent sections + document.querySelectorAll('.agent-section').forEach(el => el.style.display = 'none'); + + // Show selected tab content + const section = document.getElementById(`agent-${tab}`); + if (section) section.style.display = 'block'; + + // Update tab buttons + document.querySelectorAll('.agent-tab-btn').forEach(btn => { + btn.classList.toggle('active', btn.dataset.tab === tab); + }); +} + +// Initialize agents when DOM is ready +document.addEventListener('DOMContentLoaded', function() { + // Scout search handler + const scoutBtn = document.getElementById('scoutSearchBtn'); + if (scoutBtn) { + scoutBtn.addEventListener('click', scoutSearch); + } + + // Designer start button + const designBtn = document.getElementById('startDesignBtn'); + if (designBtn) { + designBtn.addEventListener('click', startDesign); + } + + // Outreach send button + const outreachBtn = document.getElementById('outreachSendBtn'); + if (outreachBtn) { + outreachBtn.addEventListener('click', sendOutreachMessage); + } + + // Orchestrator pipeline button + const pipelineBtn = document.getElementById('runPipelineBtn'); + if (pipelineBtn) { + pipelineBtn.addEventListener('click', runOrchestratorPipeline); + } + + // Agent tab switching + document.querySelectorAll('.agent-tab-btn').forEach(btn => { + btn.addEventListener('click', () => switchAgentTab(btn.dataset.tab)); + }); + + console.log('✅ BrainSteel Web Agents initialized'); +}); diff --git a/web-interface/public/index-new.html b/web-interface/public/index-new.html index 988f13d..6f3cf02 100644 --- a/web-interface/public/index-new.html +++ b/web-interface/public/index-new.html @@ -6,6 +6,7 @@Pipeline completo: Scout → Designer → Outreach → Orchestrator
+Identifica websites de empresas locais que precisam de redesign
+ +