lokesh341 commited on
Commit
3774e44
·
verified ·
1 Parent(s): bcca109

Update templates/chef-bot.html

Browse files
Files changed (1) hide show
  1. templates/chef-bot.html +168 -691
templates/chef-bot.html CHANGED
@@ -103,31 +103,16 @@
103
  background-color: #f57c00;
104
  }
105
 
106
- .items-grid {
107
- display: flex;
108
- flex-wrap: nowrap;
109
- overflow-x: auto;
110
- padding: 8px;
111
- margin: 5px 0;
112
- background-color: #f9f9f9;
113
- border-radius: 5px;
114
- gap: 8px;
115
- scroll-behavior: smooth;
116
- }
117
-
118
- .item-card {
119
- flex: 0 0 150px;
120
  background-color: white;
121
  border: 1px solid #ddd;
122
  border-radius: 6px;
123
  padding: 8px;
 
 
124
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
125
  }
126
 
127
- .item-card:active {
128
- transform: scale(0.98);
129
- }
130
-
131
  .item-image {
132
  width: 100%;
133
  height: 100px;
@@ -136,10 +121,6 @@
136
  margin-bottom: 5px;
137
  }
138
 
139
- .item-content {
140
- width: 100%;
141
- }
142
-
143
  .item-name {
144
  font-size: 12px;
145
  font-weight: bold;
@@ -147,45 +128,7 @@
147
  margin-bottom: 3px;
148
  }
149
 
150
- .item-field {
151
- font-size: 10px;
152
- margin: 2px 0;
153
- color: #555;
154
- }
155
-
156
- .item-field strong {
157
- color: #0288d1;
158
- }
159
-
160
- .item-description {
161
- font-size: 10px;
162
- margin: 5px 0;
163
- color: #555;
164
- }
165
-
166
- .button-container {
167
- display: flex;
168
- gap: 5px;
169
- margin-top: 5px;
170
- }
171
-
172
- .show-button {
173
- padding: 4px;
174
- background-color: #0288d1;
175
- color: white;
176
- border: none;
177
- border-radius: 5px;
178
- cursor: pointer;
179
- font-size: 10px;
180
- flex: 1;
181
- min-width: 40px;
182
- }
183
-
184
- .show-button:active {
185
- background-color: #0277bd;
186
- }
187
-
188
- .add-button {
189
  padding: 4px;
190
  background-color: #4caf50;
191
  color: white;
@@ -193,11 +136,11 @@
193
  border-radius: 5px;
194
  cursor: pointer;
195
  font-size: 10px;
196
- flex: 1;
197
- min-width: 40px;
198
  }
199
 
200
- .add-button:active {
201
  background-color: #45a049;
202
  }
203
 
@@ -222,7 +165,6 @@
222
 
