@uptrademedia/site-kit 1.1.5 → 1.1.7
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-YT74LIC4.js → chunk-CTKXFLIF.js} +169 -46
- package/dist/chunk-CTKXFLIF.js.map +1 -0
- package/dist/{chunk-TGX5Q6UK.js → chunk-FR6DV5QX.js} +36 -27
- package/dist/chunk-FR6DV5QX.js.map +1 -0
- package/dist/{chunk-NNKC3X7O.mjs → chunk-IARDGI5N.mjs} +36 -27
- package/dist/chunk-IARDGI5N.mjs.map +1 -0
- package/dist/{chunk-DUH5S5MV.mjs → chunk-TOUIKTXU.mjs} +169 -46
- package/dist/chunk-TOUIKTXU.mjs.map +1 -0
- package/dist/cli/index.js +331 -800
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/index.mjs +325 -792
- package/dist/cli/index.mjs.map +1 -1
- package/dist/commerce/index.d.mts +3 -3
- package/dist/commerce/index.d.ts +3 -3
- package/dist/commerce/index.js +42 -42
- package/dist/commerce/index.mjs +1 -1
- package/dist/commerce/server.d.mts +1 -1
- package/dist/commerce/server.d.ts +1 -1
- package/dist/engage/index.d.mts +3 -1
- package/dist/engage/index.d.ts +3 -1
- package/dist/engage/index.js +4 -4
- package/dist/engage/index.mjs +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +32 -29
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +7 -4
- package/dist/index.mjs.map +1 -1
- package/dist/seo/index.d.mts +1 -1
- package/dist/seo/index.d.ts +1 -1
- package/dist/seo/index.js +0 -3
- package/dist/seo/index.js.map +1 -1
- package/dist/seo/index.mjs +1 -1
- package/dist/sitemap/index.d.mts +1 -1
- package/dist/sitemap/index.d.ts +1 -1
- package/dist/sitemap/index.js +0 -4
- package/dist/sitemap/index.js.map +1 -1
- package/dist/sitemap/index.mjs +1 -2
- package/dist/sitemap/index.mjs.map +1 -1
- package/dist/{types-Dz2HtHds.d.mts → types-DxhEH2tX.d.mts} +3 -0
- package/dist/{types-Dz2HtHds.d.ts → types-DxhEH2tX.d.ts} +3 -0
- package/dist/{useEventModal-TppA_tfZ.d.ts → useEventModal-5fIKdIaY.d.ts} +1 -1
- package/dist/{useEventModal-cZr3PMWl.d.mts → useEventModal-x_RZRewW.d.mts} +1 -1
- package/package.json +39 -39
- package/dist/chunk-DUH5S5MV.mjs.map +0 -1
- package/dist/chunk-NNKC3X7O.mjs.map +0 -1
- package/dist/chunk-TGX5Q6UK.js.map +0 -1
- package/dist/chunk-YT74LIC4.js.map +0 -1
|
@@ -10,9 +10,13 @@ var React2__default = /*#__PURE__*/_interopDefault(React2);
|
|
|
10
10
|
|
|
11
11
|
// src/engage/ChatWidget.tsx
|
|
12
12
|
function getApiConfig() {
|
|
13
|
-
const
|
|
13
|
+
const isDev = typeof process !== "undefined" && process.env?.NODE_ENV === "development";
|
|
14
|
+
const defaultApiUrl = isDev && process.env?.NEXT_PUBLIC_UPTRADE_API_URL ? process.env.NEXT_PUBLIC_UPTRADE_API_URL : "https://api.uptrademedia.com";
|
|
15
|
+
const defaultSignalUrl = isDev && process.env?.NEXT_PUBLIC_SIGNAL_API_URL ? process.env.NEXT_PUBLIC_SIGNAL_API_URL : "https://signal.uptrademedia.com";
|
|
16
|
+
const apiUrl = typeof window !== "undefined" ? window.__SITE_KIT_API_URL__ || defaultApiUrl : defaultApiUrl;
|
|
14
17
|
const apiKey = typeof window !== "undefined" ? window.__SITE_KIT_API_KEY__ : void 0;
|
|
15
|
-
|
|
18
|
+
const signalUrl = typeof window !== "undefined" ? window.__SITE_KIT_SIGNAL_URL__ || defaultSignalUrl : defaultSignalUrl;
|
|
19
|
+
return { apiUrl, apiKey, signalUrl };
|
|
16
20
|
}
|
|
17
21
|
function generateVisitorId() {
|
|
18
22
|
const stored = typeof localStorage !== "undefined" ? localStorage.getItem("engage_visitor_id") : null;
|
|
@@ -35,7 +39,7 @@ function isLightColor(hex) {
|
|
|
35
39
|
const b = num & 255;
|
|
36
40
|
return (r * 299 + g * 587 + b * 114) / 1e3 > 160;
|
|
37
41
|
}
|
|
38
|
-
function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl }) {
|
|
42
|
+
function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl, signalUrl: propSignalUrl }) {
|
|
39
43
|
const [resolvedProjectId, setResolvedProjectId] = React2.useState(propProjectId || null);
|
|
40
44
|
const projectId = propProjectId || resolvedProjectId || "";
|
|
41
45
|
const [isOpen, setIsOpen] = React2.useState(false);
|
|
@@ -56,6 +60,7 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl }) {
|
|
|
56
60
|
const [lastFailedSend, setLastFailedSend] = React2.useState(null);
|
|
57
61
|
const [showWelcome, setShowWelcome] = React2.useState(true);
|
|
58
62
|
const [checkingAvailability, setCheckingAvailability] = React2.useState(false);
|
|
63
|
+
const [checkingHandoff, setCheckingHandoff] = React2.useState(false);
|
|
59
64
|
React2.useRef(null);
|
|
60
65
|
const pendingInitialMessageRef = React2.useRef(null);
|
|
61
66
|
const apiKeyMissingWarnedRef = React2.useRef(false);
|
|
@@ -83,6 +88,7 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl }) {
|
|
|
83
88
|
const offlineHeading = widgetConfig?.offline_heading ?? "No agents available right now";
|
|
84
89
|
const offlineSubheading = handoffOfflinePrompt ?? widgetConfig?.offline_subheading ?? widgetConfig?.form_description ?? widgetConfig?.offline_message ?? config?.offlineMessage ?? "Leave us a message and we'll get back to you!";
|
|
85
90
|
const baseUrl = propApiUrl || getApiConfig().apiUrl;
|
|
91
|
+
const signalUrl = propSignalUrl || getApiConfig().signalUrl;
|
|
86
92
|
React2.useEffect(() => {
|
|
87
93
|
if (propProjectId || resolvedProjectId) return;
|
|
88
94
|
const { apiKey } = getApiConfig();
|
|
@@ -153,11 +159,14 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl }) {
|
|
|
153
159
|
});
|
|
154
160
|
if (response.ok) {
|
|
155
161
|
const { data } = await response.json();
|
|
156
|
-
const
|
|
162
|
+
const session = data.session ?? data;
|
|
163
|
+
const sid = session?.id ?? session?.session_id ?? data.id ?? data.session_id;
|
|
164
|
+
const signalEnabled = session?.chat_mode === "ai" || session?.chat_mode === "hybrid";
|
|
157
165
|
setSessionId(sid);
|
|
158
|
-
|
|
166
|
+
const messages2 = session?.messages ?? data.messages ?? [];
|
|
167
|
+
if (messages2.length > 0) {
|
|
159
168
|
setMessages(
|
|
160
|
-
|
|
169
|
+
messages2.map((m) => ({
|
|
161
170
|
id: m.id,
|
|
162
171
|
role: m.role === "visitor" ? "user" : m.role,
|
|
163
172
|
content: m.content,
|
|
@@ -166,13 +175,40 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl }) {
|
|
|
166
175
|
}))
|
|
167
176
|
);
|
|
168
177
|
}
|
|
169
|
-
return sid;
|
|
178
|
+
return { id: sid, signalEnabled };
|
|
170
179
|
}
|
|
171
180
|
} catch (error) {
|
|
172
181
|
console.error("[ChatWidget] Session init failed:", error);
|
|
173
182
|
}
|
|
174
183
|
return null;
|
|
175
184
|
}, [projectId, visitorId, baseUrl]);
|
|
185
|
+
const sendToSignalApi = React2.useCallback(
|
|
186
|
+
async (content, conversationId) => {
|
|
187
|
+
const url = `${signalUrl.replace(/\/$/, "")}/echo/public/chat`;
|
|
188
|
+
const body = {
|
|
189
|
+
message: content,
|
|
190
|
+
projectId,
|
|
191
|
+
visitorId,
|
|
192
|
+
...conversationId ? { conversationId } : {},
|
|
193
|
+
pageUrl: typeof window !== "undefined" ? window.location.href : void 0
|
|
194
|
+
};
|
|
195
|
+
const res = await fetch(url, {
|
|
196
|
+
method: "POST",
|
|
197
|
+
headers: { "Content-Type": "application/json" },
|
|
198
|
+
body: JSON.stringify(body)
|
|
199
|
+
});
|
|
200
|
+
const json = await res.json();
|
|
201
|
+
if (!res.ok) {
|
|
202
|
+
throw new Error(json?.error?.message || json?.message || `Signal API error: ${res.status}`);
|
|
203
|
+
}
|
|
204
|
+
const data = json?.data ?? json;
|
|
205
|
+
const aiContent = data?.content ?? data?.response ?? data?.message ?? "I'm sorry, I couldn't process that.";
|
|
206
|
+
const suggestions = data?.suggestions;
|
|
207
|
+
const newConversationId = data?.conversationId ?? conversationId;
|
|
208
|
+
return { content: aiContent, suggestions, conversationId: newConversationId };
|
|
209
|
+
},
|
|
210
|
+
[signalUrl, projectId, visitorId]
|
|
211
|
+
);
|
|
176
212
|
const handleSocketMessage = React2.useCallback((data) => {
|
|
177
213
|
switch (data.type || data.event) {
|
|
178
214
|
case "message": {
|
|
@@ -361,13 +397,50 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl }) {
|
|
|
361
397
|
}, [fetchWidgetConfig, checkAvailability]);
|
|
362
398
|
React2.useEffect(() => {
|
|
363
399
|
if (isOpen && !showWelcome && !checkingAvailability && !showOfflineForm && !sessionId) {
|
|
364
|
-
initSession().then(async (
|
|
365
|
-
if (!id) return;
|
|
366
|
-
|
|
367
|
-
await connectSocket(id);
|
|
400
|
+
initSession().then(async (result) => {
|
|
401
|
+
if (!result?.id) return;
|
|
402
|
+
const { id, signalEnabled } = result;
|
|
368
403
|
const pending = pendingInitialMessageRef.current;
|
|
369
404
|
if (pending) {
|
|
370
405
|
pendingInitialMessageRef.current = null;
|
|
406
|
+
}
|
|
407
|
+
if (signalEnabled && pending) {
|
|
408
|
+
setIsLoading(true);
|
|
409
|
+
setMessages((prev) => [
|
|
410
|
+
...prev,
|
|
411
|
+
{ id: `u-${Date.now()}`, role: "user", content: pending, timestamp: /* @__PURE__ */ new Date() }
|
|
412
|
+
]);
|
|
413
|
+
try {
|
|
414
|
+
const { content: aiContent, suggestions } = await sendToSignalApi(pending, id);
|
|
415
|
+
setMessages((prev) => [
|
|
416
|
+
...prev,
|
|
417
|
+
{
|
|
418
|
+
id: `ai-${Date.now()}`,
|
|
419
|
+
role: "assistant",
|
|
420
|
+
content: aiContent,
|
|
421
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
422
|
+
...suggestions?.length ? { suggestions } : {}
|
|
423
|
+
}
|
|
424
|
+
]);
|
|
425
|
+
} catch (err) {
|
|
426
|
+
console.error("[ChatWidget] Signal API error:", err);
|
|
427
|
+
setMessages((prev) => [
|
|
428
|
+
...prev,
|
|
429
|
+
{
|
|
430
|
+
id: `err-${Date.now()}`,
|
|
431
|
+
role: "assistant",
|
|
432
|
+
content: "I apologize, but I encountered an error. Would you like to speak with a team member?",
|
|
433
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
434
|
+
suggestions: ["Talk to a person", "Try again"]
|
|
435
|
+
}
|
|
436
|
+
]);
|
|
437
|
+
} finally {
|
|
438
|
+
setIsLoading(false);
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
setConnectionStatus("connecting");
|
|
442
|
+
await connectSocket(id);
|
|
443
|
+
if (!signalEnabled && pending) {
|
|
371
444
|
const waitForSocket = () => new Promise((resolve) => {
|
|
372
445
|
const check = (attempts = 0) => {
|
|
373
446
|
if (socketRef.current?.connected || attempts > 20) {
|
|
@@ -388,7 +461,7 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl }) {
|
|
|
388
461
|
return () => {
|
|
389
462
|
if (pollingIntervalRef.current) clearInterval(pollingIntervalRef.current);
|
|
390
463
|
};
|
|
391
|
-
}, [isOpen, showWelcome, checkingAvailability, showOfflineForm, sessionId, initSession, connectSocket]);
|
|
464
|
+
}, [isOpen, showWelcome, checkingAvailability, showOfflineForm, sessionId, initSession, connectSocket, sendToSignalApi]);
|
|
392
465
|
const handleToggle = React2.useCallback(() => {
|
|
393
466
|
setIsOpen((prev) => !prev);
|
|
394
467
|
}, []);
|
|
@@ -478,6 +551,36 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl }) {
|
|
|
478
551
|
setMessages((prev) => [...prev, userMessage]);
|
|
479
552
|
setInputValue("");
|
|
480
553
|
setIsLoading(true);
|
|
554
|
+
if (widgetConfig?.signal_enabled && hasText) {
|
|
555
|
+
try {
|
|
556
|
+
const { content: aiContent, suggestions } = await sendToSignalApi(content, sessionId);
|
|
557
|
+
setMessages((prev) => [
|
|
558
|
+
...prev,
|
|
559
|
+
{
|
|
560
|
+
id: `ai-${Date.now()}`,
|
|
561
|
+
role: "assistant",
|
|
562
|
+
content: aiContent,
|
|
563
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
564
|
+
...suggestions?.length ? { suggestions } : {}
|
|
565
|
+
}
|
|
566
|
+
]);
|
|
567
|
+
} catch (err) {
|
|
568
|
+
console.error("[ChatWidget] Signal API error:", err);
|
|
569
|
+
setMessages((prev) => [
|
|
570
|
+
...prev,
|
|
571
|
+
{
|
|
572
|
+
id: `err-${Date.now()}`,
|
|
573
|
+
role: "assistant",
|
|
574
|
+
content: "I apologize, but I encountered an error. Would you like to speak with a team member?",
|
|
575
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
576
|
+
suggestions: ["Talk to a person", "Try again"]
|
|
577
|
+
}
|
|
578
|
+
]);
|
|
579
|
+
} finally {
|
|
580
|
+
setIsLoading(false);
|
|
581
|
+
}
|
|
582
|
+
return;
|
|
583
|
+
}
|
|
481
584
|
const socket = socketRef.current;
|
|
482
585
|
if (socket?.connected) {
|
|
483
586
|
socket.emit("visitor:message", { content: userMessage.content, attachments: attachments.length ? attachments : void 0 });
|
|
@@ -495,7 +598,7 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl }) {
|
|
|
495
598
|
}
|
|
496
599
|
}, 3e3);
|
|
497
600
|
},
|
|
498
|
-
[inputValue, isLoading, pendingFiles, uploadWidgetFile]
|
|
601
|
+
[inputValue, isLoading, pendingFiles, uploadWidgetFile, widgetConfig?.signal_enabled, sendToSignalApi, sessionId]
|
|
499
602
|
);
|
|
500
603
|
const retryFailedSend = React2.useCallback(() => {
|
|
501
604
|
if (!lastFailedSend || !sessionId) return;
|
|
@@ -513,33 +616,48 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl }) {
|
|
|
513
616
|
if (!sessionId) return;
|
|
514
617
|
const apiKey = ensureApiKey();
|
|
515
618
|
if (!apiKey) return;
|
|
619
|
+
setCheckingHandoff(true);
|
|
516
620
|
try {
|
|
517
|
-
const
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
621
|
+
const firstAvail = await checkAvailability();
|
|
622
|
+
if (firstAvail?.agentsOnline && firstAvail.agentsOnline > 0) {
|
|
623
|
+
setCheckingHandoff(false);
|
|
624
|
+
await fetch(`${baseUrl}/engage/widget/handoff`, {
|
|
625
|
+
method: "POST",
|
|
626
|
+
headers: { "Content-Type": "application/json", "x-api-key": apiKey },
|
|
627
|
+
body: JSON.stringify({ sessionId })
|
|
628
|
+
});
|
|
629
|
+
setMessages((prev) => [
|
|
630
|
+
...prev,
|
|
631
|
+
{ id: `handoff-${Date.now()}`, role: "system", content: "Connecting you with a team member. Please hold on!", timestamp: /* @__PURE__ */ new Date() }
|
|
632
|
+
]);
|
|
633
|
+
return;
|
|
634
|
+
}
|
|
635
|
+
await new Promise((resolve) => setTimeout(resolve, 5e3));
|
|
636
|
+
const secondAvail = await checkAvailability();
|
|
637
|
+
setCheckingHandoff(false);
|
|
638
|
+
if (secondAvail?.agentsOnline && secondAvail.agentsOnline > 0) {
|
|
639
|
+
await fetch(`${baseUrl}/engage/widget/handoff`, {
|
|
640
|
+
method: "POST",
|
|
641
|
+
headers: { "Content-Type": "application/json", "x-api-key": apiKey },
|
|
642
|
+
body: JSON.stringify({ sessionId })
|
|
643
|
+
});
|
|
644
|
+
setMessages((prev) => [
|
|
645
|
+
...prev,
|
|
646
|
+
{ id: `handoff-${Date.now()}`, role: "system", content: "Connecting you with a team member. Please hold on!", timestamp: /* @__PURE__ */ new Date() }
|
|
647
|
+
]);
|
|
648
|
+
} else {
|
|
522
649
|
setHandoffOfflinePrompt(widgetConfig?.offline_subheading ?? "Nobody is online right now. Leave your details and we'll get back to you.");
|
|
523
650
|
setShowOfflineForm(true);
|
|
524
651
|
setMessages((prev) => [
|
|
525
652
|
...prev,
|
|
526
653
|
{ id: `handoff-offline-${Date.now()}`, role: "system", content: offlineHeading, timestamp: /* @__PURE__ */ new Date() }
|
|
527
654
|
]);
|
|
528
|
-
return;
|
|
529
655
|
}
|
|
530
|
-
await fetch(`${baseUrl}/engage/widget/handoff`, {
|
|
531
|
-
method: "POST",
|
|
532
|
-
headers: { "Content-Type": "application/json", "x-api-key": apiKey },
|
|
533
|
-
body: JSON.stringify({ sessionId })
|
|
534
|
-
});
|
|
535
|
-
setMessages((prev) => [
|
|
536
|
-
...prev,
|
|
537
|
-
{ id: `handoff-${Date.now()}`, role: "system", content: "Connecting you with a team member. Please hold on!", timestamp: /* @__PURE__ */ new Date() }
|
|
538
|
-
]);
|
|
539
656
|
} catch (error) {
|
|
657
|
+
setCheckingHandoff(false);
|
|
540
658
|
console.error("[ChatWidget] Handoff request failed:", error);
|
|
541
659
|
}
|
|
542
|
-
}, [sessionId, baseUrl, projectId, widgetConfig, offlineHeading]);
|
|
660
|
+
}, [sessionId, baseUrl, projectId, widgetConfig, offlineHeading, checkAvailability]);
|
|
543
661
|
const [offlineError, setOfflineError] = React2.useState(null);
|
|
544
662
|
const handleOfflineSubmit = React2.useCallback(
|
|
545
663
|
async (e) => {
|
|
@@ -840,7 +958,7 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl }) {
|
|
|
840
958
|
)
|
|
841
959
|
] }),
|
|
842
960
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
843
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 16, fontWeight: 600, color: "#111827", marginBottom: 6 }, children: "Checking for a team member" }),
|
|
961
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 16, fontWeight: 600, color: "#111827", marginBottom: 6 }, children: checkingHandoff ? "Looking for online support" : "Checking for a team member" }),
|
|
844
962
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { fontSize: 14, color: "#6b7280", lineHeight: 1.5 }, children: [
|
|
845
963
|
"One moment please",
|
|
846
964
|
/* @__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: "..." }) })
|
|
@@ -1043,11 +1161,11 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl }) {
|
|
|
1043
1161
|
},
|
|
1044
1162
|
children: [
|
|
1045
1163
|
Header,
|
|
1046
|
-
checkingAvailability ? CheckingScreen : showOfflineForm ? OfflineFormView : showWelcome && welcomeEnabled && messages.length === 0 ? WelcomeScreen : MessagesView,
|
|
1164
|
+
checkingAvailability || checkingHandoff ? CheckingScreen : showOfflineForm ? OfflineFormView : showWelcome && welcomeEnabled && messages.length === 0 ? WelcomeScreen : MessagesView,
|
|
1047
1165
|
showPoweredBy && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { padding: "6px 0", textAlign: "center", fontSize: 11, color: "#9ca3af", backgroundColor: "#ffffff", borderTop: "1px solid #f3f4f6" }, children: [
|
|
1048
1166
|
"Powered by",
|
|
1049
1167
|
" ",
|
|
1050
|
-
/* @__PURE__ */ jsxRuntime.jsx("a", { href: "https://uptrademedia.com", target: "_blank", rel: "noopener noreferrer", style: { color: "#6b7280", textDecoration: "none", fontWeight: 500 }, children: "
|
|
1168
|
+
/* @__PURE__ */ jsxRuntime.jsx("a", { href: "https://uptrademedia.com", target: "_blank", rel: "noopener noreferrer", style: { color: "#6b7280", textDecoration: "none", fontWeight: 500 }, children: "Sonor" })
|
|
1051
1169
|
] }),
|
|
1052
1170
|
/* @__PURE__ */ jsxRuntime.jsx("style", { children: `
|
|
1053
1171
|
@keyframes chatSlideUp {
|
|
@@ -1342,7 +1460,9 @@ function DesignRenderer({
|
|
|
1342
1460
|
)) });
|
|
1343
1461
|
}
|
|
1344
1462
|
function getApiConfig2() {
|
|
1345
|
-
const
|
|
1463
|
+
const isDev = typeof process !== "undefined" && process.env?.NODE_ENV === "development";
|
|
1464
|
+
const defaultApiUrl = isDev && process.env?.NEXT_PUBLIC_UPTRADE_API_URL ? process.env.NEXT_PUBLIC_UPTRADE_API_URL : "https://api.uptrademedia.com";
|
|
1465
|
+
const apiUrl = typeof window !== "undefined" ? window.__SITE_KIT_API_URL__ || defaultApiUrl : defaultApiUrl;
|
|
1346
1466
|
const apiKey = typeof window !== "undefined" ? window.__SITE_KIT_API_KEY__ : void 0;
|
|
1347
1467
|
return { apiUrl, apiKey };
|
|
1348
1468
|
}
|
|
@@ -1368,22 +1488,25 @@ function EngageWidget({
|
|
|
1368
1488
|
if (debug) console.warn("[Engage] No API key configured");
|
|
1369
1489
|
return;
|
|
1370
1490
|
}
|
|
1491
|
+
let visitorId = typeof localStorage !== "undefined" ? localStorage.getItem("engage_visitor_id") : null;
|
|
1492
|
+
if (!visitorId) {
|
|
1493
|
+
visitorId = `visitor_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
1494
|
+
if (typeof localStorage !== "undefined") localStorage.setItem("engage_visitor_id", visitorId);
|
|
1495
|
+
}
|
|
1496
|
+
const url = typeof window !== "undefined" ? window.location.href : "";
|
|
1371
1497
|
try {
|
|
1372
|
-
const response = await fetch(
|
|
1373
|
-
|
|
1374
|
-
headers: {
|
|
1375
|
-
|
|
1376
|
-
"x-api-key": apiKey
|
|
1377
|
-
},
|
|
1378
|
-
body: JSON.stringify({})
|
|
1379
|
-
});
|
|
1498
|
+
const response = await fetch(
|
|
1499
|
+
`${apiUrl.replace(/\/$/, "")}/engage/widget/elements?url=${encodeURIComponent(url)}&visitorId=${encodeURIComponent(visitorId)}`,
|
|
1500
|
+
{ headers: { "x-api-key": apiKey } }
|
|
1501
|
+
);
|
|
1380
1502
|
if (!response.ok) {
|
|
1381
1503
|
if (debug) console.error("[Engage] Error loading elements:", response.statusText);
|
|
1382
1504
|
return;
|
|
1383
1505
|
}
|
|
1384
|
-
const
|
|
1385
|
-
|
|
1386
|
-
|
|
1506
|
+
const json = await response.json();
|
|
1507
|
+
const elementsList = json.data?.elements ?? json.elements ?? [];
|
|
1508
|
+
if (debug) console.log("[Engage] Loaded elements:", elementsList);
|
|
1509
|
+
setElements(elementsList);
|
|
1387
1510
|
} catch (error) {
|
|
1388
1511
|
if (debug) console.error("[Engage] Error loading elements:", error);
|
|
1389
1512
|
}
|
|
@@ -1700,5 +1823,5 @@ function getDeviceType() {
|
|
|
1700
1823
|
exports.ChatWidget = ChatWidget;
|
|
1701
1824
|
exports.DesignRenderer = DesignRenderer;
|
|
1702
1825
|
exports.EngageWidget = EngageWidget;
|
|
1703
|
-
//# sourceMappingURL=chunk-
|
|
1704
|
-
//# sourceMappingURL=chunk-
|
|
1826
|
+
//# sourceMappingURL=chunk-CTKXFLIF.js.map
|
|
1827
|
+
//# sourceMappingURL=chunk-CTKXFLIF.js.map
|