wineater-bot 3.0.4 → 3.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.html CHANGED
@@ -4,9 +4,9 @@
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>Chatbot</title>
7
- <!-- <script type="module" src="https://unpkg.com/wineater-bot@1.0.0/dist/wineater-chatbot.umd.js"></script> -->
8
- <script>window.wineaterData = {CLIENT_TOKEN: 'HeUw6IXuhvz6tRuXdPEGEbj3SGQ3Q2YtEc1Z8jd41Kg9LtyPb4Epu0to31SYIadG', position: 'right-center', TYPE: 'widget'};</script>
9
- <script type="module" src="./dist/wineater-chatbot.umd.js"></script>
7
+ <!-- <script type="module" src="./dist/wineater-chatbot.umd.js"></script> -->
8
+ <script>window.wineaterData = {CLIENT_TOKEN: 'HeUw6IXuhvz6tRuXdPEGEbj3SGQ3Q2YtEc1Z8jd41Kg9LtyPb4Epu0to31SYIadG', position: 'right-center', TYPE: 'widget', WIDGET_TYPE: 'bar'};</script>
9
+ <script type="module" src="./src/index.js"></script>
10
10
  </head>
11
11
  <body style="margin: 0;">
12
12
  <div id="wineater-widget-conteiner"></div> <!-- Контейнер для виджета -->
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wineater-bot",
3
- "version": "3.0.4",
3
+ "version": "3.0.6",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "module": "src/index.js",
@@ -0,0 +1,54 @@
1
+ // barConfig.js
2
+
3
+ export const barConfig = {
4
+ barName: "LENEZ",
5
+ dishGroups: [
6
+ {
7
+ groupTitle: "Entradas",
8
+ dishes: [
9
+ "Pimientos rojo asado y aceite de oliva con ajo confitado",
10
+ "Ensalada de arúgula y parmesano",
11
+ "Tomate hierloom aliñado",
12
+ "Aceitunas LENEZ",
13
+ "PapaBnaz",
14
+ "Croquetas | hongos de temporada | jamón serrano",
15
+ "Carpaccio Cesar",
16
+ "Torreznos",
17
+ "Calamares fritos"
18
+ ]
19
+ },
20
+ {
21
+ groupTitle: "Bocadillos",
22
+ dishes: [
23
+ "Brioche de pollo frito, col y salsa macha",
24
+ "Baguette de calamares rebozados en salsa brava",
25
+ "Hogaza de cola de res en recado negro y cebollas encurtidas"
26
+ ]
27
+ },
28
+ {
29
+ groupTitle: "Embutidos",
30
+ dishes: [
31
+ "Jamón Ibérico de bellota",
32
+ "Lomo ibérico",
33
+ "Chorizo ibérico",
34
+ "Plato mixto"
35
+ ]
36
+ },
37
+ {
38
+ groupTitle: "Quesos",
39
+ dishes: [
40
+ "Selección de quesos"
41
+ ]
42
+ },
43
+ {
44
+ groupTitle: "Postres",
45
+ dishes: [
46
+ "Ate con queso manchego semi curado",
47
+ "Gelato de nata con balsámico",
48
+ "Gelato de ron con pasas y “El candado”, Valdespino PX",
49
+ "Gelato Dua Lipa",
50
+ "Créme Brûlée al Orange"
51
+ ]
52
+ }
53
+ ]
54
+ };
package/src/js/i18n.js CHANGED
@@ -37,7 +37,14 @@ class Translator {
37
37
  rose: "Rosé",
38
38
  light: "Léger",
39
39
  medium: "Moyen",
40
- full: "Puissant"
40
+ full: "Puissant",
41
+
42
+ /* -- Новые ключи для bar-режима -- */
43
+ barTitle: "Sélection du bar",
44
+ barSubtitle: "Choisissez vos plats ci-dessous et cliquez sur «Envoyer»",
45
+ barSendButton: "Envoyer",
46
+ barResetButton: "Réinitialiser",
47
+ barName: "Nom du bar",
41
48
  },
