shopify-chatbot-widget 1.0.8 → 1.0.10
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/.env.development +2 -0
- package/dist/jaweb-chatbot.css +1 -1
- package/dist/jaweb-chatbot.iife.js +192 -599
- package/home.html +1 -1
- package/jawebDirect.js +1 -1
- package/package.json +1 -1
- package/src/App.tsx +9 -0
- package/src/Chatbot/Chatbot.css +193 -113
- package/src/Chatbot/Chatbot.tsx +26 -19
- package/src/Chatbot/components/Cart/Index.tsx +10 -8
- package/src/Chatbot/components/ChatInput.tsx +11 -11
- package/src/Chatbot/components/Home/Home.css +456 -0
- package/src/Chatbot/components/Home/Home.tsx +293 -0
- package/src/Chatbot/components/Messages/Addcart.tsx +1 -1
- package/src/Chatbot/components/Messages/AssistantMesage.tsx +78 -37
- package/src/Chatbot/components/Messages/CardSwiper.tsx +1 -1
- package/src/Chatbot/components/Messages/Carousel/CardSwiper.tsx +87 -92
- package/src/Chatbot/components/Messages/Carousel/ProductSwiper.css +361 -0
- package/src/Chatbot/components/Messages/Carousel/TryOn.tsx +2 -2
- package/src/Chatbot/components/Messages/ChatMessages.css +32 -1
- package/src/Chatbot/components/Messages/ChatMessages.tsx +21 -38
- package/src/Chatbot/components/Messages/OrderCard.css +177 -0
- package/src/Chatbot/components/Messages/OrderCard.tsx +120 -0
- package/src/Chatbot/components/Messages/ProductCard.css +1 -1
- package/src/Chatbot/components/Messages/Support.tsx +311 -118
- package/src/Chatbot/components/Messages/Typing.css +31 -35
- package/src/Chatbot/components/Messages/Typing.tsx +19 -18
- package/src/Chatbot/components/Messenger/Messenger.tsx +67 -14
- package/src/Chatbot/components/Powered.css +26 -28
- package/src/Chatbot/components/Powered.tsx +1 -1
- package/src/Chatbot/components/Sessions/CreateSession.tsx +12 -10
- package/src/Chatbot/components/TryOn/View.tsx +2 -2
- package/src/Chatbot/components/VoiceMode.css +247 -0
- package/src/Chatbot/components/VoiceMode.tsx +613 -0
- package/src/hooks/config.tsx +9 -10
- package/src/hooks/useChatbotAPI.tsx +146 -61
- package/src/hooks/useChatbotData.tsx +8 -5
- package/src/hooks/useSessionMessages.tsx +0 -1
- package/src/hooks/useWebsocke.tsx +40 -18
- package/src/i18n.tsx +384 -10
- package/src/Chatbot/components/Messages/Carousel/CardSwiperSalla.tsx +0 -187
- package/src/Chatbot/components/Messages/Carousel/CardSwiperZid.tsx +0 -208
- package/src/Chatbot/components/Messages/Carousel/SallaSwiper.css +0 -245
- package/src/Chatbot/components/Messages/SallaAssistantMessage.tsx +0 -202
- package/src/Chatbot/components/Messages/ZidAssistantMesage.tsx +0 -203
- package/src/Chatbot/components/Sessions/RenderList.tsx +0 -519
package/home.html
CHANGED
package/jawebDirect.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
const company = (currentScript.getAttribute('data-company') || '').trim();
|
|
6
6
|
if (!company) return console.error('[Jaweb] data-company is required');
|
|
7
7
|
|
|
8
|
-
const apiBase = currentScript.getAttribute('data-src') || 'https://
|
|
8
|
+
const apiBase = currentScript.getAttribute('data-src') || 'https://api.jaweb.me/api/proxy/iframe';
|
|
9
9
|
const corner = currentScript.getAttribute('data-corner') || 'right'; // 'right' | 'left'
|
|
10
10
|
const openWidth = currentScript.getAttribute('data-open-width') || '400px';
|
|
11
11
|
const openHeight = currentScript.getAttribute('data-open-height') || '95%';
|
package/package.json
CHANGED
package/src/App.tsx
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import Chatbot from './Chatbot/Chatbot';
|
|
2
2
|
import 'antd/dist/reset.css'; // global AntD styles
|
|
3
3
|
|
|
4
|
+
// Dev harness only (src/main.tsx) — production mounts via chatbot-widget/index.tsx
|
|
5
|
+
// inside the iframe proxy, which sets company_username itself.
|
|
6
|
+
if (import.meta.env.DEV && !localStorage.getItem('company_username')) {
|
|
7
|
+
localStorage.setItem(
|
|
8
|
+
'company_username',
|
|
9
|
+
import.meta.env.VITE_DEV_COMPANY || 'blackbellex.myshopify.com'
|
|
10
|
+
);
|
|
11
|
+
}
|
|
12
|
+
|
|
4
13
|
function App() {
|
|
5
14
|
return (
|
|
6
15
|
<div className='jaweb-reset'>
|
package/src/Chatbot/Chatbot.css
CHANGED
|
@@ -1,12 +1,30 @@
|
|
|
1
|
+
/* ============================================
|
|
2
|
+
Jaweb widget — design tokens
|
|
3
|
+
Monochrome structure; the merchant accent
|
|
4
|
+
color arrives as --jaweb-accent (set from
|
|
5
|
+
chatbot_color on .chatbot-box).
|
|
6
|
+
============================================ */
|
|
7
|
+
.jaweb-chatbot-container,
|
|
8
|
+
.chatbot-box {
|
|
9
|
+
--jaweb-accent: #111111;
|
|
10
|
+
--jaweb-ink: #111827;
|
|
11
|
+
--jaweb-ink-soft: #6b7280;
|
|
12
|
+
--jaweb-ink-faint: #9ca3af;
|
|
13
|
+
--jaweb-line: #ececec;
|
|
14
|
+
--jaweb-line-soft: #f3f4f6;
|
|
15
|
+
--jaweb-surface: #ffffff;
|
|
16
|
+
--jaweb-surface-alt: #fafafa;
|
|
17
|
+
--jaweb-radius: 20px;
|
|
18
|
+
}
|
|
19
|
+
|
|
1
20
|
.jaweb-chatbot-container {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
}
|
|
21
|
+
position: fixed;
|
|
22
|
+
bottom: 20px;
|
|
23
|
+
right: 20px;
|
|
24
|
+
z-index: 9999;
|
|
25
|
+
}
|
|
8
26
|
|
|
9
|
-
|
|
27
|
+
/* Tailwind global CSS file */
|
|
10
28
|
.scrollbar-hide::-webkit-scrollbar {
|
|
11
29
|
display: none;
|
|
12
30
|
}
|
|
@@ -15,50 +33,146 @@
|
|
|
15
33
|
scrollbar-width: none;
|
|
16
34
|
}
|
|
17
35
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
36
|
.chatbot-box {
|
|
22
37
|
position: fixed;
|
|
23
38
|
bottom: 20px;
|
|
24
39
|
right: 20px;
|
|
25
40
|
width: 420px;
|
|
26
41
|
max-width: 28%;
|
|
27
|
-
height: 85vh;
|
|
28
|
-
max-height: 800px;
|
|
42
|
+
height: 85vh;
|
|
43
|
+
max-height: 800px;
|
|
29
44
|
z-index: 9999;
|
|
30
|
-
background:
|
|
31
|
-
color:
|
|
32
|
-
border
|
|
45
|
+
background: var(--jaweb-surface);
|
|
46
|
+
color: var(--jaweb-ink);
|
|
47
|
+
border: 1px solid var(--jaweb-line);
|
|
48
|
+
border-radius: var(--jaweb-radius);
|
|
33
49
|
overflow: hidden;
|
|
34
50
|
display: flex;
|
|
35
51
|
flex-direction: column;
|
|
36
|
-
box-shadow: 0
|
|
37
|
-
font-family: 'Inter', sans-serif;
|
|
52
|
+
box-shadow: 0 24px 64px rgba(17, 24, 39, 0.16), 0 4px 16px rgba(17, 24, 39, 0.08);
|
|
53
|
+
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
38
54
|
}
|
|
39
55
|
|
|
56
|
+
/* ===== Header — glass, floats over the messages ===== */
|
|
40
57
|
.chatbot-header {
|
|
41
|
-
|
|
42
|
-
|
|
58
|
+
position: absolute;
|
|
59
|
+
top: 0;
|
|
60
|
+
left: 0;
|
|
61
|
+
right: 0;
|
|
62
|
+
z-index: 30;
|
|
63
|
+
background: rgba(255, 255, 255, 0.72);
|
|
64
|
+
backdrop-filter: blur(18px) saturate(180%);
|
|
65
|
+
-webkit-backdrop-filter: blur(18px) saturate(180%);
|
|
66
|
+
padding: 14px 16px;
|
|
67
|
+
min-height: 68px;
|
|
43
68
|
display: flex;
|
|
44
69
|
align-items: center;
|
|
45
70
|
gap: 12px;
|
|
71
|
+
border-bottom: 1px solid rgba(17, 24, 39, 0.06);
|
|
72
|
+
box-shadow: 0 6px 24px rgba(17, 24, 39, 0.04);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/* messages scroll underneath the glass */
|
|
76
|
+
.chatbot-messages {
|
|
77
|
+
padding-top: 84px !important;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.chatbot-avatarWrap {
|
|
81
|
+
position: relative;
|
|
82
|
+
display: inline-flex;
|
|
83
|
+
flex-shrink: 0;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.chatbot-avatarWrap .ant-avatar {
|
|
87
|
+
width: 40px;
|
|
88
|
+
height: 40px;
|
|
89
|
+
border: 1px solid rgba(17, 24, 39, 0.08);
|
|
90
|
+
box-shadow: 0 2px 8px rgba(17, 24, 39, 0.08);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.chatbot-avatarDot {
|
|
94
|
+
position: absolute;
|
|
95
|
+
right: -1px;
|
|
96
|
+
bottom: -1px;
|
|
97
|
+
width: 11px;
|
|
98
|
+
height: 11px;
|
|
99
|
+
border-radius: 50%;
|
|
100
|
+
background: #22c55e;
|
|
101
|
+
border: 2.5px solid #ffffff;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.chatbot-title {
|
|
105
|
+
flex-grow: 1;
|
|
106
|
+
display: flex;
|
|
107
|
+
flex-direction: column;
|
|
108
|
+
gap: 2px;
|
|
109
|
+
min-width: 0;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.chatbot-title-name {
|
|
113
|
+
font-size: 15px;
|
|
114
|
+
font-weight: 800;
|
|
115
|
+
color: var(--jaweb-ink);
|
|
116
|
+
letter-spacing: -0.02em;
|
|
117
|
+
white-space: nowrap;
|
|
118
|
+
overflow: hidden;
|
|
119
|
+
text-overflow: ellipsis;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
.chatbot-title-status {
|
|
123
|
+
font-size: 11.5px;
|
|
124
|
+
color: var(--jaweb-ink-soft);
|
|
125
|
+
font-weight: 500;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/* ghost-circle header buttons (back / close / cart) */
|
|
129
|
+
.chatbot-header .ant-btn {
|
|
130
|
+
width: 34px;
|
|
131
|
+
height: 34px;
|
|
132
|
+
border-radius: 50% !important;
|
|
133
|
+
display: flex;
|
|
134
|
+
align-items: center;
|
|
135
|
+
justify-content: center;
|
|
136
|
+
color: var(--jaweb-ink-soft);
|
|
137
|
+
transition: all 0.15s ease;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
.chatbot-header .ant-btn:hover {
|
|
141
|
+
background: rgba(17, 24, 39, 0.05) !important;
|
|
142
|
+
color: var(--jaweb-ink);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.chatbot-header .chatbot-close {
|
|
146
|
+
width: 34px;
|
|
147
|
+
height: 34px;
|
|
148
|
+
border-radius: 50%;
|
|
149
|
+
display: flex;
|
|
150
|
+
align-items: center;
|
|
151
|
+
justify-content: center;
|
|
152
|
+
transition: all 0.15s ease;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
.chatbot-header .chatbot-close:hover {
|
|
156
|
+
background: rgba(17, 24, 39, 0.05);
|
|
157
|
+
color: var(--jaweb-ink);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
.chatbot-close {
|
|
161
|
+
cursor: pointer;
|
|
46
162
|
font-size: 16px;
|
|
47
|
-
|
|
48
|
-
border-bottom: 1px solid #e0e0e0;
|
|
49
|
-
flex-shrink: 0; /* Prevent header from shrinking */
|
|
163
|
+
color: var(--jaweb-ink-faint);
|
|
50
164
|
}
|
|
51
165
|
|
|
166
|
+
/* ===== Messages area ===== */
|
|
52
167
|
.chatbot-messages {
|
|
53
|
-
flex: 1;
|
|
54
|
-
padding: 16px;
|
|
168
|
+
flex: 1;
|
|
169
|
+
padding: 16px 14px;
|
|
55
170
|
overflow-y: auto;
|
|
56
171
|
display: flex;
|
|
57
172
|
flex-direction: column;
|
|
58
|
-
gap:
|
|
59
|
-
background-color:
|
|
60
|
-
min-height: 0;
|
|
61
|
-
|
|
173
|
+
gap: 10px;
|
|
174
|
+
background-color: var(--jaweb-surface-alt);
|
|
175
|
+
min-height: 0;
|
|
62
176
|
scrollbar-width: none;
|
|
63
177
|
-ms-overflow-style: none;
|
|
64
178
|
}
|
|
@@ -67,15 +181,43 @@
|
|
|
67
181
|
display: none;
|
|
68
182
|
}
|
|
69
183
|
|
|
184
|
+
/* ===== Bubbles ===== */
|
|
185
|
+
.chat-msg {
|
|
186
|
+
max-width: 85%;
|
|
187
|
+
padding: 10px 14px;
|
|
188
|
+
font-size: 14px;
|
|
189
|
+
line-height: 1.5;
|
|
190
|
+
word-break: break-word;
|
|
191
|
+
letter-spacing: -0.005em;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
.chat-msg.assistant {
|
|
195
|
+
background: var(--jaweb-surface);
|
|
196
|
+
border: 1px solid var(--jaweb-line);
|
|
197
|
+
border-radius: 16px 16px 16px 5px;
|
|
198
|
+
align-self: flex-start;
|
|
199
|
+
color: var(--jaweb-ink);
|
|
200
|
+
box-shadow: 0 1px 2px rgba(17, 24, 39, 0.04);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
.chat-msg.user {
|
|
204
|
+
background: var(--jaweb-accent);
|
|
205
|
+
border-radius: 16px 16px 5px 16px;
|
|
206
|
+
align-self: flex-end;
|
|
207
|
+
color: #ffffff;
|
|
208
|
+
box-shadow: 0 2px 6px rgba(17, 24, 39, 0.12);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/* ===== Input area shell ===== */
|
|
70
212
|
.chatbot-input-area {
|
|
71
213
|
width: 100%;
|
|
72
214
|
display: flex;
|
|
73
215
|
flex-direction: column;
|
|
74
216
|
align-items: center;
|
|
75
|
-
background:
|
|
76
|
-
border-top: 1px solid
|
|
77
|
-
padding: 12px;
|
|
78
|
-
flex-shrink: 0;
|
|
217
|
+
background: var(--jaweb-surface);
|
|
218
|
+
border-top: 1px solid var(--jaweb-line-soft);
|
|
219
|
+
padding: 10px 12px 8px;
|
|
220
|
+
flex-shrink: 0;
|
|
79
221
|
}
|
|
80
222
|
|
|
81
223
|
@media (max-width: 768px) {
|
|
@@ -90,92 +232,30 @@
|
|
|
90
232
|
top: 0;
|
|
91
233
|
left: 0;
|
|
92
234
|
border-radius: 0;
|
|
235
|
+
border: none;
|
|
93
236
|
}
|
|
94
|
-
|
|
237
|
+
|
|
95
238
|
.chat-launcher.chatbot-open {
|
|
96
239
|
display: none;
|
|
97
240
|
}
|
|
98
241
|
}
|
|
99
242
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
.chatbot-close {
|
|
108
|
-
cursor: pointer;
|
|
109
|
-
font-size: 16px;
|
|
110
|
-
color: #888;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
.chat-msg {
|
|
115
|
-
max-width: 85%;
|
|
116
|
-
padding: 10px 14px;
|
|
117
|
-
border-radius: 16px;
|
|
118
|
-
font-size: 14px;
|
|
119
|
-
line-height: 1.4;
|
|
120
|
-
word-break: break-word;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
.chat-msg.assistant {
|
|
124
|
-
background: #f0f0f0;
|
|
125
|
-
align-self: flex-start;
|
|
126
|
-
color: #000;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
.chat-msg.user {
|
|
130
|
-
background: #7f28f8;
|
|
131
|
-
align-self: flex-end;
|
|
132
|
-
color: white;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
.typing-animation span {
|
|
138
|
-
display: inline-block;
|
|
139
|
-
animation: blink 1.2s infinite;
|
|
140
|
-
font-size: 18px;
|
|
141
|
-
margin: 0 2px;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
.typing-animation span:nth-child(2) {
|
|
145
|
-
animation-delay: 0.2s;
|
|
146
|
-
}
|
|
147
|
-
.typing-animation span:nth-child(3) {
|
|
148
|
-
animation-delay: 0.4s;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
@keyframes blink {
|
|
152
|
-
0% { opacity: 0.2; }
|
|
153
|
-
20% { opacity: 1; }
|
|
154
|
-
100% { opacity: 0.2; }
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
/* brand color hook (optional) */
|
|
158
|
-
.jaweb-chatbot-container { --jaweb-color: #7f28f8; }
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
/*
|
|
167
|
-
@media (max-width: 600px) {
|
|
168
|
-
.chatbot-box {
|
|
169
|
-
position: fixed;
|
|
170
|
-
width: 100%;
|
|
171
|
-
height: 100%;
|
|
172
|
-
right: 0;
|
|
173
|
-
bottom: 0;
|
|
174
|
-
top: 0;
|
|
243
|
+
.typing-animation span {
|
|
244
|
+
display: inline-block;
|
|
245
|
+
animation: blink 1.2s infinite;
|
|
246
|
+
font-size: 18px;
|
|
247
|
+
margin: 0 2px;
|
|
248
|
+
}
|
|
175
249
|
|
|
250
|
+
.typing-animation span:nth-child(2) {
|
|
251
|
+
animation-delay: 0.2s;
|
|
252
|
+
}
|
|
253
|
+
.typing-animation span:nth-child(3) {
|
|
254
|
+
animation-delay: 0.4s;
|
|
255
|
+
}
|
|
176
256
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
257
|
+
@keyframes blink {
|
|
258
|
+
0% { opacity: 0.2; }
|
|
259
|
+
20% { opacity: 1; }
|
|
260
|
+
100% { opacity: 0.2; }
|
|
261
|
+
}
|
package/src/Chatbot/Chatbot.tsx
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import React, { useState, useEffect,useCallback } from 'react';
|
|
2
|
+
import { useTranslation } from 'react-i18next';
|
|
3
|
+
import { widgetDir } from '../i18n';
|
|
4
|
+
import '../i18n';
|
|
2
5
|
import { useChatbotData } from '../hooks/useChatbotData';
|
|
3
|
-
import ChatSessions from './components/Sessions/RenderList';
|
|
4
6
|
import CreateSession from './components/Sessions/CreateSession';
|
|
7
|
+
import Home from './components/Home/Home';
|
|
5
8
|
import Messenger from './components/Messenger/Messenger';
|
|
6
9
|
import './Chatbot.css';
|
|
7
10
|
import config from '../hooks/config';
|
|
@@ -14,7 +17,7 @@ import TryOnLayout from './components/TryOn/View';
|
|
|
14
17
|
import { useCart } from '../hooks/useCart';
|
|
15
18
|
const Chatbot: React.FC = () => {
|
|
16
19
|
const [open, setOpen] = useState(true);
|
|
17
|
-
const [viewMode, setViewMode] = useState<'
|
|
20
|
+
const [viewMode, setViewMode] = useState<'home' | 'create' | 'messenger' | 'cartView' | 'tryOn'>('home');
|
|
18
21
|
const [activeSessionId, setActiveSessionId] = useState<string | null>(null);
|
|
19
22
|
const [HasInfo, setHasInfo] = useState(false);
|
|
20
23
|
const [activeAgentName, setActiveAgentName] = useState('');
|
|
@@ -40,7 +43,7 @@ const [viewMode, setViewMode] = useState<'sessions' | 'create' | 'messenger' | '
|
|
|
40
43
|
} = useChatbotData();
|
|
41
44
|
|
|
42
45
|
const [visitorData, setVisitorData] = useState<{ visitorId: string; country: string } | null>(null);
|
|
43
|
-
const antIcon = <LoadingOutlined style={{ fontSize: 24, color: colorCode||'#
|
|
46
|
+
const antIcon = <LoadingOutlined style={{ fontSize: 24, color: colorCode||'#111111' }} spin />;
|
|
44
47
|
|
|
45
48
|
const handleNewSessionClick = () => {
|
|
46
49
|
// console.log(disableForm)
|
|
@@ -73,7 +76,6 @@ const [viewMode, setViewMode] = useState<'sessions' | 'create' | 'messenger' | '
|
|
|
73
76
|
const backendRes = await fetch(`${config.apiUrl}register-ip/`, {
|
|
74
77
|
method: 'POST',
|
|
75
78
|
headers: { 'Content-Type': 'application/json' },
|
|
76
|
-
credentials: 'include',
|
|
77
79
|
body: JSON.stringify({ visitor_id: visitorId }),
|
|
78
80
|
});
|
|
79
81
|
|
|
@@ -148,6 +150,8 @@ const [viewMode, setViewMode] = useState<'sessions' | 'create' | 'messenger' | '
|
|
|
148
150
|
|
|
149
151
|
|
|
150
152
|
|
|
153
|
+
const { i18n: i18nInstance } = useTranslation();
|
|
154
|
+
const boxDir = widgetDir(i18nInstance.language);
|
|
151
155
|
const { addToCart, removeFromCart } = useCart(activeSessionId ?? "");
|
|
152
156
|
|
|
153
157
|
const handleToCart = useCallback(
|
|
@@ -172,29 +176,33 @@ const [viewMode, setViewMode] = useState<'sessions' | 'create' | 'messenger' | '
|
|
|
172
176
|
return (
|
|
173
177
|
<div>
|
|
174
178
|
{open && (
|
|
175
|
-
<div
|
|
179
|
+
<div
|
|
180
|
+
className="chatbot-box"
|
|
181
|
+
dir={boxDir}
|
|
182
|
+
style={{ '--jaweb-accent': colorCode || '#111111' } as React.CSSProperties}
|
|
183
|
+
>
|
|
176
184
|
{isFetchingDetails ? (
|
|
177
185
|
<div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: 300 }}>
|
|
178
186
|
<Spin indicator={antIcon} tip="..." />
|
|
179
187
|
</div>
|
|
180
188
|
) : (
|
|
181
189
|
<AnimatePresence mode="sync">
|
|
182
|
-
{viewMode === '
|
|
190
|
+
{viewMode === 'home' && (
|
|
183
191
|
<motion.div
|
|
184
|
-
key="
|
|
185
|
-
initial={{ opacity: 0,
|
|
186
|
-
animate={{ opacity: 1,
|
|
187
|
-
exit={{ opacity: 0,
|
|
188
|
-
transition={{ duration: 0.
|
|
189
|
-
style={{height:'100%'}}
|
|
192
|
+
key="home"
|
|
193
|
+
initial={{ opacity: 0, y: 20 }}
|
|
194
|
+
animate={{ opacity: 1, y: 0 }}
|
|
195
|
+
exit={{ opacity: 0, y: -20 }}
|
|
196
|
+
transition={{ duration: 0.25 }}
|
|
197
|
+
style={{ height: '100%' }}
|
|
190
198
|
>
|
|
191
|
-
<
|
|
199
|
+
<Home
|
|
192
200
|
chatbotLogo={chatbotLogo}
|
|
193
|
-
|
|
201
|
+
chatbotName={chatbotName}
|
|
194
202
|
colorCode={colorCode}
|
|
195
203
|
visitorId={visitorData?.visitorId || ''}
|
|
196
|
-
|
|
197
|
-
|
|
204
|
+
merchantPhone={merchantPhone}
|
|
205
|
+
onClose={() => requestClose()}
|
|
198
206
|
onNewSession={handleNewSessionClick}
|
|
199
207
|
onSessionSelect={handleSessionSelect}
|
|
200
208
|
/>
|
|
@@ -214,7 +222,7 @@ const [viewMode, setViewMode] = useState<'sessions' | 'create' | 'messenger' | '
|
|
|
214
222
|
colorCode={colorCode}
|
|
215
223
|
visitorId={visitorData?.visitorId || ''}
|
|
216
224
|
country={visitorData?.country || ''}
|
|
217
|
-
onBack={() => setViewMode('
|
|
225
|
+
onBack={() => setViewMode('home')}
|
|
218
226
|
onCreate={(userData) => {
|
|
219
227
|
setActiveSessionId(userData.session_id);
|
|
220
228
|
setHasInfo(userData.hasInfo);
|
|
@@ -302,9 +310,8 @@ const [viewMode, setViewMode] = useState<'sessions' | 'create' | 'messenger' | '
|
|
|
302
310
|
onTryOnSelect={(product: any) => {
|
|
303
311
|
setTryOnProduct(product);
|
|
304
312
|
setViewMode('tryOn');
|
|
305
|
-
|
|
313
|
+
|
|
306
314
|
}}
|
|
307
|
-
userType={userType}
|
|
308
315
|
disbleCheckout={disbleCheckout}
|
|
309
316
|
setMessagesSuggestions={setMessagesSuggestions}
|
|
310
317
|
enableTry={enableTryOn}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React, { useState, useMemo } from "react";
|
|
2
|
+
import { useTranslation } from 'react-i18next';
|
|
2
3
|
import {
|
|
3
4
|
CloseOutlined,
|
|
4
5
|
ArrowLeftOutlined,
|
|
@@ -28,6 +29,7 @@ const CartLayout: React.FC<CartSessionProps> = ({
|
|
|
28
29
|
}) => {
|
|
29
30
|
const { items, loading, removeFromCart, refresh } = useCart(sessionId || "");
|
|
30
31
|
const { checkOut } = useCartAPI();
|
|
32
|
+
const { t } = useTranslation();
|
|
31
33
|
const [isLoading, setIsLoading] = useState(false);
|
|
32
34
|
|
|
33
35
|
/** ✅ Parse price from strings like "$2,000" or "USD 49.99" */
|
|
@@ -64,7 +66,7 @@ const CartLayout: React.FC<CartSessionProps> = ({
|
|
|
64
66
|
try {
|
|
65
67
|
await checkOut(sessionId);
|
|
66
68
|
} catch (err: any) {
|
|
67
|
-
message.error("
|
|
69
|
+
message.error(t("cart.checkoutFailed"));
|
|
68
70
|
console.error("Checkout error:", err);
|
|
69
71
|
} finally {
|
|
70
72
|
setIsLoading(false);
|
|
@@ -73,7 +75,7 @@ const CartLayout: React.FC<CartSessionProps> = ({
|
|
|
73
75
|
|
|
74
76
|
const loadingIcon = (
|
|
75
77
|
<LoadingOutlined
|
|
76
|
-
style={{ fontSize: 24, color: colorCode || "#
|
|
78
|
+
style={{ fontSize: 24, color: colorCode || "#111111" }}
|
|
77
79
|
spin
|
|
78
80
|
/>
|
|
79
81
|
);
|
|
@@ -130,7 +132,7 @@ const CartLayout: React.FC<CartSessionProps> = ({
|
|
|
130
132
|
}}
|
|
131
133
|
onMouseEnter={(e) =>
|
|
132
134
|
((e.currentTarget as HTMLElement).style.color =
|
|
133
|
-
colorCode || "#
|
|
135
|
+
colorCode || "#111111")
|
|
134
136
|
}
|
|
135
137
|
onMouseLeave={(e) =>
|
|
136
138
|
((e.currentTarget as HTMLElement).style.color = "#555")
|
|
@@ -150,7 +152,7 @@ const CartLayout: React.FC<CartSessionProps> = ({
|
|
|
150
152
|
>
|
|
151
153
|
<h3 style={{ fontWeight: 600, marginBottom: 16 }}>
|
|
152
154
|
<ShoppingOutlined style={{ marginRight: 8 }} />
|
|
153
|
-
|
|
155
|
+
{t('cart.yourCart', { count: items.length })}
|
|
154
156
|
</h3>
|
|
155
157
|
|
|
156
158
|
{loading ? (
|
|
@@ -159,7 +161,7 @@ const CartLayout: React.FC<CartSessionProps> = ({
|
|
|
159
161
|
</div>
|
|
160
162
|
) : items.length === 0 ? (
|
|
161
163
|
<div style={{ textAlign: "center", color: "#888", marginTop: 60 }}>
|
|
162
|
-
|
|
164
|
+
{t('cart.empty')}
|
|
163
165
|
</div>
|
|
164
166
|
) : (
|
|
165
167
|
<div
|
|
@@ -215,7 +217,7 @@ const CartLayout: React.FC<CartSessionProps> = ({
|
|
|
215
217
|
{item.name}
|
|
216
218
|
</p>
|
|
217
219
|
<p style={{ fontSize: 13, color: "#777", margin: 0 }}>
|
|
218
|
-
|
|
220
|
+
{t('cart.qty', { count: item.quantity })}
|
|
219
221
|
</p>
|
|
220
222
|
</div>
|
|
221
223
|
</div>
|
|
@@ -271,7 +273,7 @@ const CartLayout: React.FC<CartSessionProps> = ({
|
|
|
271
273
|
color: "#222",
|
|
272
274
|
}}
|
|
273
275
|
>
|
|
274
|
-
<span>
|
|
276
|
+
<span>{t('cart.subtotal')}</span>
|
|
275
277
|
<span>{subtotal.toLocaleString()}</span>
|
|
276
278
|
</div>
|
|
277
279
|
|
|
@@ -289,7 +291,7 @@ const CartLayout: React.FC<CartSessionProps> = ({
|
|
|
289
291
|
fontWeight: 600,
|
|
290
292
|
}}
|
|
291
293
|
>
|
|
292
|
-
<span style={{ color: "white" }}>
|
|
294
|
+
<span style={{ color: "white" }}>{t("cart.checkout")}</span>
|
|
293
295
|
</Button>
|
|
294
296
|
</div>
|
|
295
297
|
</div>
|