wineater-bot 3.1.12 → 3.2.0

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>window.wineaterData = {CLIENT_TOKEN: 'HeUw6IXuhvz6tRuXdPEGEbj3SGQ3Q2YtEc1Z8jd41Kg9LtyPb4Epu0to31SYIadG', TYPE: 'widget', WIDGET_TYPE: 'store', WIDGET_WRAPPER: 'wineater-widget-conteiner'};</script>
8
- <script type="module" src="./dist/wineater-chatbot.umd.js"></script>
9
- <!-- <script type="module" src="./src/index.js"></script> -->
7
+ <script>window.wineaterData = {CLIENT_TOKEN: 'emZGQHlITdVpwvK2hLXRopFS2emvorRsHadgaKbJThiVCPRWRzD0JyZrxrtgt10a', TYPE: 'widget', WIDGET_TYPE: 'store', WIDGET_WRAPPER: 'wineater-widget-conteiner'};</script>
8
+ <!-- <script type="module" src="./dist/wineater-chatbot.umd.js"></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.1.12",
3
+ "version": "3.2.0",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "module": "src/index.js",
package/src/index.js CHANGED
@@ -40,7 +40,7 @@ class App {
40
40
  const storeName = this.store ? this.store.charAt(0).toUpperCase() + this.store.slice(1) : 'Test';
41
41
  await translator.fetchConfig(storeName || 'Test');
42
42
  }
43
-
43
+
44
44
  initCookies() {
45
45
  setCookie('chatbotToken', window.wineaterData?.CLIENT_TOKEN || DEMO_TOKEN, 365);
46
46
  setUniqueUserCookie();
@@ -60,37 +60,7 @@ class App {
60
60
  }
61
61
 
62
62
  createChatbotUI() {
63
- const btnTextOption = flagsmith.getValue('chat-btn-txt');
64
- const buttonText = window?.wineaterData?.BUTTON_TEXT || translator.translate(`chatButton${btnTextOption}`);
65
- const chatbotHTML = `
66
- <div id="chatbot-container">
67
- <div id="chat-icon">
68
- <img src="https://czvgkhagwvmknscoerfy.supabase.co/storage/v1/object/public/static-media/chat-icon.svg" alt="Chat Icon">
69
- <span>${buttonText}</span>
70
- </div>
71
- <div id="chat-window" class="hidden">
72
- <div id="chat-header">
73
- <div id="chat-title">
74
- <h1>${translator.translate('chatTitle')}</h1>
75
- </div>
76
- <div id="close-btn">&times;</div>
77
- </div>
78
- <div id="message-container"></div>
79
- <div id="typing-indicator" class="typing-indicator hidden">
80
- <span></span><span></span><span></span>
81
- </div>
82
- <div id="input-container">
83
- <input type="text" id="user-input" placeholder="${translator.translate('inputPlaceholder')}">
84
- <button id="send-button">${translator.translate('sendButton')}</button>
85
- </div>
86
- <div id="powered-by">
87
- <a href="https://wineater.com" target="_blank">
88
- <span>${translator.translate('poweredBy')}</span>
89
- <img src="https://czvgkhagwvmknscoerfy.supabase.co/storage/v1/object/public/static-media/logo.svg" alt="Wineater Logo" id="chatbot-logo">
90
- </a>
91
- </div>
92
- </div>
93
- `;
63
+ const chatbotHTML = ``;
94
64
  document.body.insertAdjacentHTML('beforeend', chatbotHTML);
95
65
  }
96
66
 
@@ -19,7 +19,7 @@ function setCookie(name, value, days) {
19
19
  expires = "; expires=" + date.toUTCString();
20
20
  }
21
21
  document.cookie = name + "=" + (value || "") + expires + "; path=/; secure; samesite=strict";
22
- }
22
+ }
23
23
 
24
24
  // Function to get a cookie by name
