lokesh341 commited on
Commit
edc8acc
·
verified ·
1 Parent(s): 0d2fb64

Update templates/chef-bot.html

Browse files
Files changed (1) hide show
  1. templates/chef-bot.html +722 -172
templates/chef-bot.html CHANGED
@@ -103,16 +103,31 @@
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,6 +136,10 @@
121
  margin-bottom: 5px;
122
  }
123
 
 
 
 
 
124
  .item-name {
125
  font-size: 12px;
126
  font-weight: bold;
@@ -128,7 +147,45 @@
128
  margin-bottom: 3px;
129
  }
130
 
131
- .add-button, .submit-button {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
132
  padding: 4px;
133
  background-color: #4caf50;
134
  color: white;
@@ -136,11 +193,11 @@
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,6 +222,7 @@
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,6 +238,60 @@
180
  gap: 5px;
181
  }
182
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
183
  .manual-input {
184
  padding: 4px;
185
  border: 1px solid #0288d1;
@@ -188,36 +300,199 @@
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,6 +502,8 @@
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,27 +514,33 @@
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,41 +552,214 @@
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;
@@ -317,155 +773,231 @@
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;
 
 
 
 
366
 
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,18 +1005,36 @@
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
  });
 
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
  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
  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
  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
 
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
  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
  width: 100px;
301
  }
302
 
303
+ .ingredient-input {
304
  padding: 4px;
305
  border: 1px solid #0288d1;
306
  border-radius: 5px;
307
  font-size: 12px;
308
  width: 100px;
309
+ margin-left: 5px;
310
  }
311
 
312
+ .quantity-input {
313
+ padding: 4px;
314
+ border: 1px solid #0288d1;
315
  border-radius: 5px;
 
316
  font-size: 12px;
317
+ width: 50px;
318
+ }
319
+
320
+ .order-name-input {
321
+ padding: 4px;
322
+ border: 1px solid #0288d1;
323
+ border-radius: 5px;
324
+ font-size: 12px;
325
+ width: 100px;
326
  }
327
 
