Spaces:
Runtime error
Runtime error
| /** | |
| * CodeSearch Engine - Logic Controller | |
| * Responsável por conectar a UI ao Backend FastAPI | |
| */ | |
| let localCache = []; | |
| let debounceTimer; | |
| // 1. Função de Busca com Debounce (para não travar seu PC de 4GB) | |
| function handleSearch() { | |
| clearTimeout(debounceTimer); | |
| debounceTimer = setTimeout(() => { | |
| refreshData(); | |
| }, 500); // Espera 500ms após parar de digitar | |
| } | |
| // 2. Busca os dados no Backend | |
| async function refreshData() { | |
| const query = document.getElementById('search-input').value; | |
| const resultsContainer = document.getElementById('results-list'); | |
| const statsEl = document.getElementById('total-db'); | |
| const logsEl = document.getElementById('logs'); | |
| try { | |
| const response = await fetch(`/api/data?q=${encodeURIComponent(query)}`); | |
| const data = await response.json(); | |
| // Atualiza estatísticas e logs | |
| if (statsEl) statsEl.innerText = data.total.toLocaleString(); | |
| if (logsEl) { | |
| logsEl.innerHTML = data.logs.map(log => ` | |
| <div class="log-item ${log.includes('✅') ? 'success' : ''}">${log}</div> | |
| `).join(''); | |
| } | |
| localCache = data.results; | |
| renderResults(resultsContainer); | |
| } catch (error) { | |
| console.error("Erro ao conectar com o backend:", error); | |
| } | |
| } | |
| // 3. Renderiza os cards na tela | |
| function renderResults(container) { | |
| if (localCache.length === 0) { | |
| container.innerHTML = `<div class="empty-state">O Pato ainda não encontrou nada para essa busca... 🦆</div>`; | |
| return; | |
| } | |
| container.innerHTML = localCache.map((item, i) => ` | |
| <div class="card-item" id="snippet-${i}"> | |
| <div class="card-header" onclick="toggleCodeBlock(${i})"> | |
| <div class="info"> | |
| <span class="badge">${item.language.toUpperCase()}</span> | |
| <h3 class="title">${item.title}</h3> | |
| <p class="url">${item.source_url}</p> | |
| </div> | |
| <button class="btn-copy" onclick="event.stopPropagation(); copyToClipboard(${i}, this)"> | |
| COPIAR | |
| </button> | |
| </div> | |
| <div id="code-area-${i}" class="code-body hidden"> | |
| <pre class="language-${item.language}"><code class="language-${item.language}">${escapeHTML(item.code)}</code></pre> | |
| </div> | |
| </div> | |
| `).join(''); | |
| // Aciona o highlight do Prism.js se estiver presente | |
| if (window.Prism) Prism.highlightAll(); | |
| } | |
| // 4. Funções Utilitárias | |
| function toggleCodeBlock(index) { | |
| const element = document.getElementById(`code-area-${index}`); | |
| if (element) element.classList.toggle('hidden'); | |
| } | |
| function copyToClipboard(index, button) { | |
| const snippet = localCache[index]; | |
| if (!snippet) return; | |
| navigator.clipboard.writeText(snippet.code).then(() => { | |
| const originalText = button.innerText; | |
| button.innerText = "COPIADO!"; | |
| button.classList.add('success'); | |
| setTimeout(() => { | |
| button.innerText = originalText; | |
| button.classList.remove('success'); | |
| }, 2000); | |
| }); | |
| } | |
| function escapeHTML(str) { | |
| return str.replace(/[&<>"']/g, m => ({ | |
| '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' | |
| })[m]); | |
| } | |
| // Inicialização automática | |
| window.onload = () => { | |
| refreshData(); | |
| setInterval(refreshData, 5000); // Atualiza estatísticas e logs a cada 5s | |
| // Adiciona evento ao input de busca | |
| const input = document.getElementById('search-input'); | |
| if (input) input.addEventListener('input', handleSearch); | |
| }; |