shopify-chatbot-widget 1.0.9 → 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.
Files changed (44) hide show
  1. package/.env.development +2 -0
  2. package/dist/jaweb-chatbot.css +1 -1
  3. package/dist/jaweb-chatbot.iife.js +192 -599
  4. package/package.json +1 -1
  5. package/src/App.tsx +9 -0
  6. package/src/Chatbot/Chatbot.css +193 -113
  7. package/src/Chatbot/Chatbot.tsx +26 -19
  8. package/src/Chatbot/components/Cart/Index.tsx +10 -8
  9. package/src/Chatbot/components/ChatInput.tsx +11 -11
  10. package/src/Chatbot/components/Home/Home.css +456 -0
  11. package/src/Chatbot/components/Home/Home.tsx +293 -0
  12. package/src/Chatbot/components/Messages/Addcart.tsx +1 -1
  13. package/src/Chatbot/components/Messages/AssistantMesage.tsx +78 -37
  14. package/src/Chatbot/components/Messages/CardSwiper.tsx +1 -1
  15. package/src/Chatbot/components/Messages/Carousel/CardSwiper.tsx +87 -92
  16. package/src/Chatbot/components/Messages/Carousel/ProductSwiper.css +361 -0
  17. package/src/Chatbot/components/Messages/Carousel/TryOn.tsx +2 -2
  18. package/src/Chatbot/components/Messages/ChatMessages.css +32 -1
  19. package/src/Chatbot/components/Messages/ChatMessages.tsx +21 -38
  20. package/src/Chatbot/components/Messages/OrderCard.css +177 -0
  21. package/src/Chatbot/components/Messages/OrderCard.tsx +120 -0
  22. package/src/Chatbot/components/Messages/ProductCard.css +1 -1
  23. package/src/Chatbot/components/Messages/Support.tsx +311 -118
  24. package/src/Chatbot/components/Messages/Typing.css +31 -35
  25. package/src/Chatbot/components/Messages/Typing.tsx +19 -18
  26. package/src/Chatbot/components/Messenger/Messenger.tsx +67 -14
  27. package/src/Chatbot/components/Powered.css +26 -28
  28. package/src/Chatbot/components/Powered.tsx +1 -1
  29. package/src/Chatbot/components/Sessions/CreateSession.tsx +12 -10
  30. package/src/Chatbot/components/TryOn/View.tsx +2 -2
  31. package/src/Chatbot/components/VoiceMode.css +247 -0
  32. package/src/Chatbot/components/VoiceMode.tsx +613 -0
  33. package/src/hooks/config.tsx +9 -10
  34. package/src/hooks/useChatbotAPI.tsx +146 -61
  35. package/src/hooks/useChatbotData.tsx +8 -5
  36. package/src/hooks/useSessionMessages.tsx +0 -1
  37. package/src/hooks/useWebsocke.tsx +40 -18
  38. package/src/i18n.tsx +384 -10
  39. package/src/Chatbot/components/Messages/Carousel/CardSwiperSalla.tsx +0 -187
  40. package/src/Chatbot/components/Messages/Carousel/CardSwiperZid.tsx +0 -208
  41. package/src/Chatbot/components/Messages/Carousel/SallaSwiper.css +0 -245
  42. package/src/Chatbot/components/Messages/SallaAssistantMessage.tsx +0 -202
  43. package/src/Chatbot/components/Messages/ZidAssistantMesage.tsx +0 -203
  44. package/src/Chatbot/components/Sessions/RenderList.tsx +0 -519
@@ -44,4 +44,35 @@
44
44
 
45
45
  .first-message {
46
46
  animation: fadeSlideIn 0.5s ease-out;
47
- }
47
+ }
48
+ /* Support handoff — mini equalizer bars (matches voice mode) */
49
+ .jwbS-bars {
50
+ --jwbS-accent: #111827;
51
+ display: inline-flex;
52
+ align-items: center;
53
+ gap: 3px;
54
+ height: 22px;
55
+ flex-shrink: 0;
56
+ }
57
+
58
+ .jwbS-bars span {
59
+ width: 4px;
60
+ height: 16px;
61
+ border-radius: 3px;
62
+ background: var(--jwbS-accent);
63
+ animation: jwbS-wave 1.1s ease-in-out infinite;
64
+ transform-origin: center;
65
+ }
66
+
67
+ .jwbS-bars span:nth-child(2) {
68
+ animation-delay: 0.18s;
69
+ }
70
+
71
+ .jwbS-bars span:nth-child(3) {
72
+ animation-delay: 0.36s;
73
+ }
74
+
75
+ @keyframes jwbS-wave {
76
+ 0%, 100% { transform: scaleY(0.4); opacity: 0.6; }
77
+ 50% { transform: scaleY(1); opacity: 1; }
78
+ }
@@ -11,8 +11,6 @@ import AgentStatusBanner from './AgentStatus';
11
11
  import AddToCartConfirmation from './Addcart';