42
49
  es: {
43
50
  welcomeMessage: "¿Qué vas a comer? Cuéntame tu plato y te recomendaré el maridaje perfecto.",
@@ -71,7 +78,14 @@ class Translator {
71
78
  rose: "Rosado",
72
79
  light: "Ligero",
73
80
  medium: "Medio",
74
- full: "Intenso"
81
+ full: "Intenso",
82
+
83
+ /* -- Новые ключи bar -- */
84
+ barTitle: "Platos de Bar",
85
+ barSubtitle: "Selecciona de la lista y presiona «Enviar»",
86
+ barSendButton: "Enviar",
87
+ barResetButton: "Reiniciar",
88
+ barName: "Nombre del bar",
75
89
  },
76
90
  en: {
77
91
  welcomeMessage: "What are you planning to eat? Share your dish and I'll recommend the perfect wine pairing for your meal.",
@@ -105,7 +119,14 @@ class Translator {
105
119
  rose: "Rosé",
106
120
  light: "Light",
107
121
  medium: "Medium",
108
- full: "Full"
122
+ full: "Full",
123
+
124
+ /* -- Новые ключи bar -- */
125
+ barTitle: "Bar Dishes",
126
+ barSubtitle: "Select dishes below and click ‘Send’",
127
+ barSendButton: "Send",
128
+ barResetButton: "Reset",
129
+ barName: "Bar Name",
109
130
  },
110
131
  de: {
111
132
  welcomeMessage: "Was möchten Sie essen? Beschreiben Sie Ihr Gericht und ich empfehle Ihnen den perfekten Wein dazu.",
@@ -139,21 +160,25 @@ class Translator {
139
160
  rose: "Rosé",
140
161
  light: "Leicht",
141
162
  medium: "Mittel",
142
- full: "Voll"
143
- }
163
+ full: "Voll",
164
+
165
+ /* -- Новые ключи bar -- */
166
+ barTitle: "Bar-Auswahl",
167
+ barSubtitle: "Wählen Sie Ihre Gerichte und klicken Sie auf „Senden“",
168
+ barSendButton: "Senden",
169
+ barResetButton: "Zurücksetzen",
170
+ barName: "Name der Bar",
171
+ }
144
172
  };
145
173
  }
146
174
 
147
175
  async fetchConfig(storeName) {
148
- console.log(storeName);
149
176
  try {
150
177
  const config = await this.api.getStoreConfig(storeName);
151
- console.log(config);
152
178
  this.language = config.lang;
153
179
  } catch (e) {
154
180
  this.language = 'en'; // Fallback to English
155
181
  }
156
- console.log(this.language);
157
182
  }
158
183
 
159
184
  translate(key) {
@@ -161,4 +186,4 @@ class Translator {
161
186
  }
162
187
  }
163
188
 
164
- export default new Translator();
189
+ export default new Translator();
@@ -12,6 +12,8 @@ const widgetStyles = `
12
12
  box-sizing: border-box;
13
13
  z-index: 10000;
14
14
  max-width: 1200px;
15
+ min-width: 1200px;
16
+ min-height: 500px;
15
17
  margin: 40px auto;
16
18
  }
17
19
 
@@ -312,6 +314,86 @@ const widgetStyles = `
312
314
  max-width: 100px;
313
315
  }
314
316
  }
