j1225d's picture
Role: You are an expert Python backend developer specializing in building AI-powered services.
3f46192 verified
// Frontend functionality for NutriBot chat interface
document.addEventListener('DOMContentLoaded', function() {
const messageInput = document.getElementById('messageInput');
const sendButton = document.getElementById('sendButton');
const clearButton = document.getElementById('clearButton');
const chatContainer = document.getElementById('chatContainer');
const loadingIndicator = document.getElementById('loadingIndicator');
let conversationHistory = [];
// Function to add message to chat
function addMessage(role, content) {
const messageDiv = document.createElement('div');
messageDiv.className = `message mb-4 ${role === 'user' ? 'text-right' : 'text-left'}`;
const messageContent = document.createElement('div');
messageContent.className = `inline-block max-w-xs md:max-w-md px-4 py-2 rounded-lg ${
role === 'user'
? 'bg-green-600 text-white'
: 'bg-gray-200 text-gray-800'
}`;
messageContent.textContent = content;
messageDiv.appendChild(messageContent);
chatContainer.appendChild(messageDiv);
// Scroll to bottom
chatContainer.scrollTop = chatContainer.scrollHeight;
// Reinitialize feather icons
feather.replace();
}
// Function to show typing indicator
function showTypingIndicator() {
const typingDiv = document.createElement('div');
typingDiv.className = 'message mb-4 text-left';
typingDiv.id = 'typingIndicator';
const typingContent = document.createElement('div');
typingContent.className = 'inline-block px-4 py-2 rounded-lg bg-gray-200';
typingContent.innerHTML = `
<div class="typing-indicator">
<span></span>
<span></span>
<span></span>
</div>
`;
typingDiv.appendChild(typingContent);
chatContainer.appendChild(typingDiv);
chatContainer.scrollTop = chatContainer.scrollHeight;
}
// Function to hide typing indicator
function hideTypingIndicator() {
const typingIndicator = document.getElementById('typingIndicator');
if (typingIndicator) {
typingIndicator.remove();
}
}
// Function to send message to backend
async function sendMessage() {
const message = messageInput.value.trim();
if (!message) return;
// Clear initial welcome message if it exists
if (conversationHistory.length === 0) {
chatContainer.innerHTML = '';
}
// Add user message to chat
addMessage('user', message);
messageInput.value = '';
// Add to conversation history
conversationHistory.push({ role: 'user', content: message });
// Show loading and typing indicators
loadingIndicator.classList.remove('hidden');
showTypingIndicator();
try {
const response = await fetch('http://localhost:8000/chat', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
message: message,
user_id: 'default_user'
})
});
if (!response.ok) {
throw new Error('Failed to get response from server');
}
const data = await response.json();
const assistantMessage = data.response;
// Hide typing indicator and loading
hideTypingIndicator();
loadingIndicator.classList.add('hidden');
// Add assistant response to chat
addMessage('assistant', assistantMessage);
// Add to conversation history
conversationHistory.push({ role: 'assistant', content: assistantMessage });
} catch (error) {
console.error('Error:', error);
hideTypingIndicator();
loadingIndicator.classList.add('hidden');
addMessage('assistant', 'Sorry, I encountered an error. Please try again.');
}
}
// Function to clear conversation
function clearConversation() {
conversationHistory = [];
chatContainer.innerHTML = `
<div class="text-center text-gray-500 py-8">
<i data-feather="message-circle" class="mx-auto mb-2"></i>
<p>Start a conversation with NutriBot below!</p>
</div>
`;
feather.replace();
}
// Event listeners
sendButton.addEventListener('click', sendMessage);
messageInput.addEventListener('keypress', function(e) {
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault();
sendMessage();
}
});
clearButton.addEventListener('click', clearConversation);
// Focus on input field
messageInput.focus();
});