wineater-bot 2.1.4 → 3.0.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/dist/wineater-chatbot.mjs +2756 -2213
- package/dist/wineater-chatbot.umd.js +416 -33
- package/index.html +3 -2
- package/package.json +1 -1
- package/src/index.js +119 -128
- package/src/js/api.js +26 -1
- package/src/js/i18n.js +56 -4
- package/src/js/widget-styles.js +319 -0
- package/src/js/widget.js +218 -0
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
const widgetStyles = `
|
|
2
|
+
/* Общие стили */
|
|
3
|
+
#wine-widget-container {
|
|
4
|
+
display: flex;
|
|
5
|
+
gap: 24px;
|
|
6
|
+
font-family: 'Poppins', sans-serif;
|
|
7
|
+
background-color: #f8f9fa;
|
|
8
|
+
padding: 24px;
|
|
9
|
+
padding-right: 48px;
|
|
10
|
+
border-radius: 16px;
|
|
11
|
+
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
|
|
12
|
+
box-sizing: border-box;
|
|
13
|
+
z-index: 10000;
|
|
14
|
+
max-width: 1200px;
|
|
15
|
+
margin: 40px auto;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/* Левая часть */
|
|
19
|
+
#wine-widget-left {
|
|
20
|
+
flex: 0 0 40%;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/* Правая часть */
|
|
24
|
+
#wine-widget-right {
|
|
25
|
+
display: block;
|
|
26
|
+
position: relative;
|
|
27
|
+
width: 100%;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
#wine-placeholder {
|
|
31
|
+
flex: 0 0 60%;
|
|
32
|
+
display: grid;
|
|
33
|
+
grid-template-columns: repeat(2, 1fr);
|
|
34
|
+
gap: 24px;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/* Заголовок */
|
|
38
|
+
#wine-widget-header h1 {
|
|
39
|
+
font-size: 24px;
|
|
40
|
+
font-weight: bold;
|
|
41
|
+
margin: 0;
|
|
42
|
+
color: #333;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
#wine-widget-header p {
|
|
46
|
+
font-size: 16px;
|
|
47
|
+
color: #666;
|
|
48
|
+
margin-top: 8px;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/* Поле ввода */
|
|
52
|
+
#wine-widget-search {
|
|
53
|
+
display: flex;
|
|
54
|
+
gap: 12px;
|
|
55
|
+
align-items: center;
|
|
56
|
+
margin: 12px 0;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
#wine-search-input {
|
|
60
|
+
flex: 1;
|
|
61
|
+
padding: 12px 16px;
|
|
62
|
+
border: 1px solid #ccc;
|
|
63
|
+
border-radius: 8px;
|
|
64
|
+
font-size: 16px;
|
|
65
|
+
background-color: #fff;
|
|
66
|
+
transition: border 0.2s ease;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
#wine-search-input:focus {
|
|
70
|
+
border-color: #7B2BEB;
|
|
71
|
+
outline: none;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
#wine-search-button {
|
|
75
|
+
padding: 12px 20px;
|
|
76
|
+
background: linear-gradient(90deg, #7B2BEB, #0044FF);
|
|
77
|
+
color: white;
|
|
78
|
+
border: none;
|
|
79
|
+
border-radius: 8px;
|
|
80
|
+
cursor: pointer;
|
|
81
|
+
font-size: 16px;
|
|
82
|
+
transition: all 0.2s ease;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
#wine-search-button:hover {
|
|
86
|
+
transform: scale(1.05);
|
|
87
|
+
box-shadow: 0 4px 12px rgba(123, 43, 235, 0.2);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/* Группы фильтров */
|
|
91
|
+
.filter-group {
|
|
92
|
+
margin-bottom: 16px;
|
|
93
|
+
display: flex;
|
|
94
|
+
flex-direction: column;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.filter-label {
|
|
98
|
+
font-size: 16px;
|
|
99
|
+
font-weight: bold;
|
|
100
|
+
color: #333;
|
|
101
|
+
margin-bottom: 8px;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.filter-buttons {
|
|
105
|
+
display: flex;
|
|
106
|
+
gap: 8px;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.filter-buttons button {
|
|
110
|
+
padding: 10px 16px;
|
|
111
|
+
border: 1px solid #ccc;
|
|
112
|
+
border-radius: 8px;
|
|
113
|
+
background: white;
|
|
114
|
+
cursor: pointer;
|
|
115
|
+
transition: all 0.2s ease;
|
|
116
|
+
font-size: 14px;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.filter-buttons button.selected {
|
|
120
|
+
background: linear-gradient(90deg, #7B2BEB, #0044FF);
|
|
121
|
+
color: white;
|
|
122
|
+
border: none;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.filter-buttons button:hover {
|
|
126
|
+
transform: scale(1.05);
|
|
127
|
+
box-shadow: 0 4px 8px rgba(123, 43, 235, 0.15);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/* Карточка рекомендации */
|
|
131
|
+
.wine-recommendation-tile {
|
|
132
|
+
display: flex;
|
|
133
|
+
padding: 16px;
|
|
134
|
+
border-radius: 16px;
|
|
135
|
+
background-color: white;
|
|
136
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
137
|
+
border: 1px solid #ddd;
|
|
138
|
+
opacity: 0;
|
|
139
|
+
transition: opacity 0.3s ease, transform 0.3s ease;
|
|
140
|
+
gap: 16px;
|
|
141
|
+
cursor: pointer;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
#loading-indicator {
|
|
145
|
+
position: absolute;
|
|
146
|
+
top: 50%;
|
|
147
|
+
left: 50%;
|
|
148
|
+
transform: translate(-50%, -50%);
|
|
149
|
+
z-index: 10000;
|
|
150
|
+
text-align: center;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
#loading-indicator.hidden {
|
|
154
|
+
display: none;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
#loading-indicator img {
|
|
158
|
+
width: 100px;
|
|
159
|
+
height: 100px;
|
|
160
|
+
animation: spin 1s linear infinite;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
@keyframes spin {
|
|
164
|
+
from {
|
|
165
|
+
transform: rotate(0deg);
|
|
166
|
+
}
|
|
167
|
+
to {
|
|
168
|
+
transform: rotate(360deg);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
.wine-recommendation-tile:hover {
|
|
174
|
+
transform: scale(1.03);
|
|
175
|
+
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.15);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
.somm-selection {
|
|
179
|
+
position: relative;
|
|
180
|
+
border: 2px solid #FFD700; /* Золотая рамка */
|
|
181
|
+
background: linear-gradient(white, #FFF8DC); /* Легкий золотистый фон */
|
|
182
|
+
box-shadow: 0 4px 12px rgba(255, 215, 0, 0.4); /* Золотая тень */
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/* Подпись Somm Selection */
|
|
186
|
+
.somm-selection-badge {
|
|
187
|
+
position: absolute;
|
|
188
|
+
top: -10px;
|
|
189
|
+
left: 10px;
|
|
190
|
+
background: linear-gradient(90deg, #FFD700, #FFB800); /* Градиентная золотая заливка */
|
|
191
|
+
color: #FFF;
|
|
192
|
+
font-size: 12px;
|
|
193
|
+
font-weight: bold;
|
|
194
|
+
padding: 4px 8px;
|
|
195
|
+
border-radius: 4px;
|
|
196
|
+
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2); /* Тень для выделения */
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/* Изображение */
|
|
200
|
+
.wine-recommendation-tile img {
|
|
201
|
+
width: 120px;
|
|
202
|
+
height: 120px;
|
|
203
|
+
object-fit: cover;
|
|
204
|
+
border-radius: 8px;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/* Детали карточки */
|
|
208
|
+
.tile-details {
|
|
209
|
+
font-size: 14px;
|
|
210
|
+
color: #333;
|
|
211
|
+
flex: 1;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
.tile-details strong {
|
|
215
|
+
display: block;
|
|
216
|
+
font-size: 18px;
|
|
217
|
+
margin-bottom: 4px;
|
|
218
|
+
font-weight: bold;
|
|
219
|
+
color: #1F1F1F;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
.tile-details p {
|
|
223
|
+
margin: 4px 0;
|
|
224
|
+
color: #555;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
.tile-details a {
|
|
228
|
+
font-size: 12px;
|
|
229
|
+
color: #0044FF;
|
|
230
|
+
text-decoration: underline;
|
|
231
|
+
display: block;
|
|
232
|
+
font-weight: bold;
|
|
233
|
+
margin-top: 16px;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
.tile-details a:hover {
|
|
237
|
+
text-decoration: none;
|
|
238
|
+
color: #002699;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
/* Описание карточки */
|
|
243
|
+
.wine-description-widget {
|
|
244
|
+
margin-top: 12px;
|
|
245
|
+
padding: 8px 12px;
|
|
246
|
+
font-size: 14px;
|
|
247
|
+
color: #fff;
|
|
248
|
+
border-radius: 8px;
|
|
249
|
+
background: linear-gradient(90deg, #7B2BEB, #0044FF);
|
|
250
|
+
text-align: center;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
#powered-by-widget {
|
|
254
|
+
margin-top: 20px;
|
|
255
|
+
display: flex;
|
|
256
|
+
align-items: center;
|
|
257
|
+
justify-content: center;
|
|
258
|
+
background-color: #FAFAFA;
|
|
259
|
+
padding: 12px 24px;
|
|
260
|
+
border-top: 1px solid rgba(0, 0, 0, 0.08);
|
|
261
|
+
border-radius: 12px;
|
|
262
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
#powered-by-widget {
|
|
266
|
+
display: flex;
|
|
267
|
+
align-items: center;
|
|
268
|
+
justify-content: center;
|
|
269
|
+
margin-top: 20px;
|
|
270
|
+
padding: 12px;
|
|
271
|
+
border: 1px solid transparent;
|
|
272
|
+
border-radius: 8px;
|
|
273
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
|
|
274
|
+
text-align: center;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
#powered-by-widget a {
|
|
278
|
+
text-decoration: none;
|
|
279
|
+
display: flex;
|
|
280
|
+
align-items: center;
|
|
281
|
+
gap: 8px;
|
|
282
|
+
color: #7B2BEB;
|
|
283
|
+
font-size: 12px;
|
|
284
|
+
transition: opacity 0.2s ease;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
#powered-by-widget a:hover {
|
|
288
|
+
opacity: 0.8;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
#powered-by-widget img {
|
|
292
|
+
height: 16px;
|
|
293
|
+
width: auto;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/* Адаптивность для мобильных устройств */
|
|
297
|
+
@media screen and (max-width: 768px) {
|
|
298
|
+
#wine-widget-container {
|
|
299
|
+
flex-direction: column;
|
|
300
|
+
padding: 16px;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
#wine-widget-left {
|
|
304
|
+
width: 100%;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
#wine-widget-right {
|
|
308
|
+
grid-template-columns: 1fr;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
.wine-recommendation-tile img {
|
|
312
|
+
max-width: 100px;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
`;
|
|
316
|
+
|
|
317
|
+
const style = document.createElement('style');
|
|
318
|
+
style.textContent = widgetStyles;
|
|
319
|
+
document.head.appendChild(style);
|
package/src/js/widget.js
ADDED
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
// widget.js
|
|
2
|
+
import './widget-styles.js';
|
|
3
|
+
import { Api } from './api.js';
|
|
4
|
+
import translator from './i18n.js';
|
|
5
|
+
|
|
6
|
+
export class WineWidget {
|
|
7
|
+
constructor() {
|
|
8
|
+
this.api = new Api(); // Подключаем API
|
|
9
|
+
this.selectedFilters = {
|
|
10
|
+
price: null,
|
|
11
|
+
color: null,
|
|
12
|
+
intensity: null,
|
|
13
|
+
};
|
|
14
|
+
this.initializeWidget();
|
|
15
|
+
this.loadInstantRecommendations(); // Загружаем мгновенные рекомендации
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
initializeWidget() {
|
|
19
|
+
const widgetHTML = `
|
|
20
|
+
<div id="wine-widget-container">
|
|
21
|
+
<div id="wine-widget-left">
|
|
22
|
+
<div id="wine-widget-header">
|
|
23
|
+
<h1>${translator.translate('widgetTitle')}</h1>
|
|
24
|
+
<p>${translator.translate('widgetSubtitle')}</p>
|
|
25
|
+
</div>
|
|
26
|
+
<div id="wine-widget-search">
|
|
27
|
+
<input type="text" id="wine-search-input" placeholder="${translator.translate('searchPlaceholder')}">
|
|
28
|
+
<button id="wine-search-button">${translator.translate('searchButton')}</button>
|
|
29
|
+
</div>
|
|
30
|
+
<div id="wine-widget-filters">
|
|
31
|
+
<div class="filter-group">
|
|
32
|
+
<span class="filter-label">${translator.translate('priceRange')}:</span>
|
|
33
|
+
<div class="filter-buttons" id="price-buttons">
|
|
34
|
+
<button data-value="<10"><$10</button>
|
|
35
|
+
<button data-value="10-20">$10-$20</button>
|
|
36
|
+
<button data-value=">20">>$20</button>
|
|
37
|
+
</div>
|
|
38
|
+
</div>
|
|
39
|
+
<div class="filter-group">
|
|
40
|
+
<span class="filter-label">${translator.translate('wineColor')}:</span>
|
|
41
|
+
<div class="filter-buttons" id="color-buttons">
|
|
42
|
+
<button data-value="red">${translator.translate('red')}</button>
|
|
43
|
+
<button data-value="white">${translator.translate('white')}</button>
|
|
44
|
+
<button data-value="rose">${translator.translate('rose')}</button>
|
|
45
|
+
</div>
|
|
46
|
+
</div>
|
|
47
|
+
<div class="filter-group">
|
|
48
|
+
<span class="filter-label">${translator.translate('intensity')}:</span>
|
|
49
|
+
<div class="filter-buttons" id="intensity-buttons">
|
|
50
|
+
<button data-value="light">${translator.translate('light')}</button>
|
|
51
|
+
<button data-value="medium">${translator.translate('medium')}</button>
|
|
52
|
+
<button data-value="full">${translator.translate('full')}</button>
|
|
53
|
+
</div>
|
|
54
|
+
</div>
|
|
55
|
+
</div>
|
|
56
|
+
<div id="powered-by-widget">
|
|
57
|
+
<a href="https://wineater.com" target="_blank">
|
|
58
|
+
<span>${translator.translate('poweredBy')}</span>
|
|
59
|
+
<img src="https://landing-static.s3.eu-central-1.amazonaws.com/images/logo.svg" alt="Wineater Logo">
|
|
60
|
+
</a>
|
|
61
|
+
</div>
|
|
62
|
+
</div>
|
|
63
|
+
<div id="wine-widget-right">
|
|
64
|
+
<div id="loading-indicator" class="hidden">
|
|
65
|
+
<img src="https://czvgkhagwvmknscoerfy.supabase.co/storage/v1/object/public/static-media/mascot.jpeg" alt="Loading" />
|
|
66
|
+
</div>
|
|
67
|
+
<div id="wine-placeholder"></div>
|
|
68
|
+
</div>
|
|
69
|
+
</div>
|
|
70
|
+
`;
|
|
71
|
+
document.body.insertAdjacentHTML('beforeend', widgetHTML);
|
|
72
|
+
this.addEventListeners();
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
addEventListeners() {
|
|
76
|
+
document.getElementById('wine-search-button').addEventListener('click', () => this.handleSearch());
|
|
77
|
+
this.setupFilterButtons('price-buttons', 'price');
|
|
78
|
+
this.setupFilterButtons('color-buttons', 'color');
|
|
79
|
+
this.setupFilterButtons('intensity-buttons', 'intensity');
|
|
80
|
+
// Добавляем обработчик нажатия Enter для поля ввода
|
|
81
|
+
document.getElementById('wine-search-input').addEventListener('keydown', (event) => {
|
|
82
|
+
if (event.key === 'Enter') {
|
|
83
|
+
this.handleSearch();
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
setupFilterButtons(containerId, filterKey) {
|
|
89
|
+
const buttons = document.querySelectorAll(`#${containerId} button`);
|
|
90
|
+
buttons.forEach(button => {
|
|
91
|
+
button.addEventListener('click', (e) => {
|
|
92
|
+
buttons.forEach(btn => btn.classList.remove('selected'));
|
|
93
|
+
e.target.classList.add('selected');
|
|
94
|
+
this.selectedFilters[filterKey] = e.target.dataset.value;
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
async handleSearch() {
|
|
100
|
+
const query = document.getElementById('wine-search-input').value;
|
|
101
|
+
|
|
102
|
+
// Показать эффект исчезновения карточек
|
|
103
|
+
this.animateCardDisappearance();
|
|
104
|
+
|
|
105
|
+
// Показать индикатор загрузки
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
// Учитываем текущие выбранные фильтры
|
|
109
|
+
const filters = this.selectedFilters;
|
|
110
|
+
|
|
111
|
+
// Добавляем вывод информации о запросе
|
|
112
|
+
console.log('Searching for:', query);
|
|
113
|
+
console.log('Applied filters:', filters);
|
|
114
|
+
|
|
115
|
+
try {
|
|
116
|
+
// Вызываем API метод для получения рекомендаций
|
|
117
|
+
const results = await this.api.getWineRecommendations(query);
|
|
118
|
+
|
|
119
|
+
// Проверяем, есть ли данные
|
|
120
|
+
if (results && results.length > 0) {
|
|
121
|
+
console.log('Recommendations:', results);
|
|
122
|
+
// Отображаем результаты
|
|
123
|
+
this.displayResults(results, true);
|
|
124
|
+
} else {
|
|
125
|
+
console.log('No recommendations found.');
|
|
126
|
+
this.displayNoResultsMessage();
|
|
127
|
+
}
|
|
128
|
+
} catch (error) {
|
|
129
|
+
console.error('Error fetching wine recommendations:', error.message);
|
|
130
|
+
this.displayErrorMessage();
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
displayResults(wines, isAnimated = false) {
|
|
135
|
+
const resultsContainer = document.getElementById('wine-placeholder');
|
|
136
|
+
this.hideLoadingIndicator();
|
|
137
|
+
resultsContainer.innerHTML = '';
|
|
138
|
+
|
|
139
|
+
wines.forEach((wine, index) => {
|
|
140
|
+
const wineHTML = `
|
|
141
|
+
<div class="wine-recommendation-tile ${index === wines.length - 1 ? 'somm-selection' : ''}">
|
|
142
|
+
${index === wines.length - 1 ? '<div class="somm-selection-badge">Somm Selection</div>' : ''}
|
|
143
|
+
<img src="${wine.Image}" alt="${wine.Title}" />
|
|
144
|
+
<div class="tile-details">
|
|
145
|
+
<strong>${wine.Title}</strong>
|
|
146
|
+
<p>Prix: ${wine.Price || 'N/A'}</p>
|
|
147
|
+
<p>Région: ${wine.Region || 'N/A'}</p>
|
|
148
|
+
<p>Type: ${wine.Type || 'N/A'}</p>
|
|
149
|
+
<a href="${wine.Url}" target="_blank">Plus d'infos</a>
|
|
150
|
+
</div>
|
|
151
|
+
</div>
|
|
152
|
+
`;
|
|
153
|
+
resultsContainer.insertAdjacentHTML('beforeend', wineHTML);
|
|
154
|
+
|
|
155
|
+
// Найти только что добавленную карточку
|
|
156
|
+
const currentCard = resultsContainer.children[index];
|
|
157
|
+
|
|
158
|
+
// Анимация появления
|
|
159
|
+
setTimeout(() => {
|
|
160
|
+
currentCard.style.opacity = '1';
|
|
161
|
+
currentCard.style.transform = 'translateY(0)';
|
|
162
|
+
}, isAnimated ? index * 200 : 0); // Задержка между карточками
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
animateCardDisappearance() {
|
|
167
|
+
const cards = document.querySelectorAll('.wine-recommendation-tile');
|
|
168
|
+
cards.forEach((card, index) => {
|
|
169
|
+
setTimeout(() => {
|
|
170
|
+
card.style.opacity = '0';
|
|
171
|
+
card.style.transform = 'translateY(-20px)';
|
|
172
|
+
}, index * 100); // Задержка между карточками
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
setTimeout(() => {
|
|
176
|
+
document.getElementById('wine-placeholder').innerHTML = ''; // Удалить все карточки после анимации
|
|
177
|
+
this.showLoadingIndicator();
|
|
178
|
+
}, cards.length * 100 + 300); // Дождаться завершения анимации
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
showLoadingIndicator() {
|
|
182
|
+
const loadingIndicator = document.getElementById('loading-indicator');
|
|
183
|
+
loadingIndicator.classList.remove('hidden');
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
hideLoadingIndicator() {
|
|
187
|
+
const loadingIndicator = document.getElementById('loading-indicator');
|
|
188
|
+
loadingIndicator.classList.add('hidden');
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
displayNoResultsMessage() {
|
|
192
|
+
const resultsContainer = document.getElementById('wine-placeholder');
|
|
193
|
+
resultsContainer.innerHTML = `
|
|
194
|
+
<div class="no-results">
|
|
195
|
+
<p>${translator.translate('noResultsMessage') || 'No recommendations found for your query.'}</p>
|
|
196
|
+
</div>
|
|
197
|
+
`;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
displayErrorMessage() {
|
|
201
|
+
const resultsContainer = document.getElementById('wine-placeholder');
|
|
202
|
+
resultsContainer.innerHTML = `
|
|
203
|
+
<div class="error-message">
|
|
204
|
+
<p>${translator.translate('errorMessage') || 'Something went wrong. Please try again later.'}</p>
|
|
205
|
+
</div>
|
|
206
|
+
`;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
async loadInstantRecommendations() {
|
|
210
|
+
console.log('привет')
|
|
211
|
+
try {
|
|
212
|
+
const recommendations = await this.api.getInstantRecommendations();
|
|
213
|
+
this.displayResults(recommendations); // Обновляем отображение рекомендаций
|
|
214
|
+
} catch (error) {
|
|
215
|
+
console.error('Error loading instant recommendations:', error.message);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|