@uptrademedia/site-kit 1.0.30 → 1.0.32
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-WNCM4GNY.js → chunk-7BEMFSF6.js} +41 -23
- package/dist/chunk-7BEMFSF6.js.map +1 -0
- package/dist/{chunk-L474IOHD.mjs → chunk-A37Z47FZ.mjs} +41 -23
- package/dist/chunk-A37Z47FZ.mjs.map +1 -0
- package/dist/{chunk-WPSRS352.mjs → chunk-BQOFRBGZ.mjs} +3 -3
- package/dist/chunk-BQOFRBGZ.mjs.map +1 -0
- package/dist/{chunk-HCFPU7TU.js → chunk-G7RSD56P.js} +3 -3
- package/dist/chunk-G7RSD56P.js.map +1 -0
- package/dist/{chunk-MDOHOEME.mjs → chunk-GM2ZDV2B.mjs} +63 -45
- package/dist/chunk-GM2ZDV2B.mjs.map +1 -0
- package/dist/{chunk-6J26EHDM.js → chunk-H5PVDCCM.js} +63 -45
- package/dist/chunk-H5PVDCCM.js.map +1 -0
- package/dist/{chunk-XFRPT5ZX.mjs → chunk-X66VOCWP.mjs} +26 -53
- package/dist/chunk-X66VOCWP.mjs.map +1 -0
- package/dist/{chunk-5R4R3WDP.js → chunk-Y4BW6XYJ.js} +26 -53
- package/dist/chunk-Y4BW6XYJ.js.map +1 -0
- package/dist/commerce/index.js +39 -39
- package/dist/commerce/index.mjs +1 -1
- package/dist/engage/index.d.mts +2 -2
- package/dist/engage/index.d.ts +2 -2
- package/dist/engage/index.js +4 -4
- package/dist/engage/index.mjs +1 -1
- package/dist/forms/index.d.mts +1 -1
- package/dist/forms/index.d.ts +1 -1
- package/dist/forms/index.js +6 -4
- package/dist/forms/index.js.map +1 -1
- package/dist/forms/index.mjs +6 -4
- package/dist/forms/index.mjs.map +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +51 -39
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +24 -12
- package/dist/index.mjs.map +1 -1
- package/dist/seo/index.d.mts +6 -18
- package/dist/seo/index.d.ts +6 -18
- package/dist/seo/index.js +2 -2
- package/dist/seo/index.mjs +1 -1
- package/dist/seo/register-sitemap-cli.js +112 -3
- package/dist/seo/register-sitemap-cli.js.map +1 -1
- package/dist/seo/register-sitemap-cli.mjs +106 -2
- package/dist/seo/register-sitemap-cli.mjs.map +1 -1
- package/dist/setup/client.js +3 -3
- package/dist/setup/client.mjs +1 -1
- package/dist/setup/index.js +3 -3
- package/dist/setup/index.mjs +1 -1
- package/dist/{types-B77UG-p-.d.mts → types-CYPI3-8j.d.mts} +2 -0
- package/dist/{types-B77UG-p-.d.ts → types-CYPI3-8j.d.ts} +2 -0
- package/dist/{types-CWKw0giL.d.ts → types-C_pfGZhI.d.mts} +1 -2
- package/dist/{types-CWKw0giL.d.mts → types-C_pfGZhI.d.ts} +1 -2
- package/package.json +1 -1
- package/dist/chunk-5R4R3WDP.js.map +0 -1
- package/dist/chunk-6J26EHDM.js.map +0 -1
- package/dist/chunk-HCFPU7TU.js.map +0 -1
- package/dist/chunk-L474IOHD.mjs.map +0 -1
- package/dist/chunk-MDOHOEME.mjs.map +0 -1
- package/dist/chunk-WNCM4GNY.js.map +0 -1
- package/dist/chunk-WPSRS352.mjs.map +0 -1
- package/dist/chunk-XFRPT5ZX.mjs.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { useRef, useEffect } from 'react';
|
|
3
3
|
|
|
4
|
-
// src/
|
|
4
|
+
// src/SitemapSync.tsx
|
|
5
5
|
function getApiConfig() {
|
|
6
6
|
if (typeof window === "undefined") return { apiUrl: "", apiKey: "" };
|
|
7
7
|
const apiUrl = window.__SITE_KIT_API_URL__ || "https://api.uptrademedia.com";
|
|
@@ -132,5 +132,5 @@ function SitemapSync({
|
|
|
132
132
|
}
|
|
133
133
|
|
|
134
134
|
export { SitemapSync };
|
|
135
|
-
//# sourceMappingURL=chunk-
|
|
136
|
-
//# sourceMappingURL=chunk-
|
|
135
|
+
//# sourceMappingURL=chunk-BQOFRBGZ.mjs.map
|
|
136
|
+
//# sourceMappingURL=chunk-BQOFRBGZ.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/SitemapSync.tsx"],"names":[],"mappings":"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","file":"chunk-BQOFRBGZ.mjs","sourcesContent":["/**\n * SitemapSync - Automatically sync sitemap.xml to Portal API\n *\n * Client-only component. Lives at package root so the main entry does not\n * pull in seo/ (and server-only code). For use in SiteKitProvider and\n * from @uptrademedia/site-kit/seo.\n *\n * @example\n * ```tsx\n * import { SitemapSync } from '@uptrademedia/site-kit'\n * // or\n * import { SitemapSync } from '@uptrademedia/site-kit/seo'\n * ```\n */\n\n'use client'\n\nimport { useEffect, useRef } from 'react'\n\ninterface SitemapSyncProps {\n /** Custom sitemap URL (defaults to /sitemap.xml) */\n sitemapUrl?: string\n /** How often to re-sync in minutes (0 = only on mount, default: 60) */\n syncInterval?: number\n /** Enable debug logging */\n debug?: boolean\n}\n\ninterface SitemapEntry {\n path: string\n lastmod?: string\n changefreq?: string\n priority?: number\n}\n\nfunction getApiConfig() {\n if (typeof window === 'undefined') return { apiUrl: '', apiKey: '' }\n\n const apiUrl = (window as any).__SITE_KIT_API_URL__ || 'https://api.uptrademedia.com'\n const apiKey = (window as any).__SITE_KIT_API_KEY__ || ''\n return { apiUrl, apiKey }\n}\n\nasync function parseSitemap(sitemapUrl: string, debug: boolean): Promise<SitemapEntry[]> {\n try {\n const response = await fetch(sitemapUrl)\n if (!response.ok) {\n if (debug) console.warn('[SitemapSync] Failed to fetch sitemap:', response.status)\n return []\n }\n\n const text = await response.text()\n const parser = new DOMParser()\n const doc = parser.parseFromString(text, 'application/xml')\n\n const parseError = doc.querySelector('parsererror')\n if (parseError) {\n if (debug) console.warn('[SitemapSync] Sitemap parse error:', parseError.textContent)\n return []\n }\n\n const urls = doc.querySelectorAll('url')\n const entries: SitemapEntry[] = []\n\n urls.forEach(url => {\n const loc = url.querySelector('loc')?.textContent\n if (!loc) return\n\n let path: string\n try {\n const urlObj = new URL(loc)\n path = urlObj.pathname\n } catch {\n path = loc.startsWith('/') ? loc : `/${loc}`\n }\n\n if (path !== '/' && path.endsWith('/')) {\n path = path.slice(0, -1)\n }\n\n const lastmod = url.querySelector('lastmod')?.textContent || undefined\n const changefreq = url.querySelector('changefreq')?.textContent || undefined\n const priorityStr = url.querySelector('priority')?.textContent\n const priority = priorityStr ? parseFloat(priorityStr) : undefined\n\n entries.push({ path, lastmod, changefreq, priority })\n })\n\n if (debug) {\n console.log(`[SitemapSync] Parsed ${entries.length} entries from sitemap`)\n }\n\n return entries\n } catch (error) {\n if (debug) console.error('[SitemapSync] Error parsing sitemap:', error)\n return []\n }\n}\n\nasync function syncToPortal(\n entries: SitemapEntry[],\n apiUrl: string,\n apiKey: string,\n debug: boolean\n): Promise<{ success: boolean; created: number; updated: number }> {\n if (!apiKey) {\n if (debug) console.warn('[SitemapSync] No API key configured')\n return { success: false, created: 0, updated: 0 }\n }\n\n if (entries.length === 0) {\n if (debug) console.log('[SitemapSync] No entries to sync')\n return { success: true, created: 0, updated: 0 }\n }\n\n try {\n const response = await fetch(`${apiUrl}/api/public/seo/register-sitemap`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n },\n body: JSON.stringify({\n entries: entries.map(e => ({\n path: e.path,\n priority: e.priority,\n changefreq: e.changefreq,\n })),\n }),\n })\n\n if (!response.ok) {\n if (debug) console.error('[SitemapSync] API error:', response.status, response.statusText)\n return { success: false, created: 0, updated: 0 }\n }\n\n const result = await response.json()\n\n if (debug) {\n console.log(`[SitemapSync] Synced: ${result.created} created, ${result.updated} updated`)\n }\n\n return {\n success: true,\n created: result.created || 0,\n updated: result.updated || 0,\n }\n } catch (error) {\n if (debug) console.error('[SitemapSync] Sync error:', error)\n return { success: false, created: 0, updated: 0 }\n }\n}\n\nexport function SitemapSync({\n sitemapUrl = '/sitemap.xml',\n syncInterval = 60,\n debug = false,\n}: SitemapSyncProps) {\n const hasSyncedRef = useRef(false)\n const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null)\n\n useEffect(() => {\n const doSync = async () => {\n const { apiUrl, apiKey } = getApiConfig()\n\n if (!apiKey) {\n if (debug) console.warn('[SitemapSync] No API key found')\n return\n }\n\n if (debug) console.log('[SitemapSync] Starting sitemap sync...')\n\n const entries = await parseSitemap(sitemapUrl, debug)\n\n if (entries.length > 0) {\n await syncToPortal(entries, apiUrl, apiKey, debug)\n }\n }\n\n if (!hasSyncedRef.current) {\n hasSyncedRef.current = true\n doSync()\n }\n\n if (syncInterval > 0) {\n intervalRef.current = setInterval(doSync, syncInterval * 60 * 1000)\n }\n\n return () => {\n if (intervalRef.current) {\n clearInterval(intervalRef.current)\n }\n }\n }, [sitemapUrl, syncInterval, debug])\n\n return null\n}\n\nexport default SitemapSync\n"]}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var react = require('react');
|
|
4
4
|
|
|
5
|
-
// src/
|
|
5
|
+
// src/SitemapSync.tsx
|
|
6
6
|
function getApiConfig() {
|
|
7
7
|
if (typeof window === "undefined") return { apiUrl: "", apiKey: "" };
|
|
8
8
|
const apiUrl = window.__SITE_KIT_API_URL__ || "https://api.uptrademedia.com";
|
|
@@ -133,5 +133,5 @@ function SitemapSync({
|
|
|
133
133
|
}
|
|
134
134
|
|
|
135
135
|
exports.SitemapSync = SitemapSync;
|
|
136
|
-
//# sourceMappingURL=chunk-
|
|
137
|
-
//# sourceMappingURL=chunk-
|
|
136
|
+
//# sourceMappingURL=chunk-G7RSD56P.js.map
|
|
137
|
+
//# sourceMappingURL=chunk-G7RSD56P.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/SitemapSync.tsx"],"names":["useRef","useEffect"],"mappings":"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","file":"chunk-G7RSD56P.js","sourcesContent":["/**\n * SitemapSync - Automatically sync sitemap.xml to Portal API\n *\n * Client-only component. Lives at package root so the main entry does not\n * pull in seo/ (and server-only code). For use in SiteKitProvider and\n * from @uptrademedia/site-kit/seo.\n *\n * @example\n * ```tsx\n * import { SitemapSync } from '@uptrademedia/site-kit'\n * // or\n * import { SitemapSync } from '@uptrademedia/site-kit/seo'\n * ```\n */\n\n'use client'\n\nimport { useEffect, useRef } from 'react'\n\ninterface SitemapSyncProps {\n /** Custom sitemap URL (defaults to /sitemap.xml) */\n sitemapUrl?: string\n /** How often to re-sync in minutes (0 = only on mount, default: 60) */\n syncInterval?: number\n /** Enable debug logging */\n debug?: boolean\n}\n\ninterface SitemapEntry {\n path: string\n lastmod?: string\n changefreq?: string\n priority?: number\n}\n\nfunction getApiConfig() {\n if (typeof window === 'undefined') return { apiUrl: '', apiKey: '' }\n\n const apiUrl = (window as any).__SITE_KIT_API_URL__ || 'https://api.uptrademedia.com'\n const apiKey = (window as any).__SITE_KIT_API_KEY__ || ''\n return { apiUrl, apiKey }\n}\n\nasync function parseSitemap(sitemapUrl: string, debug: boolean): Promise<SitemapEntry[]> {\n try {\n const response = await fetch(sitemapUrl)\n if (!response.ok) {\n if (debug) console.warn('[SitemapSync] Failed to fetch sitemap:', response.status)\n return []\n }\n\n const text = await response.text()\n const parser = new DOMParser()\n const doc = parser.parseFromString(text, 'application/xml')\n\n const parseError = doc.querySelector('parsererror')\n if (parseError) {\n if (debug) console.warn('[SitemapSync] Sitemap parse error:', parseError.textContent)\n return []\n }\n\n const urls = doc.querySelectorAll('url')\n const entries: SitemapEntry[] = []\n\n urls.forEach(url => {\n const loc = url.querySelector('loc')?.textContent\n if (!loc) return\n\n let path: string\n try {\n const urlObj = new URL(loc)\n path = urlObj.pathname\n } catch {\n path = loc.startsWith('/') ? loc : `/${loc}`\n }\n\n if (path !== '/' && path.endsWith('/')) {\n path = path.slice(0, -1)\n }\n\n const lastmod = url.querySelector('lastmod')?.textContent || undefined\n const changefreq = url.querySelector('changefreq')?.textContent || undefined\n const priorityStr = url.querySelector('priority')?.textContent\n const priority = priorityStr ? parseFloat(priorityStr) : undefined\n\n entries.push({ path, lastmod, changefreq, priority })\n })\n\n if (debug) {\n console.log(`[SitemapSync] Parsed ${entries.length} entries from sitemap`)\n }\n\n return entries\n } catch (error) {\n if (debug) console.error('[SitemapSync] Error parsing sitemap:', error)\n return []\n }\n}\n\nasync function syncToPortal(\n entries: SitemapEntry[],\n apiUrl: string,\n apiKey: string,\n debug: boolean\n): Promise<{ success: boolean; created: number; updated: number }> {\n if (!apiKey) {\n if (debug) console.warn('[SitemapSync] No API key configured')\n return { success: false, created: 0, updated: 0 }\n }\n\n if (entries.length === 0) {\n if (debug) console.log('[SitemapSync] No entries to sync')\n return { success: true, created: 0, updated: 0 }\n }\n\n try {\n const response = await fetch(`${apiUrl}/api/public/seo/register-sitemap`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n },\n body: JSON.stringify({\n entries: entries.map(e => ({\n path: e.path,\n priority: e.priority,\n changefreq: e.changefreq,\n })),\n }),\n })\n\n if (!response.ok) {\n if (debug) console.error('[SitemapSync] API error:', response.status, response.statusText)\n return { success: false, created: 0, updated: 0 }\n }\n\n const result = await response.json()\n\n if (debug) {\n console.log(`[SitemapSync] Synced: ${result.created} created, ${result.updated} updated`)\n }\n\n return {\n success: true,\n created: result.created || 0,\n updated: result.updated || 0,\n }\n } catch (error) {\n if (debug) console.error('[SitemapSync] Sync error:', error)\n return { success: false, created: 0, updated: 0 }\n }\n}\n\nexport function SitemapSync({\n sitemapUrl = '/sitemap.xml',\n syncInterval = 60,\n debug = false,\n}: SitemapSyncProps) {\n const hasSyncedRef = useRef(false)\n const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null)\n\n useEffect(() => {\n const doSync = async () => {\n const { apiUrl, apiKey } = getApiConfig()\n\n if (!apiKey) {\n if (debug) console.warn('[SitemapSync] No API key found')\n return\n }\n\n if (debug) console.log('[SitemapSync] Starting sitemap sync...')\n\n const entries = await parseSitemap(sitemapUrl, debug)\n\n if (entries.length > 0) {\n await syncToPortal(entries, apiUrl, apiKey, debug)\n }\n }\n\n if (!hasSyncedRef.current) {\n hasSyncedRef.current = true\n doSync()\n }\n\n if (syncInterval > 0) {\n intervalRef.current = setInterval(doSync, syncInterval * 60 * 1000)\n }\n\n return () => {\n if (intervalRef.current) {\n clearInterval(intervalRef.current)\n }\n }\n }, [sitemapUrl, syncInterval, debug])\n\n return null\n}\n\nexport default SitemapSync\n"]}
|
|
@@ -52,13 +52,22 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl }) {
|
|
|
52
52
|
const [checkingAvailability, setCheckingAvailability] = useState(false);
|
|
53
53
|
useRef(null);
|
|
54
54
|
const pendingInitialMessageRef = useRef(null);
|
|
55
|
+
const apiKeyMissingWarnedRef = useRef(false);
|
|
56
|
+
function ensureApiKey() {
|
|
57
|
+
const { apiKey } = getApiConfig();
|
|
58
|
+
if (apiKey) return apiKey;
|
|
59
|
+
if (!apiKeyMissingWarnedRef.current) {
|
|
60
|
+
apiKeyMissingWarnedRef.current = true;
|
|
61
|
+
console.warn("[ChatWidget] API key is required for Engage widget. Set __SITE_KIT_API_KEY__ or pass apiKey via SiteKitProvider.");
|
|
62
|
+
}
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
55
65
|
const messagesEndRef = useRef(null);
|
|
56
66
|
const inputRef = useRef(null);
|
|
57
67
|
const socketRef = useRef(null);
|
|
58
68
|
const pollingIntervalRef = useRef(null);
|
|
59
69
|
const position = config?.position || widgetConfig?.position || "bottom-right";
|
|
60
70
|
const primaryColor = widgetConfig?.brand_primary || config?.buttonColor || "#00afab";
|
|
61
|
-
const secondaryColor = widgetConfig?.brand_secondary || config?.brandSecondary || adjustColor(primaryColor, -30);
|
|
62
71
|
const businessName = widgetConfig?.project_name || widgetConfig?.business_info?.name || "Chat with us";
|
|
63
72
|
const logoUrl = widgetConfig?.logo_url || null;
|
|
64
73
|
const welcomeEnabled = widgetConfig?.welcome_screen_enabled !== false;
|
|
@@ -86,10 +95,11 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl }) {
|
|
|
86
95
|
}, [propProjectId, resolvedProjectId, baseUrl]);
|
|
87
96
|
const fetchWidgetConfig = useCallback(async () => {
|
|
88
97
|
if (!projectId) return;
|
|
98
|
+
const apiKey = ensureApiKey();
|
|
99
|
+
if (!apiKey) return;
|
|
89
100
|
try {
|
|
90
|
-
const { apiKey } = getApiConfig();
|
|
91
101
|
const response = await fetch(`${baseUrl}/engage/widget/config?projectId=${projectId}`, {
|
|
92
|
-
headers:
|
|
102
|
+
headers: { "x-api-key": apiKey }
|
|
93
103
|
});
|
|
94
104
|
if (response.ok) {
|
|
95
105
|
const { data } = await response.json();
|
|
@@ -103,10 +113,11 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl }) {
|
|
|
103
113
|
}, [projectId, baseUrl]);
|
|
104
114
|
const checkAvailability = useCallback(async () => {
|
|
105
115
|
if (!projectId) return null;
|
|
116
|
+
const apiKey = ensureApiKey();
|
|
117
|
+
if (!apiKey) return null;
|
|
106
118
|
try {
|
|
107
|
-
const { apiKey } = getApiConfig();
|
|
108
119
|
const response = await fetch(`${baseUrl}/engage/widget/availability?projectId=${projectId}`, {
|
|
109
|
-
headers:
|
|
120
|
+
headers: { "x-api-key": apiKey }
|
|
110
121
|
});
|
|
111
122
|
if (response.ok) {
|
|
112
123
|
const { data } = await response.json();
|
|
@@ -121,11 +132,12 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl }) {
|
|
|
121
132
|
return null;
|
|
122
133
|
}, [projectId, baseUrl]);
|
|
123
134
|
const initSession = useCallback(async () => {
|
|
135
|
+
const apiKey = ensureApiKey();
|
|
136
|
+
if (!apiKey) return null;
|
|
124
137
|
try {
|
|
125
|
-
const { apiKey } = getApiConfig();
|
|
126
138
|
const response = await fetch(`${baseUrl}/engage/widget/session`, {
|
|
127
139
|
method: "POST",
|
|
128
|
-
headers: { "Content-Type": "application/json",
|
|
140
|
+
headers: { "Content-Type": "application/json", "x-api-key": apiKey },
|
|
129
141
|
body: JSON.stringify({
|
|
130
142
|
projectId,
|
|
131
143
|
visitorId,
|
|
@@ -226,28 +238,30 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl }) {
|
|
|
226
238
|
setConnectionStatus("connected");
|
|
227
239
|
console.log("[ChatWidget] Socket.io connected");
|
|
228
240
|
if (currentSessionId) {
|
|
229
|
-
const
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
241
|
+
const apiKey = ensureApiKey();
|
|
242
|
+
if (apiKey) {
|
|
243
|
+
fetch(`${baseUrl}/engage/widget/messages?sessionId=${currentSessionId}`, {
|
|
244
|
+
headers: { "x-api-key": apiKey }
|
|
245
|
+
}).then((res) => res.ok ? res.json() : null).then((json) => {
|
|
246
|
+
const data = json?.data ?? json;
|
|
247
|
+
if (Array.isArray(data) && data.length) {
|
|
248
|
+
setMessages((prev) => {
|
|
249
|
+
const byId = new Map(prev.map((m) => [m.id, m]));
|
|
250
|
+
data.forEach(
|
|
251
|
+
(m) => byId.set(m.id, {
|
|
252
|
+
id: m.id,
|
|
253
|
+
role: m.role === "visitor" ? "user" : m.role,
|
|
254
|
+
content: m.content,
|
|
255
|
+
timestamp: new Date(m.created_at),
|
|
256
|
+
agentName: m.sender_name,
|
|
257
|
+
attachments: m.attachments
|
|
258
|
+
})
|
|
259
|
+
);
|
|
260
|
+
return Array.from(byId.values()).sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
}).catch((err) => console.warn("[ChatWidget] Refetch messages on reconnect failed", err));
|
|
264
|
+
}
|
|
251
265
|
}
|
|
252
266
|
if (lastFailedSend) {
|
|
253
267
|
socket.emit("visitor:message", {
|
|
@@ -289,9 +303,10 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl }) {
|
|
|
289
303
|
if (pollingIntervalRef.current) return;
|
|
290
304
|
pollingIntervalRef.current = setInterval(async () => {
|
|
291
305
|
try {
|
|
292
|
-
const
|
|
306
|
+
const apiKey = ensureApiKey();
|
|
307
|
+
if (!apiKey) return;
|
|
293
308
|
const response = await fetch(`${baseUrl}/engage/widget/messages?sessionId=${currentSessionId}`, {
|
|
294
|
-
headers:
|
|
309
|
+
headers: { "x-api-key": apiKey }
|
|
295
310
|
});
|
|
296
311
|
if (response.ok) {
|
|
297
312
|
const { data } = await response.json();
|
|
@@ -408,14 +423,15 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl }) {
|
|
|
408
423
|
const uploadWidgetFile = useCallback(
|
|
409
424
|
async (file) => {
|
|
410
425
|
if (!sessionId || !visitorId) return null;
|
|
411
|
-
const
|
|
426
|
+
const apiKey = ensureApiKey();
|
|
427
|
+
if (!apiKey) return null;
|
|
412
428
|
const form = new FormData();
|
|
413
429
|
form.append("file", file);
|
|
414
430
|
form.append("sessionId", sessionId);
|
|
415
431
|
form.append("visitorId", visitorId);
|
|
416
432
|
const res = await fetch(`${baseUrl}/engage/widget/upload`, {
|
|
417
433
|
method: "POST",
|
|
418
|
-
headers:
|
|
434
|
+
headers: { "x-api-key": apiKey },
|
|
419
435
|
body: form
|
|
420
436
|
});
|
|
421
437
|
if (!res.ok) throw new Error("Upload failed");
|
|
@@ -489,10 +505,11 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl }) {
|
|
|
489
505
|
}, [lastFailedSend, sessionId, connectSocket]);
|
|
490
506
|
const requestHandoff = useCallback(async () => {
|
|
491
507
|
if (!sessionId) return;
|
|
508
|
+
const apiKey = ensureApiKey();
|
|
509
|
+
if (!apiKey) return;
|
|
492
510
|
try {
|
|
493
|
-
const { apiKey } = getApiConfig();
|
|
494
511
|
const availRes = await fetch(`${baseUrl}/engage/widget/availability?projectId=${projectId}`, {
|
|
495
|
-
headers:
|
|
512
|
+
headers: { "x-api-key": apiKey }
|
|
496
513
|
});
|
|
497
514
|
const avail = availRes.ok ? (await availRes.json()).data : null;
|
|
498
515
|
if (avail?.agentsOnline === 0) {
|
|
@@ -506,7 +523,7 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl }) {
|
|
|
506
523
|
}
|
|
507
524
|
await fetch(`${baseUrl}/engage/widget/handoff`, {
|
|
508
525
|
method: "POST",
|
|
509
|
-
headers: { "Content-Type": "application/json",
|
|
526
|
+
headers: { "Content-Type": "application/json", "x-api-key": apiKey },
|
|
510
527
|
body: JSON.stringify({ sessionId })
|
|
511
528
|
});
|
|
512
529
|
setMessages((prev) => [
|
|
@@ -522,13 +539,14 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl }) {
|
|
|
522
539
|
async (e) => {
|
|
523
540
|
e.preventDefault();
|
|
524
541
|
if (!offlineForm.name || !offlineForm.email || !offlineForm.message) return;
|
|
542
|
+
const apiKey = ensureApiKey();
|
|
543
|
+
if (!apiKey) return;
|
|
525
544
|
setIsLoading(true);
|
|
526
545
|
setOfflineError(null);
|
|
527
546
|
try {
|
|
528
|
-
const { apiKey } = getApiConfig();
|
|
529
547
|
const response = await fetch(`${baseUrl}/engage/widget/offline-form`, {
|
|
530
548
|
method: "POST",
|
|
531
|
-
headers: { "Content-Type": "application/json",
|
|
549
|
+
headers: { "Content-Type": "application/json", "x-api-key": apiKey },
|
|
532
550
|
body: JSON.stringify({
|
|
533
551
|
projectId,
|
|
534
552
|
visitorId,
|
|
@@ -879,9 +897,9 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl }) {
|
|
|
879
897
|
style: {
|
|
880
898
|
padding: "6px 12px",
|
|
881
899
|
borderRadius: 16,
|
|
882
|
-
border: `1px solid ${
|
|
883
|
-
backgroundColor: `${
|
|
884
|
-
color:
|
|
900
|
+
border: `1px solid ${primaryColor}`,
|
|
901
|
+
backgroundColor: `${primaryColor}10`,
|
|
902
|
+
color: primaryColor,
|
|
885
903
|
fontSize: 13,
|
|
886
904
|
cursor: "pointer"
|
|
887
905
|
},
|
|
@@ -907,9 +925,9 @@ function ChatWidget({ projectId: propProjectId, config, apiUrl: propApiUrl }) {
|
|
|
907
925
|
marginTop: 8,
|
|
908
926
|
padding: "6px 12px",
|
|
909
927
|
borderRadius: 6,
|
|
910
|
-
border: `1px solid ${
|
|
928
|
+
border: `1px solid ${primaryColor}`,
|
|
911
929
|
backgroundColor: "transparent",
|
|
912
|
-
color:
|
|
930
|
+
color: primaryColor,
|
|
913
931
|
fontSize: 13,
|
|
914
932
|
cursor: "pointer"
|
|
915
933
|
},
|
|
@@ -1673,5 +1691,5 @@ function getDeviceType() {
|
|
|
1673
1691
|
}
|
|
1674
1692
|
|
|
1675
1693
|
export { ChatWidget, DesignRenderer, EngageWidget };
|
|
1676
|
-
//# sourceMappingURL=chunk-
|
|
1677
|
-
//# sourceMappingURL=chunk-
|
|
1694
|
+
//# sourceMappingURL=chunk-GM2ZDV2B.mjs.map
|
|
1695
|
+
//# sourceMappingURL=chunk-GM2ZDV2B.mjs.map
|