12
12
  import SupportConnect from './Support';
13
13
  import ChatImageTextAssist from './ChatImageTextAssis';
14
- import ZidAssistantChatMessage from './ZidAssistantMesage';
15
- import SallaAsssiatnt from './SallaAssistantMessage';
16
14
  import CalendlyEmbeds from './CalendlyEmbeds';
17
15
 
18
16
 
@@ -50,7 +48,6 @@ interface ChatMessagesProps {
50
48
  status?: string;
51
49
  user?: string;
52
50
  };
53
- userType: string;
54
51
  calendly: string;
55
52
  disableCheckout: boolean;
56
53
  isfetchingMessage: boolean;
@@ -117,7 +114,6 @@ const ChatMessages: React.FC<ChatMessagesProps> = ({
117
114
  isLoading,
118
115
  agentStatus,
119
116
  sessionId,
120
- userType,
121
117
  calendly,
122
118
  disableCheckout,
123
119
  isfetchingMessage,
@@ -188,7 +184,18 @@ const ChatMessages: React.FC<ChatMessagesProps> = ({
188
184
  }
189
185
 
190
186
  if (msg.isConnect) {
191
- return <SupportConnect key={i} sessionId={sessionId} />;
187
+ // Escalations carry their ticket in the message content
188
+ let ticket = null;
189
+ const rawContent = typeof msg.content === 'string' ? msg.content : '';
190
+ const tm = rawContent.match(/\[\[SUPPORT_TICKET\]\]([\s\S]*?)\[\[\/SUPPORT_TICKET\]\]/);
191
+ if (tm) {
192
+ try {
193
+ ticket = JSON.parse(tm[1]);
194
+ } catch { /* no ticket card, stage card still shows */ }
195
+ }
196
+ return (
197
+ <SupportConnect key={i} sessionId={sessionId} colorCode={colorCode} ticket={ticket} />
198
+ );
192
199
  }
193
200
 
194
201
  if (msg.isBookings) {
@@ -254,39 +261,15 @@ const ChatMessages: React.FC<ChatMessagesProps> = ({
254
261
  />
255
262
  )}
256
263
 
257
- {userType === "shopify" ? (
258
- <AssistantMessage
259
- message={msg.content || msg.text || ""}
260
- colorCode={colorCode}
261
- disableCheckout={disableCheckout}
262
- handleAddToCart={handleAddToCart}
263
- handleRemoveFromCart={handleRemoveFromCart}
264
- onTryOnSelect={onTryOnSelect}
265
- enableTry={enableTry}
266
- />
267
- ) : userType === "salla" ? (
268
- <SallaAsssiatnt
269
- message={msg.content || msg.text || ""}
270
- colorCode={colorCode}
271
- handleAddToCart={handleAddToCart}
272
- handleRemoveFromCart={handleRemoveFromCart}
273
- onTryOnSelect={onTryOnSelect}
274
- enableTry={enableTry}
275
- // enableTry={enableTry}
276
-
277
- />
278
- ) : (
279
- <ZidAssistantChatMessage
280
- message={msg.content || msg.text || ""}
281
- colorCode={colorCode}
282
- handleAddToCart={handleAddToCart}
283
- handleRemoveFromCart={handleRemoveFromCart}
284
- onTryOnSelect={onTryOnSelect}
285
- enableTry={enableTry}
286
- // enableTry={enableTry}
287
-
288
- />
289
- )}
264
+ <AssistantMessage
265
+ message={msg.content || msg.text || ""}
266
+ colorCode={colorCode}
267
+ disableCheckout={disableCheckout}
268
+ handleAddToCart={handleAddToCart}
269
+ handleRemoveFromCart={handleRemoveFromCart}
270
+ onTryOnSelect={onTryOnSelect}
271
+ enableTry={enableTry}
272
+ />
290
273
  </div>
291
274
 
292
275
  {/* ADD suggestions here - MOVED OUTSIDE the chat-msg div */}
@@ -0,0 +1,177 @@
1
+ /* Order tracking card — matches the product card design language */
2
+ .jwbO-card {
3
+ --jwbO-accent: #111111;
4
+ background: #ffffff;
5
+ border: 1px solid #ececec;
6
+ border-radius: 16px;
7
+ padding: 14px;
8
+ box-shadow: 0 1px 2px rgba(17, 24, 39, 0.05);
9
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
10
+ color: #111827;
11
+ max-width: 340px;
12
+ }
13
+
14
+ .jwbO-head {
15
+ display: flex;
16
+ align-items: center;
17
+ justify-content: space-between;
18
+ gap: 10px;
19
+ margin-bottom: 14px;
20
+ }
21
+
22
+ .jwbO-label {
23
+ display: block;
24
+ font-size: 10px;
25
+ font-weight: 700;
26
+ letter-spacing: 0.1em;
27
+ text-transform: uppercase;
28
+ color: #9ca3af;
29
+ }
30
+
31
+ .jwbO-number {
32
+ font-size: 16px;
33
+ font-weight: 700;
34
+ letter-spacing: -0.01em;
35
+ }
36
+
37
+ .jwbO-pill {
38
+ font-size: 11px;
39
+ font-weight: 700;
40
+ padding: 5px 10px;
41
+ border-radius: 999px;
42
+ background: var(--jwbO-accent);
43
+ color: #ffffff;
44
+ white-space: nowrap;
45
+ }
46
+
47
+ .jwbO-pill--done {
48
+ background: #16a34a;
49
+ }
50
+
51
+ /* ===== Timeline ===== */
52
+ .jwbO-timeline {
53
+ display: flex;
54
+ margin-bottom: 12px;
55
+ }
56
+
57
+ .jwbO-step {
58
+ flex: 1;
59
+ display: flex;
60
+ flex-direction: column;
61
+ gap: 5px;
62
+ min-width: 0;
63
+ }
64
+
65
+ .jwbO-step:last-child {
66
+ flex: 0 0 auto;
67
+ }
68
+
69
+ .jwbO-track {
70
+ display: flex;
71
+ align-items: center;
72
+ }
73
+
74
+ .jwbO-dot {
75
+ width: 18px;
76
+ height: 18px;
77
+ border-radius: 50%;
78
+ border: 2px solid #e5e7eb;
79
+ background: #ffffff;
80
+ color: #ffffff;
81
+ font-size: 10px;
82
+ font-weight: 700;
83
+ display: flex;
84
+ align-items: center;
85
+ justify-content: center;
86
+ flex-shrink: 0;
87
+ }
88
+
89
+ .jwbO-dot--done {
90
+ background: var(--jwbO-accent);
91
+ border-color: var(--jwbO-accent);
92
+ }
93
+
94
+ .jwbO-line {
95
+ flex: 1;
96
+ height: 2px;
97
+ background: #e5e7eb;
98
+ margin: 0 3px;
99
+ min-width: 14px;
100
+ }
101
+
102
+ .jwbO-line--done {
103
+ background: var(--jwbO-accent);
104
+ }
105
+
106
+ .jwbO-stepLabel {
107
+ font-size: 10px;
108
+ font-weight: 600;
109
+ color: #9ca3af;
110
+ }
111
+
112
+ .jwbO-stepLabel--done {
113
+ color: #111827;
114
+ }
115
+
116
+ /* ===== Meta ===== */
117
+ .jwbO-meta {
118
+ font-size: 12px;
119
+ color: #6b7280;
120
+ margin: 0 0 4px;
121
+ }
122
+
123
+ .jwbO-items {
124
+ font-size: 12px;
125
+ color: #6b7280;
126
+ margin: 0;
127
+ white-space: nowrap;
128
+ overflow: hidden;
129
+ text-overflow: ellipsis;
130
+ }
131
+
132
+ /* ===== Tracking footer ===== */
133
+ .jwbO-tracking {
134
+ display: flex;
135
+ align-items: center;
136
+ justify-content: space-between;
137
+ gap: 10px;
138
+ margin-top: 12px;
139
+ padding-top: 12px;
140
+ border-top: 1px solid #f3f4f6;
141
+ }
142
+
143
+ .jwbO-trackingInfo {
144
+ display: flex;
145
+ flex-direction: column;
146
+ gap: 1px;
147
+ min-width: 0;
148
+ }
149
+
150
+ .jwbO-carrier {
151
+ font-size: 12px;
152
+ font-weight: 700;
153
+ }
154
+
155
+ .jwbO-trackingNo {
156
+ font-size: 11px;
157
+ color: #6b7280;
158
+ font-variant-numeric: tabular-nums;
159
+ overflow: hidden;
160
+ text-overflow: ellipsis;
161
+ }
162
+
163
+ .jwbO-trackBtn {
164
+ flex-shrink: 0;
165
+ background: var(--jwbO-accent);
166
+ color: #ffffff;
167
+ font-size: 12px;
168
+ font-weight: 700;
169
+ padding: 9px 14px;
170
+ border-radius: 10px;
171
+ text-decoration: none;
172
+ transition: opacity 0.15s ease;
173
+ }
174
+
175
+ .jwbO-trackBtn:hover {
176
+ opacity: 0.85;
177
+ }
@@ -0,0 +1,120 @@
1
+ import type { FC } from 'react';
2
+ import './OrderCard.css';
3
+ import { useTranslation } from 'react-i18next';
4
+
5
+ export interface OrderStatusData {
6
+ order: string;
7
+ placed?: string;
8
+ payment?: string;
9
+ fulfillment?: string;
10
+ shipment_status?: string;
11
+ items?: string[];
12
+ tracking_company?: string | null;
13
+ tracking_number?: string | null;
14
+ tracking_url?: string | null;
15
+ }
16
+
17
+ interface Props {
18
+ data: OrderStatusData;
19
+ colorCode?: string;
20
+ }
21
+
22
+ const STEP_KEYS = ['order.stepPlaced', 'order.stepPaid', 'order.stepShipped', 'order.stepDelivered'] as const;
23
+
24
+ const OrderCard: FC<Props> = ({ data, colorCode = '#111111' }) => {
25
+ const { t } = useTranslation();
26
+ const payment = (data.payment || '').toUpperCase();
27
+ const fulfillment = (data.fulfillment || '').toUpperCase();
28
+ const shipment = (data.shipment_status || '').toUpperCase();
29
+
30
+ const paid = payment.includes('PAID') || payment.includes('REFUND');
31
+ const shipped =
32
+ shipment !== '' ||
33
+ fulfillment === 'FULFILLED' ||
34
+ fulfillment === 'PARTIALLY_FULFILLED';
35
+ const delivered = shipment === 'DELIVERED';
36
+
37
+ const doneCount = delivered ? 4 : shipped ? 3 : paid ? 2 : 1;
38
+
39
+ const stageLabel = delivered
40
+ ? t('order.delivered')
41
+ : shipped
42
+ ? t('order.onItsWay')
43
+ : paid
44
+ ? t('order.preparing')
45
+ : t('order.awaitingPayment');
46
+
47
+ return (
48
+ <div
49
+ className="jwbO-card"
50
+ style={{ '--jwbO-accent': colorCode } as React.CSSProperties}
51
+ >
52
+ <div className="jwbO-head">
53
+ <div>
54
+ <span className="jwbO-label">{t('order.order')}</span>
55
+ <span className="jwbO-number">{data.order}</span>
56
+ </div>
57
+ <span className={`jwbO-pill ${delivered ? 'jwbO-pill--done' : ''}`}>
58
+ {stageLabel}
59
+ </span>
60
+ </div>
61
+
62
+ <div className="jwbO-timeline" role="list" aria-label={t('order.progress')}>
63
+ {STEP_KEYS.map((step, i) => {
64
+ const done = i < doneCount;
65
+ const isLast = i === STEP_KEYS.length - 1;
66
+ return (
67
+ <div key={step} className="jwbO-step" role="listitem">
68
+ <div className="jwbO-track">
69
+ <span className={`jwbO-dot ${done ? 'jwbO-dot--done' : ''}`}>
70
+ {done ? '✓' : ''}
71
+ </span>
72
+ {!isLast && (
73
+ <span
74
+ className={`jwbO-line ${i < doneCount - 1 ? 'jwbO-line--done' : ''}`}
75
+ />
76
+ )}
77
+ </div>
78
+ <span className={`jwbO-stepLabel ${done ? 'jwbO-stepLabel--done' : ''}`}>
79
+ {t(step)}
80
+ </span>
81
+ </div>
82
+ );
83
+ })}
84
+ </div>
85
+
86
+ {data.placed && <p className="jwbO-meta">{t('order.placedOn', { date: data.placed })}</p>}
87
+
88
+ {data.items && data.items.length > 0 && (
89
+ <p className="jwbO-items" title={data.items.join(', ')}>
90
+ {data.items.join(', ')}
91
+ </p>
92
+ )}
93
+
94
+ {(data.tracking_company || data.tracking_number || data.tracking_url) && (
95
+ <div className="jwbO-tracking">
96
+ <div className="jwbO-trackingInfo">
97
+ {data.tracking_company && (
98
+ <span className="jwbO-carrier">{data.tracking_company}</span>
99
+ )}
100
+ {data.tracking_number && (
101
+ <span className="jwbO-trackingNo">{data.tracking_number}</span>
102
+ )}
103
+ </div>
104
+ {data.tracking_url && (
105
+ <a
106
+ href={data.tracking_url}
107
+ target="_blank"
108
+ rel="noopener noreferrer"
109
+ className="jwbO-trackBtn"
110
+ >
111
+ {t('order.trackPackage')}
112
+ </a>
113
+ )}
114
+ </div>
115
+ )}
116
+ </div>
117
+ );
118
+ };
119
+
120
+ export default OrderCard;
@@ -113,7 +113,7 @@
113
113
  }
114
114
 
115
115
  .increment {
116
- background-color: #7f28f8;
116
+ background-color: #111111;
117
117
  color: white;
118
118
  }
119
119