25
25
  function getCookie(name) {
@@ -25,7 +25,7 @@ body {
25
25
  display: flex;
26
26
  gap: 24px;
27
27
  font-family: 'Bricolage Grotesque', sans-serif;
28
- padding: 24px 24px 0px;
28
+ padding: 12px 12px 0px;
29
29
  border-radius: 16px;
30
30
  background-color: #fff;
31
31
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
@@ -73,7 +73,7 @@ body {
73
73
  #wine-widget-header h1 {
74
74
  font-family: "Bricolage Grotesque", serif;
75
75
  font-weight: 600;
76
- font-size: 32px;
76
+ font-size: 24px;
77
77
  margin: 0 auto;
78
78
  line-height: 1.3;
79
79
  color: #333;
@@ -124,7 +124,7 @@ body {
124
124
  /* ===================== 6) Поисковая строка (input + кнопка) ===================== */
125
125
  #wine-widget-container #wine-widget-search {
126
126
  position: relative;
127
- margin: 20px auto;
127
+ margin: 12px auto;
128
128
  display: flex;
129
129
  justify-content: center;
130
130
  }
@@ -235,6 +235,7 @@ body {
235
235
  opacity: 0;
236
236
  transform: translateY(20px); /* чтобы анимация была заметна */
237
237
  transition: opacity 0.3s ease, transform 0.3s ease;
238
+ position: relative;
238
239
  }
239
240
  #wine-widget-container .wine-recommendation-tile:last-child {
240
241
  border-right: none;
@@ -251,17 +252,63 @@ body {
251
252
 
252
253
  /* Картинка */
253
254
  #wine-widget-container .wine-image {
254
- width: 150px; /* или 200px, на ваш вкус */
255
- max-height: 200px;
255
+ height: 200px;
256
256
  object-fit: contain; /* чтобы не обрезалось, если нужно */
257
257
  margin: 0 auto 16px; /* отступ снизу */
258
258
  display: block;
259
259
  }
260
260
 
261
+ .wine-hover-popup {
262
+ display: none;
263
+ position: absolute;
264
+ top: 0;
265
+ left: 0;
266
+ width: 100%;
267
+ padding: 12px;
268
+ background-color: #fff;
269
+ border: 1px solid #ddd;
270
+ border-radius: 8px;
271
+ box-shadow: 0 4px 16px rgba(0,0,0,0.1);
272
+ transition: transform 0.3s ease;
273
+ z-index: 999;
274
+ }
275
+
276
+ .wine-hover-popup.slide-in {
277
+ transform: translateY(0);
278
+ }
279
+
280
+ /* Стили содержимого внутри попапа */
281
+ .popup-reason {
282
+ font-size: 14px;
283
+ font-weight: 400;
284
+ color: #333;
285
+ margin-bottom: 8px;
286
+ }
287
+
288
+ .popup-tags {
289
+ display: flex;
290
+ flex-wrap: wrap;
291
+ gap: 8px;
292
+ margin-top: 8px;
293
+ justify-content: center; /* Горизонтальное выравнивание по центру */
294
+ }
295
+
296
+ /* Каждый чип */
297
+ .popup-tag {
298
+ display: inline-block;
299
+ padding: 4px 8px;
300
+ border-radius: 12px;
301
+ background-color: #F5F0FF;
302
+ border: 1px solid #ddd;
303
+ font-size: 13px;
304
+ color: #333;
305
+ text-transform: capitalize; /* Делаем каждое слово с заглавной буквы */
306
+ }
307
+
261
308
  /* Детальный блок */
262
309
  #wine-widget-container .tile-details {
263
310
  /* Можно дополнительные отступы или нет */
264
- display: flex;
311
+ display: flex;
265
312
  flex-direction: column;
266
313
  align-items: center;
267
314
  /* т.к. заголовок и таблица по центру */
@@ -269,8 +316,8 @@ body {
269
316
 
270
317
  /* Заголовок вина */
271
318
  #wine-widget-container .wine-title {
272
- font-size: 20px; /* крупнее */
273
- font-weight: 700;
319
+ font-size: 18px; /* крупнее */
320
+ font-weight: 500;
274
321
  margin: 0 0 8px;
275
322
  min-height: 3rem;
276
323
  line-height: 1.2;
package/src/js/widget.js CHANGED
@@ -32,7 +32,8 @@ export class WineWidget {
32
32
 
33
33
  // Инициализируем виджет
34
34
  this.initializeWidget();
35
- this.initializeSearchAnimation();
35
+ this.initializeSearchAnimation();
36
+ this.sendEvent('widgetInitialized', { widgetType: this.widgetType });
36
37
 
37
38
  // Если нужна мгновенная загрузка рекомендаций только в store
38
39
  if (this.widgetType === 'store') {
@@ -40,6 +41,11 @@ export class WineWidget {
40
41
  }
41
42
  }
42
43
 
44
+ sendEvent(eventType, data) {
45
+ // Моковая реализация отправки событий в API
46
+ console.log('Event sent:', eventType, data);
47
+ }
48
+
43
49
  getTitle(title) {
44
50
  return !!title ? `<h1 class="wine-widget-big-title">${title}</h1>` :`<h1 class="wine-widget-big-title">
45
51
  ${translator.translate('headerLine1')}
@@ -156,9 +162,12 @@ export class WineWidget {
156
162
  }
157
163
 
158
164
  addEventListenersStoreVersion() {
159
- document
160
- .getElementById('wine-search-button')
161
- .addEventListener('click', () => this.handleSearch());
165
+ document
166
+ .getElementById('wine-search-button')
167
+ .addEventListener('click', () => {
168
+ this.sendEvent('searchButtonClicked', { query: document.getElementById('wine-search-input').value });
169
+ this.handleSearch();
170
+ });
162
171
 
163
172
  // Привязка фильтров
164
173
  this.setupFilterButtons('price-buttons', 'price');
@@ -213,6 +222,8 @@ export class WineWidget {
213
222
  // Логирование запроса
214
223
  console.log('Searching for:', fullQuery);
215
224
  console.log('Applied filters:', filters);
225
+
226
+ this.sendEvent('searchPerformed', { query: fullQuery, filters });
216
227
 
217
228
  // Показать эффект исчезновения карточек и индикатор загрузки
218
229
  this.animateCardDisappearance();
@@ -236,11 +247,32 @@ export class WineWidget {
236
247
  }
237
248
  }
238
249
 
250
+ enableHoverPopups() {
251
+ const tiles = document.querySelectorAll('.wine-recommendation-tile');
252
+
253
+ tiles.forEach(tile => {
254
+ const popup = tile.querySelector('.wine-hover-popup');
255
+ if (!popup) return;
256
+
257
+ tile.addEventListener('mouseenter', () => {
258
+ popup.style.display = 'block';
259
+ popup.classList.add('slide-in');
260
+ });
261
+
262
+ tile.addEventListener('mouseleave', () => {
263
+ popup.classList.remove('slide-in');
264
+ popup.style.display = 'none';
265
+ });
266
+ });
267
+ }
268
+
239
269
  displayResults(wines, isAnimated = false) {
240
270
  const resultsContainer = document.getElementById('wine-placeholder');
241
271
  this.hideLoadingIndicator();
242
272
  resultsContainer.innerHTML = '';
243
273
 
274
+ this.sendEvent('resultsDisplayed', { resultsCount: wines.length });
275
+
244
276
  wines.forEach((wine, index) => {
245
277
 
246
278
 
@@ -262,13 +294,32 @@ export class WineWidget {
262
294
  const paramList = [];
263
295
  if (wine.type || wine.Type) paramList.push(wine.type || wine.Type);
264
296
  if (wine.country || wine.Country) paramList.push(wine.country || wine.Country);
265
- if (wine.region || wine.Region) paramList.push(wine.region || wine.Region);
266
- if (wine.grape || wine.Grape) paramList.push(wine.grape || wine.Grape);
297
+ // if (wine.region || wine.Region) paramList.push(wine.region || wine.Region);
298
+ // if (wine.grape || wine.Grape) paramList.push(wine.grape || wine.Grape);
267
299
 
268
300
  // Допустим, первые 3 идут в одну строку, а если есть 4‑й,
269
301
  // мы выведем его на вторую строку. Или всё в одну строку — на вкус.
270
- const line1 = paramList.slice(0, 3).join(' • ');
271
- const line2 = paramList.slice(3).join(' • ');
302
+ const line1 = paramList.join(' • ');
303
+ // const line2 = paramList.slice(3).join(' • ');
304
+ const tags = wine.tags || wine.Tags;
305
+ const reasonPopupHTML = (wine.reason || tags)
306
+ ? `
307
+ <div class="wine-hover-popup">
308
+ ${wine.reason ? `<div class="popup-reason">${wine.reason}</div>` : ''}
309
+ ${
310
+ tags
311
+ ? `<div class="popup-tags">${
312
+ Array.isArray(tags)
313
+ // Для каждого тега делаем отдельный span
314
+ ? tags.map(tag => `<span class="popup-tag">${tag}</span>`).join('')
315
+ : tags
316
+ }
317
+ </div>`
318
+ : ''
319
+ }
320
+ </div>`
321
+ : '';
322
+
272
323
  const wineHTML = `
273
324
  <div class="wine-recommendation-tile ${wine.isSommSelection ? 'somm-selection' : ''}">
274
325
  ${
@@ -306,11 +357,7 @@ export class WineWidget {
306
357
  ? `<div class="wine-params">${line1}</div>`
307
358
  : ''
308
359
  }
309
- ${
310
- line2
311
- ? `<div class="wine-params">${line2}</div>`
312
- : ''
313
- }
360
+
314
361
 
315
362
  <!-- Кнопка Buy, видна только при наведении -->
316
363
  <div class="bottom-row">
@@ -318,6 +365,9 @@ export class WineWidget {
318
365
  ${translator.translate('wineDetails.buy')}
319
366
  </a>
320
367
  </div>
368
+
369
+ <!-- Добавляем HTML попапа -->
370
+ ${reasonPopupHTML}
321
371
  </div>
322
372
  `;
323
373
  resultsContainer.insertAdjacentHTML('beforeend', wineHTML);
@@ -331,6 +381,8 @@ export class WineWidget {
331
381
  currentCard.style.transform = 'translateY(0)';
332
382
  }, isAnimated ? index * 200 : 0); // Задержка между карточками
333
383
  });
384
+
385
+ this.enableHoverPopups();
334
386
  }
335
387
 
336
388
  animateCardDisappearance() {
@@ -430,6 +482,8 @@ export class WineWidget {
430
482
  const finalQuery = queryParts.join('; ');
431
483
 
432
484
  console.log('Final query =>', finalQuery);
485
+
486
+ this.sendEvent('barSearchPerformed', { query: finalQuery, selectedDishes, notes });
433
487
 
434
488
  try {
435
489
  // 4) Делаете запрос к API