wineater-bot 3.2.0 → 3.3.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/dist/wineater-chatbot.mjs +2272 -3047
- package/dist/wineater-chatbot.umd.js +259 -784
- package/index.html +1 -1
- package/package.json +1 -1
- package/src/index.js +1 -95
- package/src/js/i18n.js +29 -0
- package/src/js/widget-styles.js +190 -13
- package/src/js/widget.js +130 -271
- package/src/css/styles.css +0 -239
- package/src/js/auto-open.js +0 -64
- package/src/js/barConfig.js +0 -54
- package/src/js/chatbot.js +0 -140
- package/src/js/styles.js +0 -651
- package/src/js/ui.js +0 -107
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: '
|
|
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
package/src/index.js
CHANGED
|
@@ -1,39 +1,14 @@
|
|
|
1
|
-
import './js/styles.js';
|
|
2
1
|
import { setCookie, setUniqueUserCookie, getCookie } from './js/analytics.js';
|
|
3
2
|
import flagsmith from 'flagsmith';
|
|
4
3
|
import Tracker from '@openreplay/tracker';
|
|
5
4
|
import { WineWidget } from './js/widget.js';
|
|
6
|
-
import { Chatbot } from './js/chatbot.js';
|
|
7
5
|
import translator from './js/i18n.js';
|
|
8
|
-
import { shouldOpenChatAutomatically } from './js/auto-open.js';
|
|
9
|
-
import { toggleChatWindow, closeChatWindow, openChatWindow } from './js/ui.js';
|
|
10
6
|
|
|
11
7
|
const DEMO_TOKEN = 'HeUw6IXuhvz6tRuXdPEGEbj3SGQ3Q2YtEc1Z8jd41Kg9LtyPb4Epu0to31SYIadG';
|
|
12
8
|
|
|
13
9
|
class App {
|
|
14
10
|
constructor() {
|
|
15
|
-
this.stores = ['climats', 'telckel', 'biobio', 'weinpoint', 'vinigrandi', 'ampely', 'test'];
|
|
16
11
|
this.tracker = new Tracker({ projectKey: "PA8j9fAi49i6g2QnvpNs", '__DISABLE_SECURE_MODE': true });
|
|
17
|
-
this.position = window?.wineaterData?.POSITION || 'right-center';
|
|
18
|
-
this.type = window?.wineaterData?.TYPE || 'chatbot';
|
|
19
|
-
this.store = this.detectStore();
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
detectStore() {
|
|
23
|
-
return this.stores.find(store => window.location.href.includes(store)) || null;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
async initFlagsmith() {
|
|
27
|
-
try {
|
|
28
|
-
await flagsmith.init({
|
|
29
|
-
environmentID: '5RfiDoiqb4dHrNdQvzbkfM',
|
|
30
|
-
cacheFlags: false,
|
|
31
|
-
enableAnalytics: true,
|
|
32
|
-
identity: getCookie('uniqueUserID'),
|
|
33
|
-
});
|
|
34
|
-
} catch (error) {
|
|
35
|
-
console.error('Flagsmith initialization failed:', error);
|
|
36
|
-
}
|
|
37
12
|
}
|
|
38
13
|
|
|
39
14
|
async initTranslator() {
|
|
@@ -46,84 +21,15 @@ class App {
|
|
|
46
21
|
setUniqueUserCookie();
|
|
47
22
|
}
|
|
48
23
|
|
|
49
|
-
async initializeChatbotOrWidget() {
|
|
50
|
-
if (this.type === 'widget') {
|
|
51
|
-
new WineWidget();
|
|
52
|
-
} else {
|
|
53
|
-
this.createChatbotUI();
|
|
54
|
-
this.setupChatListeners();
|
|
55
|
-
this.setupChatButtonListener();
|
|
56
|
-
applyPositionToChat(this.position);
|
|
57
|
-
const chatbot = new Chatbot();
|
|
58
|
-
chatbot.initialize();
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
createChatbotUI() {
|
|
63
|
-
const chatbotHTML = ``;
|
|
64
|
-
document.body.insertAdjacentHTML('beforeend', chatbotHTML);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
setupChatListeners() {
|
|
68
|
-
const closeButton = document.getElementById('close-btn');
|
|
69
|
-
closeButton.addEventListener('click', toggleChatWindow);
|
|
70
|
-
|
|
71
|
-
window.addEventListener('click', event => {
|
|
72
|
-
const chatWindow = document.getElementById('chat-window');
|
|
73
|
-
const chatIcon = document.getElementById('chat-icon');
|
|
74
|
-
if (!chatWindow.contains(event.target) && !chatIcon.contains(event.target)) {
|
|
75
|
-
chatWindow.classList.remove('visible');
|
|
76
|
-
chatIcon.style.display = 'flex';
|
|
77
|
-
}
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
autoOpenChatIfNeeded() {
|
|
82
|
-
const disableAutoOpen = getCookie('disableAutoOpen');
|
|
83
|
-
if (!disableAutoOpen) {
|
|
84
|
-
shouldOpenChatAutomatically();
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
setupChatButtonListener() {
|
|
89
|
-
const chatIcon = document.getElementById('chat-icon');
|
|
90
|
-
const chatWindow = document.getElementById('chat-window');
|
|
91
|
-
|
|
92
|
-
if (!chatIcon || !chatWindow) {
|
|
93
|
-
console.error('Chat icon or chat window element not found!');
|
|
94
|
-
return;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
chatIcon.addEventListener('click', () => {
|
|
98
|
-
const isVisible = chatWindow.classList.contains('visible');
|
|
99
|
-
if (isVisible) {
|
|
100
|
-
chatWindow.classList.remove('visible');
|
|
101
|
-
chatIcon.style.display = 'flex';
|
|
102
|
-
} else {
|
|
103
|
-
chatWindow.classList.add('visible');
|
|
104
|
-
chatIcon.style.display = 'none';
|
|
105
|
-
}
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
24
|
|
|
109
25
|
async initialize() {
|
|
110
26
|
this.tracker.start();
|
|
111
|
-
await this.initFlagsmith();
|
|
112
27
|
await this.initTranslator();
|
|
113
28
|
this.initCookies();
|
|
114
|
-
|
|
115
|
-
this.autoOpenChatIfNeeded();
|
|
29
|
+
new WineWidget();
|
|
116
30
|
}
|
|
117
31
|
}
|
|
118
32
|
|
|
119
|
-
function applyPositionToChat(position = 'right-center') {
|
|
120
|
-
const chatIcon = document.getElementById('chat-icon');
|
|
121
|
-
if (!chatIcon) return;
|
|
122
|
-
|
|
123
|
-
// Применение классов для позиции
|
|
124
|
-
chatIcon.className = `chat-icon-${position}`;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
33
|
// Initialize the application on DOM ready
|
|
128
34
|
document.addEventListener('DOMContentLoaded', () => {
|
|
129
35
|
const app = new App();
|
package/src/js/i18n.js
CHANGED
|
@@ -4,6 +4,18 @@ class Translator {
|
|
|
4
4
|
constructor() {
|
|
5
5
|
this.api = new Api();
|
|
6
6
|
this.language = 'en'; // Default to English
|
|
7
|
+
this.currency = 'USD';
|
|
8
|
+
this.currencies = {
|
|
9
|
+
'USD': {
|
|
10
|
+
label: '$'
|
|
11
|
+
},
|
|
12
|
+
'EUR': {
|
|
13
|
+
label: '€'
|
|
14
|
+
},
|
|
15
|
+
'MXN': {
|
|
16
|
+
label: '$'
|
|
17
|
+
}
|
|
18
|
+
}
|
|
7
19
|
this.translations = {
|
|
8
20
|
fr: {
|
|
9
21
|
lang: 'fr',
|
|
@@ -400,9 +412,26 @@ class Translator {
|
|
|
400
412
|
try {
|
|
401
413
|
const config = await this.api.getStoreConfig(storeName);
|
|
402
414
|
this.language = config.lang;
|
|
415
|
+
this.currency = config.currency;
|
|
403
416
|
} catch (e) {
|
|
404
417
|
this.language = 'en'; // Fallback to English
|
|
418
|
+
this.currency = 'USD';
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
getCurrency(key) {
|
|
423
|
+
const keys = key.split('.'); // Разбиваем ключ на части
|
|
424
|
+
let value = this.currencies[this.currency];
|
|
425
|
+
|
|
426
|
+
for (const k of keys) {
|
|
427
|
+
if (value && typeof value === 'object' && k in value) {
|
|
428
|
+
value = value[k]; // Переходим к следующему уровню
|
|
429
|
+
} else {
|
|
430
|
+
return this.currency; // Если ключ не найден, возвращаем сам ключ
|
|
431
|
+
}
|
|
405
432
|
}
|
|
433
|
+
|
|
434
|
+
return value;
|
|
406
435
|
}
|
|
407
436
|
|
|
408
437
|
translate(key) {
|
package/src/js/widget-styles.js
CHANGED
|
@@ -125,17 +125,18 @@ body {
|
|
|
125
125
|
#wine-widget-container #wine-widget-search {
|
|
126
126
|
position: relative;
|
|
127
127
|
margin: 12px auto;
|
|
128
|
+
padding: 0 6px;
|
|
128
129
|
display: flex;
|
|
129
|
-
|
|
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
|
-
|
|
147
|
-
padding: 12px
|
|
147
|
+
flex: 1 1 auto;
|
|
148
|
+
padding: 12px; /* место под иконку и кнопку */
|
|
148
149
|
font-size: 16px;
|
|
149
|
-
border:
|
|
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
|
-
|
|
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;
|
|
@@ -316,7 +313,7 @@ body {
|
|
|
316
313
|
|
|
317
314
|
/* Заголовок вина */
|
|
318
315
|
#wine-widget-container .wine-title {
|
|
319
|
-
font-size:
|
|
316
|
+
font-size: 15px; /* крупнее */
|
|
320
317
|
font-weight: 500;
|
|
321
318
|
margin: 0 0 8px;
|
|
322
319
|
min-height: 3rem;
|
|
@@ -492,6 +489,58 @@ margin-top: auto; /* прижимает .bottom-row к низу
|
|
|
492
489
|
animation: spin 1s linear infinite;
|
|
493
490
|
}
|
|
494
491
|
|
|
492
|
+
.typing-indicator {
|
|
493
|
+
display: flex;
|
|
494
|
+
justify-content: center;
|
|
495
|
+
align-items: center;
|
|
496
|
+
height: 0;
|
|
497
|
+
visibility: hidden;
|
|
498
|
+
background-color: white;
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
#loading-indicator .typing-indicator {
|
|
502
|
+
visibility: visible;
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
.typing-indicator span {
|
|
506
|
+
display: block;
|
|
507
|
+
width: 8px;
|
|
508
|
+
height: 8px;
|
|
509
|
+
margin: 0 3px;
|
|
510
|
+
border-radius: 50%;
|
|
511
|
+
background: linear-gradient(90deg, var(--wineater-color), var(--wineater-corp-color));
|
|
512
|
+
opacity: 0.7;
|
|
513
|
+
animation: typing 1s infinite;
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
@keyframes typing {
|
|
517
|
+
0%, 100% {
|
|
518
|
+
transform: translateY(0);
|
|
519
|
+
opacity: 0.7;
|
|
520
|
+
}
|
|
521
|
+
50% {
|
|
522
|
+
transform: translateY(-8px);
|
|
523
|
+
opacity: 1;
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
/* Staggered animation for typing dots */
|
|
528
|
+
.typing-indicator span:nth-child(1) {
|
|
529
|
+
animation-delay: 0s;
|
|
530
|
+
}
|
|
531
|
+
.typing-indicator span:nth-child(2) {
|
|
532
|
+
animation-delay: 0.15s;
|
|
533
|
+
}
|
|
534
|
+
.typing-indicator span:nth-child(3) {
|
|
535
|
+
animation-delay: 0.3s;
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
/* Show the typing indicator */
|
|
539
|
+
.typing-indicator.visible {
|
|
540
|
+
visibility: visible;
|
|
541
|
+
height: 40px;
|
|
542
|
+
}
|
|
543
|
+
|
|
495
544
|
/* ===================== 11) keyframes анимации ===================== */
|
|
496
545
|
@keyframes spin {
|
|
497
546
|
from { transform: rotate(0deg); }
|
|
@@ -631,6 +680,134 @@ margin-top: auto; /* прижимает .bottom-row к низу
|
|
|
631
680
|
}
|
|
632
681
|
}
|
|
633
682
|
|
|
683
|
+
.card-popup {
|
|
684
|
+
position: absolute;
|
|
685
|
+
top: 0;
|
|
686
|
+
left: 0;
|
|
687
|
+
z-index: 10;
|
|
688
|
+
width: 100%;
|
|
689
|
+
background-color: white;
|
|
690
|
+
padding: 16px;
|
|
691
|
+
border-radius: 16px;
|
|
692
|
+
box-shadow: 0 6px 30px rgba(0,0,0,0.2);
|
|
693
|
+
text-align: left;
|
|
694
|
+
font-size: 14px;
|
|
695
|
+
box-sizing: border-box;
|
|
696
|
+
display: flex;
|
|
697
|
+
flex-direction: column;
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
.card-popup p {
|
|
701
|
+
margin: 5px 0;
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
.card-popup.hidden {
|
|
705
|
+
display: none;
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
.card-popup-header {
|
|
709
|
+
display: flex;
|
|
710
|
+
justify-content: space-between;
|
|
711
|
+
align-items: flex-start;
|
|
712
|
+
gap: 12px;
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
.card-popup-header h2 {
|
|
716
|
+
font-size: 16px;
|
|
717
|
+
font-weight: 600;
|
|
718
|
+
margin: 0;
|
|
719
|
+
flex: 1;
|
|
720
|
+
line-height: 1.3;
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
.card-popup-close {
|
|
724
|
+
font-size: 20px;
|
|
725
|
+
font-weight: bold;
|
|
726
|
+
cursor: pointer;
|
|
727
|
+
color: #999;
|
|
728
|
+
border: none;
|
|
729
|
+
background: transparent;
|
|
730
|
+
line-height: 1;
|
|
731
|
+
}
|
|
732
|
+
.card-popup-close:hover {
|
|
733
|
+
color: #000;
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
.global-card-popup {
|
|
737
|
+
position: fixed;
|
|
738
|
+
top: 0;
|
|
739
|
+
left: 0;
|
|
740
|
+
right: 0;
|
|
741
|
+
bottom: 0;
|
|
742
|
+
z-index: 10000;
|
|
743
|
+
padding: 24px 16px;
|
|
744
|
+
background-color: #fff;
|
|
745
|
+
overflow-y: auto;
|
|
746
|
+
border-radius: 0;
|
|
747
|
+
font-size: 14px;
|
|
748
|
+
box-shadow: 0 6px 20px rgba(0,0,0,0.2);
|
|
749
|
+
display: flex;
|
|
750
|
+
flex-direction: column;
|
|
751
|
+
gap: 12px;
|
|
752
|
+
max-width: 100vw;
|
|
753
|
+
max-height: 100vh;
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
.global-card-popup .card-popup-header {
|
|
757
|
+
display: flex;
|
|
758
|
+
justify-content: space-between;
|
|
759
|
+
align-items: flex-start;
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
.global-card-popup .card-popup-close {
|
|
763
|
+
font-size: 24px;
|
|
764
|
+
font-weight: bold;
|
|
765
|
+
cursor: pointer;
|
|
766
|
+
background: transparent;
|
|
767
|
+
border: none;
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
.mobile-fullscreen-popup {
|
|
771
|
+
font-family: 'Bricolage Grotesque', sans-serif;
|
|
772
|
+
position: fixed;
|
|
773
|
+
width: calc(100% - 20px);
|
|
774
|
+
top: 50px;
|
|
775
|
+
left: 10px;
|
|
776
|
+
z-index: 10000;
|
|
777
|
+
background-color: #fff;
|
|
778
|
+
padding: 24px;
|
|
779
|
+
overflow-y: auto;
|
|
780
|
+
border-radius: 0;
|
|
781
|
+
border-radius: 16px;
|
|
782
|
+
font-size: 14px;
|
|
783
|
+
display: flex;
|
|
784
|
+
flex-direction: column;
|
|
785
|
+
gap: 12px;
|
|
786
|
+
}
|
|
787
|
+
.mobile-fullscreen-popup .card-popup-header {
|
|
788
|
+
display: flex;
|
|
789
|
+
justify-content: space-between;
|
|
790
|
+
align-items: flex-start;
|
|
791
|
+
}
|
|
792
|
+
.mobile-fullscreen-overlay {
|
|
793
|
+
position: absolute;
|
|
794
|
+
top: 0;
|
|
795
|
+
left: 0;
|
|
796
|
+
right: 0;
|
|
797
|
+
bottom: 0;
|
|
798
|
+
background: #fff;
|
|
799
|
+
opacity: 0.96;
|
|
800
|
+
z-index: 0;
|
|
801
|
+
}
|
|
802
|
+
.mobile-fullscreen-popup .card-popup-close {
|
|
803
|
+
font-size: 24px;
|
|
804
|
+
font-weight: bold;
|
|
805
|
+
cursor: pointer;
|
|
806
|
+
background: transparent;
|
|
807
|
+
border: none;
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
|
|
634
811
|
/* Пример более узких экранов (i.e. <480px) можно добавить при необходимости */
|
|
635
812
|
`;
|
|
636
813
|
const fontLink = document.createElement('link');
|