328
  @media (max-width: 480px) {
329
+ .chat-header {
330
+ font-size: 14px;
331
+ padding: 6px;
332
+ }
333
+ .chat-messages {
334
+ padding: 3px;
335
+ }
336
+ .bot-message, .user-message {
337
+ font-size: 11px;
338
+ padding: 6px;
339
+ margin: 3px 0;
340
+ }
341
+ .chat-input input {
342
+ font-size: 11px;
343
+ min-height: 30px;
344
+ padding: 5px;
345
+ }
346
+ .chat-input button {
347
+ font-size: 11px;
348
+ min-height: 30px;
349
+ padding: 5px 8px;
350
+ min-width: 50px;
351
+ }
352
+ .items-grid {
353
+ flex-direction: column;
354
+ overflow-x: hidden;
355
+ gap: 6px;
356
+ padding: 6px;
357
+ }
358
+ .item-card {
359
+ width: 100%;
360
+ flex: 0 0 auto;
361
+ max-width: 120px;
362
+ }
363
+ .item-image {
364
+ height: 80px;
365
+ }
366
+ .item-name {
367
+ font-size: 10px;
368
+ }
369
+ .item-field, .item-description {
370
+ font-size: 9px;
371
+ }
372
+ .show-button, .add-button {
373
+ font-size: 9px;
374
+ padding: 3px;
375
+ min-width: 35px;
376
+ }
377
+ .options-container {
378
+ gap: 3px;
379
+ }
380
+ .option-button {
381
+ font-size: 11px;
382
+ padding: 5px 8px;
383
+ min-width: 50px;
384
+ }
385
+ .selection-box {
386
+ padding: 6px;
387
+ gap: 3px;
388
+ }
389
+ .selection-box span {
390
+ font-size: 11px;
391
+ padding: 2px 6px;
392
+ }
393
+ .selected-item {
394
+ font-size: 10px;
395
+ padding: 2px 6px;
396
+ }
397
+ .selected-item-image {
398
+ width: 20px;
399
+ height: 20px;
400
+ }
401
+ .submit-button {
402
+ font-size: 11px;
403
+ padding: 5px 8px;
404
+ min-width: 50px;
405
+ }
406
+ .remove-button {
407
+ font-size: 9px;
408
+ padding: 2px 5px;
409
+ }
410
+ .manual-input, .order-name-input, .ingredient-input {
411
+ width: 80px;
412
+ font-size: 11px;
413
+ padding: 3px;
414
+ }
415
+ .quantity-input {
416
+ width: 40px;
417
+ font-size: 11px;
418
+ padding: 3px;
419
+ }
420
+ }
421
+
422
+ @media (min-width: 481px) and (max-width: 768px) {
423
+ .chat-header {
424
+ font-size: 15px;
425
+ }
426
+ .chat-messages {
427
+ padding: 4px;
428
+ }
429
+ .bot-message, .user-message {
430
+ font-size: 12px;
431
+ padding: 7px;
432
+ }
433
+ .chat-input input {
434
+ font-size: 12px;
435
+ min-height: 35px;
436
+ }
437
+ .chat-input button {
438
+ font-size: 12px;
439
+ min-height: 35px;
440
+ padding: 6px 10px;
441
+ }
442
+ .items-grid {
443
+ gap: 8px;
444
+ }
445
+ .item-card {
446
+ flex: 0 0 140px;
447
+ }
448
+ .item-image {
449
+ height: 90px;
450
+ }
451
+ .item-name {
452
+ font-size: 11px;
453
+ }
454
+ .item-field, .item-description {
455
+ font-size: 10px;
456
+ }
457
+ .show-button, .add-button {
458
+ font-size: 10px;
459
+ padding: 4px;
460
+ min-width: 40px;
461
+ }
462
+ .option-button {
463
+ font-size: 12px;
464
+ padding: 6px 10px;
465
+ }
466
+ .selection-box {
467
+ padding: 8px;
468
+ gap: 5px;
469
+ }
470
+ .selection-box span {
471
+ font-size: 12px;
472
+ }
473
+ .selected-item {
474
+ font-size: 11px;
475
+ }
476
+ .selected-item-image {
477
+ width: 25px;
478
+ height: 25px;
479
+ }
480
+ .submit-button {
481
+ font-size: 12px;
482
+ padding: 6px 10px;
483
+ }
484
+ .remove-button {
485
+ font-size: 10px;
486
+ padding: 3px 6px;
487
+ }
488
+ .manual-input, .order-name-input, .ingredient-input {
489
+ width: 100px;
490
+ font-size: 12px;
491
+ }
492
+ .quantity-input {
493
+ width: 50px;
494
+ font-size: 12px;
495
+ }
496
  }
497
  </style>
498
  </head>
 
502
  <div class="chat-messages" id="chatMessages">
503
  <div class="bot-message">Hello! I’m Chef Bot, your culinary assistant! What’s your name?</div>
504
  </div>
505
+ <div class="suggestions-list" id="suggestionsList"></div>
506
+ <div class="ingredients-list" id="menuItemsList"></div>
507
  <div class="chat-input">
508
  <input type="text" id="userInput" placeholder="Type here (e.g., paneer, chicken)...">
509
  <button onclick="sendMessage()">Send</button>
 
514
  let conversation = [
515
  { role: 'bot', message: 'Hello! I’m Chef Bot, your culinary assistant! What’s your name?' }
516
  ];
517
+ let selectedItems = [];
 
518
  let selectionBoxVisible = false;
519
 
520
  function addMessage(role, message) {
521
  const chatMessages = document.getElementById('chatMessages');
522
+ if (!chatMessages) {
523
+ console.error('Chat messages container not found!');
524
+ return;
525
+ }
526
  const messageDiv = document.createElement('div');
527
  messageDiv.className = role === 'bot' ? 'bot-message' : 'user-message';
528
  messageDiv.textContent = message;
529
  chatMessages.appendChild(messageDiv);
530
  chatMessages.scrollTop = chatMessages.scrollHeight;
531
+ console.log(`Added ${role} message: ${message}`);
532
  }
533
 
