Files
webclone/web-interface/public/app-premium.js
T

162 lines
5.1 KiB
JavaScript

const urlInput = document.getElementById('urlInput');
const startBtn = document.getElementById('startBtn');
const heroSection = document.getElementById('hero');
const loadingSection = document.getElementById('loading');
const resultSection = document.getElementById('result');
const terminalLog = document.getElementById('terminalLog');
const progressCircle = document.getElementById('progressCircle');
let clonedData = null;
startBtn.addEventListener('click', startCloning);
urlInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter') startCloning();
});
document.getElementById('btnOpenSite').addEventListener('click', () => {
if (clonedData && clonedData.data && clonedData.data.path) {
const dirName = clonedData.data.path.split('\\').pop().split('/').pop();
window.open(`/api/preview/${dirName}`, '_blank');
}
});
document.getElementById('btnOpenFolder').addEventListener('click', () => {
if (clonedData && clonedData.data && clonedData.data.path) {
fetch('/api/open-folder', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ path: clonedData.data.path })
}).then(res => res.json())
.then(data => {
if (data.success && data.url) {
window.open(data.url, '_blank');
}
});
}
});
async function startCloning() {
const url = urlInput.value.trim();
if (!url) {
showToast('Por favor, insira uma URL válida', 'error');
return;
}
// Switch UI
heroSection.classList.add('hidden');
loadingSection.classList.remove('hidden');
// Simulate Terminal Logs
log('Iniciando puppeteer...');
let progress = 0;
const progressInterval = setInterval(() => {
if (progress < 90) {
progress += Math.random() * 5;
updateProgress(progress);
}
}, 1000);
const logMessages = [
'Configurando viewport 1920x1080...',
'Interceptando requisições de rede...',
'Analisando DOM e Shadow DOM...',
'Baixando assets estáticos...',
'Processando estilos computados...',
'Otimizando imagens...',
'Verificando integridade...'
];
let msgIndex = 0;
const msgInterval = setInterval(() => {
if (msgIndex < logMessages.length) {
log(logMessages[msgIndex]);
msgIndex++;
}
}, 2500);
try {
const response = await fetch('/api/smart-clone', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ url })
});
const data = await response.json();
clonedData = data;
clearInterval(progressInterval);
clearInterval(msgInterval);
updateProgress(100);
if (data.success) {
log('Clonagem concluída com sucesso!');
setTimeout(() => {
showResult(data);
}, 1000);
} else {
throw new Error(data.error || 'Erro desconhecido');
}
} catch (error) {
clearInterval(progressInterval);
clearInterval(msgInterval);
showToast('Erro: ' + error.message, 'error');
log('❌ Erro fatal: ' + error.message);
setTimeout(() => {
heroSection.classList.remove('hidden');
loadingSection.classList.add('hidden');
}, 3000);
}
}
function updateProgress(value) {
// 283 is the circumference
const dashboard = 283;
const offset = dashboard - (value / 100) * dashboard;
progressCircle.style.strokeDashoffset = offset;
}
function log(msg) {
const div = document.createElement('div');
div.className = 'log-line';
div.innerText = `> ${msg}`;
terminalLog.appendChild(div);
terminalLog.scrollTop = terminalLog.scrollHeight;
}
function showResult(data) {
loadingSection.classList.add('hidden');
resultSection.classList.remove('hidden');
// Handle Verification Images
const verifyContainer = document.getElementById('verificationContainer');
if (data.data.verification) {
verifyContainer.style.display = 'block';
// Paths are relative to site dir.
// We need to construct URL to fetch them.
const dirName = data.data.path.split('\\').pop().split('/').pop();
document.getElementById('imgOriginal').src = `/${dirName}/${data.data.verification.original}`;
document.getElementById('imgClone').src = `/${dirName}/${data.data.verification.clone}`;
} else {
verifyContainer.style.display = 'none';
}
}
function showToast(msg, type = 'info') {
const toast = document.createElement('div');
toast.style.position = 'fixed';
toast.style.bottom = '20px';
toast.style.right = '20px';
toast.style.background = type === 'error' ? '#ef4444' : '#10b981';
toast.style.color = 'white';
toast.style.padding = '1rem 2rem';
toast.style.borderRadius = '8px';
toast.style.zIndex = '1000';
toast.innerText = msg;
document.body.appendChild(toast);
setTimeout(() => toast.remove(), 3000);
}