Spaces:
Sleeping
Sleeping
Update templates/chef-bot.html
Browse files- templates/chef-bot.html +187 -332
templates/chef-bot.html
CHANGED
@@ -164,8 +164,10 @@
|
|
164 |
margin-top: 8px;
|
165 |
}
|
166 |
|
167 |
-
.
|
168 |
padding: 8px;
|
|
|
|
|
169 |
border: none;
|
170 |
border-radius: 6px;
|
171 |
cursor: pointer;
|
@@ -173,20 +175,6 @@
|
|
173 |
flex: 1;
|
174 |
}
|
175 |
|
176 |
-
.show-button {
|
177 |
-
background-color: #0078d4;
|
178 |
-
color: #ffffff;
|
179 |
-
}
|
180 |
-
|
181 |
-
.show-button:hover {
|
182 |
-
background-color: #005ea2;
|
183 |
-
}
|
184 |
-
|
185 |
-
.add-button {
|
186 |
-
background-color: #28a745;
|
187 |
-
color: #ffffff;
|
188 |
-
}
|
189 |
-
|
190 |
.add-button:hover {
|
191 |
background-color: #218838;
|
192 |
}
|
@@ -200,7 +188,6 @@
|
|
200 |
|
201 |
.option-button {
|
202 |
padding: 10px 20px;
|
203 |
-
background-color: #6c757d;
|
204 |
color: #ffffff;
|
205 |
border: none;
|
206 |
border-radius: 8px;
|
@@ -225,7 +212,7 @@
|
|
225 |
background-color: #c82333;
|
226 |
}
|
227 |
|
228 |
-
.selection-box
|
229 |
background-color: #f1f8ff;
|
230 |
padding: 15px;
|
231 |
border: 1px solid #b3d7ff;
|
@@ -238,7 +225,7 @@
|
|
238 |
gap: 10px;
|
239 |
}
|
240 |
|
241 |
-
.selection-box span
|
242 |
background-color: #d6e9ff;
|
243 |
padding: 5px 10px;
|
244 |
border-radius: 6px;
|
@@ -252,6 +239,8 @@
|
|
252 |
padding: 5px 10px;
|
253 |
border-radius: 6px;
|
254 |
font-size: 13px;
|
|
|
|
|
255 |
}
|
256 |
|
257 |
.selected-item-image {
|
@@ -262,6 +251,15 @@
|
|
262 |
margin-right: 8px;
|
263 |
}
|
264 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
265 |
.submit-button {
|
266 |
padding: 10px 20px;
|
267 |
background-color: #0078d4;
|
@@ -292,7 +290,7 @@
|
|
292 |
background-color: #c82333;
|
293 |
}
|
294 |
|
295 |
-
.
|
296 |
padding: 8px;
|
297 |
border: 1px solid #b3d7ff;
|
298 |
border-radius: 6px;
|
@@ -319,12 +317,6 @@
|
|
319 |
outline: none;
|
320 |
}
|
321 |
|
322 |
-
.sector-buttons {
|
323 |
-
display: flex;
|
324 |
-
gap: 10px;
|
325 |
-
margin: 10px 0;
|
326 |
-
}
|
327 |
-
|
328 |
/* Responsive Design */
|
329 |
@media (max-width: 480px) {
|
330 |
.chat-container {
|
@@ -381,7 +373,7 @@
|
|
381 |
font-size: 11px;
|
382 |
}
|
383 |
|
384 |
-
.
|
385 |
font-size: 11px;
|
386 |
padding: 6px;
|
387 |
}
|
@@ -391,7 +383,7 @@
|
|
391 |
padding: 8px 15px;
|
392 |
}
|
393 |
|
394 |
-
.selection-box
|
395 |
padding: 10px;
|
396 |
gap: 8px;
|
397 |
}
|
@@ -406,7 +398,7 @@
|
|
406 |
height: 25px;
|
407 |
}
|
408 |
|
409 |
-
.
|
410 |
width: 120px;
|
411 |
font-size: 13px;
|
412 |
padding: 6px;
|
@@ -427,6 +419,11 @@
|
|
427 |
font-size: 11px;
|
428 |
padding: 4px 8px;
|
429 |
}
|
|
|
|
|
|
|
|
|
|
|
430 |
}
|
431 |
|
432 |
@media (min-width: 481px) and (max-width: 768px) {
|
@@ -443,25 +440,6 @@
|
|
443 |
padding: 12px;
|
444 |
}
|
445 |
|
446 |
-
.bot-message, .user-message {
|
447 |
-
font-size: 14px;
|
448 |
-
padding: 9px 14px;
|
449 |
-
}
|
450 |
-
|
451 |
-
.chat-input input {
|
452 |
-
font-size: 14px;
|
453 |
-
padding: 9px;
|
454 |
-
}
|
455 |
-
|
456 |
-
.chat-input button {
|
457 |
-
font-size: 14px;
|
458 |
-
padding: 9px 18px;
|
459 |
-
}
|
460 |
-
|
461 |
-
.items-grid {
|
462 |
-
gap: 12px;
|
463 |
-
}
|
464 |
-
|
465 |
.item-card {
|
466 |
flex: 0 0 180px;
|
467 |
}
|
@@ -469,67 +447,6 @@
|
|
469 |
.item-image {
|
470 |
height: 110px;
|
471 |
}
|
472 |
-
|
473 |
-
.item-name {
|
474 |
-
font-size: 14px;
|
475 |
-
}
|
476 |
-
|
477 |
-
.item-field, .item-description {
|
478 |
-
font-size: 12px;
|
479 |
-
}
|
480 |
-
|
481 |
-
.show-button, .add-button {
|
482 |
-
font-size: 12px;
|
483 |
-
padding: 7px;
|
484 |
-
}
|
485 |
-
|
486 |
-
.option-button {
|
487 |
-
font-size: 14px;
|
488 |
-
padding: 9px 18px;
|
489 |
-
}
|
490 |
-
|
491 |
-
.selection-box, .custom-box, .submit-box {
|
492 |
-
padding: 12px;
|
493 |
-
gap: 9px;
|
494 |
-
}
|
495 |
-
|
496 |
-
.selected-item {
|
497 |
-
font-size: 13px;
|
498 |
-
padding: 5px 9px;
|
499 |
-
}
|
500 |
-
|
501 |
-
.selected-item-image {
|
502 |
-
width: 28px;
|
503 |
-
height: 28px;
|
504 |
-
}
|
505 |
-
|
506 |
-
.manual-input, .custom-input, .submit-input, .order-name-input {
|
507 |
-
width: 140px;
|
508 |
-
font-size: 14px;
|
509 |
-
padding: 7px;
|
510 |
-
}
|
511 |
-
|
512 |
-
.quantity-input {
|
513 |
-
width: 55px;
|
514 |
-
font-size: 14px;
|
515 |
-
padding: 7px;
|
516 |
-
}
|
517 |
-
|
518 |
-
.submit-button {
|
519 |
-
font-size: 14px;
|
520 |
-
padding: 9px 18px;
|
521 |
-
}
|
522 |
-
|
523 |
-
.remove-button {
|
524 |
-
font-size: 12px;
|
525 |
-
padding: 5px 9px;
|
526 |
-
}
|
527 |
-
}
|
528 |
-
|
529 |
-
@media (min-width: 769px) {
|
530 |
-
.chat-container {
|
531 |
-
max-width: 800px;
|
532 |
-
}
|
533 |
}
|
534 |
</style>
|
535 |
</head>
|
@@ -537,20 +454,24 @@
|
|
537 |
<div class="chat-container">
|
538 |
<div class="chat-header">🍳 Chef Bot</div>
|
539 |
<div class="chat-messages" id="chatMessages">
|
540 |
-
<div class="bot-message">Hello!
|
541 |
</div>
|
542 |
<div class="chat-input">
|
543 |
-
<input type="text" id="userInput" placeholder="Type
|
544 |
<button onclick="sendMessage()">Send</button>
|
545 |
</div>
|
546 |
</div>
|
547 |
|
548 |
<script>
|
549 |
let conversation = [
|
550 |
-
{ role: 'bot', message:
|
551 |
];
|
|
|
|
|
552 |
let selectedItems = [];
|
553 |
let selectionBoxVisible = false;
|
|
|
|
|
554 |
|
555 |
function addMessage(role, message) {
|
556 |
const chatMessages = document.getElementById('chatMessages');
|
@@ -576,27 +497,31 @@
|
|
576 |
if (message) {
|
577 |
addMessage('user', message);
|
578 |
conversation.push({ role: 'user', message: message });
|
579 |
-
selectionBoxVisible = true;
|
580 |
handleResponse(message);
|
581 |
} else {
|
582 |
-
addMessage('bot', 'Please type
|
583 |
}
|
584 |
userInput.value = '';
|
585 |
updateSelectionBox();
|
586 |
}
|
587 |
|
588 |
function handleResponse(userInput) {
|
589 |
-
|
590 |
-
|
591 |
-
|
592 |
-
|
593 |
-
|
594 |
-
|
595 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
596 |
} else {
|
597 |
-
|
598 |
-
addMessage('bot', botResponse);
|
599 |
-
fetchMenuItems(null, userInput);
|
600 |
}
|
601 |
}
|
602 |
|
@@ -607,14 +532,28 @@
|
|
607 |
const existingBox = document.querySelector('.selection-box');
|
608 |
if (existingBox) existingBox.remove();
|
609 |
|
610 |
-
|
611 |
-
if (
|
|
|
|
|
612 |
|
613 |
-
|
614 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
615 |
|
616 |
-
|
617 |
-
if (selectionBoxVisible) {
|
618 |
const selectionBox = document.createElement('div');
|
619 |
selectionBox.className = 'selection-box';
|
620 |
|
@@ -638,10 +577,15 @@
|
|
638 |
};
|
639 |
selectionBox.appendChild(nonVegButton);
|
640 |
|
|
|
|
|
|
|
|
|
|
|
641 |
const nameInput = document.createElement('input');
|
642 |
nameInput.type = 'text';
|
643 |
nameInput.placeholder = 'Enter dish name...';
|
644 |
-
nameInput.className = '
|
645 |
nameInput.addEventListener('keypress', (e) => {
|
646 |
if (e.key === 'Enter' && nameInput.value.trim()) {
|
647 |
const itemName = nameInput.value.trim();
|
@@ -653,156 +597,104 @@
|
|
653 |
});
|
654 |
selectionBox.appendChild(nameInput);
|
655 |
|
656 |
-
|
657 |
-
|
658 |
-
|
659 |
-
|
660 |
-
|
661 |
-
|
662 |
-
|
663 |
-
|
664 |
-
|
665 |
-
|
666 |
-
|
667 |
-
|
668 |
-
|
669 |
-
|
670 |
-
|
671 |
-
|
672 |
-
|
673 |
-
|
674 |
-
|
675 |
-
|
676 |
-
|
677 |
-
|
678 |
-
|
679 |
-
|
680 |
-
|
681 |
-
|
682 |
-
|
683 |
-
|
684 |
-
|
685 |
-
|
686 |
-
|
687 |
-
|
688 |
-
|
689 |
-
|
690 |
-
|
691 |
-
|
692 |
-
|
693 |
-
|
694 |
-
|
695 |
-
|
696 |
-
|
697 |
-
|
698 |
-
|
699 |
-
|
700 |
-
|
701 |
-
|
702 |
-
|
703 |
-
const removeButton = document.createElement('button');
|
704 |
-
removeButton.textContent = 'X';
|
705 |
-
removeButton.className = 'remove-button';
|
706 |
-
removeButton.onclick = () => {
|
707 |
-
selectedItems.splice(index, 1);
|
708 |
-
addMessage('bot', `Removed "${itemName}".`);
|
709 |
-
updateSelectionBox();
|
710 |
-
};
|
711 |
-
itemContainer.appendChild(removeButton);
|
712 |
-
|
713 |
-
customBox.appendChild(itemContainer);
|
714 |
-
|
715 |
-
// Display original item if customized
|
716 |
-
if (item.additionalIngredients && item.additionalIngredients.length > 0) {
|
717 |
-
const originalContainer = document.createElement('div');
|
718 |
-
originalContainer.className = 'selected-item';
|
719 |
-
|
720 |
-
const originalImg = document.createElement('img');
|
721 |
-
originalImg.src = item.image_url || 'https://via.placeholder.com/30';
|
722 |
-
originalImg.alt = item.name;
|
723 |
-
originalImg.className = 'selected-item-image';
|
724 |
-
originalContainer.appendChild(originalImg);
|
725 |
-
|
726 |
-
const originalContentDiv = document.createElement('div');
|
727 |
-
originalContentDiv.className = 'selected-item-content';
|
728 |
-
|
729 |
-
const originalSpan = document.createElement('span');
|
730 |
-
originalSpan.textContent = `${item.name} (Qty: ${item.quantity || 1})`;
|
731 |
-
originalContentDiv.appendChild(originalSpan);
|
732 |
|
733 |
-
|
734 |
|
735 |
-
const
|
736 |
-
|
737 |
-
|
738 |
-
|
739 |
selectedItems.splice(index, 1);
|
740 |
-
addMessage('bot', `Removed "${
|
741 |
updateSelectionBox();
|
742 |
};
|
743 |
-
|
744 |
|
745 |
-
|
746 |
-
}
|
747 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
748 |
|
749 |
-
chatMessages.appendChild(
|
750 |
-
|
751 |
-
// Sector_Detail__c Buttons
|
752 |
-
const sectorButtons = document.createElement('div');
|
753 |
-
sectorButtons.className = 'sector-buttons';
|
754 |
-
|
755 |
-
const vegItemsButton = document.createElement('button');
|
756 |
-
vegItemsButton.textContent = 'Veg Items';
|
757 |
-
vegItemsButton.className = 'option-button green';
|
758 |
-
vegItemsButton.onclick = () => fetchSectorItems('vegetarian');
|
759 |
-
sectorButtons.appendChild(vegItemsButton);
|
760 |
-
|
761 |
-
const nonVegItemsButton = document.createElement('button');
|
762 |
-
nonVegItemsButton.textContent = 'Non-Veg Items';
|
763 |
-
nonVegItemsButton.className = 'option-button red';
|
764 |
-
nonVegItemsButton.onclick = () => fetchSectorItems('non-vegetarian');
|
765 |
-
sectorButtons.appendChild(nonVegItemsButton);
|
766 |
-
|
767 |
-
chatMessages.appendChild(sectorButtons);
|
768 |
-
|
769 |
-
// Third Submit Box
|
770 |
-
const submitBox = document.createElement('div');
|
771 |
-
submitBox.className = 'selection-box submit-box';
|
772 |
-
|
773 |
-
const submitLabel = document.createElement('span');
|
774 |
-
submitLabel.textContent = 'Submit Order:';
|
775 |
-
submitBox.appendChild(submitLabel);
|
776 |
-
|
777 |
-
const quantityInput = document.createElement('input');
|
778 |
-
quantityInput.type = 'number';
|
779 |
-
quantityInput.min = '1';
|
780 |
-
quantityInput.value = '1';
|
781 |
-
quantityInput.placeholder = 'Qty';
|
782 |
-
quantityInput.className = 'quantity-input';
|
783 |
-
submitBox.appendChild(quantityInput);
|
784 |
-
|
785 |
-
const orderNameInput = document.createElement('input');
|
786 |
-
orderNameInput.type = 'text';
|
787 |
-
orderNameInput.placeholder = 'Order Name';
|
788 |
-
orderNameInput.className = 'order-name-input';
|
789 |
-
submitBox.appendChild(orderNameInput);
|
790 |
-
|
791 |
-
const submitButton = document.createElement('button');
|
792 |
-
submitButton.textContent = 'Submit';
|
793 |
-
submitButton.className = 'submit-button';
|
794 |
-
submitButton.onclick = () => promptAndSubmit(quantityInput.value, orderNameInput.value);
|
795 |
-
submitBox.appendChild(submitButton);
|
796 |
-
|
797 |
-
chatMessages.appendChild(submitBox);
|
798 |
}
|
799 |
|
800 |
chatMessages.scrollTop = chatMessages.scrollHeight;
|
801 |
-
console.log('Updated selection
|
802 |
}
|
803 |
|
804 |
function fetchMenuItems(dietaryPreference = '', searchTerm = '') {
|
805 |
-
const payload = {};
|
806 |
if (dietaryPreference) payload.dietary_preference = dietaryPreference;
|
807 |
if (searchTerm) payload.search_term = searchTerm;
|
808 |
fetch('/get_menu_items', {
|
@@ -826,74 +718,37 @@
|
|
826 |
addMessage('bot', `Connection issue: ${error.message}. Retrying...`);
|
827 |
setTimeout(() => fetchMenuItems(dietaryPreference, searchTerm), 2000);
|
828 |
});
|
829 |
-
}
|
830 |
|
831 |
-
|
832 |
-
|
833 |
-
|
834 |
-
|
835 |
-
|
836 |
-
|
837 |
-
.then(response => response.json())
|
838 |
-
.then(data => {
|
839 |
-
if (data.error) {
|
840 |
-
addMessage('bot', `Error: ${data.error}. Try again!`);
|
841 |
-
} else {
|
842 |
-
const sectorItems = data.menu_items.filter(item => item.source === 'Sector_Detail__c');
|
843 |
-
if (sectorItems.length > 0) {
|
844 |
-
addMessage('bot', `--- Found ${sectorItems.length} ${dietaryPreference} items from Sector_Detail__c ---`);
|
845 |
-
displayItemsList(sectorItems);
|
846 |
-
} else {
|
847 |
-
addMessage('bot', `No ${dietaryPreference} items found in Sector_Detail__c.`);
|
848 |
-
}
|
849 |
-
}
|
850 |
})
|
851 |
-
|
852 |
-
|
853 |
-
|
854 |
-
|
|
|
|
|
|
|
|
|
|
|
855 |
}
|
856 |
|
857 |
-
function
|
858 |
-
|
859 |
-
|
860 |
-
|
861 |
-
|
862 |
-
|
863 |
-
.
|
864 |
-
|
865 |
-
|
866 |
-
|
867 |
-
|
868 |
-
|
869 |
-
if (itemIndex !== null) {
|
870 |
-
// Adding as an additional ingredient
|
871 |
-
if (!selectedItems[itemIndex].additionalIngredients) {
|
872 |
-
selectedItems[itemIndex].additionalIngredients = [];
|
873 |
-
}
|
874 |
-
if (!selectedItems[itemIndex].additionalIngredients.includes(details.name)) {
|
875 |
-
selectedItems[itemIndex].additionalIngredients.push(details.name);
|
876 |
-
selectedItems[itemIndex].description += `, with ${details.name}`;
|
877 |
-
addMessage('bot', `Added "${details.name}" to "${selectedItems[itemIndex].name}"!`);
|
878 |
-
} else {
|
879 |
-
addMessage('bot', `"${details.name}" already added to "${selectedItems[itemIndex].name}"!`);
|
880 |
-
}
|
881 |
-
} else {
|
882 |
-
// Adding as a new item
|
883 |
-
if (selectedItems.some(item => item.name === details.name && !item.additionalIngredients)) {
|
884 |
-
addMessage('bot', `"${details.name}" already selected!`);
|
885 |
-
} else {
|
886 |
-
selectedItems.push({ ...details, quantity: 1, additionalIngredients: [] });
|
887 |
-
addMessage('bot', `Added "${details.name}"!`);
|
888 |
-
}
|
889 |
-
}
|
890 |
-
updateSelectionBox();
|
891 |
-
}
|
892 |
-
})
|
893 |
-
.catch(error => {
|
894 |
-
addMessage('bot', `Error for "${itemName}". Retrying...`);
|
895 |
-
setTimeout(() => fetchSectorItemDetails(itemName, itemIndex), 2000);
|
896 |
-
});
|
897 |
}
|
898 |
|
899 |
function displayItemsList(items) {
|
@@ -1025,7 +880,7 @@
|
|
1025 |
if (e.key === 'Enter') sendMessage();
|
1026 |
});
|
1027 |
|
1028 |
-
// Initial
|
1029 |
updateSelectionBox();
|
1030 |
console.log('Chef Bot script loaded!');
|
1031 |
</script>
|
|
|
164 |
margin-top: 8px;
|
165 |
}
|
166 |
|
167 |
+
.add-button {
|
168 |
padding: 8px;
|
169 |
+
background-color: #28a745;
|
170 |
+
color: #ffffff;
|
171 |
border: none;
|
172 |
border-radius: 6px;
|
173 |
cursor: pointer;
|
|
|
175 |
flex: 1;
|
176 |
}
|
177 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
178 |
.add-button:hover {
|
179 |
background-color: #218838;
|
180 |
}
|
|
|
188 |
|
189 |
.option-button {
|
190 |
padding: 10px 20px;
|
|
|
191 |
color: #ffffff;
|
192 |
border: none;
|
193 |
border-radius: 8px;
|
|
|
212 |
background-color: #c82333;
|
213 |
}
|
214 |
|
215 |
+
.selection-box {
|
216 |
background-color: #f1f8ff;
|
217 |
padding: 15px;
|
218 |
border: 1px solid #b3d7ff;
|
|
|
225 |
gap: 10px;
|
226 |
}
|
227 |
|
228 |
+
.selection-box span {
|
229 |
background-color: #d6e9ff;
|
230 |
padding: 5px 10px;
|
231 |
border-radius: 6px;
|
|
|
239 |
padding: 5px 10px;
|
240 |
border-radius: 6px;
|
241 |
font-size: 13px;
|
242 |
+
margin: 5px 0;
|
243 |
+
width: 100%;
|
244 |
}
|
245 |
|
246 |
.selected-item-image {
|
|
|
251 |
margin-right: 8px;
|
252 |
}
|
253 |
|
254 |
+
.ingredient-select {
|
255 |
+
padding: 8px;
|
256 |
+
border: 1px solid #b3d7ff;
|
257 |
+
border-radius: 6px;
|
258 |
+
font-size: 13px;
|
259 |
+
width: 150px;
|
260 |
+
outline: none;
|
261 |
+
}
|
262 |
+
|
263 |
.submit-button {
|
264 |
padding: 10px 20px;
|
265 |
background-color: #0078d4;
|
|
|
290 |
background-color: #c82333;
|
291 |
}
|
292 |
|
293 |
+
.name-input {
|
294 |
padding: 8px;
|
295 |
border: 1px solid #b3d7ff;
|
296 |
border-radius: 6px;
|
|
|
317 |
outline: none;
|
318 |
}
|
319 |
|
|
|
|
|
|
|
|
|
|
|
|
|
320 |
/* Responsive Design */
|
321 |
@media (max-width: 480px) {
|
322 |
.chat-container {
|
|
|
373 |
font-size: 11px;
|
374 |
}
|
375 |
|
376 |
+
.add-button {
|
377 |
font-size: 11px;
|
378 |
padding: 6px;
|
379 |
}
|
|
|
383 |
padding: 8px 15px;
|
384 |
}
|
385 |
|
386 |
+
.selection-box {
|
387 |
padding: 10px;
|
388 |
gap: 8px;
|
389 |
}
|
|
|
398 |
height: 25px;
|
399 |
}
|
400 |
|
401 |
+
.name-input, .order-name-input {
|
402 |
width: 120px;
|
403 |
font-size: 13px;
|
404 |
padding: 6px;
|
|
|
419 |
font-size: 11px;
|
420 |
padding: 4px 8px;
|
421 |
}
|
422 |
+
|
423 |
+
.ingredient-select {
|
424 |
+
width: 120px;
|
425 |
+
font-size: 12px;
|
426 |
+
}
|
427 |
}
|
428 |
|
429 |
@media (min-width: 481px) and (max-width: 768px) {
|
|
|
440 |
padding: 12px;
|
441 |
}
|
442 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
443 |
.item-card {
|
444 |
flex: 0 0 180px;
|
445 |
}
|
|
|
447 |
.item-image {
|
448 |
height: 110px;
|
449 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
450 |
}
|
451 |
</style>
|
452 |
</head>
|
|
|
454 |
<div class="chat-container">
|
455 |
<div class="chat-header">🍳 Chef Bot</div>
|
456 |
<div class="chat-messages" id="chatMessages">
|
457 |
+
<div class="bot-message">Hello! What's your name?</div>
|
458 |
</div>
|
459 |
<div class="chat-input">
|
460 |
+
<input type="text" id="userInput" placeholder="Type your name or dish...">
|
461 |
<button onclick="sendMessage()">Send</button>
|
462 |
</div>
|
463 |
</div>
|
464 |
|
465 |
<script>
|
466 |
let conversation = [
|
467 |
+
{ role: 'bot', message: "Hello! What's your name?" }
|
468 |
];
|
469 |
+
let userName = '';
|
470 |
+
let selectedPreference = '';
|
471 |
let selectedItems = [];
|
472 |
let selectionBoxVisible = false;
|
473 |
+
let nameInputVisible = false;
|
474 |
+
let sectorIngredients = [];
|
475 |
|
476 |
function addMessage(role, message) {
|
477 |
const chatMessages = document.getElementById('chatMessages');
|
|
|
497 |
if (message) {
|
498 |
addMessage('user', message);
|
499 |
conversation.push({ role: 'user', message: message });
|
|
|
500 |
handleResponse(message);
|
501 |
} else {
|
502 |
+
addMessage('bot', 'Please type something! 😄');
|
503 |
}
|
504 |
userInput.value = '';
|
505 |
updateSelectionBox();
|
506 |
}
|
507 |
|
508 |
function handleResponse(userInput) {
|
509 |
+
if (!userName) {
|
510 |
+
userName = userInput;
|
511 |
+
addMessage('bot', `Nice to meet you, ${userName}! Choose your preference: Veg or Non-Veg.`);
|
512 |
+
selectionBoxVisible = true;
|
513 |
+
updateSelectionBox();
|
514 |
+
} else if (!selectedPreference && (userInput.toLowerCase() === 'vegetarian' || userInput.toLowerCase() === 'non-vegetarian')) {
|
515 |
+
selectedPreference = userInput.toLowerCase();
|
516 |
+
addMessage('bot', `Fetching ${selectedPreference} dishes...`);
|
517 |
+
fetchMenuItems(selectedPreference);
|
518 |
+
nameInputVisible = true;
|
519 |
+
updateSelectionBox();
|
520 |
+
} else if (nameInputVisible) {
|
521 |
+
addMessage('bot', `Searching for "${userInput}"...`);
|
522 |
+
fetchMenuItems(selectedPreference, userInput);
|
523 |
} else {
|
524 |
+
addMessage('bot', 'Please select Veg or Non-Veg first!');
|
|
|
|
|
525 |
}
|
526 |
}
|
527 |
|
|
|
532 |
const existingBox = document.querySelector('.selection-box');
|
533 |
if (existingBox) existingBox.remove();
|
534 |
|
535 |
+
// Selection Box
|
536 |
+
if (selectionBoxVisible && !userName) {
|
537 |
+
const selectionBox = document.createElement('div');
|
538 |
+
selectionBox.className = 'selection-box';
|
539 |
|
540 |
+
const nameInput = document.createElement('input');
|
541 |
+
nameInput.type = 'text';
|
542 |
+
nameInput.placeholder = 'Enter your name...';
|
543 |
+
nameInput.className = 'name-input';
|
544 |
+
nameInput.addEventListener('keypress', (e) => {
|
545 |
+
if (e.key === 'Enter' && nameInput.value.trim()) {
|
546 |
+
const name = nameInput.value.trim();
|
547 |
+
addMessage('user', name);
|
548 |
+
conversation.push({ role: 'user', message: name });
|
549 |
+
handleResponse(name);
|
550 |
+
nameInput.value = '';
|
551 |
+
}
|
552 |
+
});
|
553 |
+
selectionBox.appendChild(nameInput);
|
554 |
|
555 |
+
chatMessages.appendChild(selectionBox);
|
556 |
+
} else if (selectionBoxVisible && userName && !selectedPreference) {
|
557 |
const selectionBox = document.createElement('div');
|
558 |
selectionBox.className = 'selection-box';
|
559 |
|
|
|
577 |
};
|
578 |
selectionBox.appendChild(nonVegButton);
|
579 |
|
580 |
+
chatMessages.appendChild(selectionBox);
|
581 |
+
} else if (nameInputVisible && selectedPreference) {
|
582 |
+
const selectionBox = document.createElement('div');
|
583 |
+
selectionBox.className = 'selection-box';
|
584 |
+
|
585 |
const nameInput = document.createElement('input');
|
586 |
nameInput.type = 'text';
|
587 |
nameInput.placeholder = 'Enter dish name...';
|
588 |
+
nameInput.className = 'name-input';
|
589 |
nameInput.addEventListener('keypress', (e) => {
|
590 |
if (e.key === 'Enter' && nameInput.value.trim()) {
|
591 |
const itemName = nameInput.value.trim();
|
|
|
597 |
});
|
598 |
selectionBox.appendChild(nameInput);
|
599 |
|
600 |
+
// Selected Items
|
601 |
+
if (selectedItems.length > 0) {
|
602 |
+
const itemsLabel = document.createElement('span');
|
603 |
+
itemsLabel.textContent = 'Selected Items:';
|
604 |
+
selectionBox.appendChild(itemsLabel);
|
605 |
+
|
606 |
+
selectedItems.forEach((item, index) => {
|
607 |
+
const itemContainer = document.createElement('div');
|
608 |
+
itemContainer.className = 'selected-item';
|
609 |
+
|
610 |
+
const img = document.createElement('img');
|
611 |
+
img.src = item.image_url || 'https://via.placeholder.com/30';
|
612 |
+
img.alt = item.name;
|
613 |
+
img.className = 'selected-item-image';
|
614 |
+
itemContainer.appendChild(img);
|
615 |
+
|
616 |
+
const contentDiv = document.createElement('div');
|
617 |
+
contentDiv.className = 'selected-item-content';
|
618 |
+
|
619 |
+
const itemName = item.additionalIngredients && item.additionalIngredients.length > 0
|
620 |
+
? `${item.name} with ${item.additionalIngredients.join(', ')}`
|
621 |
+
: item.name;
|
622 |
+
const itemSpan = document.createElement('span');
|
623 |
+
itemSpan.textContent = `${itemName} (Qty: ${item.quantity || 1})`;
|
624 |
+
contentDiv.appendChild(itemSpan);
|
625 |
+
|
626 |
+
// Ingredient Selector
|
627 |
+
const ingredientSelect = document.createElement('select');
|
628 |
+
ingredientSelect.className = 'ingredient-select';
|
629 |
+
const defaultOption = document.createElement('option');
|
630 |
+
defaultOption.value = '';
|
631 |
+
defaultOption.textContent = 'Add ingredient...';
|
632 |
+
ingredientSelect.appendChild(defaultOption);
|
633 |
+
sectorIngredients.forEach(ingredient => {
|
634 |
+
const option = document.createElement('option');
|
635 |
+
option.value = ingredient.name;
|
636 |
+
option.textContent = ingredient.name;
|
637 |
+
ingredientSelect.appendChild(option);
|
638 |
+
});
|
639 |
+
ingredientSelect.addEventListener('change', (e) => {
|
640 |
+
const ingredientName = e.target.value;
|
641 |
+
if (ingredientName) {
|
642 |
+
addIngredientToItem(ingredientName, index);
|
643 |
+
e.target.value = '';
|
644 |
+
}
|
645 |
+
});
|
646 |
+
contentDiv.appendChild(ingredientSelect);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
647 |
|
648 |
+
itemContainer.appendChild(contentDiv);
|
649 |
|
650 |
+
const removeButton = document.createElement('button');
|
651 |
+
removeButton.textContent = 'X';
|
652 |
+
removeButton.className = 'remove-button';
|
653 |
+
removeButton.onclick = () => {
|
654 |
selectedItems.splice(index, 1);
|
655 |
+
addMessage('bot', `Removed "${itemName}".`);
|
656 |
updateSelectionBox();
|
657 |
};
|
658 |
+
itemContainer.appendChild(removeButton);
|
659 |
|
660 |
+
selectionBox.appendChild(itemContainer);
|
661 |
+
});
|
662 |
+
|
663 |
+
// Submit Order
|
664 |
+
const submitLabel = document.createElement('span');
|
665 |
+
submitLabel.textContent = 'Submit Order:';
|
666 |
+
selectionBox.appendChild(submitLabel);
|
667 |
+
|
668 |
+
const quantityInput = document.createElement('input');
|
669 |
+
quantityInput.type = 'number';
|
670 |
+
quantityInput.min = '1';
|
671 |
+
quantityInput.value = '1';
|
672 |
+
quantityInput.placeholder = 'Qty';
|
673 |
+
quantityInput.className = 'quantity-input';
|
674 |
+
selectionBox.appendChild(quantityInput);
|
675 |
+
|
676 |
+
const orderNameInput = document.createElement('input');
|
677 |
+
orderNameInput.type = 'text';
|
678 |
+
orderNameInput.placeholder = 'Order Name';
|
679 |
+
orderNameInput.className = 'order-name-input';
|
680 |
+
selectionBox.appendChild(orderNameInput);
|
681 |
+
|
682 |
+
const submitButton = document.createElement('button');
|
683 |
+
submitButton.textContent = 'Submit';
|
684 |
+
submitButton.className = 'submit-button';
|
685 |
+
submitButton.onclick = () => promptAndSubmit(quantityInput.value, orderNameInput.value);
|
686 |
+
selectionBox.appendChild(submitButton);
|
687 |
+
}
|
688 |
|
689 |
+
chatMessages.appendChild(selectionBox);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
690 |
}
|
691 |
|
692 |
chatMessages.scrollTop = chatMessages.scrollHeight;
|
693 |
+
console.log('Updated selection box:', selectedItems.map(item => ({ name: item.name, additionalIngredients: item.additionalIngredients })));
|
694 |
}
|
695 |
|
696 |
function fetchMenuItems(dietaryPreference = '', searchTerm = '') {
|
697 |
+
const payload = { source: 'Menu_Item__c' };
|
698 |
if (dietaryPreference) payload.dietary_preference = dietaryPreference;
|
699 |
if (searchTerm) payload.search_term = searchTerm;
|
700 |
fetch('/get_menu_items', {
|
|
|
718 |
addMessage('bot', `Connection issue: ${error.message}. Retrying...`);
|
719 |
setTimeout(() => fetchMenuItems(dietaryPreference, searchTerm), 2000);
|
720 |
});
|
|
|
721 |
|
722 |
+
// Fetch Sector_Detail__c ingredients
|
723 |
+
if (!sectorIngredients.length) {
|
724 |
+
fetch('/get_sector_ingredients', {
|
725 |
+
method: 'POST',
|
726 |
+
headers: { 'Content-Type': 'application/json' },
|
727 |
+
body: JSON.stringify({ dietary_preference: dietaryPreference })
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
728 |
})
|
729 |
+
.then(response => response.json())
|
730 |
+
.then(data => {
|
731 |
+
if (!data.error) {
|
732 |
+
sectorIngredients = data.ingredients;
|
733 |
+
console.log('Fetched Sector_Detail__c ingredients:', sectorIngredients);
|
734 |
+
}
|
735 |
+
})
|
736 |
+
.catch(error => console.error('Error fetching Sector_Detail__c ingredients:', error));
|
737 |
+
}
|
738 |
}
|
739 |
|
740 |
+
function addIngredientToItem(ingredientName, itemIndex) {
|
741 |
+
if (!selectedItems[itemIndex].additionalIngredients) {
|
742 |
+
selectedItems[itemIndex].additionalIngredients = [];
|
743 |
+
}
|
744 |
+
if (!selectedItems[itemIndex].additionalIngredients.includes(ingredientName)) {
|
745 |
+
selectedItems[itemIndex].additionalIngredients.push(ingredientName);
|
746 |
+
selectedItems[itemIndex].description += `, with ${ingredientName}`;
|
747 |
+
addMessage('bot', `Added "${ingredientName}" to "${selectedItems[itemIndex].name}"!`);
|
748 |
+
} else {
|
749 |
+
addMessage('bot', `"${ingredientName}" already added to "${selectedItems[itemIndex].name}"!`);
|
750 |
+
}
|
751 |
+
updateSelectionBox();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
752 |
}
|
753 |
|
754 |
function displayItemsList(items) {
|
|
|
880 |
if (e.key === 'Enter') sendMessage();
|
881 |
});
|
882 |
|
883 |
+
// Initial setup
|
884 |
updateSelectionBox();
|
885 |
console.log('Chef Bot script loaded!');
|
886 |
</script>
|