let conversation = [ { role: 'bot', message: 'Hello! I’m Chef Bot, your culinary assistant! What’s your name?' } ]; let selectedItems = []; let selectionBoxVisible = false; function addMessage(role, message) { const chatMessages = document.getElementById('chatMessages'); if (!chatMessages) { console.error('Chat messages container not found!'); return; } const messageDiv = document.createElement('div'); messageDiv.className = role === 'bot' ? 'bot-message' : 'user-message'; messageDiv.textContent = message; chatMessages.appendChild(messageDiv); chatMessages.scrollTop = chatMessages.scrollHeight; console.log(`Added ${role} message: ${message}`); } function sendMessage() { const userInput = document.getElementById('userInput'); if (!userInput) { console.error('User input field not found!'); return; } const message = userInput.value.trim(); if (message) { addMessage('user', message); conversation.push({ role: 'user', message: message }); selectionBoxVisible = true; setTimeout(() => handleResponse(message), 500); } else { addMessage('bot', 'Hey, don’t be shy! Type something or add some items to get started! 😄'); } userInput.value = ''; updateSelectionBox(); } function updateSelectionBox() { const chatMessages = document.getElementById('chatMessages'); if (!chatMessages) return; const existingBox = document.querySelector('.selection-box'); if (existingBox) existingBox.remove(); if (!selectionBoxVisible && selectedItems.length === 0) return; const selectionBox = document.createElement('div'); selectionBox.className = 'selection-box'; const vegButton = document.createElement('button'); vegButton.textContent = 'Vegetarian'; vegButton.className = 'dietary-button green'; vegButton.onclick = () => fetchMenuItems('vegetarian'); selectionBox.appendChild(vegButton); const nonVegButton = document.createElement('button'); nonVegButton.textContent = 'Non-Vegetarian'; nonVegButton.className = 'dietary-button red'; nonVegButton.onclick = () => fetchMenuItems('non-vegetarian'); selectionBox.appendChild(nonVegButton); const bothButton = document.createElement('button'); bothButton.textContent = 'Both'; bothButton.className = 'dietary-button gray'; bothButton.onclick = () => fetchMenuItems('both'); selectionBox.appendChild(bothButton); const label = document.createElement('span'); label.textContent = 'Selected Items:'; selectionBox.appendChild(label); selectedItems.forEach((item, index) => { const itemContainer = document.createElement('div'); itemContainer.className = 'selected-item'; const img = document.createElement('img'); img.src = item.image_url || 'https://via.placeholder.com/30'; img.alt = item.name; img.className = 'selected-item-image'; itemContainer.appendChild(img); const itemSpan = document.createElement('span'); itemSpan.textContent = item.name; itemContainer.appendChild(itemSpan); const removeButton = document.createElement('button'); removeButton.textContent = 'Remove'; removeButton.className = 'remove-button'; removeButton.onclick = () => { selectedItems.splice(index, 1); addMessage('bot', `Removed "${item.name}" from your selection.`); updateSelectionBox(); }; itemContainer.appendChild(removeButton); selectionBox.appendChild(itemContainer); }); const textInput = document.createElement('input'); textInput.type = 'text'; textInput.placeholder = 'Add Sector_Detail__c item...'; textInput.className = 'manual-input'; textInput.addEventListener('keypress', (e) => { if (e.key === 'Enter' && textInput.value.trim()) { const itemName = textInput.value.trim(); fetchSectorItemDetails(itemName); textInput.value = ''; } }); selectionBox.appendChild(textInput); if (selectedItems.length > 0) { const submitButton = document.createElement('button'); submitButton.textContent = 'Submit to Salesforce'; submitButton.className = 'submit-button'; submitButton.onclick = submitToSalesforce; selectionBox.appendChild(submitButton); } chatMessages.appendChild(selectionBox); chatMessages.scrollTop = chatMessages.scrollHeight; console.log('Updated selection box with items:', selectedItems.map(item => item.name)); } function handleResponse(userInput) { const lowerInput = userInput.toLowerCase(); let botResponse = ''; if (conversation.length === 2) { botResponse = `Great to meet you, ${userInput}! 🍳 What kind of food are you craving today?`; displayOptions([ { text: 'Vegetarian', class: 'green' }, { text: 'Non-Vegetarian', class: 'red' }, { text: 'Both', class: 'gray' } ]); } else if (lowerInput === 'vegetarian' || lowerInput === 'non-vegetarian' || lowerInput === 'both') { botResponse = `Nice choice! Let me whip up some ${lowerInput} options for you...`; addMessage('bot', botResponse); fetchMenuItems(lowerInput); return; } else { // Treat input as an item name and fetch details botResponse = `Looking up details for "${userInput}"...`; addMessage('bot', botResponse); fetchItemDetailsByName(userInput); return; } addMessage('bot', botResponse); } function fetchMenuItems(dietaryPreference) { fetch('/get_menu_items', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ dietary_preference: dietaryPreference }) }) .then(response => response.json()) .then(data => { if (data.error) { addMessage('bot', `Oops! Trouble fetching ${dietaryPreference} items: ${data.error}. Try again or search something specific.`); } else if (data.menu_items.length > 0) { displayItemsList(data.menu_items, 'menuItemsList', true); } else { addMessage('bot', `No ${dietaryPreference} items found in Sector_Detail__c. Try searching for something like "paneer" or "chicken"!`); } console.log(`Fetched items from Sector_Detail__c for ${dietaryPreference}:`, data.menu_items); }) .catch(error => { addMessage('bot', `Yikes! Couldn’t reach Salesforce: ${error.message}. I’ll retry in a sec...`); setTimeout(() => fetchMenuItems(dietaryPreference), 2000); }); } function suggestItems(searchTerm) { fetch('/suggest_items', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ search_term: searchTerm }) }) .then(response => response.json()) .then(data => { if (data.error) { addMessage('bot', `Couldn’t find anything for "${searchTerm}": ${data.error}. Got another idea?`); } else if (data.suggestions.length > 0) { addMessage('bot', `Check out these suggestions for "${searchTerm}" from Ingredient_Object__c:`); displayItemsList(data.suggestions, 'suggestionsList', false); } else { addMessage('bot', `No matches for "${searchTerm}" in Ingredient_Object__c. Try "chicken" or "paneer"?`); } console.log(`Suggestions for ${searchTerm}:`, data.suggestions); }) .catch(error => { addMessage('bot', `Error fetching suggestions: ${error.message}. Retrying...`); setTimeout(() => suggestItems(searchTerm), 2000); }); } function fetchItemDetails(itemName) { fetch('/get_item_details', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ item_name: itemName }) }) .then(response => response.json()) .then(data => { if (data.error) { addMessage('bot', `Couldn’t find "${itemName}" in Ingredient_Object__c. Add it manually in the box below!`); updateSelectionBox(); } else { const details = data.item_details; if (selectedItems.some(item => item.name === details.name)) { addMessage('bot', `"${details.name}" is already in your selection!`); } else { selectedItems.push(details); addMessage('bot', `Added "${itemName}" to your selection! Check the box below.`); updateSelectionBox(); } } }) .catch(error => { addMessage('bot', `Trouble fetching "${itemName}": ${error.message}. Add it manually or I’ll retry...`); updateSelectionBox(); setTimeout(() => fetchItemDetails(itemName), 2000); }); } function fetchItemDetailsByName(itemName) { fetch('/get_item_details_by_name', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ item_name: itemName }) }) .then(response => response.json()) .then(data => { if (data.error) { addMessage('bot', `Sorry, I couldn’t find "${itemName}" in Sector_Detail__c. Try another item or use the options below!`); } else { const details = data.item_details; addMessage('bot', `Details for "${details.name}":\n- Category: ${details.category}\n- Description: ${details.description}`); } }) .catch(error => { addMessage('bot', `Error fetching details for "${itemName}": ${error.message}. I’ll retry in a sec...`); setTimeout(() => fetchItemDetailsByName(itemName), 2000); }); } function fetchSectorItemDetails(itemName) { fetch('/get_sector_item_details', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ item_name: itemName }) }) .then(response => response.json()) .then(data => { if (data.error) { addMessage('bot', `Sorry, I couldn’t find "${itemName}" in Sector_Detail__c. Try another item!`); } else { const details = data.item_details; if (selectedItems.some(item => item.name === details.name)) { addMessage('bot', `"${details.name}" is already in your selection!`); } else { selectedItems.push(details); addMessage('bot', `Added "${details.name}" to your selection with image! Check the box below.`); updateSelectionBox(); } } }) .catch(error => { addMessage('bot', `Error fetching details for "${itemName}": ${error.message}. I’ll retry in a sec...`); setTimeout(() => fetchSectorItemDetails(itemName), 2000); }); } function showDescriptionPopup(item) { const existingPopup = document.querySelector('.description-popup'); if (existingPopup) existingPopup.remove(); const popup = document.createElement('div'); popup.className = 'description-popup'; const content = document.createElement('div'); content.className = 'popup-content'; const img = document.createElement('img'); img.src = item.image_url || 'https://via.placeholder.com/100'; img.alt = item.name; img.className = 'popup-image'; content.appendChild(img); const title = document.createElement('h3'); title.textContent = item.name; content.appendChild(title); const desc = document.createElement('p'); desc.textContent = item.description; content.appendChild(desc); const buttonContainer = document.createElement('div'); buttonContainer.className = 'button-container'; const addButton = document.createElement('button'); addButton.textContent = 'Add'; addButton.className = 'popup-add-button'; addButton.onclick = () => { const sectorItem = { name: item.name, image_url: item.image_url || '', category: item.category || 'Unknown', description: item.description || 'No description available' }; if (selectedItems.some(existing => existing.name === sectorItem.name)) { addMessage('bot', `"${sectorItem.name}" is already in your selection!`); } else { selectedItems.push(sectorItem); addMessage('bot', `Added "${sectorItem.name}" to your selection! Check the box below.`); updateSelectionBox(); } popup.remove(); }; buttonContainer.appendChild(addButton); const closeButton = document.createElement('button'); closeButton.textContent = 'Close'; closeButton.className = 'popup-close-button'; closeButton.onclick = () => popup.remove(); buttonContainer.appendChild(closeButton); content.appendChild(buttonContainer); popup.appendChild(content); document.body.appendChild(popup); } function displayItemsList(items, containerId, isSectorDetail = false) { const container = document.getElementById(containerId); if (!container) { console.error(`${containerId} container not found!`); addMessage('bot', 'Something’s off with the display. Try again?'); return; } container.innerHTML = ''; container.className = 'ingredients-list'; items.forEach(item => { const itemDiv = document.createElement('div'); itemDiv.className = 'ingredient-item'; const img = document.createElement('img'); img.src = item.image_url || 'https://via.placeholder.com/60'; img.alt = item.name; img.className = 'ingredient-image'; itemDiv.appendChild(img); const nameDiv = document.createElement('div'); nameDiv.textContent = item.name; nameDiv.className = 'ingredient-name'; itemDiv.appendChild(nameDiv); if (isSectorDetail && item.description) { const showDescButton = document.createElement('button'); showDescButton.textContent = 'Show Description'; showDescButton.className = 'show-desc-button'; showDescButton.onclick = () => showDescriptionPopup(item); itemDiv.appendChild(showDescButton); } else { const addButton = document.createElement('button'); addButton.textContent = 'Add'; addButton.onclick = () => fetchItemDetails(item.name); itemDiv.appendChild(addButton); } container.appendChild(itemDiv); }); } function displayOptions(options) { const chatMessages = document.getElementById('chatMessages'); if (!chatMessages) { console.error('Chat messages container not found for options!'); return; } const optionsDiv = document.createElement('div'); optionsDiv.style.marginTop = '10px'; options.forEach(opt => { const button = document.createElement('button'); button.textContent = opt.text; button.className = `option-button ${opt.class}`; button.onclick = () => { addMessage('user', opt.text); conversation.push({ role: 'user', message: opt.text }); selectionBoxVisible = true; handleResponse(opt.text); updateSelectionBox(); }; optionsDiv.appendChild(button); }); const backButton = document.createElement('button'); backButton.textContent = 'Go Back'; backButton.className = 'option-button'; backButton.style.marginTop = '10px'; backButton.onclick = () => resetConversation(); optionsDiv.appendChild(document.createElement('br')); optionsDiv.appendChild(backButton); chatMessages.appendChild(optionsDiv); } function submitToSalesforce() { if (selectedItems.length === 0) { addMessage('bot', 'No items to submit yet! Add some tasty picks first! 😊'); return; } const itemsToSubmit = selectedItems.map(item => ({ name: item.name, category: item.category || 'Unknown', // Include Category__c description: item.description || 'No description available' // Ensure description })); fetch('/submit_items', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ items: itemsToSubmit }) }) .then(response => response.json()) .then(data => { if (data.error) { addMessage('bot', `Uh-oh! Failed to submit items: ${data.error}. Want to try again?`); } else { addMessage('bot', `${data.success}! Your culinary choices are now saved. What’s next on the menu?`); selectedItems = []; updateSelectionBox(); } }) .catch(error => { addMessage('bot', `Error submitting items: ${error.message}. I’ll retry shortly...`); setTimeout(submitToSalesforce, 2000); }); } function resetConversation() { const userName = conversation.length > 1 ? conversation[1].message : 'Friend'; conversation = [ { role: 'bot', message: `Hello! I’m Chef Bot, your culinary assistant! What’s your name?` }, { role: 'user', message: userName }, { role: 'bot', message: `Great to meet you, ${userName}! 🍳 What kind of food are you craving today?` } ]; selectedItems = []; selectionBoxVisible = true; const chatMessages = document.getElementById('chatMessages'); chatMessages.innerHTML = ''; conversation.forEach(msg => addMessage(msg.role, msg.message)); displayOptions([ { text: 'Vegetarian', class: 'green' }, { text: 'Non-Vegetarian', class: 'red' }, { text: 'Both', class: 'gray' } ]); document.getElementById('suggestionsList').innerHTML = ''; document.getElementById('menuItemsList').innerHTML = ''; updateSelectionBox(); } document.getElementById('userInput').addEventListener('keypress', (e) => { if (e.key === 'Enter') sendMessage(); }); console.log('Chef Bot script loaded successfully!');