feat: adicionar painel Agentes BrainSteel Web (Scout, Designer, Outreach, Orchestrator)
This commit is contained in:
@@ -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 = '<p class="text-muted">Nenhum candidato encontrado</p>';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const html = targets.map(t => `
|
||||||
|
<div class="scout-target-card" data-id="${t.id}">
|
||||||
|
<div class="target-header">
|
||||||
|
<span class="target-score score-${t.score >= 8 ? 'high' : t.score >= 6 ? 'medium' : 'low'}">${t.score}</span>
|
||||||
|
<div class="target-info">
|
||||||
|
<h4>${t.name}</h4>
|
||||||
|
<a href="${t.url}" target="_blank" class="target-url">${t.url}</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="target-body">
|
||||||
|
<p class="target-reason">${t.reason}</p>
|
||||||
|
<div class="target-meta">
|
||||||
|
<span><i class="fab fa-instagram"></i> ${t.social}</span>
|
||||||
|
<span class="target-niche">${t.niche}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="target-actions">
|
||||||
|
<button class="btn btn-sm btn-primary" onclick="selectTargetForDesign(${t.id})">
|
||||||
|
<i class="fas fa-magic"></i> Redesign
|
||||||
|
</button>
|
||||||
|
<button class="btn btn-sm btn-secondary" onclick="openTargetURL(${t.id})">
|
||||||
|
<i class="fas fa-external-link-alt"></i> Ver Site
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`).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
|
||||||
|
? '<i class="fas fa-spinner fa-spin"></i> Pesquisando...'
|
||||||
|
: '<i class="fas fa-search"></i> 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
|
||||||
|
? '<i class="fas fa-spinner fa-spin"></i> Processando...'
|
||||||
|
: '<i class="fas fa-magic"></i> 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
|
||||||
|
? '<i class="fas fa-spinner fa-spin"></i> Executando...'
|
||||||
|
: '<i class="fas fa-play"></i> 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');
|
||||||
|
});
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
<title>CloneWeb Pro - Clonagem Profissional de Sites</title>
|
<title>CloneWeb Pro - Clonagem Profissional de Sites</title>
|
||||||
<link rel="stylesheet" href="styles-new.css">
|
<link rel="stylesheet" href="styles-new.css">
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
||||||
|
<script src="agents-panel.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<!-- Sidebar -->
|
<!-- Sidebar -->
|
||||||
@@ -28,6 +29,11 @@
|
|||||||
<i class="fas fa-history"></i>
|
<i class="fas fa-history"></i>
|
||||||
<span>Histórico</span>
|
<span>Histórico</span>
|
||||||
</a>
|
</a>
|
||||||
|
<a href="#" class="nav-item" data-page="agents">
|
||||||
|
<i class="fas fa-robot"></i>
|
||||||
|
<span>Agentes AI</span>
|
||||||
|
</a>
|
||||||
|
|
||||||
<a href="#" class="nav-item" data-page="settings">
|
<a href="#" class="nav-item" data-page="settings">
|
||||||
<i class="fas fa-cog"></i>
|
<i class="fas fa-cog"></i>
|
||||||
<span>Configurações</span>
|
<span>Configurações</span>
|
||||||
@@ -290,6 +296,124 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Agents Page - BrainSteel Web -->
|
||||||
|
<div class="page" id="agents">
|
||||||
|
<div class="agents-header">
|
||||||
|
<h2>🤖 Agentes BrainSteel Web</h2>
|
||||||
|
<p>Pipeline completo: Scout → Designer → Outreach → Orchestrator</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Agent Tabs -->
|
||||||
|
<div class="agent-tabs">
|
||||||
|
<button class="agent-tab-btn active" data-tab="scout">
|
||||||
|
<i class="fas fa-search"></i> Scout
|
||||||
|
</button>
|
||||||
|
<button class="agent-tab-btn" data-tab="designer">
|
||||||
|
<i class="fas fa-magic"></i> Designer
|
||||||
|
</button>
|
||||||
|
<button class="agent-tab-btn" data-tab="outreach">
|
||||||
|
<i class="fas fa-envelope"></i> Outreach
|
||||||
|
</button>
|
||||||
|
<button class="agent-tab-btn" data-tab="orchestrator">
|
||||||
|
<i class="fas fa-tasks"></i> Orchestrator
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- SCOUT SECTION -->
|
||||||
|
<div class="agent-section" id="agent-scout">
|
||||||
|
<div class="agent-card">
|
||||||
|
<h3><i class="fas fa-search"></i> Scout - Prospecção</h3>
|
||||||
|
<p class="agent-description">Identifica websites de empresas locais que precisam de redesign</p>
|
||||||
|
|
||||||
|
<div class="agent-inputs">
|
||||||
|
<input type="text" id="scoutNiche" class="form-control" placeholder="Nichos: restaurantes, academias, padarias...">
|
||||||
|
<input type="text" id="scoutRegion" class="form-control" placeholder="Região: São Paulo, ABC, Zona Sul...">
|
||||||
|
<button id="scoutSearchBtn" class="btn btn-primary">
|
||||||
|
<i class="fas fa-search"></i> Pesquisar Alvos
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="agent-status" id="scoutStatus">Aguardando pesquisa...</div>
|
||||||
|
|
||||||
|
<div id="scoutResults" class="scout-results">
|
||||||
|
<!-- Results will be rendered here -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- DESIGNER SECTION -->
|
||||||
|
<div class="agent-section" id="agent-designer" style="display:none;">
|
||||||
|
<div class="agent-card">
|
||||||
|
<h3><i class="fas fa-magic"></i> Designer - Redesign Ultra-Moderno</h3>
|
||||||
|
<p class="agent-description">Transforma sites clonados em interfaces premium com estética anime/moderna</p>
|
||||||
|
|
||||||
|
<div class="agent-inputs">
|
||||||
|
<input type="text" id="designUrl" class="form-control" placeholder="URL do site para redesign...">
|
||||||
|
<button id="startDesignBtn" class="btn btn-primary">
|
||||||
|
<i class="fas fa-rocket"></i> Iniciar Redesign
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="agent-status" id="designerStatus">Aguardando instruções...</div>
|
||||||
|
|
||||||
|
<div id="designPreview" class="design-preview" style="display:none;">
|
||||||
|
<iframe id="previewFrame" src="" width="100%" height="500"></iframe>
|
||||||
|
<button id="downloadRedesignBtn" class="btn btn-secondary" style="display:none;">
|
||||||
|
<i class="fas fa-download"></i> Baixar Site Redesenhado
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- OUTREACH SECTION -->
|
||||||
|
<div class="agent-section" id="agent-outreach" style="display:none;">
|
||||||
|
<div class="agent-card">
|
||||||
|
<h3><i class="fas fa-envelope"></i> Outreach - Comunicação</h3>
|
||||||
|
<p class="agent-description">Envia mensagens para proprietários de sites identificados pelo Scout</p>
|
||||||
|
|
||||||
|
<div class="agent-inputs">
|
||||||
|
<select id="outreachTargetId" class="form-control">
|
||||||
|
<option value="">Selecione um alvo do Scout...</option>
|
||||||
|
</select>
|
||||||
|
<textarea id="outreachMessage" class="form-control" rows="3" placeholder="Sua mensagem...">Olá! vimos o seu site e acreditamos que podemos ajudá-lo com um redesign moderno que pode aumentar suas vendas. Posso enviar uma proposta?</textarea>
|
||||||
|
<button id="outreachSendBtn" class="btn btn-primary">
|
||||||
|
<i class="fas fa-paper-plane"></i> Enviar Mensagem
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="agent-status" id="outreachConfirmation" style="display:none;"></div>
|
||||||
|
|
||||||
|
<div class="outreach-stats">
|
||||||
|
<span><i class="fas fa-check"></i> Enviadas: <strong id="outreachSent">0</strong></span>
|
||||||
|
<span><i class="fas fa-times"></i> Falhas: <strong id="outreachFailed">0</strong></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- ORCHESTRATOR SECTION -->
|
||||||
|
<div class="agent-section" id="agent-orchestrator" style="display:none;">
|
||||||
|
<div class="agent-card">
|
||||||
|
<h3><i class="fas fa-tasks"></i> Orchestrator - Pipeline Completo</h3>
|
||||||
|
<p class="agent-description">Executa o pipeline completo: Scout → Designer → Outreach para múltiplos alvos</p>
|
||||||
|
|
||||||
|
<div class="orchestrator-info">
|
||||||
|
<p><i class="fas fa-info-circle"></i> Execute primeiro o Scout para identificar alvos com score >= 7</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button id="runPipelineBtn" class="btn btn-primary btn-lg">
|
||||||
|
<i class="fas fa-play"></i> Executar Pipeline Completo
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<div class="agent-status" id="orchestratorStatus">Aguardando...</div>
|
||||||
|
|
||||||
|
<div class="progress-bar-container">
|
||||||
|
<div id="orchestratorProgress" class="progress-bar" style="width:0%"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="app-new.js"></script>
|
<script src="app-new.js"></script>
|
||||||
|
|||||||
@@ -738,3 +738,334 @@ input:checked + .slider:before {
|
|||||||
font-size: 1.25rem;
|
font-size: 1.25rem;
|
||||||
margin-bottom: 0.5rem;
|
margin-bottom: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ============================================
|
||||||
|
BRAINSTEEL WEB - AGENTS PANEL STYLES
|
||||||
|
============================================ */
|
||||||
|
|
||||||
|
.agents-header {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.agents-header h2 {
|
||||||
|
font-size: 28px;
|
||||||
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
|
background-clip: text;
|
||||||
|
}
|
||||||
|
|
||||||
|
.agents-header p {
|
||||||
|
color: var(--text-secondary);
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Agent Tabs */
|
||||||
|
.agent-tabs {
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
border-bottom: 2px solid var(--border-color);
|
||||||
|
padding-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.agent-tab-btn {
|
||||||
|
padding: 12px 24px;
|
||||||
|
border: none;
|
||||||
|
background: transparent;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 600;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 8px 8px 0 0;
|
||||||
|
transition: var(--transition);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.agent-tab-btn:hover {
|
||||||
|
background: var(--bg-primary);
|
||||||
|
color: var(--text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.agent-tab-btn.active {
|
||||||
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.agent-tab-btn i {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Agent Cards */
|
||||||
|
.agent-section .agent-card {
|
||||||
|
background: var(--bg-secondary);
|
||||||
|
border-radius: 16px;
|
||||||
|
padding: 30px;
|
||||||
|
box-shadow: var(--shadow-md);
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.agent-card h3 {
|
||||||
|
font-size: 20px;
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin-bottom: 10px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.agent-card h3 i {
|
||||||
|
color: var(--primary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.agent-description {
|
||||||
|
color: var(--text-secondary);
|
||||||
|
margin-bottom: 25px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Agent Inputs */
|
||||||
|
.agent-inputs {
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.agent-inputs .form-control {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 200px;
|
||||||
|
padding: 12px 16px;
|
||||||
|
border: 2px solid var(--border-color);
|
||||||
|
border-radius: 10px;
|
||||||
|
font-size: 14px;
|
||||||
|
transition: var(--transition);
|
||||||
|
}
|
||||||
|
|
||||||
|
.agent-inputs .form-control:focus {
|
||||||
|
border-color: var(--primary-color);
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.agent-inputs .btn {
|
||||||
|
padding: 12px 24px;
|
||||||
|
border-radius: 10px;
|
||||||
|
font-weight: 600;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Agent Status */
|
||||||
|
.agent-status {
|
||||||
|
padding: 12px 16px;
|
||||||
|
background: var(--bg-primary);
|
||||||
|
border-radius: 8px;
|
||||||
|
font-size: 14px;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
margin-bottom: 20px;
|
||||||
|
border-left: 4px solid var(--primary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Scout Results */
|
||||||
|
.scout-results {
|
||||||
|
display: grid;
|
||||||
|
gap: 15px;
|
||||||
|
max-height: 500px;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scout-target-card {
|
||||||
|
background: var(--bg-primary);
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 20px;
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
transition: var(--transition);
|
||||||
|
}
|
||||||
|
|
||||||
|
.scout-target-card:hover {
|
||||||
|
border-color: var(--primary-color);
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: var(--shadow-md);
|
||||||
|
}
|
||||||
|
|
||||||
|
.target-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 15px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.target-score {
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 16px;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.target-score.score-high { background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%); }
|
||||||
|
.target-score.score-medium { background: linear-gradient(135deg, #ffa726 0%, #ff9800 100%); }
|
||||||
|
.target-score.score-low { background: linear-gradient(135deg, #718096 0%, #546e7a 100%); }
|
||||||
|
|
||||||
|
.target-info h4 {
|
||||||
|
font-size: 16px;
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.target-url {
|
||||||
|
font-size: 12px;
|
||||||
|
color: var(--primary-color);
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.target-body {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.target-reason {
|
||||||
|
font-size: 13px;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.target-meta {
|
||||||
|
display: flex;
|
||||||
|
gap: 15px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: var(--text-light);
|
||||||
|
}
|
||||||
|
|
||||||
|
.target-meta i {
|
||||||
|
margin-right: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.target-niche {
|
||||||
|
background: var(--bg-secondary);
|
||||||
|
padding: 2px 8px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.target-actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.target-actions .btn {
|
||||||
|
padding: 8px 16px;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Design Preview */
|
||||||
|
.design-preview {
|
||||||
|
background: var(--bg-primary);
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 15px;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.design-preview iframe {
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 2px solid var(--border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Outreach Stats */
|
||||||
|
.outreach-stats {
|
||||||
|
display: flex;
|
||||||
|
gap: 30px;
|
||||||
|
margin-top: 20px;
|
||||||
|
padding: 15px;
|
||||||
|
background: var(--bg-primary);
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.outreach-stats span {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.outreach-stats i {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.outreach-stats strong {
|
||||||
|
font-size: 18px;
|
||||||
|
color: var(--text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Orchestrator */
|
||||||
|
.orchestrator-info {
|
||||||
|
background: var(--bg-primary);
|
||||||
|
padding: 15px;
|
||||||
|
border-radius: 8px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
font-size: 14px;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.orchestrator-info i {
|
||||||
|
color: var(--info-color);
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-lg {
|
||||||
|
padding: 16px 32px;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress-bar-container {
|
||||||
|
height: 8px;
|
||||||
|
background: var(--bg-primary);
|
||||||
|
border-radius: 4px;
|
||||||
|
margin-top: 20px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress-bar {
|
||||||
|
height: 100%;
|
||||||
|
background: linear-gradient(90deg, var(--primary-color), var(--secondary-color));
|
||||||
|
border-radius: 4px;
|
||||||
|
transition: width 0.5s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Responsive */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.agent-tabs {
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.agent-tab-btn {
|
||||||
|
flex: 1;
|
||||||
|
justify-content: center;
|
||||||
|
min-width: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.agent-inputs {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.agent-inputs .form-control,
|
||||||
|
.agent-inputs .btn {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.target-actions {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.outreach-stats {
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -246,7 +246,7 @@ app.post('/api/open-navigation', (req, res) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
app.get('/', (req, res) => {
|
app.get('/', (req, res) => {
|
||||||
res.sendFile(path.join(__dirname, 'public', 'index-premium.html'));
|
res.sendFile(path.join(__dirname, 'public', 'index-new.html'));
|
||||||
});
|
});
|
||||||
|
|
||||||
// Serve old interface
|
// Serve old interface
|
||||||
|
|||||||
Reference in New Issue
Block a user