// API base URL const API_BASE = '/api'; // Initialize document.addEventListener('DOMContentLoaded', () => { loadBooks(); loadSchedules(); // Event listeners document.getElementById('send-btn').addEventListener('click', sendChatMessage); document.getElementById('chat-input').addEventListener('keypress', (e) => { if (e.key === 'Enter') sendChatMessage(); }); document.getElementById('upload-btn').addEventListener('click', uploadPDF); document.getElementById('add-schedule-btn').addEventListener('click', addSchedule); }); async function sendChatMessage() { const input = document.getElementById('chat-input'); const message = input.value.trim(); if (!message) return; // Add user message to chat addMessage(message, 'user'); input.value = ''; // Show loading showLoading(); try { const response = await fetch(`${API_BASE}/chat`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ message, top_k: 3 }), }); if (!response.ok) { throw new Error('Erro ao enviar mensagem'); } const data = await response.json(); // Remove loading hideLoading(); // Add bot response addMessage(data.response, 'bot'); // Add sources if (data.sources && data.sources.length > 0) { const sourceText = data.sources.map(s => `📖 ${s.metadata.title} (chunk ${s.metadata.chunk_id})`).join('\n'); addMessage(`Fontes: ${sourceText}`, 'bot', true); } } catch (error) { hideLoading(); addMessage(`❌ Erro: ${error.message}`, 'bot'); } } function addMessage(content, type, isSource = false) { const container = document.getElementById('chat-messages'); const messageDiv = document.createElement('div'); messageDiv.className = `message ${type}`; if (isSource) { messageDiv.style.fontSize = '0.85rem'; } messageDiv.innerHTML = `
${content}
`; container.appendChild(messageDiv); container.scrollTop = container.scrollHeight; } function showLoading() { const container = document.getElementById('chat-messages'); const loadingDiv = document.createElement('div'); loadingDiv.id = 'chat-loading'; loadingDiv.className = 'message bot'; loadingDiv.innerHTML = '
Carregando...
'; container.appendChild(loadingDiv); container.scrollTop = container.scrollHeight; } function hideLoading() { const loading = document.getElementById('chat-loading'); if (loading) loading.remove(); } async function loadBooks() { try { const response = await fetch(`${API_BASE}/books`); const books = await response.json(); const booksList = document.getElementById('books-list'); booksList.innerHTML = ''; if (books.length === 0) { booksList.innerHTML = '

Nenhum livro encontrado.

'; return; } books.forEach(book => { const bookDiv = document.createElement('div'); bookDiv.className = 'book-item'; bookDiv.innerHTML = `
📖
${book.title}
`; booksList.appendChild(bookDiv); }); // Update book dropdown const select = document.getElementById('schedule-book'); select.innerHTML = ''; books.forEach(book => { const option = document.createElement('option'); option.value = book.title; option.textContent = book.title; select.appendChild(option); }); } catch (error) { console.error('Erro ao carregar livros:', error); } } async function uploadPDF() { const fileInput = document.getElementById('file-input'); const file = fileInput.files[0]; if (!file) { alert('Selecione um arquivo PDF primeiro'); return; } const statusDiv = document.getElementById('upload-status'); statusDiv.textContent = 'Enviando...'; try { const formData = new FormData(); formData.append('file', file); const response = await fetch(`${API_BASE}/upload`, { method: 'POST', body: formData, }); if (!response.ok) { throw new Error('Erro ao fazer upload'); } const data = await response.json(); statusDiv.textContent = `✅ ${data.filename} enviado com sucesso!`; statusDiv.style.color = '#4caf50'; setTimeout(() => { statusDiv.textContent = ''; fileInput.value = ''; }, 3000); // Reload books loadBooks(); } catch (error) { statusDiv.textContent = `❌ Erro: ${error.message}`; statusDiv.style.color = '#f44336'; } } async function loadSchedules() { try { const response = await fetch(`${API_BASE}/schedules`); const schedules = await response.json(); renderSchedules(schedules); } catch (error) { console.error('Erro ao carregar agendamentos:', error); } } function renderSchedules(schedules) { const container = document.getElementById('schedules-list'); container.innerHTML = ''; if (schedules.length === 0) { container.innerHTML = '

Nenhum agendamento.

'; return; } schedules.forEach(schedule => { const div = document.createElement('div'); div.className = 'schedule-item'; div.innerHTML = `
🕐 ${formatDateTime(schedule.time)} ${schedule.book || 'Todos os livros'}
`; container.appendChild(div); // Add delete handler div.querySelector('.schedule-delete').addEventListener('click', () => deleteSchedule(schedule.id)); }); } async function addSchedule() { const timeInput = document.getElementById('schedule-time'); const bookSelect = document.getElementById('schedule-book'); if (!timeInput.value) { alert('Selecione uma data e hora'); return; } try { const response = await fetch(`${API_BASE}/schedules`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ time: timeInput.value, book: bookSelect.value || null, enabled: true, }), }); if (!response.ok) { throw new Error('Erro ao criar agendamento'); } const schedule = await response.json(); loadSchedules(); timeInput.value = ''; bookSelect.value = ''; } catch (error) { alert(`Erro: ${error.message}`); } } async function deleteSchedule(scheduleId) { if (!confirm('Tem certeza que deseja excluir este agendamento?')) { return; } try { const response = await fetch(`${API_BASE}/schedules/${scheduleId}`, { method: 'DELETE', }); if (!response.ok) { throw new Error('Erro ao excluir agendamento'); } loadSchedules(); } catch (error) { alert(`Erro: ${error.message}`); } } function formatDateTime(dateString) { const date = new Date(dateString); return date.toLocaleString('pt-BR'); }