@uptrademedia/site-kit 1.0.19 → 1.0.20
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/{chunk-AZUOQAV6.js → chunk-D5VBZVOE.js} +135 -31
- package/dist/chunk-D5VBZVOE.js.map +1 -0
- package/dist/chunk-EL5QTAA3.mjs +1 -0
- package/dist/chunk-IJVPYQAB.mjs +1 -0
- package/dist/chunk-QD66FTXZ.mjs +1 -0
- package/dist/{chunk-XIF2CBLV.mjs → chunk-UWUYO5DJ.mjs} +135 -31
- package/dist/chunk-UWUYO5DJ.mjs.map +1 -0
- package/dist/chunk-WPSRS352.mjs +1 -0
- package/dist/chunk-XFRPT5ZX.mjs +1 -0
- package/dist/chunk-YHQHSM76.mjs +1 -0
- package/dist/engage/index.js +4 -4
- package/dist/engage/index.mjs +1 -1
- package/dist/index.js +2 -2
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
- package/dist/chunk-AZUOQAV6.js.map +0 -1
- package/dist/chunk-XIF2CBLV.mjs.map +0 -1
|
@@ -54,6 +54,7 @@ function ChatWidget({ projectId, config, apiUrl: propApiUrl }) {
|
|
|
54
54
|
const [pendingFiles, setPendingFiles] = React2.useState([]);
|
|
55
55
|
const [lastFailedSend, setLastFailedSend] = React2.useState(null);
|
|
56
56
|
const [showWelcome, setShowWelcome] = React2.useState(true);
|
|
57
|
+
const [checkingAvailability, setCheckingAvailability] = React2.useState(false);
|
|
57
58
|
React2.useRef(null);
|
|
58
59
|
const messagesEndRef = React2.useRef(null);
|
|
59
60
|
const inputRef = React2.useRef(null);
|
|
@@ -74,7 +75,7 @@ function ChatWidget({ projectId, config, apiUrl: propApiUrl }) {
|
|
|
74
75
|
const fetchWidgetConfig = React2.useCallback(async () => {
|
|
75
76
|
try {
|
|
76
77
|
const { apiKey } = getApiConfig();
|
|
77
|
-
const response = await fetch(`${baseUrl}/
|
|
78
|
+
const response = await fetch(`${baseUrl}/engage/widget/config?projectId=${projectId}`, {
|
|
78
79
|
headers: apiKey ? { "x-api-key": apiKey } : {}
|
|
79
80
|
});
|
|
80
81
|
if (response.ok) {
|
|
@@ -88,25 +89,23 @@ function ChatWidget({ projectId, config, apiUrl: propApiUrl }) {
|
|
|
88
89
|
const checkAvailability = React2.useCallback(async () => {
|
|
89
90
|
try {
|
|
90
91
|
const { apiKey } = getApiConfig();
|
|
91
|
-
const response = await fetch(`${baseUrl}/
|
|
92
|
+
const response = await fetch(`${baseUrl}/engage/widget/availability?projectId=${projectId}`, {
|
|
92
93
|
headers: apiKey ? { "x-api-key": apiKey } : {}
|
|
93
94
|
});
|
|
94
95
|
if (response.ok) {
|
|
95
96
|
const { data } = await response.json();
|
|
96
97
|
setAvailability(data);
|
|
97
|
-
|
|
98
|
-
setShowOfflineForm(true);
|
|
99
|
-
setShowWelcome(false);
|
|
100
|
-
}
|
|
98
|
+
return data;
|
|
101
99
|
}
|
|
102
100
|
} catch (error) {
|
|
103
101
|
console.error("[ChatWidget] Availability check failed:", error);
|
|
104
102
|
}
|
|
105
|
-
|
|
103
|
+
return null;
|
|
104
|
+
}, [projectId, baseUrl]);
|
|
106
105
|
const initSession = React2.useCallback(async () => {
|
|
107
106
|
try {
|
|
108
107
|
const { apiKey } = getApiConfig();
|
|
109
|
-
const response = await fetch(`${baseUrl}/
|
|
108
|
+
const response = await fetch(`${baseUrl}/engage/widget/session`, {
|
|
110
109
|
method: "POST",
|
|
111
110
|
headers: { "Content-Type": "application/json", ...apiKey && { "x-api-key": apiKey } },
|
|
112
111
|
body: JSON.stringify({
|
|
@@ -209,7 +208,7 @@ function ChatWidget({ projectId, config, apiUrl: propApiUrl }) {
|
|
|
209
208
|
console.log("[ChatWidget] Socket.io connected");
|
|
210
209
|
if (currentSessionId) {
|
|
211
210
|
const { apiKey } = getApiConfig();
|
|
212
|
-
fetch(`${baseUrl}/
|
|
211
|
+
fetch(`${baseUrl}/engage/widget/messages?sessionId=${currentSessionId}`, {
|
|
213
212
|
headers: apiKey ? { "x-api-key": apiKey } : {}
|
|
214
213
|
}).then((res) => res.ok ? res.json() : null).then((json) => {
|
|
215
214
|
const data = json?.data ?? json;
|
|
@@ -272,7 +271,7 @@ function ChatWidget({ projectId, config, apiUrl: propApiUrl }) {
|
|
|
272
271
|
pollingIntervalRef.current = setInterval(async () => {
|
|
273
272
|
try {
|
|
274
273
|
const { apiKey } = getApiConfig();
|
|
275
|
-
const response = await fetch(`${baseUrl}/
|
|
274
|
+
const response = await fetch(`${baseUrl}/engage/widget/messages?sessionId=${currentSessionId}`, {
|
|
276
275
|
headers: apiKey ? { "x-api-key": apiKey } : {}
|
|
277
276
|
});
|
|
278
277
|
if (response.ok) {
|
|
@@ -321,7 +320,7 @@ function ChatWidget({ projectId, config, apiUrl: propApiUrl }) {
|
|
|
321
320
|
};
|
|
322
321
|
}, [fetchWidgetConfig, checkAvailability]);
|
|
323
322
|
React2.useEffect(() => {
|
|
324
|
-
if (isOpen && !showWelcome && !sessionId && availability?.mode !== "offline") {
|
|
323
|
+
if (isOpen && !showWelcome && !checkingAvailability && !showOfflineForm && !sessionId && availability?.mode !== "offline") {
|
|
325
324
|
initSession().then((id) => {
|
|
326
325
|
if (id && (availability?.mode === "live" || availability?.mode === "ai")) {
|
|
327
326
|
setConnectionStatus("connecting");
|
|
@@ -332,26 +331,47 @@ function ChatWidget({ projectId, config, apiUrl: propApiUrl }) {
|
|
|
332
331
|
return () => {
|
|
333
332
|
if (pollingIntervalRef.current) clearInterval(pollingIntervalRef.current);
|
|
334
333
|
};
|
|
335
|
-
}, [isOpen, showWelcome, sessionId, availability?.mode, initSession, connectSocket]);
|
|
334
|
+
}, [isOpen, showWelcome, checkingAvailability, showOfflineForm, sessionId, availability?.mode, initSession, connectSocket]);
|
|
336
335
|
const handleToggle = React2.useCallback(() => {
|
|
337
336
|
setIsOpen((prev) => !prev);
|
|
338
337
|
}, []);
|
|
339
338
|
const startChat = React2.useCallback(
|
|
340
|
-
(initialMessage) => {
|
|
339
|
+
async (initialMessage) => {
|
|
341
340
|
setShowWelcome(false);
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
341
|
+
const beginChatSession = () => {
|
|
342
|
+
setMessages([{ id: "welcome", role: "assistant", content: welcomeMessage, timestamp: /* @__PURE__ */ new Date() }]);
|
|
343
|
+
if (initialMessage) {
|
|
344
|
+
setInputValue(initialMessage);
|
|
345
|
+
setTimeout(() => {
|
|
346
|
+
setInputValue("");
|
|
347
|
+
const userMsg = { id: `user-${Date.now()}`, role: "user", content: initialMessage, timestamp: /* @__PURE__ */ new Date() };
|
|
348
|
+
setMessages((prev) => [...prev, userMsg]);
|
|
349
|
+
setIsLoading(true);
|
|
350
|
+
setLastFailedSend({ content: initialMessage, attachments: [] });
|
|
351
|
+
}, 100);
|
|
352
|
+
}
|
|
353
|
+
};
|
|
354
|
+
if (availability?.mode === "ai") {
|
|
355
|
+
beginChatSession();
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
setCheckingAvailability(true);
|
|
359
|
+
const firstCheck = await checkAvailability();
|
|
360
|
+
if (firstCheck?.available && firstCheck.agentsOnline > 0) {
|
|
361
|
+
setCheckingAvailability(false);
|
|
362
|
+
beginChatSession();
|
|
363
|
+
return;
|
|
364
|
+
}
|
|
365
|
+
await new Promise((resolve) => setTimeout(resolve, 5e3));
|
|
366
|
+
const secondCheck = await checkAvailability();
|
|
367
|
+
setCheckingAvailability(false);
|
|
368
|
+
if (secondCheck?.available && secondCheck.agentsOnline > 0) {
|
|
369
|
+
beginChatSession();
|
|
370
|
+
} else {
|
|
371
|
+
setShowOfflineForm(true);
|
|
352
372
|
}
|
|
353
373
|
},
|
|
354
|
-
[welcomeMessage]
|
|
374
|
+
[availability, welcomeMessage, checkAvailability]
|
|
355
375
|
);
|
|
356
376
|
const uploadWidgetFile = React2.useCallback(
|
|
357
377
|
async (file) => {
|
|
@@ -361,7 +381,7 @@ function ChatWidget({ projectId, config, apiUrl: propApiUrl }) {
|
|
|
361
381
|
form.append("file", file);
|
|
362
382
|
form.append("sessionId", sessionId);
|
|
363
383
|
form.append("visitorId", visitorId);
|
|
364
|
-
const res = await fetch(`${baseUrl}/
|
|
384
|
+
const res = await fetch(`${baseUrl}/engage/widget/upload`, {
|
|
365
385
|
method: "POST",
|
|
366
386
|
headers: apiKey ? { "x-api-key": apiKey } : {},
|
|
367
387
|
body: form
|
|
@@ -439,7 +459,7 @@ function ChatWidget({ projectId, config, apiUrl: propApiUrl }) {
|
|
|
439
459
|
if (!sessionId) return;
|
|
440
460
|
try {
|
|
441
461
|
const { apiKey } = getApiConfig();
|
|
442
|
-
const availRes = await fetch(`${baseUrl}/
|
|
462
|
+
const availRes = await fetch(`${baseUrl}/engage/widget/availability?projectId=${projectId}`, {
|
|
443
463
|
headers: apiKey ? { "x-api-key": apiKey } : {}
|
|
444
464
|
});
|
|
445
465
|
const avail = availRes.ok ? (await availRes.json()).data : null;
|
|
@@ -452,7 +472,7 @@ function ChatWidget({ projectId, config, apiUrl: propApiUrl }) {
|
|
|
452
472
|
]);
|
|
453
473
|
return;
|
|
454
474
|
}
|
|
455
|
-
await fetch(`${baseUrl}/
|
|
475
|
+
await fetch(`${baseUrl}/engage/widget/handoff`, {
|
|
456
476
|
method: "POST",
|
|
457
477
|
headers: { "Content-Type": "application/json", ...apiKey && { "x-api-key": apiKey } },
|
|
458
478
|
body: JSON.stringify({ sessionId })
|
|
@@ -472,7 +492,7 @@ function ChatWidget({ projectId, config, apiUrl: propApiUrl }) {
|
|
|
472
492
|
setIsLoading(true);
|
|
473
493
|
try {
|
|
474
494
|
const { apiKey } = getApiConfig();
|
|
475
|
-
const response = await fetch(`${baseUrl}/
|
|
495
|
+
const response = await fetch(`${baseUrl}/engage/widget/offline-form`, {
|
|
476
496
|
method: "POST",
|
|
477
497
|
headers: { "Content-Type": "application/json", ...apiKey && { "x-api-key": apiKey } },
|
|
478
498
|
body: JSON.stringify({
|
|
@@ -509,6 +529,7 @@ function ChatWidget({ projectId, config, apiUrl: propApiUrl }) {
|
|
|
509
529
|
}, []);
|
|
510
530
|
const statusLabel = (() => {
|
|
511
531
|
if (showOfflineForm) return null;
|
|
532
|
+
if (checkingAvailability) return { dot: "#f59e0b", text: "Checking availability..." };
|
|
512
533
|
if (availability?.mode === "live" && availability.agentsOnline > 0) return { dot: "#22c55e", text: "Online" };
|
|
513
534
|
if (availability?.mode === "ai") return { dot: "#a78bfa", text: "AI Assistant" };
|
|
514
535
|
return { dot: "#9ca3af", text: "We'll respond soon" };
|
|
@@ -705,6 +726,75 @@ function ChatWidget({ projectId, config, apiUrl: propApiUrl }) {
|
|
|
705
726
|
}
|
|
706
727
|
)
|
|
707
728
|
] }) });
|
|
729
|
+
const CheckingScreen = /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { flex: 1, display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", padding: 32, gap: 20, textAlign: "center" }, children: [
|
|
730
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { position: "relative", width: 64, height: 64 }, children: [
|
|
731
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
732
|
+
"div",
|
|
733
|
+
{
|
|
734
|
+
style: {
|
|
735
|
+
position: "absolute",
|
|
736
|
+
inset: 0,
|
|
737
|
+
borderRadius: "50%",
|
|
738
|
+
backgroundColor: `${primaryColor}15`,
|
|
739
|
+
animation: "checkPulse 2s infinite ease-out"
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
),
|
|
743
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
744
|
+
"div",
|
|
745
|
+
{
|
|
746
|
+
style: {
|
|
747
|
+
position: "absolute",
|
|
748
|
+
inset: 8,
|
|
749
|
+
borderRadius: "50%",
|
|
750
|
+
backgroundColor: `${primaryColor}25`,
|
|
751
|
+
animation: "checkPulse 2s infinite ease-out 0.4s"
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
),
|
|
755
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
756
|
+
"div",
|
|
757
|
+
{
|
|
758
|
+
style: {
|
|
759
|
+
position: "absolute",
|
|
760
|
+
inset: 16,
|
|
761
|
+
borderRadius: "50%",
|
|
762
|
+
backgroundColor: primaryColor,
|
|
763
|
+
display: "flex",
|
|
764
|
+
alignItems: "center",
|
|
765
|
+
justifyContent: "center"
|
|
766
|
+
},
|
|
767
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: isLightColor(primaryColor) ? "#1a1a1a" : "white", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
768
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M16 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2" }),
|
|
769
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "8.5", cy: "7", r: "4" }),
|
|
770
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: "20", y1: "8", x2: "20", y2: "14" }),
|
|
771
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: "23", y1: "11", x2: "17", y2: "11" })
|
|
772
|
+
] })
|
|
773
|
+
}
|
|
774
|
+
)
|
|
775
|
+
] }),
|
|
776
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
777
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 16, fontWeight: 600, color: "#111827", marginBottom: 6 }, children: "Checking if any agents are available" }),
|
|
778
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { fontSize: 14, color: "#6b7280", lineHeight: 1.5 }, children: [
|
|
779
|
+
"One moment please",
|
|
780
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { display: "inline-flex", width: 20 }, children: /* @__PURE__ */ jsxRuntime.jsx("span", { style: { animation: "checkDots 1.5s infinite steps(4, end)" }, children: "..." }) })
|
|
781
|
+
] })
|
|
782
|
+
] }),
|
|
783
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { width: "80%", height: 3, backgroundColor: "#e5e7eb", borderRadius: 2, overflow: "hidden" }, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
784
|
+
"div",
|
|
785
|
+
{
|
|
786
|
+
style: {
|
|
787
|
+
width: "100%",
|
|
788
|
+
height: "100%",
|
|
789
|
+
backgroundColor: primaryColor,
|
|
790
|
+
borderRadius: 2,
|
|
791
|
+
animation: "checkProgress 5s linear forwards",
|
|
792
|
+
transformOrigin: "left"
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
) }),
|
|
796
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 12, color: "#9ca3af" }, children: "This usually takes just a few seconds" })
|
|
797
|
+
] });
|
|
708
798
|
const MessagesView = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
709
799
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
710
800
|
"div",
|
|
@@ -887,7 +977,7 @@ function ChatWidget({ projectId, config, apiUrl: propApiUrl }) {
|
|
|
887
977
|
},
|
|
888
978
|
children: [
|
|
889
979
|
Header,
|
|
890
|
-
showOfflineForm ? OfflineFormView : showWelcome && welcomeEnabled && messages.length === 0 ? WelcomeScreen : MessagesView,
|
|
980
|
+
checkingAvailability ? CheckingScreen : showOfflineForm ? OfflineFormView : showWelcome && welcomeEnabled && messages.length === 0 ? WelcomeScreen : MessagesView,
|
|
891
981
|
showPoweredBy && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { padding: "6px 0", textAlign: "center", fontSize: 11, color: "#9ca3af", backgroundColor: "#ffffff", borderTop: "1px solid #f3f4f6" }, children: [
|
|
892
982
|
"Powered by",
|
|
893
983
|
" ",
|
|
@@ -902,6 +992,20 @@ function ChatWidget({ projectId, config, apiUrl: propApiUrl }) {
|
|
|
902
992
|
0%, 80%, 100% { opacity: 0.3; }
|
|
903
993
|
40% { opacity: 1; }
|
|
904
994
|
}
|
|
995
|
+
@keyframes checkPulse {
|
|
996
|
+
0% { transform: scale(1); opacity: 1; }
|
|
997
|
+
100% { transform: scale(1.8); opacity: 0; }
|
|
998
|
+
}
|
|
999
|
+
@keyframes checkDots {
|
|
1000
|
+
0% { content: ''; }
|
|
1001
|
+
25% { content: '.'; }
|
|
1002
|
+
50% { content: '..'; }
|
|
1003
|
+
75% { content: '...'; }
|
|
1004
|
+
}
|
|
1005
|
+
@keyframes checkProgress {
|
|
1006
|
+
from { transform: scaleX(0); }
|
|
1007
|
+
to { transform: scaleX(1); }
|
|
1008
|
+
}
|
|
905
1009
|
` })
|
|
906
1010
|
]
|
|
907
1011
|
}
|
|
@@ -1528,5 +1632,5 @@ function getDeviceType() {
|
|
|
1528
1632
|
exports.ChatWidget = ChatWidget;
|
|
1529
1633
|
exports.DesignRenderer = DesignRenderer;
|
|
1530
1634
|
exports.EngageWidget = EngageWidget;
|
|
1531
|
-
//# sourceMappingURL=chunk-
|
|
1532
|
-
//# sourceMappingURL=chunk-
|
|
1635
|
+
//# sourceMappingURL=chunk-D5VBZVOE.js.map
|
|
1636
|
+
//# sourceMappingURL=chunk-D5VBZVOE.js.map
|