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/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: 'emZGQHlITdVpwvK2hLXRopFS2emvorRsHadgaKbJThiVCPRWRzD0JyZrxrtgt10a', 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.2.0",
3
+ "version": "3.3.0",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "module": "src/index.js",
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
- await this.initializeChatbotOrWidget();
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) {
@@ -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
- 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;
@@ -316,7 +313,7 @@ body {
316
313
 
317
314
  /* Заголовок вина */
318
315
  #wine-widget-container .wine-title {
319
- font-size: 18px; /* крупнее */
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');