534
  function sendMessage() {
535
  const userInput = document.getElementById('userInput');
536
+ if (!userInput) {
537
+ console.error('User input field not found!');
538
+ return;
539
+ }
540
  const message = userInput.value.trim();
541
  if (message) {
542
  addMessage('user', message);
543
+ conversation.push({ role: 'user', message: message });
544
  selectionBoxVisible = true;
545
  handleResponse(message);
546
  } else {
 
552
 
553
  function handleResponse(userInput) {
554
  const lowerInput = userInput.toLowerCase();
555
+ let botResponse = '';
556
+
557
  if (conversation.length === 2) {
558
+ botResponse = `Hi ${userInput}! 🍳 Search for a dish or choose a preference below!`;
559
  displayOptions([
560
  { text: 'Vegetarian', class: 'green' },
561
+ { text: 'Non-Vegetarian', class: 'red' },
562
+ { text: 'Both', class: 'gray' }
563
  ]);
564
+ addMessage('bot', botResponse);
565
+ } else if (lowerInput === 'vegetarian' || lowerInput === 'non-vegetarian' || lowerInput === 'both') {
566
+ botResponse = `Fetching ${lowerInput} dishes...`;
567
+ addMessage('bot', botResponse);
568
+ fetchMenuItems(lowerInput);
569
  } else {
570
+ botResponse = `Looking for "${userInput}"...`;
571
+ addMessage('bot', botResponse);
572
+ fetchMenuItems(null, userInput);
573
  }
574
  }
575
 
576
+ function updateSelectionBox() {
577
  const chatMessages = document.getElementById('chatMessages');
578
  if (!chatMessages) return;
579
+
580
+ const existingBox = document.querySelector('.selection-box');
581
+ if (existingBox) existingBox.remove();
582
+
583
+ if (!selectionBoxVisible && selectedItems.length === 0) return;
584
+
585
+ const selectionBox = document.createElement('div');
586
+ selectionBox.className = 'selection-box';
587
+
588
+ const vegButton = document.createElement('button');
589
+ vegButton.textContent = 'Veg';
590
+ vegButton.className = 'dietary-button green';
591
+ vegButton.onclick = () => {
592
+ addMessage('user', 'Vegetarian');
593
+ conversation.push({ role: 'user', message: 'Vegetarian' });
594
+ handleResponse('vegetarian');
595
+ };
596
+ selectionBox.appendChild(vegButton);
597
+
598
+ const nonVegButton = document.createElement('button');
599
+ nonVegButton.textContent = 'Non-Veg';
600
+ nonVegButton.className = 'dietary-button red';
601
+ nonVegButton.onclick = () => {
602
+ addMessage('user', 'Non-Vegetarian');
603
+ conversation.push({ role: 'user', message: 'Non-Vegetarian' });
604
+ handleResponse('non-vegetarian');
605
+ };
606
+ selectionBox.appendChild(nonVegButton);
607
+
608
+ const bothButton = document.createElement('button');
609
+ bothButton.textContent = 'Both';
610
+ bothButton.className = 'dietary-button gray';
611
+ bothButton.onclick = () => {
612
+ addMessage('user', 'Both');
613
+ conversation.push({ role: 'user', message: 'Both' });
614
+ handleResponse('both');
615
+ };
616
+ selectionBox.appendChild(bothButton);
617
+
618
+ const label = document.createElement('span');
619
+ label.textContent = 'Selected:';
620
+ selectionBox.appendChild(label);
621
+
622
+ selectedItems.forEach((item, index) => {
623
+ const itemContainer = document.createElement('div');
624
+ itemContainer.className = 'selected-item';
625
+ itemContainer.dataset.hidden = item.source === 'Sector_Detail__c' ? 'true' : 'false';
626
+
627
+ const img = document.createElement('img');
628
+ img.src = item.image_url || 'https://via.placeholder.com/30';
629
+ img.alt = item.name;
630
+ img.className = 'selected-item-image';
631
+ itemContainer.appendChild(img);
632
+
633
+ const contentDiv = document.createElement('div');
634
+ contentDiv.className = 'selected-item-content';
635
+
636
+ const itemName = item.additionalIngredients && item.additionalIngredients.length > 0
637
+ ? `${item.name} with ${item.additionalIngredients.join(', ')}`
638
+ : item.name;
639
+ const itemSpan = document.createElement('span');
640
+ itemSpan.textContent = `${itemName} (Qty: ${item.quantity || 1})`;
641
+ contentDiv.appendChild(itemSpan);
642
+
643
+ if (item.source === 'Sector_Detail__c') {
644
+ const showButton = document.createElement('button');
645
+ showButton.textContent = 'Show';
646
+ showButton.className = 'show-button';
647
+ showButton.onclick = () => toggleDescription(itemContainer, item.description, itemName);
648
+ contentDiv.appendChild(showButton);
649
+ }
650
+
651
+ // Add ingredient input for customization
652
+ const ingredientInput = document.createElement('input');
653
+ ingredientInput.type = 'text';
654
+ ingredientInput.placeholder = 'Add ingredient...';
655
+ ingredientInput.className = 'ingredient-input';
656
+ ingredientInput.addEventListener('keypress', (e) => {
657
+ if (e.key === 'Enter' && ingredientInput.value.trim()) {
658
+ const ingredientName = ingredientInput.value.trim();
659
+ fetchSectorItemDetails(ingredientName, index);
660
+ ingredientInput.value = '';
661
+ }
662
+ });
663
+ contentDiv.appendChild(ingredientInput);
664
+
665
+ itemContainer.appendChild(contentDiv);
666
+
667
+ const removeButton = document.createElement('button');
668
+ removeButton.textContent = 'X';
669
+ removeButton.className = 'remove-button';
670
+ removeButton.onclick = () => {
671
+ selectedItems.splice(index, 1);
672
+ addMessage('bot', `Removed "${itemName}".`);
673
+ updateSelectionBox();
674
  };
675
+ itemContainer.appendChild(removeButton);
676
+
677
+ selectionBox.appendChild(itemContainer);
678
+
679
+ // Display original item if customized
680
+ if (item.additionalIngredients && item.additionalIngredients.length > 0) {
681
+ const originalContainer = document.createElement('div');
682
+ originalContainer.className = 'selected-item';
683
+ originalContainer.dataset.hidden = item.source === 'Sector_Detail__c' ? 'true' : 'false';
684
+
685
+ const originalImg = document.createElement('img');
686
+ originalImg.src = item.image_url || 'https://via.placeholder.com/30';
687
+ originalImg.alt = item.name;
688
+ originalImg.className = 'selected-item-image';
689
+ originalContainer.appendChild(originalImg);
690
+
691
+ const originalContentDiv = document.createElement('div');
692
+ originalContentDiv.className = 'selected-item-content';
693
+
694
+ const originalSpan = document.createElement('span');
695
+ originalSpan.textContent = `${item.name} (Qty: ${item.quantity || 1})`;
696
+ originalContentDiv.appendChild(originalSpan);
697
+
698
+ if (item.source === 'Sector_Detail__c') {
699
+ const originalShowButton = document.createElement('button');
700
+ originalShowButton.textContent = 'Show';
701
+ originalShowButton.className = 'show-button';
702
+ originalShowButton.onclick = () => toggleDescription(originalContainer, item.description, item.name);
703
+ originalContentDiv.appendChild(originalShowButton);
704
+ }
705
+
706
+ originalContainer.appendChild(originalContentDiv);
707
+
708
+ const originalRemoveButton = document.createElement('button');
709
+ originalRemoveButton.textContent = 'X';
710
+ originalRemoveButton.className = 'remove-button';
711
+ originalRemoveButton.onclick = () => {
712
+ selectedItems.splice(index, 1);
713
+ addMessage('bot', `Removed "${item.name}".`);
714
+ updateSelectionBox();
715
+ };
716
+ originalContainer.appendChild(originalRemoveButton);
717
+
718
+ selectionBox.appendChild(originalContainer);
719
+ }
720
  });
721
+
722
+ const textInput = document.createElement('input');
723
+ textInput.type = 'text';
724
+ textInput.placeholder = 'Add item...';
725
+ textInput.className = 'manual-input';
726
+ textInput.addEventListener('keypress', (e) => {
727
+ if (e.key === 'Enter' && textInput.value.trim()) {
728
+ const itemName = textInput.value.trim();
729
+ fetchSectorItemDetails(itemName);
730
+ textInput.value = '';
731
+ }
732
+ });
733
+ selectionBox.appendChild(textInput);
734
+
735
+ if (selectedItems.length > 0) {
736
+ const quantityInput = document.createElement('input');
737
+ quantityInput.type = 'number';
738
+ quantityInput.min = '1';
739
+ quantityInput.value = '1';
740
+ quantityInput.placeholder = 'Qty';
741
+ quantityInput.className = 'quantity-input';
742
+ selectionBox.appendChild(quantityInput);
743
+
744
+ const submitButton = document.createElement('button');
745
+ submitButton.textContent = 'Submit';
746
+ submitButton.className = 'submit-button';
747
+ submitButton.onclick = () => promptAndSubmit(quantityInput.value);
748
+ selectionBox.appendChild(submitButton);
749
+
750
+ const orderNameInput = document.createElement('input');
751
+ orderNameInput.type = 'text';
752
+ orderNameInput.placeholder = 'Order Name';
753
+ orderNameInput.className = 'order-name-input';
754
+ selectionBox.appendChild(orderNameInput);
755
+ }
756
+
757
+ chatMessages.appendChild(selectionBox);
758
+ chatMessages.scrollTop = chatMessages.scrollHeight;
759
+ console.log('Updated selection box:', selectedItems.map(item => ({ name: item.name, additionalIngredients: item.additionalIngredients })));
760
  }
761
 
762
+ function fetchMenuItems(dietaryPreference = '', searchTerm = '') {
763
  const payload = {};
764
  if (dietaryPreference) payload.dietary_preference = dietaryPreference;
765
  if (searchTerm) payload.search_term = searchTerm;
 
773
  if (data.error) {
774
  addMessage('bot', `Error: ${data.error}. Try again!`);
775
  } else if (data.menu_items.length > 0) {
776
+ addMessage('bot', `--- Found ${data.menu_items.length} item${data.menu_items.length > 1 ? 's' : ''} ---`);
777
+ displayItemsList(data.menu_items);
 
778
  } else {
779
  addMessage('bot', `No matches for "${searchTerm || dietaryPreference}". Try "paneer"!`);
780
  }
781
+ console.log(`Fetched items for ${searchTerm || dietaryPreference}:`, data.menu_items);
782
  })
783
  .catch(error => {
784
  addMessage('bot', `Connection issue: ${error.message}. Retrying...`);
785
+ setTimeout(() => fetchMenuItems(dietaryPreference, searchTerm), 2000);
786
  });
787
  }