317
+
318
+ /* --- Стили для бар-версии --- */
319
+
320
+ /* Сетка для блюд бара */
321
+ .dish-grid {
322
+ display: grid;
323
+ grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
324
+ gap: 12px;
325
+ margin: 16px 0;
326
+ }
327
+
328
+ /* Отдельная плитка блюда */
329
+ .dish-tile {
330
+ display: flex;
331
+ justify-content: center;
332
+ align-items: center;
333
+ padding: 16px;
334
+ font-size: 14px;
335
+ font-weight: 500;
336
+ border: 1px solid #ccc;
337
+ border-radius: 8px;
338
+ background-color: #fff;
339
+ cursor: pointer;
340
+ user-select: none;
341
+ transition: all 0.2s ease;
342
+ }
343
+
344
+ .dish-tile:hover {
345
+ transform: scale(1.05);
346
+ box-shadow: 0 4px 8px rgba(123, 43, 235, 0.15);
347
+ }
348
+
349
+ .dish-tile.selected {
350
+ background: linear-gradient(90deg, #7B2BEB, #0044FF);
351
+ color: #fff;
352
+ }
353
+
354
+ /* Кнопка "Отправить" для бар-версии */
355
+ #bar-send-button {
356
+ padding: 12px 20px;
357
+ background: linear-gradient(90deg, #7B2BEB, #0044FF);
358
+ color: white;
359
+ border: none;
360
+ border-radius: 8px;
361
+ cursor: pointer;
362
+ font-size: 16px;
363
+ transition: all 0.2s ease;
364
+ text-align:center;
365
+ margin-top: 16px;
366
+ }
367
+
368
+ #bar-send-button:hover {
369
+ transform: scale(1.05);
370
+ box-shadow: 0 4px 8px rgba(123, 43, 235, 0.15);
371
+ }
372
+
373
+ /* Кнопка "Сбросить" (bar-reset-button), стили как у bar-send-button */
374
+ #bar-reset-button {
375
+ padding: 12px 20px;
376
+ background: linear-gradient(90deg, #7B2BEB, #0044FF);
377
+ color: white;
378
+ border: none;
379
+ border-radius: 8px;
380
+ cursor: pointer;
381
+ font-size: 16px;
382
+ transition: all 0.2s ease;
383
+ margin-top: 16px; /* или подстройте под свой макет */
384
+ margin-left: 12px; /* чтобы отступить от кнопки "Отправить" */
385
+ }
386
+
387
+ #bar-reset-button
388
+
389
+ #bar-reset-button:hover {
390
+ transform: scale(1.05);
391
+ box-shadow: 0 4px 8px rgba(123, 43, 235, 0.15);
392
+ }
393
+
394
+ .hidden {
395
+ display: none;
396
+ }
315
397
  `;
316
398
 
317
399
  const style = document.createElement('style');
package/src/js/widget.js CHANGED
@@ -2,21 +2,42 @@
2
2
  import './widget-styles.js';
3
3
  import { Api } from './api.js';
4
4
  import translator from './i18n.js';
5
+ import { barConfig } from './barConfig.js';
5
6
 
6
7
  export class WineWidget {
7
8
  constructor() {
8
- this.api = new Api(); // Подключаем API
9
+ // Определяем тип виджета: 'store' (старый) или 'bar' (новый)
10
+ this.widgetType = window?.wineaterData?.WIDGET_TYPE || 'bar';
11
+ this.api = new Api();
12
+
13
+ // Фильтры для store
9
14
  this.selectedFilters = {
10
15
  price: null,
11
16
  color: null,
12
17
  intensity: null,
13
18
  };
19
+
20
+ // Если bar — берем название и список блюд из barConfig
21
+ if (this.widgetType === 'bar') {
22
+ this.barName = barConfig.barName; // "LENEZ"
23
+ this.barDishes = barConfig.dishes; // Список блюд из barConfig
24
+ } else {
25
+ this.barName = '';
26
+ this.barDishes = [];
27
+ }
28
+
29
+ // Инициализируем виджет
14
30
  this.initializeWidget();
15
- this.loadInstantRecommendations(); // Загружаем мгновенные рекомендации
31
+
32
+ // Если нужна мгновенная загрузка рекомендаций только в store
33
+ if (this.widgetType === 'store') {
34
+ this.loadInstantRecommendations();
35
+ }
16
36
  }
17
37
 
18
38
  initializeWidget() {
19
39
  const widgetContainer = document.getElementById('wineater-widget-conteiner');
40
+ if (this.widgetType === 'store') {
20
41
  const widgetHTML = `
21
42
  <div id="wine-widget-container">
22
43
  <div id="wine-widget-left">
