document.addEventListener('DOMContentLoaded', function() { const chatForm = document.getElementById('chat-form'); const messageInput = document.getElementById('message-input'); const chatMessages = document.getElementById('chat-messages'); const sendButton = document.getElementById('send-button'); const loadingIndicator = document.getElementById('loading'); const suggestionButtons = document.querySelectorAll('.suggestion-btn'); const clearButton = document.getElementById('clear-chat'); const exportButton = document.getElementById('export-chat'); let conversationHistory = []; // Character counter for message input const maxChars = 1000; const charCounter = document.createElement('div'); charCounter.className = 'char-counter'; charCounter.textContent = `0/${maxChars}`; messageInput.parentNode.appendChild(charCounter); messageInput.addEventListener('input', function() { const currentLength = this.value.length; charCounter.textContent = `${currentLength}/${maxChars}`; charCounter.style.color = currentLength > maxChars * 0.9 ? '#e74c3c' : '#666'; // Enable/disable send button based on input sendButton.disabled = currentLength === 0 || currentLength > maxChars; }); // Handle suggestion button clicks suggestionButtons.forEach(button => { button.addEventListener('click', function() { const suggestion = this.textContent; messageInput.value = suggestion; messageInput.focus(); messageInput.dispatchEvent(new Event('input')); }); }); // Handle form submission chatForm.addEventListener('submit', function(e) { e.preventDefault(); const message = messageInput.value.trim(); if (message && message.length <= maxChars) { sendMessage(message); } }); // Clear chat functionality if (clearButton) { clearButton.addEventListener('click', function() { if (confirm('Are you sure you want to clear the chat history?')) { chatMessages.innerHTML = ''; conversationHistory = []; addSystemMessage('Chat cleared. How can I help you with company policies?'); } }); } // Export chat functionality if (exportButton) { exportButton.addEventListener('click', function() { exportChatHistory(); }); } function sendMessage(message) { // Add user message to chat addMessage(message, 'user'); // Clear input and show loading messageInput.value = ''; charCounter.textContent = `0/${maxChars}`; sendButton.disabled = true; showLoading(true); // Send to backend fetch('/chat', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ message: message, conversation_history: conversationHistory }) }) .then(response => { if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } return response.json(); }) .then(data => { showLoading(false); if (data.response) { addMessage(data.response, 'assistant', data.sources); // Update conversation history conversationHistory.push({ user: message, assistant: data.response }); // Limit conversation history to last 10 exchanges if (conversationHistory.length > 10) { conversationHistory = conversationHistory.slice(-10); } } else { addSystemMessage('Sorry, I encountered an error processing your request. Please try again.'); } }) .catch(error => { console.error('Error:', error); showLoading(false); addSystemMessage('Sorry, there was a connection error. Please check your internet connection and try again.'); }); } function addMessage(content, sender, sources = null) { const messageDiv = document.createElement('div'); messageDiv.className = `message ${sender}-message`; const messageContent = document.createElement('div'); messageContent.className = 'message-content'; messageContent.textContent = content; const timestamp = document.createElement('div'); timestamp.className = 'message-timestamp'; timestamp.textContent = new Date().toLocaleTimeString(); messageDiv.appendChild(messageContent); messageDiv.appendChild(timestamp); // Add sources if provided if (sources && sources.length > 0) { const sourcesDiv = document.createElement('div'); sourcesDiv.className = 'message-sources'; sourcesDiv.innerHTML = 'Sources:'; sources.forEach((source, index) => { const sourceSpan = document.createElement('span'); sourceSpan.className = 'source-tag'; sourceSpan.textContent = `${source.filename} (${Math.round(source.score * 100)}% relevant)`; sourceSpan.title = `Chunk: ${source.chunk_id}\nScore: ${source.score.toFixed(3)}`; sourcesDiv.appendChild(sourceSpan); }); messageDiv.appendChild(sourcesDiv); } chatMessages.appendChild(messageDiv); chatMessages.scrollTop = chatMessages.scrollHeight; } function addSystemMessage(content) { const messageDiv = document.createElement('div'); messageDiv.className = 'message system-message'; const messageContent = document.createElement('div'); messageContent.className = 'message-content'; messageContent.textContent = content; messageDiv.appendChild(messageContent); chatMessages.appendChild(messageDiv); chatMessages.scrollTop = chatMessages.scrollHeight; } function showLoading(show) { if (loadingIndicator) { loadingIndicator.style.display = show ? 'block' : 'none'; } sendButton.disabled = show; } function exportChatHistory() { if (conversationHistory.length === 0) { alert('No conversation history to export.'); return; } let exportText = 'PolicyWise Chat Export\n'; exportText += '======================\n'; exportText += `Exported on: ${new Date().toLocaleString()}\n\n`; conversationHistory.forEach((exchange, index) => { exportText += `--- Exchange ${index + 1} ---\n`; exportText += `User: ${exchange.user}\n`; exportText += `Assistant: ${exchange.assistant}\n\n`; }); const blob = new Blob([exportText], { type: 'text/plain' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = `policywise-chat-${new Date().toISOString().split('T')[0]}.txt`; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); } // Initialize with welcome message addSystemMessage('Hello! I\'m PolicyWise, your intelligent policy assistant. I can help you find information from our company policy documents. What would you like to know?'); // Focus on input field messageInput.focus(); // Handle keyboard shortcuts document.addEventListener('keydown', function(e) { // Ctrl/Cmd + Enter to send message if ((e.ctrlKey || e.metaKey) && e.key === 'Enter') { if (messageInput.value.trim()) { chatForm.dispatchEvent(new Event('submit')); } } // Escape to clear input if (e.key === 'Escape') { messageInput.value = ''; messageInput.dispatchEvent(new Event('input')); messageInput.focus(); } }); });