788
 
789
+ function fetchSectorItemDetails(itemName, itemIndex = null) {
790
+ fetch('/get_sector_item_details', {
791
+ method: 'POST',
792
+ headers: { 'Content-Type': 'application/json' },
793
+ body: JSON.stringify({ item_name: itemName })
794
+ })
795
+ .then(response => response.json())
796
+ .then(data => {
797
+ if (data.error) {
798
+ addMessage('bot', `No "${itemName}" found. Try another!`);
799
+ } else {
800
+ const details = data.item_details;
801
+ if (itemIndex !== null) {
802
+ // Adding as an additional ingredient
803
+ if (!selectedItems[itemIndex].additionalIngredients) {
804
+ selectedItems[itemIndex].additionalIngredients = [];
805
+ }
806
+ if (!selectedItems[itemIndex].additionalIngredients.includes(details.name)) {
807
+ selectedItems[itemIndex].additionalIngredients.push(details.name);
808
+ selectedItems[itemIndex].description += `, with ${details.name}`;
809
+ addMessage('bot', `Added "${details.name}" to "${selectedItems[itemIndex].name}"!`);
810
+ } else {
811
+ addMessage('bot', `"${details.name}" already added to "${selectedItems[itemIndex].name}"!`);
812
+ }
813
+ } else {
814
+ // Adding as a new item
815
+ if (selectedItems.some(item => item.name === details.name && !item.additionalIngredients)) {
816
+ addMessage('bot', `"${details.name}" already selected!`);
817
+ } else {
818
+ selectedItems.push({ ...details, quantity: 1, additionalIngredients: [] });
819
+ addMessage('bot', `Added "${details.name}"!`);
820
+ }
821
+ }
822
+ updateSelectionBox();
823
+ }
824
+ })
825
+ .catch(error => {
826
+ addMessage('bot', `Error for "${itemName}". Retrying...`);
827
+ setTimeout(() => fetchSectorItemDetails(itemName, itemIndex), 2000);
828
+ });
829
+ }
830
 
