wineater-bot 3.1.13 → 3.2.1

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,7 +4,7 @@
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>
7
+ <script>window.wineaterData = {CLIENT_TOKEN: 'dRBwg6wB6LeEKFUiLHdlXa84TgSVDuR8HhE0hhq1l4vVeq3cE12DJkPDwXvuhT01', TYPE: 'widget', WIDGET_TYPE: 'store', WIDGET_WRAPPER: 'wineater-widget-conteiner'};</script>
8
8
  <!-- <script type="module" src="./dist/wineater-chatbot.umd.js"></script> -->
9
9
  <script type="module" src="./src/index.js"></script>
10
10
  </head>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wineater-bot",
3
- "version": "3.1.13",
3
+ "version": "3.2.1",
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();
@@ -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,18 +124,19 @@ 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
+ padding: 0 6px;
128
129
  display: flex;
129
- justify-content: center;
130
+ align-items: center;
131
+ border: 2px solid #D5D9EE;
132
+ border-radius: 10px;
130
133
  }
131
134
 
132
135
  #wine-widget-container .search-icon {
133
- position: absolute;
134
136
  left: 12px;
135
- top: 50%;
136
- transform: translateY(-50%);
137
137
  width: 24px;
138
138
  height: 24px;
139
+ flex: 0 0 auto;
139
140
  background-image: url('https://czvgkhagwvmknscoerfy.supabase.co/storage/v1/object/public/static-media//search.svg?x=1');
140
141
  background-repeat: no-repeat;
141
142
  background-size: contain;
@@ -143,14 +144,13 @@ body {
143
144
  }
144
145
 
145
146
  #wine-widget-container #wine-search-input {
146
- width: 100%;
147
- padding: 12px 60px 12px 40px; /* место под иконку и кнопку */
147
+ flex: 1 1 auto;
148
+ padding: 12px; /* место под иконку и кнопку */
148
149
  font-size: 16px;
149
- border: 2px solid #D5D9EE;
150
+ border: none;
150
151
  border-radius: 10px;
151
152
  outline: none;
152
153
  transition: border 0.2s ease;
153
- background-color: #fff;
154
154
  }
155
155
 
156
156
  #wine-search-input::placeholder {
@@ -168,10 +168,7 @@ body {
168
168
 
169
169
  /* Кнопка поиска */
170
170
  #wine-search-button {
171
- position: absolute;
172
- right: 6px;
173
- top: 50%;
174
- transform: translateY(-50%);
171
+ flex: 0 0 auto;
175
172
  background-color: var(--wineater-color);
176
173
  color: #fff;
177
174
  border: none;
@@ -235,6 +232,7 @@ body {
235
232
  opacity: 0;
236
233
  transform: translateY(20px); /* чтобы анимация была заметна */
237
234
  transition: opacity 0.3s ease, transform 0.3s ease;
235
+ position: relative;
238
236
  }
239
237
  #wine-widget-container .wine-recommendation-tile:last-child {
240
238
  border-right: none;
@@ -251,17 +249,63 @@ body {
251
249
 
252
250
  /* Картинка */
253
251
  #wine-widget-container .wine-image {
254
- width: 150px; /* или 200px, на ваш вкус */
255
- max-height: 200px;
252
+ height: 200px;
256
253
  object-fit: contain; /* чтобы не обрезалось, если нужно */
257
254
  margin: 0 auto 16px; /* отступ снизу */
258
255
  display: block;
259
256
  }
260
257
 
258
+ .wine-hover-popup {
259
+ display: none;
260
+ position: absolute;
261
+ top: 0;
262
+ left: 0;
263
+ width: 100%;
264
+ padding: 12px;
265
+ background-color: #fff;
266
+ border: 1px solid #ddd;
267
+ border-radius: 8px;
268
+ box-shadow: 0 4px 16px rgba(0,0,0,0.1);
269
+ transition: transform 0.3s ease;
270
+ z-index: 999;
271
+ }
272
+
273
+ .wine-hover-popup.slide-in {
274
+ transform: translateY(0);
275
+ }
276
+
277
+ /* Стили содержимого внутри попапа */
278
+ .popup-reason {
279
+ font-size: 14px;
280
+ font-weight: 400;
281
+ color: #333;
282
+ margin-bottom: 8px;
283
+ }
284
+
285
+ .popup-tags {
286
+ display: flex;
287
+ flex-wrap: wrap;
288
+ gap: 8px;
289
+ margin-top: 8px;
290
+ justify-content: center; /* Горизонтальное выравнивание по центру */
291
+ }
292
+
293
+ /* Каждый чип */
294
+ .popup-tag {
295
+ display: inline-block;
296
+ padding: 4px 8px;
297
+ border-radius: 12px;
298
+ background-color: #F5F0FF;
299
+ border: 1px solid #ddd;
300
+ font-size: 13px;
301
+ color: #333;
302
+ text-transform: capitalize; /* Делаем каждое слово с заглавной буквы */
303
+ }
304
+
261
305
  /* Детальный блок */
262
306
  #wine-widget-container .tile-details {
263
307
  /* Можно дополнительные отступы или нет */
264
- display: flex;
308
+ display: flex;
265
309
  flex-direction: column;
266
310
  align-items: center;
267
311
  /* т.к. заголовок и таблица по центру */
@@ -269,8 +313,8 @@ body {
269
313
 
270
314
  /* Заголовок вина */
271
315
  #wine-widget-container .wine-title {
272
- font-size: 20px; /* крупнее */
273
- font-weight: 700;
316
+ font-size: 18px; /* крупнее */
317
+ font-weight: 500;
274
318
  margin: 0 0 8px;
275
319
  min-height: 3rem;
276
320
  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