223
  .option-button.green { background-color: #4caf50; }
224
  .option-button.red { background-color: #d32f2f; }
225
- .option-button.gray { background-color: #616161; }
226
  .option-button:active { opacity: 0.9; }
227
 
228
  .selection-box {
@@ -238,60 +180,6 @@
238
  gap: 5px;
239
  }
240
 
241
- .selection-box span {
242
- background-color: #bbdefb;
243
- padding: 3px 8px;
244
- border-radius: 5px;
245
- font-size: 12px;
246
- }
247
-
248
- .selected-item {
249
- display: flex;
250
- align-items: center;
251
- background-color: #bbdefb;
252
- padding: 3px 8px;
253
- border-radius: 5px;
254
- font-size: 11px;
255
- }
256
-
257
- .selected-item-image {
258
- width: 25px;
259
- height: 25px;
260
- object-fit: cover;
261
- border-radius: 5px;
262
- margin-right: 5px;
263
- }
264
-
265
- .submit-button {
266
- padding: 6px 10px;
267
- background-color: #0288d1;
268
- color: white;
269
- border: none;
270
- border-radius: 5px;
271
- cursor: pointer;
272
- font-size: 12px;
273
- min-width: 60px;
274
- }
275
-
276
- .submit-button:active {
277
- background-color: #0277bd;
278
- }
279
-
280
- .remove-button {
281
- padding: 3px 6px;
282
- margin-left: 5px;
283
- background-color: #d32f2f;
284
- color: white;
285
- border: none;
286
- border-radius: 5px;
287
- cursor: pointer;
288
- font-size: 10px;
289
- }
290
-
291
- .remove-button:active {
292
- background-color: #b71c1c;
293
- }
294
-
295
  .manual-input {
296
  padding: 4px;
297
  border: 1px solid #0288d1;
@@ -300,190 +188,36 @@
300
  width: 100px;
301
  }
302
 
303
- .quantity-input {
304
  padding: 4px;
305
  border: 1px solid #0288d1;
306
  border-radius: 5px;
307
  font-size: 12px;
308
- width: 50px;
309
  }
310
 
311
- .order-name-input {
312
- padding: 4px;
313
- border: 1px solid #0288d1;
314
  border-radius: 5px;
 
315
  font-size: 12px;
316
- width: 100px;
317
  }
318
 
319
  @media (max-width: 480px) {
320
- .chat-header {
321
- font-size: 14px;
322
- padding: 6px;
323
- }
324
- .chat-messages {
325
- padding: 3px;
326
- }
327
- .bot-message, .user-message {
328
- font-size: 11px;
329
- padding: 6px;
330
- margin: 3px 0;
331
- }
332
- .chat-input input {
333
- font-size: 11px;
334
- min-height: 30px;
335
- padding: 5px;
336
- }
337
- .chat-input button {
338
- font-size: 11px;
339
- min-height: 30px;
340
- padding: 5px 8px;
341
- min-width: 50px;
342
- }
343
- .items-grid {
344
- flex-direction: column;
345
- overflow-x: hidden;
346
- gap: 6px;
347
- padding: 6px;
348
- }
349
- .item-card {
350
- width: 100%;
351
- flex: 0 0 auto;
352
- max-width: 120px;
353
- }
354
- .item-image {
355
- height: 80px;
356
- }
357
- .item-name {
358
- font-size: 10px;
359
- }
360
- .item-field, .item-description {
361
- font-size: 9px;
362
- }
363
- .show-button, .add-button {
364
- font-size: 9px;
365
- padding: 3px;
366
- min-width: 35px;
367
- }
368
- .options-container {
369
- gap: 3px;
370
- }
371
- .option-button {
372
- font-size: 11px;
373
- padding: 5px 8px;
374
- min-width: 50px;
375
- }
376
- .selection-box {
377
- padding: 6px;
378
- gap: 3px;
379
- }
380
- .selection-box span {
381
- font-size: 11px;
382
- padding: 2px 6px;
383
- }
384
- .selected-item {
385
- font-size: 10px;
386
- padding: 2px 6px;
387
- }
388
- .selected-item-image {
389
- width: 20px;
390
- height: 20px;
391
- }
392
- .submit-button {
393
- font-size: 11px;
394
- padding: 5px 8px;
395
- min-width: 50px;
396
- }
397
- .remove-button {
398
- font-size: 9px;
399
- padding: 2px 5px;
400
- }
401
- .manual-input, .order-name-input {
402
- width: 80px;
403
- font-size: 11px;
404
- padding: 3px;
405
- }
406
- .quantity-input {
407
- width: 40px;
408
- font-size: 11px;
409
- padding: 3px;
410
- }
411
- }
412
-
413
- @media (min-width: 481px) and (max-width: 768px) {
414
- .chat-header {
415
- font-size: 15px;
416
- }
417
- .chat-messages {
418
- padding: 4px;
419
- }
420
- .bot-message, .user-message {
421
- font-size: 12px;
422
- padding: 7px;
423
- }
424
- .chat-input input {
425
- font-size: 12px;
426
- min-height: 35px;
427
- }
428
- .chat-input button {
429
- font-size: 12px;
430
- min-height: 35px;
431
- padding: 6px 10px;
432
- }
433
- .items-grid {
434
- gap: 8px;
435
- }
436
- .item-card {
437
- flex: 0 0 140px;
438
- }
439
- .item-image {
440
- height: 90px;
441
- }
442
- .item-name {
443
- font-size: 11px;
444
- }
445
- .item-field, .item-description {
446
- font-size: 10px;
447
- }
448
- .show-button, .add-button {
449
- font-size: 10px;
450
- padding: 4px;
451
- min-width: 40px;
452
- }
453
- .option-button {
454
- font-size: 12px;
455
- padding: 6px 10px;
456
- }
457
- .selection-box {
458
- padding: 8px;
459
- gap: 5px;
460
- }
461
- .selection-box span {
462
- font-size: 12px;
463
- }
464
- .selected-item {
465
- font-size: 11px;
466
- }
467
- .selected-item-image {
468
- width: 25px;
469
- height: 25px;
470
- }
471
- .submit-button {
472
- font-size: 12px;
473
- padding: 6px 10px;
474
- }
475
- .remove-button {
476
- font-size: 10px;
477
- padding: 3px 6px;
478
- }
479
- .manual-input, .order-name-input {
480
- width: 100px;
481
- font-size: 12px;
482
- }
483
- .quantity-input {
484
- width: 50px;
485
- font-size: 12px;
486
- }
487
  }
488
  </style>
489
  </head>
@@ -493,8 +227,6 @@
493
  <div class="chat-messages" id="chatMessages">
494
  <div class="bot-message">Hello! I’m Chef Bot, your culinary assistant! What’s your name?</div>
495
  </div>
496
- <div class="suggestions-list" id="suggestionsList"></div>
497
- <div class="ingredients-list" id="menuItemsList"></div>
498
  <div class="chat-input">
499
  <input type="text" id="userInput" placeholder="Type here (e.g., paneer, chicken)...">
500
  <button onclick="sendMessage()">Send</button>
@@ -505,33 +237,27 @@
505
  let conversation = [
506
  { role: 'bot', message: 'Hello! I’m Chef Bot, your culinary assistant! What’s your name?' }
507
  ];
508
- let selectedItems = [];
 
509
  let selectionBoxVisible = false;
510
 
511
  function addMessage(role, message) {
512
  const chatMessages = document.getElementById('chatMessages');
513
- if (!chatMessages) {
514
- console.error('Chat messages container not found!');
515
- return;
516
- }
517
  const messageDiv = document.createElement('div');
518
  messageDiv.className = role === 'bot' ? 'bot-message' : 'user-message';
519
  messageDiv.textContent = message;
520
  chatMessages.appendChild(messageDiv);
521
  chatMessages.scrollTop = chatMessages.scrollHeight;
522
- console.log(`Added ${role} message: ${message}`);
523
  }
524
 
525
  function sendMessage() {
526
  const userInput = document.getElementById('userInput');
527
- if (!userInput) {
528
- console.error('User input field not found!');
529
- return;
530
- }
531
  const message = userInput.value.trim();
532
  if (message) {
533
  addMessage('user', message);
534
- conversation.push({ role: 'user', message: message });
535
  selectionBoxVisible = true;
536
  handleResponse(message);
537
  } else {
@@ -543,85 +269,97 @@
543
 
544
  function handleResponse(userInput) {
545
  const lowerInput = userInput.toLowerCase();
546
- let botResponse = '';
547
-
548
  if (conversation.length === 2) {
549
- botResponse = `Hi ${userInput}! 🍳 Search for a dish or choose a preference below!`;
550
  displayOptions([
551
  { text: 'Vegetarian', class: 'green' },
552
- { text: 'Non-Vegetarian', class: 'red' },
553
- { text: 'Both', class: 'gray' }
554
  ]);
555
- addMessage('bot', botResponse);
556
- } else if (lowerInput === 'vegetarian' || lowerInput === 'non-vegetarian' || lowerInput === 'both') {
557
- botResponse = `Fetching ${lowerInput} dishes...`;
558
- addMessage('bot', botResponse);
559
- fetchMenuItems(lowerInput);
560
- } else if (lowerInput.startsWith('add')) {
561
- handleAddItem(lowerInput);
562
  } else {
563
- botResponse = `Looking for "${userInput}"...`;
564
- addMessage('bot', botResponse);
565
- fetchMenuItems(null, userInput);
566
  }
567
  }
568
 
569
- function handleAddItem(input) {
570
- const addMatch = input.match(/^add\s+(.+?)(?:\s+with\s+(.+))?$/i);
571
- if (!addMatch) {
572
- addMessage('bot', 'Please use format: "Add [dish name] [with extra ingredients]"');
573
- return;
574
- }
575
- const dishName = addMatch[1].trim();
576
- const extraIngredients = addMatch[2] ? addMatch[2].trim() : '';
577
- fetch('/get_sector_item_details', {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
578
  method: 'POST',
579
  headers: { 'Content-Type': 'application/json' },
580
- body: JSON.stringify({ item_name: dishName })
581
  })
582
  .then(response => response.json())
583
  .then(data => {
584
  if (data.error) {
585
- addMessage('bot', `No "${dishName}" found. Try another dish!`);
586
- return;
587
- }
588
- const item = data.item_details;
589
- const originalItem = {
590
- name: item.name,
591
- image_url: item.image_url || '',
592
- category: item.category || 'Not specified',
593
- description: item.description || 'No description available',
594
- source: item.source,
595
- quantity: 1
596
- };
597
- if (selectedItems.some(existing => existing.name === originalItem.name && !existing.custom)) {
598
- addMessage('bot', `"${originalItem.name}" already added!`);
599
  } else {
600
- selectedItems.push(originalItem);
601
- addMessage('bot', `Added "${originalItem.name}"!`);
602
- }
603
- if (extraIngredients) {
604
- const customItem = {
605
- ...originalItem,
606
- name: `${item.name} (Custom)`,
607
- description: `${item.description}, ${extraIngredients}`,
608
- custom: true
609
- };
610
- if (selectedItems.some(existing => existing.name === customItem.name)) {
611
- addMessage('bot', `"${customItem.name}" already added!`);
612
- } else {
613
- selectedItems.push(customItem);
614
- addMessage('bot', `Added customized "${customItem.name}" with ${extraIngredients}!`);
615
- }
616
  }
617
- updateSelectionBox();
618
  })
619
  .catch(error => {
620
- addMessage('bot', `Error fetching "${dishName}": ${error.message}. Retrying...`);
621
- setTimeout(() => fetchSectorItemDetails(dishName), 2000);
622
  });
623
  }
624
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
625
  function updateSelectionBox() {
626
  const chatMessages = document.getElementById('chatMessages');
627
  if (!chatMessages) return;
@@ -629,348 +367,105 @@
629
  const existingBox = document.querySelector('.selection-box');
630
  if (existingBox) existingBox.remove();
631
 
632
- if (!selectionBoxVisible && selectedItems.length === 0) return;
633
 
634
  const selectionBox = document.createElement('div');
635
  selectionBox.className = 'selection-box';
636
 
637
- const vegButton = document.createElement('button');
638
- vegButton.textContent = 'Veg';
639
- vegButton.className = 'dietary-button green';
640
- vegButton.onclick = () => {
641
- addMessage('user', 'Vegetarian');
642
- conversation.push({ role: 'user', message: 'Vegetarian' });
643
- handleResponse('vegetarian');
644
- };
645
- selectionBox.appendChild(vegButton);
646
-
647
- const nonVegButton = document.createElement('button');
648
- nonVegButton.textContent = 'Non-Veg';
649
- nonVegButton.className = 'dietary-button red';
650
- nonVegButton.onclick = () => {
651
- addMessage('user', 'Non-Vegetarian');
652
- conversation.push({ role: 'user', message: 'Non-Vegetarian' });
653
- handleResponse('non-vegetarian');
654
- };
655
- selectionBox.appendChild(nonVegButton);
656
-
657
- const bothButton = document.createElement('button');
658
- bothButton.textContent = 'Both';
659
- bothButton.className = 'dietary-button gray';
660
- bothButton.onclick = () => {
661
- addMessage('user', 'Both');
662
- conversation.push({ role: 'user', message: 'Both' });
663
- handleResponse('both');
664
- };
665
- selectionBox.appendChild(bothButton);
666
-
667
  const label = document.createElement('span');
668
  label.textContent = 'Selected:';
669
  selectionBox.appendChild(label);
670
 
671
- selectedItems.forEach((item, index) => {
672
- const itemContainer = document.createElement('div');
673
- itemContainer.className = 'selected-item';
674
- itemContainer.dataset.hidden = item.source === 'Sector_Detail__c' ? 'true' : 'false';
675
-
676
- const img = document.createElement('img');
677
- img.src = item.image_url || 'https://via.placeholder.com/30';
678
- img.alt = item.name;
679
- img.className = 'selected-item-image';
680
- itemContainer.appendChild(img);
681
-
682
- const contentDiv = document.createElement('div');
683
- contentDiv.className = 'selected-item-content';
684
-
685
- const itemSpan = document.createElement('span');
686
- itemSpan.textContent = `${item.name} (Qty: ${item.quantity || 1})`;
687
- contentDiv.appendChild(itemSpan);
688
-
689
- if (item.source === 'Sector_Detail__c') {
690
- const showButton = document.createElement('button');
691
- showButton.textContent = 'Show';
692
- showButton.className = 'show-button';
693
- showButton.onclick = () => toggleDescription(itemContainer, item.description, item.name);
694
- contentDiv.appendChild(showButton);
695
- }
696
-
697
- itemContainer.appendChild(contentDiv);
698
-
699
- const removeButton = document.createElement('button');
700
- removeButton.textContent = 'X';
701
- removeButton.className = 'remove-button';
702
- removeButton.onclick = () => {
703
- selectedItems.splice(index, 1);
704
- addMessage('bot', `Removed "${item.name}".`);
705
- updateSelectionBox();
706
- };
707
- itemContainer.appendChild(removeButton);
708
-
709
- selectionBox.appendChild(itemContainer);
710
- });
711
-
712
- const textInput = document.createElement('input');
713
- textInput.type = 'text';
714
- textInput.placeholder = 'Add item (e.g., Paneer Tikka with onions)';
715
- textInput.className = 'manual-input';
716
- textInput.addEventListener('keypress', (e) => {
717
- if (e.key === 'Enter' && textInput.value.trim()) {
718
- const input = textInput.value.trim();
719
- addMessage('user', `Add ${input}`);
720
- conversation.push({ role: 'user', message: `Add ${input}` });
721
- handleAddItem(`add ${input}`);
722
- textInput.value = '';
723
  }
724
  });
725
- selectionBox.appendChild(textInput);
726
-
727
- if (selectedItems.length > 0) {
728
- const quantityInput = document.createElement('input');
729
- quantityInput.type = 'number';
730
- quantityInput.min = '1';
731
- quantityInput.value = '1';
732
- quantityInput.placeholder = 'Qty';
733
- quantityInput.className = 'quantity-input';
734
- selectionBox.appendChild(quantityInput);
735
-
736
- const submitButton = document.createElement('button');
737
- submitButton.textContent = 'Submit';
738
- submitButton.className = 'submit-button';
739
- submitButton.onclick = () => promptAndSubmit(quantityInput.value);
740
- selectionBox.appendChild(submitButton);
741
-
742
- const orderNameInput = document.createElement('input');
743
- orderNameInput.type = 'text';
744
- orderNameInput.placeholder = 'Order Name';
745
- orderNameInput.className = 'order-name-input';
746
- selectionBox.appendChild(orderNameInput);
747
- }
748
 
749
  chatMessages.appendChild(selectionBox);
750
  chatMessages.scrollTop = chatMessages.scrollHeight;
751
- console.log('Updated selection box:', selectedItems.map(item => ({ name: item.name, category: item.category })));
752
  }
753
 
754
- function fetchMenuItems(dietaryPreference = '', searchTerm = '') {
755
- const payload = {};
756
- if (dietaryPreference) payload.dietary_preference = dietaryPreference;
757
- if (searchTerm) payload.search_term = searchTerm;
758
- fetch('/get_menu_items', {
759
- method: 'POST',
760
- headers: { 'Content-Type': 'application/json' },
761
- body: JSON.stringify(payload)
762
- })
763
- .then(response => response.json())
764
- .then(data => {
765
- if (data.error) {
766
- addMessage('bot', `Error: ${data.error}. Try again!`);
767
- } else if (data.menu_items.length > 0) {
768
- addMessage('bot', `--- Found ${data.menu_items.length} item${data.menu_items.length > 1 ? 's' : ''} ---`);
769
- displayItemsList(data.menu_items);
770
- } else {
771
- addMessage('bot', `No matches for "${searchTerm || dietaryPreference}". Try "paneer"!`);
772
- }
773
- console.log(`Fetched items for ${searchTerm || dietaryPreference}:`, data.menu_items);
774
- })
775
- .catch(error => {
776
- addMessage('bot', `Connection issue: ${error.message}. Retrying...`);
777
- setTimeout(() => fetchMenuItems(dietaryPreference, searchTerm), 2000);
778
- });
779
- }
780
-
781
- function fetchSectorItemDetails(itemName) {
782
  fetch('/get_sector_item_details', {
783
  method: 'POST',
784
  headers: { 'Content-Type': 'application/json' },
785
- body: JSON.stringify({ item_name: itemName })
786
  })
787
  .then(response => response.json())
788
  .then(data => {
789
  if (data.error) {
790
- addMessage('bot', `No "${itemName}" found. Try another!`);
791
  } else {
792
- const details = data.item_details;
793
- if (selectedItems.some(item => item.name === details.name && !item.custom)) {
794
- addMessage('bot', `"${details.name}" already selected!`);
795
- } else {
796
- selectedItems.push({ ...details, quantity: 1 });
797
- addMessage('bot', `Added "${details.name}"!`);
798
- updateSelectionBox();
799
- }
800
  }
801
  })
802
  .catch(error => {
803
- addMessage('bot', `Error for "${itemName}". Retrying...`);
804
- setTimeout(() => fetchSectorItemDetails(itemName), 2000);
805
  });
806
  }
807
 
808
- function toggleDescription(itemContainer, description, itemName) {
809
- let descElement = itemContainer.querySelector('.item-description');
810
- if (!descElement) {
811
- descElement = document.createElement('p');
812
- descElement.className = 'item-description';
813
- descElement.textContent = description;
814
- itemContainer.querySelector('.selected-item-content').appendChild(descElement);
815
- itemContainer.dataset.hidden = 'false';
816
- console.log(`Showed description for ${itemName}`);
817
- } else {
818
- descElement.remove();
819
- itemContainer.dataset.hidden = 'true';
820
- console.log(`Hid description for ${itemName}`);
821
- }
822
- }
823
-
824
- function displayItemsList(items) {
825
- const chatMessages = document.getElementById('chatMessages');
826
- if (!chatMessages) {
827
- console.error('Chat messages container not found!');
828
- addMessage('bot', 'Display issue. Try again?');
829
- return;
830
- }
831
-
832
- const itemsGrid = document.createElement('div');
833
- itemsGrid.className = 'items-grid';
834
-
835
- items.forEach(item => {
836
- const itemDiv = document.createElement('div');
837
- itemDiv.className = 'item-card';
838
-
839
- const img = document.createElement('img');
840
- img.src = item.image_url || 'https://via.placeholder.com/60';
841
- img.alt = item.name;
842
- img.className = 'item-image';
843
- itemDiv.appendChild(img);
844
-
845
- const contentDiv = document.createElement('div');
846
- contentDiv.className = 'item-content';
847
-
848
- const nameDiv = document.createElement('div');
849
- nameDiv.textContent = item.name;
850
- nameDiv.className = 'item-name';
851
- contentDiv.appendChild(nameDiv);
852
-
853
- const fields = [
854
- { label: 'Price', value: item.price ? `$${item.price.toFixed(2)}` : 'N/A' },
855
- { label: 'Veg/Non-Veg', value: item.veg_nonveg },
856
- { label: 'Spice', value: item.spice_levels },
857
- { label: 'Category', value: item.category },
858
- { label: 'Ingredients', value: item.ingredients },
859
- { label: 'Nutrition', value: item.nutritional_info },
860
- { label: 'Sector', value: item.sector },
861
- { label: 'Dynamic', value: item.dynamic_dish ? 'Yes' : 'No' }
862
- ];
863
- fields.forEach(field => {
864
- if (field.value) {
865
- const p = document.createElement('p');
866
- p.className = 'item-field';
867
- p.innerHTML = `<strong>${field.label}:</strong> ${field.value}`;
868
- contentDiv.appendChild(p);
869
- }
870
- });
871
-
872
- itemDiv.appendChild(contentDiv);
873
-
874
- const buttonContainer = document.createElement('div');
875
- buttonContainer.className = 'button-container';
876
-
877
- const addButton = document.createElement('button');
878
- addButton.textContent = 'Add';
879
- addButton.className = 'add-button';
880
- addButton.onclick = () => {
881
- const selectedItem = {
882
- name: item.name,
883
- image_url: item.image_url || '',
884
- category: item.category || 'Not specified',
885
- description: item.description || 'No description available',
886
- source: item.source,
887
- quantity: 1,
888
- ingredients: item.ingredients,
889
- nutritional_info: item.nutritional_info,
890
- price: item.price,
891
- sector: item.sector,
892
- spice_levels: item.spice_levels,
893
- veg_nonveg: item.veg_nonveg,
894
- dynamic_dish: item.dynamic_dish
895
- };
896
- if (selectedItems.some(existing => existing.name === selectedItem.name && !existing.custom)) {
897
- addMessage('bot', `"${selectedItem.name}" already selected!`);
898
- } else {
899
- selectedItems.push(selectedItem);
900
- addMessage('bot', `Added "${selectedItem.name}"!`);
901
- updateSelectionBox();
902
- }
903
- };
904
- buttonContainer.appendChild(addButton);
905
-
906
- itemDiv.appendChild(buttonContainer);
907
- itemsGrid.appendChild(itemDiv);
908
- });
909
-
910
- chatMessages.appendChild(itemsGrid);
911
- chatMessages.scrollTop = chatMessages.scrollHeight;
912
- }
913
-
914
- function displayOptions(options) {
915
- const chatMessages = document.getElementById('chatMessages');
916
- if (!chatMessages) {
917
- console.error('Chat messages container not found!');
918
  return;
919
  }
920
- const optionsDiv = document.createElement('div');
921
- optionsDiv.className = 'options-container';
922
-
923
- options.forEach(opt => {
924
- const button = document.createElement('button');
925
- button.textContent = opt.text;
926
- button.className = `option-button ${opt.class}`;
927
- button.onclick = () => {
928
- addMessage('user', opt.text);
929
- conversation.push({ role: 'user', message: opt.text });
930
- selectionBoxVisible = true;
931
- handleResponse(opt.text);
932
- updateSelectionBox();
933
- };
934
- optionsDiv.appendChild(button);
935
- });
936
 
937
- const backButton = document.createElement('button');
938
- backButton.textContent = 'Back';
939
- backButton.className = 'option-button';
940
- backButton.onclick = () => resetConversation();
941
- optionsDiv.appendChild(backButton);
942
-
943
- chatMessages.appendChild(optionsDiv);
944
- }
945
-
946
- function promptAndSubmit(quantity) {
947
- const orderNameInput = document.querySelector('.order-name-input');
948
- const customOrderName = orderNameInput ? orderNameInput.value.trim() : '';
949
- if (confirm(`Submit ${selectedItems.length} items (Qty: ${quantity})?`)) {
950
- submitToSalesforce(customOrderName, quantity);
951
- } else {
952
- addMessage('bot', 'Cancelled. Add more items?');
953
- }
954
- }
955
-
956
- function submitToSalesforce(customOrderName, quantity) {
957
- if (selectedItems.length === 0) {
958
- addMessage('bot', 'No items selected! Add some dishes! 😊');
959
- return;
960
- }
961
-
962
- const itemsToSubmit = selectedItems.map(item => ({
963
- name: item.name,
964
- category: item.category || 'Not specified',
965
- description: item.description || 'No description available',
966
- image_url: item.image_url || '',
967
- quantity: parseInt(quantity) || 1
968
- }));
969
 
970
  fetch('/submit_items', {
971
  method: 'POST',
972
  headers: { 'Content-Type': 'application/json' },
973
- body: JSON.stringify({ items: itemsToSubmit, custom_order_name: customOrderName })
974
  })
975
  .then(response => response.json())
976
  .then(data => {
@@ -978,36 +473,18 @@
978
  addMessage('bot', `Submission failed: ${data.error}. Try again?`);
979
  } else {
980
  addMessage('bot', `Submitted ${data.ingredient_name}! What's next?`);
981
- selectedItems = [];
 
 
982
  updateSelectionBox();
983
  }
984
  })
985
  .catch(error => {
986
  addMessage('bot', `Submission error: ${error.message}. Retrying...`);
987
- setTimeout(() => submitToSalesforce(customOrderName, quantity), 2000);
988
  });
989
  }
990
 
991
- function resetConversation() {
992
- const userName = conversation.length > 1 ? conversation[1].message : 'Friend';
993
- conversation = [
994
- { role: 'bot', message: `Hello! I’m Chef Bot, your culinary assistant! What’s your name?` },
995
- { role: 'user', message: userName },
996
- { role: 'bot', message: `Hi ${userName}! 🍳 Search for a dish or choose a preference below!` }
997
- ];
998
- selectedItems = [];
999
- selectionBoxVisible = true;
1000
- const chatMessages = document.getElementById('chatMessages');
1001
- chatMessages.innerHTML = '';
1002
- conversation.forEach(msg => addMessage(msg.role, msg.message));
1003
- displayOptions([
1004
- { text: 'Vegetarian', class: 'green' },
1005
- { text: 'Non-Vegetarian', class: 'red' },
1006
- { text: 'Both', class: 'gray' }
1007
- ]);
1008
- updateSelectionBox();
1009
- }
1010
-
1011
  document.getElementById('userInput').addEventListener('keypress', (e) => {
1012
  if (e.key === 'Enter') sendMessage();
1013
  });
 
103
  background-color: #f57c00;
104
  }
105
 
106
+ .item-box {
 
 
 
 
 
 
 
 
 
 
 
 
 
107
  background-color: white;
108
  border: 1px solid #ddd;
109
  border-radius: 6px;
110
  padding: 8px;
111
+ margin: 5px 0;
112
+ max-width: 200px;
113
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
114
  }
115
 
 
 
 
 
116
  .item-image {
117
  width: 100%;
118
  height: 100px;
 
121
  margin-bottom: 5px;
122
  }
123
 
 
 
 
 
124
  .item-name {
125
  font-size: 12px;
126
  font-weight: bold;
 
128
  margin-bottom: 3px;
129
  }
130
 
131
+ .add-button, .submit-button {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
132
  padding: 4px;
133
  background-color: #4caf50;
134
  color: white;
 
136
  border-radius: 5px;
137
  cursor: pointer;
138
  font-size: 10px;
139
+ width: 100%;
140
+ margin-top: 5px;
141
  }
142
 
143
+ .add-button:active, .submit-button:active {
144
  background-color: #45a049;
145
  }
146
 
 
165
 
166
  .option-button.green { background-color: #4caf50; }
167
  .option-button.red { background-color: #d32f2f; }
 
168
  .option-button:active { opacity: 0.9; }
169
 
170
  .selection-box {
 
180
  gap: 5px;
181
  }
182
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
183
  .manual-input {
184
  padding: 4px;
185
  border: 1px solid #0288d1;
 
188
  width: 100px;
189
  }
190
 
191
+ .order-name-input {
192
  padding: 4px;
193
  border: 1px solid #0288d1;
194
  border-radius: 5px;
195
  font-size: 12px;
196
+ width: 100px;
197
  }
198
 
199
+ .customized-item {
200
+ background-color: #bbdefb;
201
+ padding: 8px;
202
  border-radius: 5px;
203
+ margin: 5px 0;
204
  font-size: 12px;
 
205
  }
206
 
207
  @media (max-width: 480px) {
208
+ .chat-header { font-size: 14px; padding: 6px; }
209
+ .chat-messages { padding: 3px; }
210
+ .bot-message, .user-message { font-size: 11px; padding: 6px; margin: 3px 0; }
211
+ .chat-input input { font-size: 11px; min-height: 30px; padding: 5px; }
212
+ .chat-input button { font-size: 11px; min-height: 30px; padding: 5px 8px; min-width: 50px; }
213
+ .item-box { max-width: 150px; }
214
+ .item-image { height: 80px; }
215
+ .item-name { font-size: 10px; }
216
+ .add-button, .submit-button { font-size: 9px; }
217
+ .option-button { font-size: 11px; padding: 5px 8px; min-width: 50px; }
218
+ .selection-box { padding: 6px; gap: 3px; }
219
+ .manual-input, .order-name-input { width: 80px; font-size: 11px; padding: 3px; }
220
+ .customized-item { font-size: 11px; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
221
  }
222
  </style>
223
  </head>
 
227
  <div class="chat-messages" id="chatMessages">
228
  <div class="bot-message">Hello! I’m Chef Bot, your culinary assistant! What’s your name?</div>
229
  </div>
 
 
230
  <div class="chat-input">
231
  <input type="text" id="userInput" placeholder="Type here (e.g., paneer, chicken)...">
232
  <button onclick="sendMessage()">Send</button>
 
237
  let conversation = [
238
  { role: 'bot', message: 'Hello! I’m Chef Bot, your culinary assistant! What’s your name?' }
239
  ];
240
+ let selectedItem = null;
241
+ let customIngredients = [];
242
  let selectionBoxVisible = false;
243
 
244
  function addMessage(role, message) {
245
  const chatMessages = document.getElementById('chatMessages');
246
+ if (!chatMessages) return;
 
 
 
247
  const messageDiv = document.createElement('div');
248
  messageDiv.className = role === 'bot' ? 'bot-message' : 'user-message';
249
  messageDiv.textContent = message;
250
  chatMessages.appendChild(messageDiv);
251
  chatMessages.scrollTop = chatMessages.scrollHeight;
 
252
  }
253
 
254
  function sendMessage() {
255
  const userInput = document.getElementById('userInput');
256
+ if (!userInput) return;
 
 
 
257
  const message = userInput.value.trim();
258
  if (message) {
259
  addMessage('user', message);
260
+ conversation.push({ role: 'user', message });
261
  selectionBoxVisible = true;
262
  handleResponse(message);
263
  } else {
 
269
 
270
  function handleResponse(userInput) {
271
  const lowerInput = userInput.toLowerCase();
 
 
272
  if (conversation.length === 2) {
273
+ addMessage('bot', `Hi ${userInput}! 🍳 Choose a dish or preference below!`);
274
  displayOptions([
275
  { text: 'Vegetarian', class: 'green' },
276
+ { text: 'Non-Vegetarian', class: 'red' }
 
277
  ]);
278
+ } else if (lowerInput === 'vegetarian' || lowerInput === 'non-vegetarian') {
279
+ addMessage('bot', `Fetching ${lowerInput} dish...`);
280
+ fetchMenuItem(lowerInput);
 
 
 
 
281
  } else {
282
+ addMessage('bot', `Looking for "${userInput}"...`);
283
+ fetchMenuItem(null, userInput);
 
284
  }
285
  }
286
 
287
+ function displayOptions(options) {
288
+ const chatMessages = document.getElementById('chatMessages');
289
+ if (!chatMessages) return;
290
+ const optionsDiv = document.createElement('div');
291
+ optionsDiv.className = 'options-container';
292
+ options.forEach(opt => {
293
+ const button = document.createElement('button');
294
+ button.textContent = opt.text;
295
+ button.className = `option-button ${opt.class}`;
296
+ button.onclick = () => {
297
+ addMessage('user', opt.text);
298
+ conversation.push({ role: 'user', message: opt.text });
299
+ handleResponse(opt.text);
300
+ };
301
+ optionsDiv.appendChild(button);
302
+ });
303
+ chatMessages.appendChild(optionsDiv);
304
+ }
305
+
306
+ function fetchMenuItem(dietaryPreference = '', searchTerm = '') {
307
+ const payload = {};
308
+ if (dietaryPreference) payload.dietary_preference = dietaryPreference;
309
+ if (searchTerm) payload.search_term = searchTerm;
310
+ fetch('/get_menu_items', {
311
  method: 'POST',
312
  headers: { 'Content-Type': 'application/json' },
313
+ body: JSON.stringify(payload)
314
  })
315
  .then(response => response.json())
316
  .then(data => {
317
  if (data.error) {
318
+ addMessage('bot', `Error: ${data.error}. Try again!`);
319
+ } else if (data.menu_items.length > 0) {
320
+ selectedItem = data.menu_items[0]; // Select the first item
321
+ addMessage('bot', `Found "${selectedItem.name}"!`);
322
+ displayItemBox(selectedItem);
 
 
 
 
 
 
 
 
 
323
  } else {
324
+ addMessage('bot', `No matches for "${searchTerm || dietaryPreference}". Try "paneer"!`);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
325
  }
 
326
  })
327
  .catch(error => {
328
+ addMessage('bot', `Connection issue: ${error.message}. Retrying...`);
329
+ setTimeout(() => fetchMenuItem(dietaryPreference, searchTerm), 2000);
330
  });
331
  }
332
 
333
+ function displayItemBox(item) {
334
+ const chatMessages = document.getElementById('chatMessages');
335
+ if (!chatMessages) return;
336
+ const itemBox = document.createElement('div');
337
+ itemBox.className = 'item-box';
338
+
339
+ const img = document.createElement('img');
340
+ img.src = item.image_url || 'https://via.placeholder.com/100';
341
+ img.alt = item.name;
342
+ img.className = 'item-image';
343
+ itemBox.appendChild(img);
344
+
345
+ const nameDiv = document.createElement('div');
346
+ nameDiv.className = 'item-name';
347
+ nameDiv.textContent = item.name;
348
+ itemBox.appendChild(nameDiv);
349
+
350
+ const addButton = document.createElement('button');
351
+ addButton.className = 'add-button';
352
+ addButton.textContent = 'Select';
353
+ addButton.onclick = () => {
354
+ addMessage('bot', `Selected "${item.name}". Add custom ingredients or submit!`);
355
+ updateSelectionBox();
356
+ };
357
+ itemBox.appendChild(addButton);
358
+
359
+ chatMessages.appendChild(itemBox);
360
+ chatMessages.scrollTop = chatMessages.scrollHeight;
361
+ }
362
+
363
  function updateSelectionBox() {
364
  const chatMessages = document.getElementById('chatMessages');
365
  if (!chatMessages) return;
 
367
  const existingBox = document.querySelector('.selection-box');
368
  if (existingBox) existingBox.remove();
369
 
370
+ if (!selectionBoxVisible || !selectedItem) return;
371
 
372
  const selectionBox = document.createElement('div');
373
  selectionBox.className = 'selection-box';
374
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
375
  const label = document.createElement('span');
376
  label.textContent = 'Selected:';
377
  selectionBox.appendChild(label);
378
 
379
+ // Display original item
380
+ const originalItemDiv = document.createElement('div');
381
+ originalItemDiv.className = 'customized-item';
382
+ originalItemDiv.textContent = `Original: ${selectedItem.name}`;
383
+ selectionBox.appendChild(originalItemDiv);
384
+
385
+ // Display customized item with ingredients
386
+ if (customIngredients.length > 0) {
387
+ const customItemDiv = document.createElement('div');
388
+ customItemDiv.className = 'customized-item';
389
+ customItemDiv.textContent = `Customized: ${selectedItem.name} with ${customIngredients.join(', ')}`;
390
+ selectionBox.appendChild(customItemDiv);
391
+ }
392
+
393
+ // Input for custom ingredients
394
+ const ingredientInput = document.createElement('input');
395
+ ingredientInput.type = 'text';
396
+ ingredientInput.placeholder = 'Add ingredient (e.g., onion)';
397
+ ingredientInput.className = 'manual-input';
398
+ ingredientInput.addEventListener('keypress', (e) => {
399
+ if (e.key === 'Enter' && ingredientInput.value.trim()) {
400
+ const ingredient = ingredientInput.value.trim();
401
+ fetchIngredient(ingredient);
402
+ ingredientInput.value = '';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
403
  }
404
  });
405
+ selectionBox.appendChild(ingredientInput);
406
+
407
+ // Order name input
408
+ const orderNameInput = document.createElement('input');
409
+ orderNameInput.type = 'text';
410
+ orderNameInput.placeholder = 'Order Name';
411
+ orderNameInput.className = 'order-name-input';
412
+ selectionBox.appendChild(orderNameInput);
413
+
414
+ // Submit button
415
+ const submitButton = document.createElement('button');
416
+ submitButton.className = 'submit-button';
417
+ submitButton.textContent = 'Submit';
418
+ submitButton.onclick = () => {
419
+ const customOrderName = orderNameInput.value.trim();
420
+ submitToSalesforce(customOrderName);
421
+ };
422
+ selectionBox.appendChild(submitButton);
 
 
 
 
 
423
 
424
  chatMessages.appendChild(selectionBox);
425
  chatMessages.scrollTop = chatMessages.scrollHeight;
 
426
  }
427
 
428
+ function fetchIngredient(ingredientName) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
429
  fetch('/get_sector_item_details', {
430
  method: 'POST',
431
  headers: { 'Content-Type': 'application/json' },
432
+ body: JSON.stringify({ item_name: ingredientName })
433
  })
434
  .then(response => response.json())
435
  .then(data => {
436
  if (data.error) {
437
+ addMessage('bot', `Ingredient "${ingredientName}" not found. Try another!`);
438
  } else {
439
+ customIngredients.push(data.item_details.name);
440
+ addMessage('bot', `Added ingredient "${data.item_details.name}" to "${selectedItem.name}"!`);
441
+ updateSelectionBox();
 
 
 
 
 
442
  }
443
  })
444
  .catch(error => {
445
+ addMessage('bot', `Error fetching "${ingredientName}". Retrying...`);
446
+ setTimeout(() => fetchIngredient(ingredientName), 2000);
447
  });
448
  }
449
 
450
+ function submitToSalesforce(customOrderName) {
451
+ if (!selectedItem) {
452
+ addMessage('bot', 'No item selected! Please select a dish! 😊');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
453
  return;
454
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
455
 
456
+ const order = {
457
+ name: selectedItem.name,
458
+ category: selectedItem.category || 'Not specified',
459
+ description: selectedItem.description || 'No description available',
460
+ image_url: selectedItem.image_url || '',
461
+ custom_ingredients: customIngredients,
462
+ quantity: 1
463
+ };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
464
 
465
  fetch('/submit_items', {
466
  method: 'POST',
467
  headers: { 'Content-Type': 'application/json' },
468
+ body: JSON.stringify({ items: [order], custom_order_name: customOrderName })
469
  })
470
  .then(response => response.json())
471
  .then(data => {
 
473
  addMessage('bot', `Submission failed: ${data.error}. Try again?`);
474
  } else {
475
  addMessage('bot', `Submitted ${data.ingredient_name}! What's next?`);
476
+ selectedItem = null;
477
+ customIngredients = [];
478
+ selectionBoxVisible = false;
479
  updateSelectionBox();
480
  }
481
  })
482
  .catch(error => {
483
  addMessage('bot', `Submission error: ${error.message}. Retrying...`);
484
+ setTimeout(() => submitToSalesforce(customOrderName), 2000);
485
  });
486
  }
487
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
488
  document.getElementById('userInput').addEventListener('keypress', (e) => {
489
  if (e.key === 'Enter') sendMessage();
490
  });