831
+ function toggleDescription(itemContainer, description, itemName) {
832
+ let descElement = itemContainer.querySelector('.item-description');
833
+ if (!descElement) {
834
+ descElement = document.createElement('p');
835
+ descElement.className = 'item-description';
836
+ descElement.textContent = description;
837
+ itemContainer.querySelector('.selected-item-content').appendChild(descElement);
838
+ itemContainer.dataset.hidden = 'false';
839
+ console.log(`Showed description for ${itemName}`);
840
+ } else {
841
+ descElement.remove();
842
+ itemContainer.dataset.hidden = 'true';
843
+ console.log(`Hid description for ${itemName}`);
844
+ }
845
  }
846
 
847
+ function displayItemsList(items) {
848
  const chatMessages = document.getElementById('chatMessages');
849
+ if (!chatMessages) {
850
+ console.error('Chat messages container not found!');
851
+ addMessage('bot', 'Display issue. Try again?');
852
+ return;
853
+ }
854
 
855
+ const itemsGrid = document.createElement('div');
856
+ itemsGrid.className = 'items-grid';
857
 
858
+ items.forEach(item => {
859
+ const itemDiv = document.createElement('div');
860
+ itemDiv.className = 'item-card';
861
 
862
+ const img = document.createElement('img');
863
+ img.src = item.image_url || 'https://via.placeholder.com/60';
864
+ img.alt = item.name;
865
+ img.className = 'item-image';
866
+ itemDiv.appendChild(img);
867
 
868
+ const contentDiv = document.createElement('div');
869
+ contentDiv.className = 'item-content';
 
870
 
871
+ const nameDiv = document.createElement('div');
872
+ nameDiv.textContent = item.name;
873
+ nameDiv.className = 'item-name';
874
+ contentDiv.appendChild(nameDiv);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
875
 
876
+ const fields = [
877
+ { label: 'Price', value: item.price ? `$${item.price.toFixed(2)}` : 'N/A' },
878
+ { label: 'Veg/Non-Veg', value: item.veg_nonveg },
879
+ { label: 'Spice', value: item.spice_levels },
880
+ { label: 'Category', value: item.category },
881
+ { label: 'Ingredients', value: item.ingredients },
882
+ { label: 'Nutrition', value: item.nutritional_info },
883
+ { label: 'Sector', value: item.sector },
884
+ { label: 'Dynamic', value: item.dynamic_dish ? 'Yes' : 'No' }
885
+ ];
886
+ fields.forEach(field => {
887
+ if (field.value) {
888
+ const p = document.createElement('p');
889
+ p.className = 'item-field';
890
+ p.innerHTML = `<strong>${field.label}:</strong> ${field.value}`;
891
+ contentDiv.appendChild(p);
892
+ }
893
+ });
894
 
895
+ itemDiv.appendChild(contentDiv);
896
+
897
+ const buttonContainer = document.createElement('div');
898
+ buttonContainer.className = 'button-container';
899
+
900
+ const addButton = document.createElement('button');
901
+ addButton.textContent = 'Add';
902
+ addButton.className = 'add-button';
903
+ addButton.onclick = () => {
904
+ const selectedItem = {
905
+ name: item.name,
906
+ image_url: item.image_url || '',
907
+ category: item.category || 'Not specified',
908
+ description: item.description || 'No description available',
909
+ source: item.source,
910
+ quantity: 1,
911
+ ingredients: item.ingredients,
912
+ nutritional_info: item.nutritional_info,
913
+ price: item.price,
914
+ sector: item.sector,
915
+ spice_levels: item.spice_levels,
916
+ veg_nonveg: item.veg_nonveg,
917
+ dynamic_dish: item.dynamic_dish,
918
+ additionalIngredients: []
919
+ };
920
+ if (selectedItems.some(existing => existing.name === selectedItem.name && !existing.additionalIngredients)) {
921
+ addMessage('bot', `"${selectedItem.name}" already selected!`);
922
  } else {
923
+ selectedItems.push(selectedItem);
924
+ addMessage('bot', `Added "${selectedItem.name}"!`);
925
  updateSelectionBox();
926
  }
927
+ };
928
+ buttonContainer.appendChild(addButton);
929
+
930
+ itemDiv.appendChild(buttonContainer);
931
+ itemsGrid.appendChild(itemDiv);
932
+ });
933
+
934
+ chatMessages.appendChild(itemsGrid);
935
+ chatMessages.scrollTop = chatMessages.scrollHeight;
936
  }
