document.addEventListener('DOMContentLoaded', () => { const messageForm = document.getElementById('message-form'); const messageInput = document.getElementById('message-input'); const messagesContainer = document.getElementById('messages-container'); const endpoint = '/chatbot'; /** * Handles the form submission event. * @param {Event} event - The form submission event. */ const sendMessage = async (event) => { event.preventDefault(); const userInput = messageInput.value.trim(); if (userInput === '') return; createBubble(userInput, 'user'); messageInput.value = ''; autoResizeTextarea(); showLoadingIndicator(); try { const response = await fetch(endpoint, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ prompt: userInput }) }); if (!response.ok) { throw new Error(`Network error: ${response.statusText}`); } const data = await response.json(); removeLoadingIndicator(); createBubble(data.response, 'aibot'); } catch (error) { console.error('Fetch Error:', error); removeLoadingIndicator(); createBubble('Sorry, something went wrong. Please check the server connection and try again.', 'error'); } }; /** * Creates and appends a new chat bubble to the message container. * @param {string} text - The message text. * @param {string} type - The bubble type ('user', 'aibot', or 'error'). */ const createBubble = (text, type) => { const messageDiv = document.createElement('div'); messageDiv.classList.add('message', type); const avatarSrc = { user: '/static/user.jpeg', aibot: '/static/Bot_logo.png', error: '/static/Error.png' }; messageDiv.innerHTML = ` ${type} avatar

${text.replace(/\n/g, '
')}

`; // Replaces newlines with
for better formatting messagesContainer.appendChild(messageDiv); messagesContainer.scrollTop = messagesContainer.scrollHeight; }; /** * Displays a loading indicator. */ const showLoadingIndicator = () => { const loadingDiv = document.createElement('div'); loadingDiv.id = 'loading-indicator'; loadingDiv.classList.add('loading-container'); loadingDiv.innerHTML = `

Assistant is thinking...

`; messagesContainer.appendChild(loadingDiv); messagesContainer.scrollTop = messagesContainer.scrollHeight; }; /** * Removes the loading indicator. */ const removeLoadingIndicator = () => { const loadingIndicator = document.getElementById('loading-indicator'); if (loadingIndicator) { messagesContainer.removeChild(loadingIndicator); } }; /** * Automatically resizes the textarea to fit its content. */ const autoResizeTextarea = () => { messageInput.style.height = 'auto'; messageInput.style.height = (messageInput.scrollHeight) + 'px'; }; messageForm.addEventListener('submit', sendMessage); messageInput.addEventListener('input', autoResizeTextarea); // Allow sending message with Enter key, but new line with Shift+Enter messageInput.addEventListener('keydown', (event) => { if (event.key === 'Enter' && !event.shiftKey) { event.preventDefault(); sendMessage(event); } }); });