@@ -75,20 +96,71 @@ export class WineWidget {
75
96
  </div>
76
97
  `;
77
98
  widgetContainer.insertAdjacentHTML('beforeend', widgetHTML);
78
- this.addEventListeners();
99
+ this.addEventListenersStoreVersion();
100
+ } else {
101
+ const barHTML = `
102
+ <div id="wine-widget-container">
103
+ <div id="wine-widget-right">
104
+ ${barConfig.dishGroups.map(group => `
105
+ <!-- Обёртка группы -->
106
+ <div class="dish-group">
107
+ <!-- Заголовок группы, если нужен -->
108
+ <!-- Сетка блюд конкретной группы -->
109
+ <div class="dish-grid">
110
+ ${group.dishes.map(dish => `
111
+ <div class="dish-tile" data-dish="${dish}">
112
+ ${dish}
113
+ </div>
114
+ `).join('')}
115
+ </div>
116
+ </div>
117
+ `).join('')}
118
+
119
+ <div id="wine-placeholder"></div>
120
+
121
+ <!-- Кнопки для отправки и сброса -->
122
+ <div id="bar-buttons">
123
+ <button id="bar-send-button">
124
+ ${translator.translate('barSendButton')}
125
+ </button>
126
+ <button id="bar-reset-button" class="hidden">
127
+ ${translator.translate('barResetButton')}
128
+ </button>
129
+ </div>
130
+
131
+ <div id="loading-indicator" class="hidden">
132
+ <div id="typing-indicator" class="typing-indicator">
133
+ <span></span><span></span><span></span>
134
+ </div>
135
+ </div>
136
+ </div>
137
+ </div>
138
+ `;
139
+ widgetContainer.insertAdjacentHTML('beforeend', barHTML);
140
+
141
+ // Привязка обработчиков "плиток" и кнопки
142
+ this.addEventListenersBarVersion();
143
+ }
79
144
  }
80
145
 
81
- addEventListeners() {
82
- document.getElementById('wine-search-button').addEventListener('click', () => this.handleSearch());
146
+ addEventListenersStoreVersion() {
147
+ document
148
+ .getElementById('wine-search-button')
149
+ .addEventListener('click', () => this.handleSearch());
150
+
151
+ // Привязка фильтров
83
152
  this.setupFilterButtons('price-buttons', 'price');
84
153
  this.setupFilterButtons('color-buttons', 'color');
85
154
  this.setupFilterButtons('intensity-buttons', 'intensity');
86
- // Добавляем обработчик нажатия Enter для поля ввода
87
- document.getElementById('wine-search-input').addEventListener('keydown', (event) => {
88
- if (event.key === 'Enter') {
89
- this.handleSearch();
90
- }
91
- });
155
+
156
+ // Обработчик Enter в поле ввода
157
+ document
158
+ .getElementById('wine-search-input')
159
+ .addEventListener('keydown', (event) => {
160
+ if (event.key === 'Enter') {
161
+ this.handleSearch();
162
+ }
163
+ });
92
164
  }
93
165
 
94
166
  setupFilterButtons(containerId, filterKey) {
@@ -236,4 +308,76 @@ export class WineWidget {
236
308
  console.error('Error loading instant recommendations:', error.message);
237
309
  }
238
310
  }
311
+ addEventListenersBarVersion() {
312
+ // Клик по плиткам
313
+ const tileElements = document.querySelectorAll('.dish-tile');
314
+ tileElements.forEach((tile) => {
315
+ tile.addEventListener('click', () => {
316
+ tile.classList.toggle('selected');
317
+ });
318
+ });
319
+
320
+ // Собираем все .dish-grid
321
+ const dishGrids = document.querySelectorAll('.dish-grid');
322
+
323
+ // Кнопки
324
+ const sendButton = document.getElementById('bar-send-button');
325
+ const resetButton = document.getElementById('bar-reset-button');
326
+ const winePlaceholder = document.getElementById('wine-placeholder');
327
+
328
+ if (!sendButton || !resetButton || !winePlaceholder) return;
329
+
330
+ // Нажатие «Отправить»
331
+ sendButton.addEventListener('click', async () => {
332
+ this.showLoadingIndicator();
333
+
334
+ // Скрываем все группы/гриды блюд
335
+ dishGrids.forEach((dg) => dg.classList.add('hidden'));
336
+ // Прячем кнопку «Отправить»
337
+ sendButton.classList.add('hidden');
338
+
339
+ // Собираем выбранные блюда
340
+ const selectedDishes = [];
341
+ document.querySelectorAll('.dish-tile.selected').forEach(selectedTile => {
342
+ selectedDishes.push(selectedTile.dataset.dish);
343
+ });
344
+
345
+ const query = selectedDishes.join(', ');
346
+ console.log('Selected bar dishes =>', query);
347
+
348
+ try {
349
+ const results = await this.api.getWineRecommendationsSearch(query);
350
+ if (results && results.length > 0) {
351
+ this.displayResults(results, true);
352
+ } else {
353
+ this.displayNoResultsMessage();
354
+ }
355
+ // Показываем кнопку «Сбросить»
356
+ resetButton.classList.remove('hidden');
357
+ } catch (error) {
358
+ console.error('Error while fetching bar recommendations:', error);
359
+ this.displayErrorMessage();
360
+ } finally {
361
+ this.hideLoadingIndicator();
362
+ }
363
+ });
364
+
365
+ // Нажатие «Сбросить»
366
+ resetButton.addEventListener('click', () => {
367
+ // Показываем снова все гриды
368
+ dishGrids.forEach((dg) => dg.classList.remove('hidden'));
369
+
370
+ // Снимаем выделение со всех плиток
371
+ tileElements.forEach(tile => tile.classList.remove('selected'));
372
+
373
+ // Очищаем контейнер с результатами
374
+ winePlaceholder.innerHTML = '';
375
+
376
+ // Прячем кнопку «Сбросить»
377
+ resetButton.classList.add('hidden');
378
+
379
+ // Снова показываем кнопку «Отправить»
380
+ sendButton.classList.remove('hidden');
381
+ });
382
+ }
239
383
  }