937
 
938
+ function displayOptions(options) {
939
+ const chatMessages = document.getElementById('chatMessages');
940
+ if (!chatMessages) {
941
+ console.error('Chat messages container not found!');
942
  return;
943
  }
944
+ const optionsDiv = document.createElement('div');
945
+ optionsDiv.className = 'options-container';
946
 
947
+ options.forEach(opt => {
948
+ const button = document.createElement('button');
949
+ button.textContent = opt.text;
950
+ button.className = `option-button ${opt.class}`;
951
+ button.onclick = () => {
952
+ addMessage('user', opt.text);
953
+ conversation.push({ role: 'user', message: opt.text });
954
+ selectionBoxVisible = true;
955
+ handleResponse(opt.text);
956
+ updateSelectionBox();
957
+ };
958
+ optionsDiv.appendChild(button);
959
+ });
960
+
961
+ const backButton = document.createElement('button');
962
+ backButton.textContent = 'Back';
963
+ backButton.className = 'option-button';
964
+ backButton.onclick = () => resetConversation();
965
+ optionsDiv.appendChild(backButton);
966
+
967
+ chatMessages.appendChild(optionsDiv);
968
+ }
969
+
970
+ function promptAndSubmit(quantity) {
971
+ const orderNameInput = document.querySelector('.order-name-input');
972
+ const customOrderName = orderNameInput ? orderNameInput.value.trim() : '';
973
+ if (confirm(`Submit ${selectedItems.length} items (Qty: ${quantity})?`)) {
974
+ submitToSalesforce(customOrderName, quantity);
975
+ } else {
976
+ addMessage('bot', 'Cancelled. Add more items?');
977
+ }
978
+ }
979
+
980
+ function submitToSalesforce(customOrderName, quantity) {
981
+ if (selectedItems.length === 0) {
982
+ addMessage('bot', 'No items selected! Add some dishes! 😊');
983
+ return;
984
+ }
985
+
986
+ const itemsToSubmit = selectedItems.map(item => ({
987
+ name: item.additionalIngredients && item.additionalIngredients.length > 0
988
+ ? `${item.name} with ${item.additionalIngredients.join(', ')}`
989
+ : item.name,
990
+ category: item.category || 'Not specified',
991
+ description: item.description || 'No description available',
992
+ image_url: item.image_url || '',
993
+ quantity: parseInt(quantity) || 1,
994
+ additionalIngredients: item.additionalIngredients || []
995
+ }));
996
 
997
  fetch('/submit_items', {
998
  method: 'POST',
999
  headers: { 'Content-Type': 'application/json' },
1000
+ body: JSON.stringify({ items: itemsToSubmit, custom_order_name: customOrderName })
1001
  })
1002
  .then(response => response.json())
1003
  .then(data => {
 
1005
  addMessage('bot', `Submission failed: ${data.error}. Try again?`);
1006
  } else {
1007
  addMessage('bot', `Submitted ${data.ingredient_name}! What's next?`);
1008
+ selectedItems = [];
 
 
1009
  updateSelectionBox();
1010
  }
1011
  })
