// Script for handling file uploads and chat interactions. // DOM elements const dropZone = document.getElementById('drop-zone'); const fileInput = document.getElementById('file-input'); const uploadContent = document.getElementById('upload-content'); const uploadIcon = document.getElementById('upload-icon'); const chatMessages = document.getElementById('chat-messages'); const chatInput = document.getElementById('chat-input'); const sendBtn = document.getElementById('send-btn'); const chatStatus = document.getElementById('chat-status'); const apiKeyInput = document.getElementById('api-key-input'); const saveApiKeyBtn = document.getElementById('save-api-key-btn'); const helpBtn = document.getElementById('help-btn'); const helpModal = document.getElementById('help-modal'); const closeHelpBtn = document.getElementById('close-help-btn'); // state variables let uploadedFileName = null; let messages = []; // notification popups section function showToast(message, type = 'success') { const toast = document.createElement('div'); toast.className = `toast ${type}`; toast.innerHTML = ` ${type === 'success' ? '' : ''} ${message} `; document.body.appendChild(toast); setTimeout(() => toast.remove(), 3000); } // apiKey Handling section function saveApiKey() { const key = apiKeyInput.value.trim(); if (!key) { showToast('Please enter a valid Gemini API key', 'error'); return; } localStorage.setItem('gemini_api_key', key); showToast('Gemini API key saved successfully!'); } if (saveApiKeyBtn) saveApiKeyBtn.addEventListener('click', saveApiKey); window.addEventListener('DOMContentLoaded', () => { const savedKey = localStorage.getItem('gemini_api_key'); if (savedKey && apiKeyInput) { apiKeyInput.value = savedKey; } }); // api key help handling if (helpBtn && helpModal && closeHelpBtn) { helpBtn.addEventListener('click', () => { helpModal.style.display = 'flex'; }); closeHelpBtn.addEventListener('click', () => { helpModal.style.display = 'none'; }); helpModal.addEventListener('click', (e) => { if (e.target === helpModal) helpModal.style.display = 'none'; }); } // File Upload Handling section dropZone.addEventListener('dragover', (e) => { e.preventDefault(); dropZone.classList.add('drag-over'); }); dropZone.addEventListener('dragleave', () => { dropZone.classList.remove('drag-over'); }); dropZone.addEventListener('drop', (e) => { e.preventDefault(); dropZone.classList.remove('drag-over'); if (e.dataTransfer.files.length > 0) { handleFile(e.dataTransfer.files[0]); } }); fileInput.addEventListener('change', (e) => { if (e.target.files.length > 0) { handleFile(e.target.files[0]); } }); async function handleFile(file) { const apiKey = localStorage.getItem('gemini_api_key'); if (!apiKey) { showToast('Please enter and save your Gemini API key before uploading.', 'error'); // Add delay for second toast setTimeout(() => { showToast('See the help button at the top for details.', 'error'); }, 3000); return; } const validTypes = ['application/pdf', 'text/plain']; if (!validTypes.includes(file.type)) { showToast('Please upload a PDF or TXT file', 'error'); return; } uploadContent.innerHTML = '

Please hold, your document is being processed...

'; const formData = new FormData(); formData.append('file', file); formData.append('apiKey', apiKey); try { const response = await fetch(`/upload`, { method: 'POST', body: formData }); const result = await response.text(); if (!response.ok) throw new Error(result || 'Upload failed'); uploadedFileName = file.name; dropZone.classList.add('uploaded'); uploadIcon.innerHTML = ''; uploadIcon.style.color = 'var(--accent)'; uploadContent.innerHTML = `

Document Uploaded

${file.name}

`; chatInput.disabled = false; sendBtn.disabled = false; chatStatus.textContent = `Chatting with: ${file.name}`; chatMessages.innerHTML = ''; messages = []; showToast('Document processed successfully!'); } catch (error) { console.error('Upload error:', error); showToast(error.message, 'error'); resetUpload(); } } function resetUpload() { uploadedFileName = null; dropZone.classList.remove('uploaded'); uploadIcon.innerHTML = ''; uploadIcon.style.color = ''; uploadContent.innerHTML = `

Drop your file here

or

Supports PDF and TXT files

`; chatInput.disabled = true; sendBtn.disabled = true; chatStatus.textContent = 'No document uploaded'; chatMessages.innerHTML = `

Upload a Document First


Please upload a PDF or TXT file to start asking questions.

`; messages = []; fileInput.value = ''; showToast('Ready for a new document'); } // Chatbot handling and replies async function sendMessage() { const apiKey = localStorage.getItem('gemini_api_key'); if (!apiKey) { showToast('Please enter and save your Gemini API key before chatting.', 'error'); return; } const question = chatInput.value.trim(); if (!question || !uploadedFileName) return; addMessage('user', question); chatInput.value = ''; const typingId = addTypingIndicator(); try { const response = await fetch(`/chat`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ question, apiKey }) }); const data = await response.json(); removeTypingIndicator(typingId); if (!response.ok) throw new Error(data.error || 'Chat failed'); addMessage('assistant', data.answer); } catch (error) { console.error('Chat error:', error); removeTypingIndicator(typingId); showToast(error.message, 'error'); addMessage('assistant', 'Error: ' + error.message); } } function addMessage(role, content) { messages.push({ role, content }); const messageDiv = document.createElement('div'); messageDiv.className = `message ${role}`; messageDiv.innerHTML = `
${role === 'assistant' ? '' : ''}
${content}
`; chatMessages.appendChild(messageDiv); chatMessages.scrollTop = chatMessages.scrollHeight; } function addTypingIndicator() { const id = 'typing-' + Date.now(); const typingDiv = document.createElement('div'); typingDiv.id = id; typingDiv.className = 'message assistant'; typingDiv.innerHTML = `
`; chatMessages.appendChild(typingDiv); chatMessages.scrollTop = chatMessages.scrollHeight; return id; } function removeTypingIndicator(id) { const element = document.getElementById(id); if (element) element.remove(); } sendBtn.addEventListener('click', sendMessage); chatInput.addEventListener('keypress', (e) => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); sendMessage(); } }); // End