1012
  .catch(error => {
1013
  addMessage('bot', `Submission error: ${error.message}. Retrying...`);
1014
+ setTimeout(() => submitToSalesforce(customOrderName, quantity), 2000);
1015
  });
1016
  }
1017
 
1018
+ function resetConversation() {
1019
+ const userName = conversation.length > 1 ? conversation[1].message : 'Friend';
1020
+ conversation = [
1021
+ { role: 'bot', message: `Hello! I’m Chef Bot, your culinary assistant! What’s your name?` },
1022
+ { role: 'user', message: userName },
1023
+ { role: 'bot', message: `Hi ${userName}! 🍳 Search for a dish or choose a preference below!` }
1024
+ ];
1025
+ selectedItems = [];
1026
+ selectionBoxVisible = true;
1027
+ const chatMessages = document.getElementById('chatMessages');
1028
+ chatMessages.innerHTML = '';
1029
+ conversation.forEach(msg => addMessage(msg.role, msg.message));
1030
+ displayOptions([
1031
+ { text: 'Vegetarian', class: 'green' },
1032
+ { text: 'Non-Vegetarian', class: 'red' },
1033
+ { text: 'Both', class: 'gray' }
1034
+ ]);
1035
+ updateSelectionBox();
1036
+ }
1037
+
1038
  document.getElementById('userInput').addEventListener('keypress', (e) => {
1039
  if (e.key === 'Enter') sendMessage();
1040
  });