@shop-prompter/react 0.1.1 → 1.1.0
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/CHANGELOG.md +12 -0
- package/dist/index.js +1433 -373
- package/dist/index.mjs +1434 -374
- package/package.json +24 -23
- package/src/api/icons.ts +9 -0
- package/src/api/product-api.ts +121 -0
- package/src/api/session-handler.ts +153 -0
- package/src/api/shop-prompter-api.ts +58 -30
- package/src/api/shop-prompter.types.ts +3 -1
- package/src/product-card-list.component.jsx +271 -0
- package/src/shop-prompter.component.jsx +922 -276
- package/src/shop-prompter.service.ts +60 -18
- package/src/thumbs-down-icon.component.jsx +25 -0
- package/src/thumbs-up-icon.component.jsx +25 -0
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// src/shop-prompter.component.jsx
|
|
2
|
-
import * as
|
|
3
|
-
import { useState, useEffect } from "react";
|
|
2
|
+
import * as React4 from "react";
|
|
3
|
+
import { useState as useState2, useEffect as useEffect2 } from "react";
|
|
4
|
+
import { marked } from "marked";
|
|
4
5
|
|
|
5
6
|
// src/api/shop-prompter-api.ts
|
|
6
7
|
var DefaultShopPrompterApi = class {
|
|
@@ -10,16 +11,27 @@ var DefaultShopPrompterApi = class {
|
|
|
10
11
|
setApiConfig(config) {
|
|
11
12
|
this.config = config;
|
|
12
13
|
}
|
|
14
|
+
getHeaders() {
|
|
15
|
+
if (!this.config) {
|
|
16
|
+
return { "Content-Type": "application/json" };
|
|
17
|
+
}
|
|
18
|
+
const headers = {
|
|
19
|
+
"Content-Type": "application/json"
|
|
20
|
+
};
|
|
21
|
+
if (this.config.shopPrompterToken) {
|
|
22
|
+
headers["Authorization"] = `Bearer ${this.config.shopPrompterToken}`;
|
|
23
|
+
} else if (this.config.apiKey) {
|
|
24
|
+
headers["X-Api-Key"] = this.config.apiKey;
|
|
25
|
+
}
|
|
26
|
+
return headers;
|
|
27
|
+
}
|
|
13
28
|
async execute(prompt, userId, sessionId) {
|
|
14
29
|
if (!this.config) {
|
|
15
30
|
throw new Error("API configuration not set. Call setApiConfig first.");
|
|
16
31
|
}
|
|
17
32
|
const response = await fetch(`${this.config.baseUrl}/interaction`, {
|
|
18
33
|
method: "POST",
|
|
19
|
-
headers:
|
|
20
|
-
"Content-Type": "application/json",
|
|
21
|
-
"X-Api-Key": this.config.apiKey
|
|
22
|
-
},
|
|
34
|
+
headers: this.getHeaders(),
|
|
23
35
|
body: JSON.stringify({
|
|
24
36
|
prompt,
|
|
25
37
|
userId,
|
|
@@ -37,20 +49,12 @@ var DefaultShopPrompterApi = class {
|
|
|
37
49
|
throw new Error("API configuration not set. Call setApiConfig first.");
|
|
38
50
|
}
|
|
39
51
|
const url = `${this.config.baseUrl}/interaction/stream`;
|
|
40
|
-
console.log("ShopPrompter Request:", {
|
|
41
|
-
url,
|
|
42
|
-
prompt,
|
|
43
|
-
userId,
|
|
44
|
-
sessionId,
|
|
45
|
-
cartContext
|
|
46
|
-
});
|
|
47
52
|
let response;
|
|
48
53
|
try {
|
|
49
54
|
response = await fetch(url, {
|
|
50
55
|
method: "POST",
|
|
51
56
|
headers: {
|
|
52
|
-
|
|
53
|
-
"X-Api-Key": this.config.apiKey,
|
|
57
|
+
...this.getHeaders(),
|
|
54
58
|
Accept: "text/event-stream",
|
|
55
59
|
"Cache-Control": "no-cache"
|
|
56
60
|
},
|
|
@@ -69,7 +73,6 @@ var DefaultShopPrompterApi = class {
|
|
|
69
73
|
});
|
|
70
74
|
return;
|
|
71
75
|
}
|
|
72
|
-
console.log("ShopPrompter Response:", response.status);
|
|
73
76
|
if (!response.ok) {
|
|
74
77
|
const errorText = await response.text().catch(() => "");
|
|
75
78
|
console.error("ShopPrompter API Error:", response.status, errorText);
|
|
@@ -90,21 +93,17 @@ var DefaultShopPrompterApi = class {
|
|
|
90
93
|
while (true) {
|
|
91
94
|
const { done, value } = await reader.read();
|
|
92
95
|
if (done) {
|
|
93
|
-
console.log("ShopPrompter Stream done");
|
|
94
96
|
onEvent({ type: "close" });
|
|
95
97
|
break;
|
|
96
98
|
}
|
|
97
99
|
const chunk = decoder.decode(value, { stream: true });
|
|
98
|
-
console.log("ShopPrompter Raw chunk:", chunk);
|
|
99
100
|
buffer += chunk;
|
|
100
101
|
const lines = buffer.split("\n");
|
|
101
102
|
buffer = lines.pop() || "";
|
|
102
103
|
let currentEventType = "";
|
|
103
104
|
for (const line of lines) {
|
|
104
|
-
console.log("ShopPrompter Line:", line);
|
|
105
105
|
if (line.startsWith("event:")) {
|
|
106
106
|
currentEventType = line.slice(6).trim();
|
|
107
|
-
console.log("ShopPrompter Event type:", currentEventType);
|
|
108
107
|
if (currentEventType === "error") {
|
|
109
108
|
onEvent({
|
|
110
109
|
type: "error",
|
|
@@ -113,7 +112,6 @@ var DefaultShopPrompterApi = class {
|
|
|
113
112
|
}
|
|
114
113
|
} else if (line.startsWith("data:")) {
|
|
115
114
|
const data = line.slice(5).trim();
|
|
116
|
-
console.log("ShopPrompter Data:", data);
|
|
117
115
|
if (data) {
|
|
118
116
|
if (currentEventType === "error") {
|
|
119
117
|
try {
|
|
@@ -130,7 +128,6 @@ var DefaultShopPrompterApi = class {
|
|
|
130
128
|
}
|
|
131
129
|
} else {
|
|
132
130
|
const event = this.parseEvent(data);
|
|
133
|
-
console.log("ShopPrompter Parsed event:", event);
|
|
134
131
|
if (event) {
|
|
135
132
|
onEvent(event);
|
|
136
133
|
}
|
|
@@ -156,26 +153,47 @@ var DefaultShopPrompterApi = class {
|
|
|
156
153
|
try {
|
|
157
154
|
const response = await fetch(`${this.config.baseUrl}/agent-experience`, {
|
|
158
155
|
method: "GET",
|
|
159
|
-
headers:
|
|
160
|
-
"Content-Type": "application/json",
|
|
161
|
-
"X-Api-Key": this.config.apiKey
|
|
162
|
-
}
|
|
156
|
+
headers: this.getHeaders()
|
|
163
157
|
});
|
|
164
158
|
if (!response.ok) {
|
|
165
159
|
console.error(`Failed to fetch agent experience: ${response.status}`);
|
|
166
160
|
return null;
|
|
167
161
|
}
|
|
168
162
|
const data = await response.json();
|
|
169
|
-
console.log(
|
|
170
|
-
"## ~ DefaultShopPrompterApi ~ getAgentExperience ~ data:",
|
|
171
|
-
data
|
|
172
|
-
);
|
|
173
163
|
return data;
|
|
174
164
|
} catch (error) {
|
|
175
165
|
console.error("Error fetching agent experience:", error);
|
|
176
166
|
return null;
|
|
177
167
|
}
|
|
178
168
|
}
|
|
169
|
+
async sendFeedback(threadId, message, feedback) {
|
|
170
|
+
if (!this.config) {
|
|
171
|
+
throw new Error("API configuration not set. Call setApiConfig first.");
|
|
172
|
+
}
|
|
173
|
+
try {
|
|
174
|
+
const response = await fetch(`${this.config.baseUrl}/feedback`, {
|
|
175
|
+
method: "POST",
|
|
176
|
+
headers: this.getHeaders(),
|
|
177
|
+
body: JSON.stringify({
|
|
178
|
+
threadId,
|
|
179
|
+
message,
|
|
180
|
+
feedback
|
|
181
|
+
})
|
|
182
|
+
});
|
|
183
|
+
if (!response.ok) {
|
|
184
|
+
throw new Error(
|
|
185
|
+
"We are sorry, but we could not process your feedback. Please try again later."
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
} catch (error) {
|
|
189
|
+
if (error instanceof Error && error.message.startsWith("We are sorry")) {
|
|
190
|
+
throw error;
|
|
191
|
+
}
|
|
192
|
+
throw new Error(
|
|
193
|
+
"We are sorry, but we could not process your feedback. Please try again later."
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
179
197
|
parseEvent(data) {
|
|
180
198
|
try {
|
|
181
199
|
const json = JSON.parse(data);
|
|
@@ -285,10 +303,78 @@ var DefaultShopPrompterApi = class {
|
|
|
285
303
|
};
|
|
286
304
|
var shopPrompterApi = new DefaultShopPrompterApi();
|
|
287
305
|
|
|
306
|
+
// src/api/product-api.ts
|
|
307
|
+
var DefaultProductApi = class {
|
|
308
|
+
constructor() {
|
|
309
|
+
this.config = null;
|
|
310
|
+
this.cache = /* @__PURE__ */ new Map();
|
|
311
|
+
}
|
|
312
|
+
setApiConfig(config) {
|
|
313
|
+
this.config = config;
|
|
314
|
+
}
|
|
315
|
+
isCached(skus) {
|
|
316
|
+
if (!skus || skus.length === 0) return true;
|
|
317
|
+
return skus.every((sku) => this.cache.has(sku));
|
|
318
|
+
}
|
|
319
|
+
getCached(skus) {
|
|
320
|
+
if (!skus || skus.length === 0) return [];
|
|
321
|
+
return skus.map((sku) => this.cache.get(sku)).filter(Boolean);
|
|
322
|
+
}
|
|
323
|
+
async getProducts(skus) {
|
|
324
|
+
if (!this.config) {
|
|
325
|
+
throw new Error("API configuration not set. Call setApiConfig first.");
|
|
326
|
+
}
|
|
327
|
+
const cachedProducts = [];
|
|
328
|
+
const missingSkus = [];
|
|
329
|
+
for (const sku of skus) {
|
|
330
|
+
if (this.cache.has(sku)) {
|
|
331
|
+
const cachedVal = this.cache.get(sku);
|
|
332
|
+
if (cachedVal) {
|
|
333
|
+
cachedProducts.push(cachedVal);
|
|
334
|
+
}
|
|
335
|
+
} else {
|
|
336
|
+
missingSkus.push(sku);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
if (missingSkus.length === 0) {
|
|
340
|
+
return skus.map((sku) => this.cache.get(sku)).filter(Boolean);
|
|
341
|
+
}
|
|
342
|
+
const baseUrl = this.config.productsBaseUrl || this.config.baseUrl;
|
|
343
|
+
const url = `${baseUrl}/products?skus=${encodeURIComponent(missingSkus.join(","))}`;
|
|
344
|
+
const headers = {
|
|
345
|
+
"Content-Type": "application/json"
|
|
346
|
+
};
|
|
347
|
+
const response = await fetch(url, {
|
|
348
|
+
method: "GET",
|
|
349
|
+
headers
|
|
350
|
+
});
|
|
351
|
+
if (!response.ok) {
|
|
352
|
+
throw new Error(`Product API error: ${response.status}`);
|
|
353
|
+
}
|
|
354
|
+
const newProducts = await response.json();
|
|
355
|
+
const returnedSkus = /* @__PURE__ */ new Set();
|
|
356
|
+
for (const p of newProducts) {
|
|
357
|
+
if (p.sku) {
|
|
358
|
+
this.cache.set(p.sku, p);
|
|
359
|
+
returnedSkus.add(p.sku);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
for (const sku of missingSkus) {
|
|
363
|
+
if (!returnedSkus.has(sku)) {
|
|
364
|
+
this.cache.set(sku, null);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
return skus.map((sku) => this.cache.get(sku)).filter(Boolean);
|
|
368
|
+
}
|
|
369
|
+
};
|
|
370
|
+
var productApi = new DefaultProductApi();
|
|
371
|
+
|
|
288
372
|
// src/api/session-handler.ts
|
|
289
373
|
import { v4 as uuidv4 } from "uuid";
|
|
290
374
|
var SESSION_KEY = "shopprompter_sessionId";
|
|
291
375
|
var USER_KEY = "shopprompter_userId";
|
|
376
|
+
var SESSIONS_KEY = "shopprompter_sessions";
|
|
377
|
+
var MAX_SESSIONS = 3;
|
|
292
378
|
var DefaultSessionHandler = class {
|
|
293
379
|
constructor() {
|
|
294
380
|
this.sessionId = "";
|
|
@@ -316,6 +402,98 @@ var DefaultSessionHandler = class {
|
|
|
316
402
|
}
|
|
317
403
|
return this.userId;
|
|
318
404
|
}
|
|
405
|
+
// -------------------------------------------------------------------------
|
|
406
|
+
// Message persistence
|
|
407
|
+
// -------------------------------------------------------------------------
|
|
408
|
+
/** Persist a user message immediately when it is sent. */
|
|
409
|
+
saveUserMessage(sessionId, message) {
|
|
410
|
+
try {
|
|
411
|
+
const store = this.loadSessionStore();
|
|
412
|
+
if (!store[sessionId]) {
|
|
413
|
+
this.evictIfNeeded(store);
|
|
414
|
+
store[sessionId] = { createdAt: Date.now(), messages: [] };
|
|
415
|
+
}
|
|
416
|
+
store[sessionId].messages.push(message);
|
|
417
|
+
this.saveSessionStore(store);
|
|
418
|
+
} catch {
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
/**
|
|
422
|
+
* Persist the fully-streamed assistant message.
|
|
423
|
+
* If the message ID already exists in the store (shouldn't normally happen)
|
|
424
|
+
* it is replaced; otherwise it is appended.
|
|
425
|
+
*/
|
|
426
|
+
saveAssistantMessage(sessionId, message) {
|
|
427
|
+
try {
|
|
428
|
+
const store = this.loadSessionStore();
|
|
429
|
+
if (!store[sessionId]) {
|
|
430
|
+
store[sessionId] = { createdAt: Date.now(), messages: [] };
|
|
431
|
+
}
|
|
432
|
+
const msgs = store[sessionId].messages;
|
|
433
|
+
const existingIdx = msgs.findIndex((m) => m.id === message.id);
|
|
434
|
+
if (existingIdx !== -1) {
|
|
435
|
+
msgs[existingIdx] = message;
|
|
436
|
+
} else {
|
|
437
|
+
msgs.push(message);
|
|
438
|
+
}
|
|
439
|
+
this.saveSessionStore(store);
|
|
440
|
+
} catch {
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
/** Return the persisted messages for the given session (newest first order preserved). */
|
|
444
|
+
loadMessages(sessionId) {
|
|
445
|
+
var _a, _b;
|
|
446
|
+
try {
|
|
447
|
+
const store = this.loadSessionStore();
|
|
448
|
+
return (_b = (_a = store[sessionId]) == null ? void 0 : _a.messages) != null ? _b : [];
|
|
449
|
+
} catch {
|
|
450
|
+
return [];
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
/** Update the feedback field of a specific persisted message. */
|
|
454
|
+
updateMessageFeedback(sessionId, messageId, feedback) {
|
|
455
|
+
try {
|
|
456
|
+
const store = this.loadSessionStore();
|
|
457
|
+
const session = store[sessionId];
|
|
458
|
+
if (!session) return;
|
|
459
|
+
const msg = session.messages.find((m) => m.id === messageId);
|
|
460
|
+
if (!msg) return;
|
|
461
|
+
msg.feedback = feedback;
|
|
462
|
+
this.saveSessionStore(store);
|
|
463
|
+
} catch {
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
// -------------------------------------------------------------------------
|
|
467
|
+
// Private helpers
|
|
468
|
+
// -------------------------------------------------------------------------
|
|
469
|
+
/**
|
|
470
|
+
* Remove the single oldest session from the store when it already holds
|
|
471
|
+
* MAX_SESSIONS entries. Mutates the store object in place.
|
|
472
|
+
*/
|
|
473
|
+
evictIfNeeded(store) {
|
|
474
|
+
const sessionIds = Object.keys(store);
|
|
475
|
+
if (sessionIds.length < MAX_SESSIONS) return;
|
|
476
|
+
let oldestId = sessionIds[0];
|
|
477
|
+
let oldestTime = store[oldestId].createdAt;
|
|
478
|
+
for (const id of sessionIds) {
|
|
479
|
+
if (store[id].createdAt < oldestTime) {
|
|
480
|
+
oldestId = id;
|
|
481
|
+
oldestTime = store[id].createdAt;
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
delete store[oldestId];
|
|
485
|
+
}
|
|
486
|
+
loadSessionStore() {
|
|
487
|
+
try {
|
|
488
|
+
const raw = localStorage.getItem(SESSIONS_KEY);
|
|
489
|
+
return raw ? JSON.parse(raw) : {};
|
|
490
|
+
} catch {
|
|
491
|
+
return {};
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
saveSessionStore(store) {
|
|
495
|
+
localStorage.setItem(SESSIONS_KEY, JSON.stringify(store));
|
|
496
|
+
}
|
|
319
497
|
getPersistedSessionId() {
|
|
320
498
|
try {
|
|
321
499
|
return localStorage.getItem(SESSION_KEY);
|
|
@@ -346,16 +524,13 @@ var DefaultSessionHandler = class {
|
|
|
346
524
|
var sessionHandler = new DefaultSessionHandler();
|
|
347
525
|
|
|
348
526
|
// src/shop-prompter.service.ts
|
|
349
|
-
var SHOP_PROMPTER_CONFIG = {
|
|
350
|
-
baseUrl: "https://demo.dev.shop-prompter.com/touch-points-api",
|
|
351
|
-
apiKey: "864c87266ef52c079c09b3248d86b4b5ef430bf9e5a4188476124c93ee2f6dda380f337986837b30b60f73e6aceefe7a0e0f778b3d21a7fa7698cf8546afc709"
|
|
352
|
-
};
|
|
353
527
|
var ShopPrompterService = class {
|
|
354
|
-
constructor() {
|
|
528
|
+
constructor(apiConfig) {
|
|
355
529
|
this.isLoading = false;
|
|
356
530
|
this.error = null;
|
|
357
531
|
this.streamingText = "";
|
|
358
|
-
shopPrompterApi.setApiConfig(
|
|
532
|
+
shopPrompterApi.setApiConfig(apiConfig);
|
|
533
|
+
productApi.setApiConfig(apiConfig);
|
|
359
534
|
sessionHandler.initialize();
|
|
360
535
|
}
|
|
361
536
|
async sendMessage(prompt, callbacks, cartContext) {
|
|
@@ -366,7 +541,16 @@ var ShopPrompterService = class {
|
|
|
366
541
|
this.streamingText = "";
|
|
367
542
|
const userId = sessionHandler.getUserId();
|
|
368
543
|
const sessionId = sessionHandler.getSessionId();
|
|
544
|
+
const userMsgId = Date.now().toString() + "-user";
|
|
545
|
+
sessionHandler.saveUserMessage(sessionId, {
|
|
546
|
+
id: userMsgId,
|
|
547
|
+
role: "user",
|
|
548
|
+
content: prompt,
|
|
549
|
+
productSkus: []
|
|
550
|
+
});
|
|
551
|
+
const assistantMsgId = Date.now().toString() + "-assistant";
|
|
369
552
|
let accumulatedText = "";
|
|
553
|
+
let accumulatedSkus = [];
|
|
370
554
|
try {
|
|
371
555
|
await shopPrompterApi.executeStream(
|
|
372
556
|
prompt,
|
|
@@ -381,6 +565,7 @@ var ShopPrompterService = class {
|
|
|
381
565
|
(_a2 = callbacks.onTextUpdate) == null ? void 0 : _a2.call(callbacks, accumulatedText);
|
|
382
566
|
break;
|
|
383
567
|
case "productSkus":
|
|
568
|
+
accumulatedSkus = event.skus;
|
|
384
569
|
(_b2 = callbacks.onProductSkus) == null ? void 0 : _b2.call(callbacks, event.skus);
|
|
385
570
|
break;
|
|
386
571
|
case "navigation":
|
|
@@ -393,6 +578,12 @@ var ShopPrompterService = class {
|
|
|
393
578
|
this.isLoading = false;
|
|
394
579
|
(_d = callbacks.onLoadingChange) == null ? void 0 : _d.call(callbacks, false);
|
|
395
580
|
(_e = callbacks.onComplete) == null ? void 0 : _e.call(callbacks);
|
|
581
|
+
sessionHandler.saveAssistantMessage(sessionId, {
|
|
582
|
+
id: assistantMsgId,
|
|
583
|
+
role: "assistant",
|
|
584
|
+
content: accumulatedText,
|
|
585
|
+
productSkus: accumulatedSkus
|
|
586
|
+
});
|
|
396
587
|
break;
|
|
397
588
|
case "error":
|
|
398
589
|
this.error = event.reason;
|
|
@@ -414,9 +605,6 @@ var ShopPrompterService = class {
|
|
|
414
605
|
return accumulatedText;
|
|
415
606
|
}
|
|
416
607
|
async getAgentExperience() {
|
|
417
|
-
console.log(
|
|
418
|
-
"## ~ ShopPrompterService ~ getAgentExperience ~ getAgentExperience:"
|
|
419
|
-
);
|
|
420
608
|
try {
|
|
421
609
|
return await shopPrompterApi.getAgentExperience();
|
|
422
610
|
} catch (err) {
|
|
@@ -424,6 +612,32 @@ var ShopPrompterService = class {
|
|
|
424
612
|
throw err;
|
|
425
613
|
}
|
|
426
614
|
}
|
|
615
|
+
/**
|
|
616
|
+
* Load persisted chat messages for the current session from localStorage.
|
|
617
|
+
* Returns an empty array if nothing is stored yet.
|
|
618
|
+
*/
|
|
619
|
+
loadMessages() {
|
|
620
|
+
const sessionId = sessionHandler.getSessionId();
|
|
621
|
+
const persisted = sessionHandler.loadMessages(sessionId);
|
|
622
|
+
return persisted.map((msg) => {
|
|
623
|
+
var _a, _b;
|
|
624
|
+
return {
|
|
625
|
+
id: msg.id,
|
|
626
|
+
role: msg.role,
|
|
627
|
+
content: msg.content,
|
|
628
|
+
productSkus: (_a = msg.productSkus) != null ? _a : [],
|
|
629
|
+
feedback: (_b = msg.feedback) != null ? _b : null
|
|
630
|
+
};
|
|
631
|
+
});
|
|
632
|
+
}
|
|
633
|
+
async sendFeedback(messageId, messageContent, feedback) {
|
|
634
|
+
const userId = sessionHandler.getUserId();
|
|
635
|
+
const sessionId = sessionHandler.getSessionId();
|
|
636
|
+
const threadId = `${userId}:${sessionId}`;
|
|
637
|
+
await shopPrompterApi.sendFeedback(threadId, messageContent, feedback);
|
|
638
|
+
const storedFeedback = feedback === "clear" ? null : feedback;
|
|
639
|
+
sessionHandler.updateMessageFeedback(sessionId, messageId, storedFeedback);
|
|
640
|
+
}
|
|
427
641
|
resetSession() {
|
|
428
642
|
sessionHandler.regenerate();
|
|
429
643
|
}
|
|
@@ -436,14 +650,297 @@ var ShopPrompterService = class {
|
|
|
436
650
|
}
|
|
437
651
|
};
|
|
438
652
|
|
|
439
|
-
// src/
|
|
440
|
-
import
|
|
653
|
+
// src/thumbs-up-icon.component.jsx
|
|
654
|
+
import * as React from "react";
|
|
655
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
656
|
+
function ThumbsUpIcon(props) {
|
|
657
|
+
return /* @__PURE__ */ jsxs(
|
|
658
|
+
"svg",
|
|
659
|
+
{
|
|
660
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
661
|
+
width: "18",
|
|
662
|
+
height: "18",
|
|
663
|
+
viewBox: "0 0 24 24",
|
|
664
|
+
"stroke-width": "2",
|
|
665
|
+
"stroke-linecap": "round",
|
|
666
|
+
"stroke-linejoin": "round",
|
|
667
|
+
fill: props.fill || "none",
|
|
668
|
+
stroke: props.stroke || "currentColor",
|
|
669
|
+
style: {
|
|
670
|
+
overflow: "visible"
|
|
671
|
+
},
|
|
672
|
+
children: [
|
|
673
|
+
/* @__PURE__ */ jsx("path", { d: "M7 10v12" }),
|
|
674
|
+
/* @__PURE__ */ jsx("path", { d: "M15 5.88 14 10h5.83a2 2 0 0 1 1.92 2.56l-2.33 8A2 2 0 0 1 17.5 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h2.76a2 2 0 0 0 1.79-1.11L12 2h0a3.13 3.13 0 0 1 3 3.88Z" })
|
|
675
|
+
]
|
|
676
|
+
}
|
|
677
|
+
);
|
|
678
|
+
}
|
|
679
|
+
var thumbs_up_icon_component_default = ThumbsUpIcon;
|
|
680
|
+
|
|
681
|
+
// src/thumbs-down-icon.component.jsx
|
|
682
|
+
import * as React2 from "react";
|
|
683
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
684
|
+
function ThumbsDownIcon(props) {
|
|
685
|
+
return /* @__PURE__ */ jsxs2(
|
|
686
|
+
"svg",
|
|
687
|
+
{
|
|
688
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
689
|
+
width: "18",
|
|
690
|
+
height: "18",
|
|
691
|
+
viewBox: "0 0 24 24",
|
|
692
|
+
"stroke-width": "2",
|
|
693
|
+
"stroke-linecap": "round",
|
|
694
|
+
"stroke-linejoin": "round",
|
|
695
|
+
fill: props.fill || "none",
|
|
696
|
+
stroke: props.stroke || "currentColor",
|
|
697
|
+
style: {
|
|
698
|
+
overflow: "visible"
|
|
699
|
+
},
|
|
700
|
+
children: [
|
|
701
|
+
/* @__PURE__ */ jsx2("path", { d: "M17 14V2" }),
|
|
702
|
+
/* @__PURE__ */ jsx2("path", { d: "M9 18.12 10 14H4.17a2 2 0 0 1-1.92-2.56l2.33-8A2 2 0 0 1 6.5 2H20a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2h-2.76a2 2 0 0 0-1.79 1.11L12 22h0a3.13 3.13 0 0 1-3-3.88Z" })
|
|
703
|
+
]
|
|
704
|
+
}
|
|
705
|
+
);
|
|
706
|
+
}
|
|
707
|
+
var thumbs_down_icon_component_default = ThumbsDownIcon;
|
|
708
|
+
|
|
709
|
+
// src/product-card-list.component.jsx
|
|
710
|
+
import * as React3 from "react";
|
|
711
|
+
import { useState, useEffect } from "react";
|
|
712
|
+
import { Fragment, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
441
713
|
var styles = {
|
|
714
|
+
productCardsContainer: {
|
|
715
|
+
marginTop: "0.75rem",
|
|
716
|
+
display: "flex",
|
|
717
|
+
gap: "0.75rem",
|
|
718
|
+
overflowX: "auto",
|
|
719
|
+
width: "100%",
|
|
720
|
+
paddingBottom: "0.5rem",
|
|
721
|
+
boxSizing: "border-box",
|
|
722
|
+
scrollbarWidth: "thin",
|
|
723
|
+
scrollSnapType: "x mandatory",
|
|
724
|
+
WebkitOverflowScrolling: "touch"
|
|
725
|
+
},
|
|
726
|
+
productCard: {
|
|
727
|
+
minWidth: "9.5rem",
|
|
728
|
+
maxWidth: "9.5rem",
|
|
729
|
+
backgroundColor: "white",
|
|
730
|
+
border: "1px solid #f3f4f6",
|
|
731
|
+
borderRadius: "0.75rem",
|
|
732
|
+
overflow: "hidden",
|
|
733
|
+
boxShadow: "0 4px 6px -1px rgba(0, 0, 0, 0.05), 0 2px 4px -1px rgba(0, 0, 0, 0.03)",
|
|
734
|
+
display: "flex",
|
|
735
|
+
flexDirection: "column",
|
|
736
|
+
scrollSnapAlign: "start"
|
|
737
|
+
},
|
|
738
|
+
productImageContainer: {
|
|
739
|
+
height: "7rem",
|
|
740
|
+
backgroundColor: "#f9fafb",
|
|
741
|
+
display: "flex",
|
|
742
|
+
alignItems: "center",
|
|
743
|
+
justifyContent: "center",
|
|
744
|
+
padding: "0.5rem",
|
|
745
|
+
borderBottom: "1px solid #f3f4f6"
|
|
746
|
+
},
|
|
747
|
+
productImage: {
|
|
748
|
+
maxHeight: "100%",
|
|
749
|
+
maxWidth: "100%",
|
|
750
|
+
objectFit: "contain"
|
|
751
|
+
},
|
|
752
|
+
productInfo: {
|
|
753
|
+
padding: "0.625rem",
|
|
754
|
+
display: "flex",
|
|
755
|
+
flexDirection: "column",
|
|
756
|
+
gap: "0.25rem"
|
|
757
|
+
},
|
|
758
|
+
productName: {
|
|
759
|
+
fontSize: "0.8125rem",
|
|
760
|
+
fontWeight: 600,
|
|
761
|
+
color: "#1f2937",
|
|
762
|
+
margin: 0,
|
|
763
|
+
whiteSpace: "nowrap",
|
|
764
|
+
overflow: "hidden",
|
|
765
|
+
textOverflow: "ellipsis"
|
|
766
|
+
},
|
|
767
|
+
productDynamicField: {
|
|
768
|
+
fontSize: "0.6875rem",
|
|
769
|
+
color: "#6b7280",
|
|
770
|
+
margin: 0,
|
|
771
|
+
whiteSpace: "nowrap",
|
|
772
|
+
overflow: "hidden",
|
|
773
|
+
textOverflow: "ellipsis"
|
|
774
|
+
},
|
|
775
|
+
productPrice: {
|
|
776
|
+
fontSize: "0.8125rem",
|
|
777
|
+
fontWeight: 500,
|
|
778
|
+
color: "#4b5563",
|
|
779
|
+
margin: 0
|
|
780
|
+
},
|
|
781
|
+
statusContainer: {
|
|
782
|
+
padding: "0.5rem 0",
|
|
783
|
+
fontSize: "0.75rem",
|
|
784
|
+
color: "#6b7280",
|
|
785
|
+
display: "flex",
|
|
786
|
+
alignItems: "center",
|
|
787
|
+
gap: "0.5rem"
|
|
788
|
+
},
|
|
789
|
+
errorText: {
|
|
790
|
+
color: "#ef4444"
|
|
791
|
+
},
|
|
792
|
+
spinner: {
|
|
793
|
+
color: "#6b7280"
|
|
794
|
+
},
|
|
795
|
+
wrapper: {
|
|
796
|
+
width: "100%",
|
|
797
|
+
maxWidth: "100%",
|
|
798
|
+
boxSizing: "border-box",
|
|
799
|
+
overflow: "hidden"
|
|
800
|
+
}
|
|
801
|
+
};
|
|
802
|
+
function ProductCardList(props) {
|
|
803
|
+
const [products, setProducts] = useState(() => []);
|
|
804
|
+
const [loading, setLoading] = useState(() => false);
|
|
805
|
+
const [error, setError] = useState(() => null);
|
|
806
|
+
function fetchProducts() {
|
|
807
|
+
let skusList = props.skus;
|
|
808
|
+
if (typeof skusList === "string") {
|
|
809
|
+
skusList = skusList.split(",").map((s) => s.trim()).filter(Boolean);
|
|
810
|
+
}
|
|
811
|
+
if (!skusList || skusList.length === 0) {
|
|
812
|
+
setProducts([]);
|
|
813
|
+
setLoading(false);
|
|
814
|
+
return;
|
|
815
|
+
}
|
|
816
|
+
if (productApi.isCached(skusList)) {
|
|
817
|
+
setProducts(productApi.getCached(skusList));
|
|
818
|
+
setLoading(false);
|
|
819
|
+
setError(null);
|
|
820
|
+
return;
|
|
821
|
+
}
|
|
822
|
+
setLoading(true);
|
|
823
|
+
setError(null);
|
|
824
|
+
productApi.getProducts(skusList).then((data) => {
|
|
825
|
+
setProducts(data || []);
|
|
826
|
+
setLoading(false);
|
|
827
|
+
}).catch((err) => {
|
|
828
|
+
console.error("Failed to fetch products:", err);
|
|
829
|
+
setError((err == null ? void 0 : err.message) || "Failed to load products");
|
|
830
|
+
setLoading(false);
|
|
831
|
+
});
|
|
832
|
+
}
|
|
833
|
+
function getProductName(product) {
|
|
834
|
+
var _a;
|
|
835
|
+
const locale = props.defaultLocale || "de";
|
|
836
|
+
const localized = ((_a = product.localization) == null ? void 0 : _a[locale]) || Object.values(product.localization || {})[0];
|
|
837
|
+
return (localized == null ? void 0 : localized.name) || product.sku;
|
|
838
|
+
}
|
|
839
|
+
function showPriceIfEmptyVal() {
|
|
840
|
+
const val = props.showPriceIfEmpty;
|
|
841
|
+
if (typeof val === "string") {
|
|
842
|
+
return val === "true";
|
|
843
|
+
}
|
|
844
|
+
return val != null ? val : false;
|
|
845
|
+
}
|
|
846
|
+
function visibleFieldsList() {
|
|
847
|
+
const val = props.visibleFields;
|
|
848
|
+
if (typeof val === "string") {
|
|
849
|
+
try {
|
|
850
|
+
return JSON.parse(val);
|
|
851
|
+
} catch (e) {
|
|
852
|
+
return val.split(",").map((s) => s.trim()).filter(Boolean);
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
return val || [];
|
|
856
|
+
}
|
|
857
|
+
function getDynamicField(product, field) {
|
|
858
|
+
var _a;
|
|
859
|
+
const locale = props.defaultLocale || "de";
|
|
860
|
+
const localized = ((_a = product.localization) == null ? void 0 : _a[locale]) || Object.values(product.localization || {})[0];
|
|
861
|
+
if (!localized) return void 0;
|
|
862
|
+
const parts = field.split(".");
|
|
863
|
+
let current = localized;
|
|
864
|
+
for (let i = 0; i < parts.length; i++) {
|
|
865
|
+
if (current === void 0 || current === null) return void 0;
|
|
866
|
+
current = current[parts[i]];
|
|
867
|
+
}
|
|
868
|
+
return current;
|
|
869
|
+
}
|
|
870
|
+
function getProductPrice(product) {
|
|
871
|
+
if (!product.pricing) return "";
|
|
872
|
+
const priceVal = product.pricing.gross;
|
|
873
|
+
const currency = product.pricing.currency;
|
|
874
|
+
if (priceVal === void 0 || priceVal === null) return "";
|
|
875
|
+
if (priceVal === 0 && !showPriceIfEmptyVal()) return "";
|
|
876
|
+
return priceVal.toFixed(2) + " " + (currency || "\u20AC");
|
|
877
|
+
}
|
|
878
|
+
function getProductImage(product) {
|
|
879
|
+
var _a;
|
|
880
|
+
return ((_a = product.images) == null ? void 0 : _a[0]) || "https://placehold.co/150x150?text=" + product.sku;
|
|
881
|
+
}
|
|
882
|
+
useEffect(() => {
|
|
883
|
+
fetchProducts();
|
|
884
|
+
}, []);
|
|
885
|
+
useEffect(() => {
|
|
886
|
+
fetchProducts();
|
|
887
|
+
}, [
|
|
888
|
+
props.skus ? Array.isArray(props.skus) ? props.skus.join(",") : props.skus : ""
|
|
889
|
+
]);
|
|
890
|
+
return /* @__PURE__ */ jsx3(Fragment, { children: props.skus && props.skus.length > 0 ? /* @__PURE__ */ jsx3(Fragment, { children: /* @__PURE__ */ jsxs3("div", { style: styles.wrapper, children: [
|
|
891
|
+
loading ? /* @__PURE__ */ jsx3("div", { style: styles.statusContainer, children: /* @__PURE__ */ jsx3("span", { children: "Loading products..." }) }) : null,
|
|
892
|
+
!loading && error ? /* @__PURE__ */ jsx3("div", { style: styles.statusContainer, children: /* @__PURE__ */ jsxs3("span", { style: styles.errorText, children: [
|
|
893
|
+
"Error: ",
|
|
894
|
+
error
|
|
895
|
+
] }) }) : null,
|
|
896
|
+
!loading && products && products.length > 0 ? /* @__PURE__ */ jsx3("div", { style: styles.productCardsContainer, children: products == null ? void 0 : products.map((product) => {
|
|
897
|
+
var _a;
|
|
898
|
+
return /* @__PURE__ */ jsxs3("div", { style: styles.productCard, children: [
|
|
899
|
+
/* @__PURE__ */ jsx3("div", { style: styles.productImageContainer, children: /* @__PURE__ */ jsx3(
|
|
900
|
+
"img",
|
|
901
|
+
{
|
|
902
|
+
src: getProductImage(product),
|
|
903
|
+
alt: getProductName(product),
|
|
904
|
+
style: styles.productImage
|
|
905
|
+
}
|
|
906
|
+
) }),
|
|
907
|
+
/* @__PURE__ */ jsxs3("div", { style: styles.productInfo, children: [
|
|
908
|
+
/* @__PURE__ */ jsx3(
|
|
909
|
+
"p",
|
|
910
|
+
{
|
|
911
|
+
style: styles.productName,
|
|
912
|
+
title: getProductName(product),
|
|
913
|
+
children: getProductName(product)
|
|
914
|
+
}
|
|
915
|
+
),
|
|
916
|
+
(_a = visibleFieldsList()) == null ? void 0 : _a.map(
|
|
917
|
+
(field) => getDynamicField(product, field) !== void 0 ? /* @__PURE__ */ jsx3(
|
|
918
|
+
"p",
|
|
919
|
+
{
|
|
920
|
+
style: styles.productDynamicField,
|
|
921
|
+
title: String(getDynamicField(product, field)),
|
|
922
|
+
children: String(getDynamicField(product, field))
|
|
923
|
+
}
|
|
924
|
+
) : null
|
|
925
|
+
),
|
|
926
|
+
getProductPrice(product) !== "" ? /* @__PURE__ */ jsx3("p", { style: styles.productPrice, children: getProductPrice(product) }) : null
|
|
927
|
+
] })
|
|
928
|
+
] }, product.sku);
|
|
929
|
+
}) }) : null
|
|
930
|
+
] }) }) : null });
|
|
931
|
+
}
|
|
932
|
+
var product_card_list_component_default = ProductCardList;
|
|
933
|
+
|
|
934
|
+
// src/shop-prompter.component.jsx
|
|
935
|
+
import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
936
|
+
var THINKING_SPINNER = "M21 12a9 9 0 1 1-6.219-8.56";
|
|
937
|
+
var styles2 = {
|
|
442
938
|
header: {
|
|
443
939
|
display: "flex",
|
|
444
940
|
alignItems: "center",
|
|
445
941
|
justifyContent: "space-between",
|
|
446
|
-
padding: "16px"
|
|
942
|
+
padding: "16px",
|
|
943
|
+
borderBottom: "1px solid #e5e7eb"
|
|
447
944
|
},
|
|
448
945
|
subHeaderContainer: {
|
|
449
946
|
display: "flex",
|
|
@@ -459,6 +956,7 @@ var styles = {
|
|
|
459
956
|
border: "none",
|
|
460
957
|
cursor: "pointer",
|
|
461
958
|
transition: "background-color 0.2s, color 0.2s",
|
|
959
|
+
fontFamily: "inherit",
|
|
462
960
|
onHover: {
|
|
463
961
|
backgroundColor: "hsl(220 14% 96%)",
|
|
464
962
|
color: "hsl(220 13% 13%)"
|
|
@@ -479,7 +977,8 @@ var styles = {
|
|
|
479
977
|
gap: "0.5rem",
|
|
480
978
|
cursor: "pointer",
|
|
481
979
|
fontSize: "0.875rem",
|
|
482
|
-
color: "#09090b"
|
|
980
|
+
color: "#09090b",
|
|
981
|
+
fontFamily: "inherit"
|
|
483
982
|
},
|
|
484
983
|
ButtonSheetButton: {
|
|
485
984
|
color: "#6b7280",
|
|
@@ -488,11 +987,13 @@ var styles = {
|
|
|
488
987
|
cursor: "pointer",
|
|
489
988
|
padding: "0.25rem",
|
|
490
989
|
fontSize: "1.25rem",
|
|
491
|
-
transition: "color 0.2s"
|
|
990
|
+
transition: "color 0.2s",
|
|
991
|
+
fontFamily: "inherit"
|
|
492
992
|
},
|
|
493
993
|
chatContainer: {
|
|
494
994
|
flex: 1,
|
|
495
995
|
overflowY: "auto",
|
|
996
|
+
overflowX: "hidden",
|
|
496
997
|
padding: "1rem",
|
|
497
998
|
backgroundColor: "white"
|
|
498
999
|
},
|
|
@@ -538,12 +1039,17 @@ var styles = {
|
|
|
538
1039
|
messageContainerUser: {
|
|
539
1040
|
display: "flex",
|
|
540
1041
|
flexDirection: "column",
|
|
541
|
-
alignItems: "flex-end"
|
|
1042
|
+
alignItems: "flex-end",
|
|
1043
|
+
marginBottom: "8px"
|
|
542
1044
|
},
|
|
543
1045
|
messageContainerAssistant: {
|
|
544
1046
|
display: "flex",
|
|
545
1047
|
flexDirection: "column",
|
|
546
|
-
alignItems: "flex-start"
|
|
1048
|
+
alignItems: "flex-start",
|
|
1049
|
+
marginBottom: "8px",
|
|
1050
|
+
width: "100%",
|
|
1051
|
+
maxWidth: "100%",
|
|
1052
|
+
boxSizing: "border-box"
|
|
547
1053
|
},
|
|
548
1054
|
messageBubbleUser: {
|
|
549
1055
|
backgroundColor: "#111827",
|
|
@@ -553,7 +1059,8 @@ var styles = {
|
|
|
553
1059
|
padding: "0.5rem 1rem",
|
|
554
1060
|
fontSize: "0.875rem",
|
|
555
1061
|
boxShadow: "0 1px 2px 0 rgba(0, 0, 0, 0.05)",
|
|
556
|
-
maxWidth: "85%"
|
|
1062
|
+
maxWidth: "85%",
|
|
1063
|
+
textAlign: "left"
|
|
557
1064
|
},
|
|
558
1065
|
messageBubbleAssistant: {
|
|
559
1066
|
backgroundColor: "#f3f4f6",
|
|
@@ -563,7 +1070,8 @@ var styles = {
|
|
|
563
1070
|
padding: "0.5rem 1rem",
|
|
564
1071
|
fontSize: "0.875rem",
|
|
565
1072
|
boxShadow: "0 1px 2px 0 rgba(0, 0, 0, 0.05)",
|
|
566
|
-
maxWidth: "85%"
|
|
1073
|
+
maxWidth: "85%",
|
|
1074
|
+
textAlign: "left"
|
|
567
1075
|
},
|
|
568
1076
|
thinkingIndicator: {
|
|
569
1077
|
display: "flex",
|
|
@@ -645,7 +1153,8 @@ var styles = {
|
|
|
645
1153
|
outline: "none",
|
|
646
1154
|
fontSize: "0.875rem",
|
|
647
1155
|
color: "#111827",
|
|
648
|
-
padding: "0.25rem 0"
|
|
1156
|
+
padding: "0.25rem 0",
|
|
1157
|
+
fontFamily: "inherit"
|
|
649
1158
|
},
|
|
650
1159
|
formButton: {
|
|
651
1160
|
backgroundColor: "transparent",
|
|
@@ -658,7 +1167,8 @@ var styles = {
|
|
|
658
1167
|
fontWeight: "bold",
|
|
659
1168
|
border: "none",
|
|
660
1169
|
cursor: "pointer",
|
|
661
|
-
transition: "background-color 0.2s"
|
|
1170
|
+
transition: "background-color 0.2s",
|
|
1171
|
+
fontFamily: "inherit"
|
|
662
1172
|
},
|
|
663
1173
|
sendButton: {
|
|
664
1174
|
backgroundColor: "#AD59FF1A"
|
|
@@ -668,90 +1178,297 @@ var styles = {
|
|
|
668
1178
|
color: "#9ca3af",
|
|
669
1179
|
textAlign: "center",
|
|
670
1180
|
marginTop: "0.75rem"
|
|
1181
|
+
},
|
|
1182
|
+
backdrop: {
|
|
1183
|
+
position: "fixed",
|
|
1184
|
+
top: 0,
|
|
1185
|
+
left: 0,
|
|
1186
|
+
right: 0,
|
|
1187
|
+
bottom: 0,
|
|
1188
|
+
backgroundColor: "rgba(0, 0, 0, 0.5)",
|
|
1189
|
+
backdropFilter: "blur(4px)",
|
|
1190
|
+
zIndex: 1e3
|
|
1191
|
+
},
|
|
1192
|
+
feedbackRow: {
|
|
1193
|
+
display: "flex",
|
|
1194
|
+
alignItems: "center",
|
|
1195
|
+
gap: "0.5rem",
|
|
1196
|
+
marginTop: "0.5rem",
|
|
1197
|
+
marginLeft: "0.75rem"
|
|
1198
|
+
},
|
|
1199
|
+
feedbackButton: {
|
|
1200
|
+
backgroundColor: "transparent",
|
|
1201
|
+
border: "none",
|
|
1202
|
+
cursor: "pointer",
|
|
1203
|
+
padding: "6px",
|
|
1204
|
+
borderRadius: "6px",
|
|
1205
|
+
display: "flex",
|
|
1206
|
+
alignItems: "center",
|
|
1207
|
+
justifyContent: "center",
|
|
1208
|
+
transition: "background-color 0.2s"
|
|
1209
|
+
},
|
|
1210
|
+
warningBanner: {
|
|
1211
|
+
backgroundColor: "#fffbeb",
|
|
1212
|
+
color: "#b45309",
|
|
1213
|
+
border: "1px solid #fde68a",
|
|
1214
|
+
borderRadius: "0.375rem",
|
|
1215
|
+
padding: "0.25rem 0.5rem",
|
|
1216
|
+
fontSize: "0.6875rem",
|
|
1217
|
+
fontWeight: 500,
|
|
1218
|
+
textAlign: "center",
|
|
1219
|
+
margin: "0 0.5rem",
|
|
1220
|
+
flex: 1,
|
|
1221
|
+
display: "flex",
|
|
1222
|
+
alignItems: "center",
|
|
1223
|
+
justifyContent: "center"
|
|
1224
|
+
},
|
|
1225
|
+
insufficientConfigContainer: {
|
|
1226
|
+
flex: 1,
|
|
1227
|
+
display: "flex",
|
|
1228
|
+
flexDirection: "column",
|
|
1229
|
+
alignItems: "center",
|
|
1230
|
+
justifyContent: "center",
|
|
1231
|
+
padding: "2rem",
|
|
1232
|
+
textAlign: "center",
|
|
1233
|
+
backgroundColor: "#fff5f5",
|
|
1234
|
+
color: "#2d3748"
|
|
1235
|
+
},
|
|
1236
|
+
insufficientConfigIconContainer: {
|
|
1237
|
+
backgroundColor: "#fee2e2",
|
|
1238
|
+
padding: "1rem",
|
|
1239
|
+
borderRadius: "50%",
|
|
1240
|
+
marginBottom: "1rem",
|
|
1241
|
+
display: "flex",
|
|
1242
|
+
alignItems: "center",
|
|
1243
|
+
justifyContent: "center",
|
|
1244
|
+
boxShadow: "0 4px 6px -1px rgba(239, 68, 68, 0.1), 0 2px 4px -1px rgba(239, 68, 68, 0.06)"
|
|
1245
|
+
},
|
|
1246
|
+
insufficientConfigTitle: {
|
|
1247
|
+
fontSize: "1.25rem",
|
|
1248
|
+
fontWeight: 700,
|
|
1249
|
+
color: "#991b1b",
|
|
1250
|
+
marginBottom: "0.5rem"
|
|
1251
|
+
},
|
|
1252
|
+
insufficientConfigMessage: {
|
|
1253
|
+
fontSize: "0.875rem",
|
|
1254
|
+
color: "#7f1d1d",
|
|
1255
|
+
marginBottom: "1.5rem",
|
|
1256
|
+
lineHeight: "1.5",
|
|
1257
|
+
maxWidth: "280px"
|
|
1258
|
+
},
|
|
1259
|
+
insufficientConfigDetails: {
|
|
1260
|
+
backgroundColor: "white",
|
|
1261
|
+
border: "1px solid #fee2e2",
|
|
1262
|
+
borderRadius: "0.5rem",
|
|
1263
|
+
padding: "1rem",
|
|
1264
|
+
textAlign: "left",
|
|
1265
|
+
width: "100%",
|
|
1266
|
+
maxWidth: "300px",
|
|
1267
|
+
boxShadow: "0 1px 3px 0 rgba(0, 0, 0, 0.05)"
|
|
671
1268
|
}
|
|
672
1269
|
};
|
|
1270
|
+
var ANIMATION_STYLES = `
|
|
1271
|
+
@keyframes sh-fade-in {
|
|
1272
|
+
from {
|
|
1273
|
+
opacity: 0;
|
|
1274
|
+
transform: translate(-50%, -48%) scale(0.96);
|
|
1275
|
+
}
|
|
1276
|
+
to {
|
|
1277
|
+
opacity: 1;
|
|
1278
|
+
transform: translate(-50%, -50%) scale(1);
|
|
1279
|
+
}
|
|
1280
|
+
}
|
|
1281
|
+
@keyframes sh-fade-out {
|
|
1282
|
+
from {
|
|
1283
|
+
opacity: 1;
|
|
1284
|
+
transform: translate(-50%, -50%) scale(1);
|
|
1285
|
+
}
|
|
1286
|
+
to {
|
|
1287
|
+
opacity: 0;
|
|
1288
|
+
transform: translate(-50%, -48%) scale(0.96);
|
|
1289
|
+
}
|
|
1290
|
+
}
|
|
1291
|
+
@keyframes sh-backdrop-fade-in {
|
|
1292
|
+
from {
|
|
1293
|
+
opacity: 0;
|
|
1294
|
+
}
|
|
1295
|
+
to {
|
|
1296
|
+
opacity: 1;
|
|
1297
|
+
}
|
|
1298
|
+
}
|
|
1299
|
+
@keyframes sh-backdrop-fade-out {
|
|
1300
|
+
from {
|
|
1301
|
+
opacity: 1;
|
|
1302
|
+
}
|
|
1303
|
+
to {
|
|
1304
|
+
opacity: 0;
|
|
1305
|
+
}
|
|
1306
|
+
}
|
|
1307
|
+
.sh-dialog-animate {
|
|
1308
|
+
animation: sh-fade-in 0.22s cubic-bezier(0.16, 1, 0.3, 1) forwards;
|
|
1309
|
+
}
|
|
1310
|
+
.sh-dialog-animate-out {
|
|
1311
|
+
animation: sh-fade-out 0.2s cubic-bezier(0.16, 1, 0.3, 1) forwards;
|
|
1312
|
+
}
|
|
1313
|
+
.sh-backdrop-animate {
|
|
1314
|
+
animation: sh-backdrop-fade-in 0.18s ease-out forwards;
|
|
1315
|
+
}
|
|
1316
|
+
.sh-backdrop-animate-out {
|
|
1317
|
+
animation: sh-backdrop-fade-out 0.18s ease-out forwards;
|
|
1318
|
+
}
|
|
1319
|
+
.sh-feedback-btn {
|
|
1320
|
+
color: #a1a1aa;
|
|
1321
|
+
border-radius: 4px;
|
|
1322
|
+
transition: color 0.2s, background-color 0.2s;
|
|
1323
|
+
}
|
|
1324
|
+
.sh-feedback-btn:hover {
|
|
1325
|
+
background-color: #f4f4f5 !important;
|
|
1326
|
+
color: #3f3f46 !important;
|
|
1327
|
+
}
|
|
1328
|
+
.sh-header-btn {
|
|
1329
|
+
transition: all 0.2s;
|
|
1330
|
+
}
|
|
1331
|
+
.sh-header-btn:hover {
|
|
1332
|
+
background-color: #f9fafb !important;
|
|
1333
|
+
border-color: #d1d5db !important;
|
|
1334
|
+
}
|
|
1335
|
+
`;
|
|
673
1336
|
var TRANSLATIONS = {
|
|
674
1337
|
newChat: "New Chat",
|
|
675
1338
|
welcomeToShopPrompter: "Welcome to ShopPrompter",
|
|
676
1339
|
welcomeDescription: "I am your personal AI shopping assistant. Ask me anything about our products!",
|
|
677
1340
|
askMeAnything: "Ask me anything...",
|
|
678
1341
|
thinking: "Thinking...",
|
|
679
|
-
|
|
680
|
-
compareProducts: "Compare products",
|
|
681
|
-
findByBudget: "Find by budget"
|
|
1342
|
+
feedbackError: "We are sorry, but we could not process your feedback. Please try again later."
|
|
682
1343
|
};
|
|
683
1344
|
var ICONS = {
|
|
684
1345
|
chat: "https://cdn.jsdelivr.net/gh/lucide-icons/lucide@latest/icons/message-square.svg",
|
|
685
1346
|
shopprompter: "https://cdn.jsdelivr.net/gh/lucide-icons/lucide@latest/icons/bot.svg",
|
|
686
1347
|
popularitems: "https://cdn.jsdelivr.net/gh/lucide-icons/lucide@latest/icons/fire.svg",
|
|
687
1348
|
compareproducts: "https://cdn.jsdelivr.net/gh/lucide-icons/lucide@latest/icons/box.svg",
|
|
688
|
-
findbybudget: "https://cdn.jsdelivr.net/gh/lucide-icons/lucide@latest/icons/foto.svg",
|
|
689
1349
|
sendHorizontal: "https://cdn.jsdelivr.net/gh/lucide-icons/lucide@latest/icons/send-horizontal.svg"
|
|
690
1350
|
};
|
|
691
1351
|
function ShopPrompter(props) {
|
|
692
|
-
var _a, _b, _c;
|
|
693
|
-
const [input, setInput] =
|
|
694
|
-
const [isLoading, setIsLoading] =
|
|
695
|
-
const [error, setError] =
|
|
696
|
-
const [chatMessages, setChatMessages] =
|
|
697
|
-
const [showChat, setShowChat] =
|
|
698
|
-
|
|
1352
|
+
var _a, _b, _c, _d;
|
|
1353
|
+
const [input, setInput] = useState2(() => "");
|
|
1354
|
+
const [isLoading, setIsLoading] = useState2(() => false);
|
|
1355
|
+
const [error, setError] = useState2(() => null);
|
|
1356
|
+
const [chatMessages, setChatMessages] = useState2(() => []);
|
|
1357
|
+
const [showChat, setShowChat] = useState2(() => false);
|
|
1358
|
+
const [isClosing, setIsClosing] = useState2(() => false);
|
|
1359
|
+
const [closeTimeout, setCloseTimeout] = useState2(() => null);
|
|
1360
|
+
const [service, setService] = useState2(() => null);
|
|
1361
|
+
const [agentExperience, setAgentExperience] = useState2(() => null);
|
|
1362
|
+
const [animationClass, setAnimationClass] = useState2(() => "");
|
|
1363
|
+
const [backdropAnimationClass, setBackdropAnimationClass] = useState2(
|
|
1364
|
+
() => ""
|
|
699
1365
|
);
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
()
|
|
703
|
-
|
|
704
|
-
|
|
1366
|
+
function hasToken() {
|
|
1367
|
+
var _a2;
|
|
1368
|
+
const token = props.shopPrompterToken || ((_a2 = apiConfigObj == null ? void 0 : apiConfigObj()) == null ? void 0 : _a2.shopPrompterToken);
|
|
1369
|
+
return !!token;
|
|
1370
|
+
}
|
|
1371
|
+
function isConfigInsufficient() {
|
|
1372
|
+
var _a2, _b2;
|
|
1373
|
+
const token = props.shopPrompterToken || ((_a2 = apiConfigObj == null ? void 0 : apiConfigObj()) == null ? void 0 : _a2.shopPrompterToken);
|
|
1374
|
+
const apiKey = (_b2 = apiConfigObj == null ? void 0 : apiConfigObj()) == null ? void 0 : _b2.apiKey;
|
|
1375
|
+
return !token && !apiKey;
|
|
1376
|
+
}
|
|
1377
|
+
function showPriceIfEmptyVal() {
|
|
1378
|
+
const val = props.showPriceIfEmpty;
|
|
1379
|
+
if (typeof val === "string") {
|
|
1380
|
+
return val === "true";
|
|
1381
|
+
}
|
|
1382
|
+
return val != null ? val : false;
|
|
1383
|
+
}
|
|
1384
|
+
function visibleFieldsList() {
|
|
1385
|
+
const val = props.visibleFields;
|
|
1386
|
+
if (typeof val === "string") {
|
|
1387
|
+
try {
|
|
1388
|
+
return JSON.parse(val);
|
|
1389
|
+
} catch (e) {
|
|
1390
|
+
return val.split(",").map((s) => s.trim()).filter(Boolean);
|
|
1391
|
+
}
|
|
1392
|
+
}
|
|
1393
|
+
return val || [];
|
|
1394
|
+
}
|
|
1395
|
+
function themeObj() {
|
|
1396
|
+
if (typeof props.theme === "string") {
|
|
1397
|
+
try {
|
|
1398
|
+
return JSON.parse(props.theme);
|
|
1399
|
+
} catch (e) {
|
|
1400
|
+
return {};
|
|
1401
|
+
}
|
|
1402
|
+
}
|
|
1403
|
+
return props.theme || {};
|
|
1404
|
+
}
|
|
1405
|
+
function prompts() {
|
|
1406
|
+
return (agentExperience == null ? void 0 : agentExperience.predefinedPrompts) || [];
|
|
1407
|
+
}
|
|
1408
|
+
function apiConfigObj() {
|
|
1409
|
+
if (typeof props.apiConfig === "string") {
|
|
1410
|
+
try {
|
|
1411
|
+
return JSON.parse(props.apiConfig);
|
|
1412
|
+
} catch (e) {
|
|
1413
|
+
return null;
|
|
1414
|
+
}
|
|
1415
|
+
}
|
|
1416
|
+
return props.apiConfig || null;
|
|
1417
|
+
}
|
|
705
1418
|
function containerStyle() {
|
|
706
1419
|
const pos = props.chatPosition || "classic-chatbot";
|
|
707
1420
|
const isFull = pos === "full-page";
|
|
708
|
-
const
|
|
1421
|
+
const isDialog = pos === "dialog";
|
|
709
1422
|
const isClassic = pos === "classic-chatbot";
|
|
710
1423
|
const isRight = pos === "right-panel";
|
|
711
1424
|
return {
|
|
712
1425
|
position: isFull ? "relative" : "fixed",
|
|
713
|
-
bottom: isClassic ? "1rem" :
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
1426
|
+
bottom: isClassic ? "1rem" : isDialog ? "auto" : "0",
|
|
1427
|
+
top: isDialog ? "50%" : "auto",
|
|
1428
|
+
right: isClassic || isRight ? "1rem" : isDialog ? "auto" : "0",
|
|
1429
|
+
left: isDialog ? "50%" : isClassic || isRight || isFull ? "auto" : "0",
|
|
1430
|
+
transform: isDialog ? "translate(-50%, -50%)" : "none",
|
|
1431
|
+
width: isFull ? "100%" : isDialog ? "90%" : "24rem",
|
|
1432
|
+
height: isClassic ? "550px" : isDialog ? "700px" : isFull ? "600px" : "100%",
|
|
1433
|
+
maxWidth: isDialog ? "900px" : "none",
|
|
1434
|
+
maxHeight: isDialog ? "90vh" : "none",
|
|
1435
|
+
zIndex: isDialog ? 1001 : isClassic || isRight ? 1001 : 50,
|
|
1436
|
+
backgroundColor: themeObj().mainBackgroundColor || "white",
|
|
722
1437
|
display: "flex",
|
|
723
1438
|
flexDirection: "column",
|
|
724
1439
|
overflow: "hidden",
|
|
725
1440
|
borderRadius: isFull ? "0" : "0.5rem",
|
|
726
1441
|
border: isFull ? "none" : "1px solid #e5e7eb",
|
|
727
|
-
boxShadow: isFull ? "none" : "0 25px 50px -12px rgba(0, 0, 0, 0.25)"
|
|
1442
|
+
boxShadow: isFull ? "none" : "0 25px 50px -12px rgba(0, 0, 0, 0.25)",
|
|
1443
|
+
fontFamily: themeObj().fontFamily || void 0
|
|
728
1444
|
};
|
|
729
1445
|
}
|
|
730
1446
|
function containerClass() {
|
|
731
1447
|
const pos = props.chatPosition || "classic-chatbot";
|
|
732
1448
|
if (pos === "classic-chatbot") return "sh-classic";
|
|
733
1449
|
if (pos === "right-panel") return "sh-right";
|
|
734
|
-
if (pos === "
|
|
1450
|
+
if (pos === "dialog") {
|
|
1451
|
+
return "sh-dialog " + animationClass;
|
|
1452
|
+
}
|
|
735
1453
|
return "sh-full";
|
|
736
1454
|
}
|
|
737
1455
|
function messages() {
|
|
738
|
-
return chatMessages
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
1456
|
+
return chatMessages;
|
|
1457
|
+
}
|
|
1458
|
+
function parseMarkdown(content) {
|
|
1459
|
+
if (!content) return "";
|
|
1460
|
+
return String(marked.parse(content));
|
|
742
1461
|
}
|
|
743
1462
|
function showWelcome() {
|
|
744
1463
|
return chatMessages.length === 0;
|
|
745
1464
|
}
|
|
746
|
-
function
|
|
747
|
-
return
|
|
1465
|
+
function getShowProducts(message) {
|
|
1466
|
+
return message.productSkus && message.productSkus.length > 0;
|
|
748
1467
|
}
|
|
749
|
-
function
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
if (!input.trim() || isLoading) return;
|
|
754
|
-
const userQuery = input;
|
|
1468
|
+
function handleSend(overrideQuery) {
|
|
1469
|
+
const actualQuery = overrideQuery || input;
|
|
1470
|
+
if (!actualQuery.trim() || isLoading) return;
|
|
1471
|
+
const userQuery = actualQuery;
|
|
755
1472
|
setInput("");
|
|
756
1473
|
const userMsg = {
|
|
757
1474
|
id: Date.now().toString() + "-user",
|
|
@@ -759,30 +1476,45 @@ function ShopPrompter(props) {
|
|
|
759
1476
|
content: userQuery,
|
|
760
1477
|
productSkus: []
|
|
761
1478
|
};
|
|
762
|
-
setChatMessages([...chatMessages, userMsg]);
|
|
763
1479
|
const assistantMsg = {
|
|
764
1480
|
id: Date.now().toString() + "-assistant",
|
|
765
1481
|
role: "assistant",
|
|
766
1482
|
content: "",
|
|
767
1483
|
productSkus: []
|
|
768
1484
|
};
|
|
769
|
-
|
|
1485
|
+
let currentMessages = [...chatMessages, userMsg, assistantMsg];
|
|
1486
|
+
setChatMessages(currentMessages);
|
|
1487
|
+
setTimeout(() => {
|
|
1488
|
+
const inputEl = document.getElementById("shop-prompter-input");
|
|
1489
|
+
if (inputEl) {
|
|
1490
|
+
inputEl.value = "";
|
|
1491
|
+
inputEl.focus();
|
|
1492
|
+
}
|
|
1493
|
+
}, 0);
|
|
770
1494
|
service == null ? void 0 : service.sendMessage(
|
|
771
1495
|
userQuery,
|
|
772
1496
|
{
|
|
773
1497
|
onTextUpdate: (text) => {
|
|
774
|
-
const updatedMessages = [...
|
|
1498
|
+
const updatedMessages = [...currentMessages];
|
|
775
1499
|
const lastMsg = updatedMessages[updatedMessages.length - 1];
|
|
776
1500
|
if (lastMsg) {
|
|
777
|
-
|
|
1501
|
+
updatedMessages[updatedMessages.length - 1] = {
|
|
1502
|
+
...lastMsg,
|
|
1503
|
+
content: text
|
|
1504
|
+
};
|
|
1505
|
+
currentMessages = updatedMessages;
|
|
778
1506
|
setChatMessages(updatedMessages);
|
|
779
1507
|
}
|
|
780
1508
|
},
|
|
781
1509
|
onProductSkus: (skus) => {
|
|
782
|
-
const updatedMessages = [...
|
|
1510
|
+
const updatedMessages = [...currentMessages];
|
|
783
1511
|
const lastMsg = updatedMessages[updatedMessages.length - 1];
|
|
784
1512
|
if (lastMsg) {
|
|
785
|
-
|
|
1513
|
+
updatedMessages[updatedMessages.length - 1] = {
|
|
1514
|
+
...lastMsg,
|
|
1515
|
+
productSkus: skus
|
|
1516
|
+
};
|
|
1517
|
+
currentMessages = updatedMessages;
|
|
786
1518
|
setChatMessages(updatedMessages);
|
|
787
1519
|
}
|
|
788
1520
|
},
|
|
@@ -796,29 +1528,63 @@ function ShopPrompter(props) {
|
|
|
796
1528
|
if (props.onCartOperation) {
|
|
797
1529
|
props.onCartOperation(ops);
|
|
798
1530
|
}
|
|
1531
|
+
dispatchCartOperation(ops);
|
|
799
1532
|
}
|
|
800
1533
|
},
|
|
801
1534
|
props.cart || []
|
|
802
1535
|
);
|
|
803
1536
|
}
|
|
1537
|
+
function dispatchCartOperation(ops) {
|
|
1538
|
+
if (typeof window !== "undefined") {
|
|
1539
|
+
const root = typeof self !== "undefined" && self && "dispatchEvent" in self && !(self instanceof Window) ? self : null;
|
|
1540
|
+
if (root) {
|
|
1541
|
+
root.dispatchEvent(
|
|
1542
|
+
new CustomEvent("cartOperation", {
|
|
1543
|
+
detail: ops
|
|
1544
|
+
})
|
|
1545
|
+
);
|
|
1546
|
+
}
|
|
1547
|
+
}
|
|
1548
|
+
}
|
|
804
1549
|
function toggleChat() {
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
1550
|
+
if (showChat) {
|
|
1551
|
+
setIsClosing(true);
|
|
1552
|
+
setAnimationClass("sh-dialog-animate-out");
|
|
1553
|
+
setBackdropAnimationClass("sh-backdrop-animate-out");
|
|
1554
|
+
if (closeTimeout) {
|
|
1555
|
+
clearTimeout(closeTimeout);
|
|
1556
|
+
}
|
|
1557
|
+
setCloseTimeout(
|
|
1558
|
+
setTimeout(() => {
|
|
1559
|
+
setShowChat(false);
|
|
1560
|
+
setIsClosing(false);
|
|
1561
|
+
setAnimationClass("");
|
|
1562
|
+
setBackdropAnimationClass("");
|
|
1563
|
+
setCloseTimeout(null);
|
|
1564
|
+
if (props.onClose) {
|
|
1565
|
+
props.onClose();
|
|
1566
|
+
}
|
|
1567
|
+
}, 200)
|
|
1568
|
+
);
|
|
1569
|
+
} else {
|
|
1570
|
+
if (closeTimeout) {
|
|
1571
|
+
clearTimeout(closeTimeout);
|
|
1572
|
+
setCloseTimeout(null);
|
|
1573
|
+
}
|
|
1574
|
+
setShowChat(true);
|
|
1575
|
+
setIsClosing(false);
|
|
1576
|
+
setAnimationClass("sh-dialog-animate");
|
|
1577
|
+
setBackdropAnimationClass("sh-backdrop-animate");
|
|
1578
|
+
setTimeout(() => {
|
|
1579
|
+
setAnimationClass("");
|
|
1580
|
+
setBackdropAnimationClass("");
|
|
1581
|
+
}, 250);
|
|
808
1582
|
}
|
|
809
1583
|
}
|
|
810
1584
|
function handleNewChat() {
|
|
811
1585
|
setChatMessages([]);
|
|
812
1586
|
service == null ? void 0 : service.resetSession();
|
|
813
1587
|
}
|
|
814
|
-
function onPopularItemsClick() {
|
|
815
|
-
setInput(TRANSLATIONS.showPopularItems);
|
|
816
|
-
handleSend();
|
|
817
|
-
}
|
|
818
|
-
function onCompareProductsClick() {
|
|
819
|
-
setInput(TRANSLATIONS.compareProducts);
|
|
820
|
-
handleSend();
|
|
821
|
-
}
|
|
822
1588
|
function onInputChange(event) {
|
|
823
1589
|
setInput(event.target.value);
|
|
824
1590
|
}
|
|
@@ -827,49 +1593,196 @@ function ShopPrompter(props) {
|
|
|
827
1593
|
handleSend();
|
|
828
1594
|
}
|
|
829
1595
|
}
|
|
830
|
-
function
|
|
831
|
-
|
|
1596
|
+
function handleTriggerClick(e) {
|
|
1597
|
+
if (props.chatPosition !== "dialog") return;
|
|
1598
|
+
if (!props.dialogTrigger) return;
|
|
1599
|
+
const isTargetClicked = typeof props.dialogTrigger === "string" ? e.target.closest(props.dialogTrigger) : (() => {
|
|
1600
|
+
let target = null;
|
|
1601
|
+
if (typeof props.dialogTrigger === "object") {
|
|
1602
|
+
if ("current" in props.dialogTrigger) {
|
|
1603
|
+
target = props.dialogTrigger.current;
|
|
1604
|
+
} else {
|
|
1605
|
+
target = props.dialogTrigger;
|
|
1606
|
+
}
|
|
1607
|
+
}
|
|
1608
|
+
return target && target.contains && target.contains(e.target);
|
|
1609
|
+
})();
|
|
1610
|
+
if (isTargetClicked) {
|
|
1611
|
+
if (closeTimeout) {
|
|
1612
|
+
clearTimeout(closeTimeout);
|
|
1613
|
+
setCloseTimeout(null);
|
|
1614
|
+
}
|
|
1615
|
+
setShowChat(true);
|
|
1616
|
+
setIsClosing(false);
|
|
1617
|
+
setAnimationClass("sh-dialog-animate");
|
|
1618
|
+
setBackdropAnimationClass("sh-backdrop-animate");
|
|
1619
|
+
setTimeout(() => {
|
|
1620
|
+
setAnimationClass("");
|
|
1621
|
+
setBackdropAnimationClass("");
|
|
1622
|
+
}, 250);
|
|
1623
|
+
}
|
|
832
1624
|
}
|
|
833
|
-
function
|
|
834
|
-
|
|
1625
|
+
function loadCustomFont(fontFamily) {
|
|
1626
|
+
if (!fontFamily || typeof window === "undefined") return;
|
|
1627
|
+
const systemFonts = [
|
|
1628
|
+
"sans-serif",
|
|
1629
|
+
"serif",
|
|
1630
|
+
"monospace",
|
|
1631
|
+
"cursive",
|
|
1632
|
+
"fantasy",
|
|
1633
|
+
"system-ui",
|
|
1634
|
+
"-apple-system",
|
|
1635
|
+
"blinkmacsystemfont",
|
|
1636
|
+
"segoe ui",
|
|
1637
|
+
"roboto",
|
|
1638
|
+
"helvetica",
|
|
1639
|
+
"arial",
|
|
1640
|
+
"inherit"
|
|
1641
|
+
];
|
|
1642
|
+
const cleanFont = fontFamily.split(",")[0].trim().replace(new RegExp(`['"]`, "g"), "");
|
|
1643
|
+
if (!cleanFont || systemFonts.includes(cleanFont.toLowerCase())) return;
|
|
1644
|
+
const linkId = `shopprompter-font-${cleanFont.toLowerCase().replace(new RegExp("\\s+", "g"), "-")}`;
|
|
1645
|
+
if (document.getElementById(linkId)) return;
|
|
1646
|
+
const link = document.createElement("link");
|
|
1647
|
+
link.id = linkId;
|
|
1648
|
+
link.rel = "stylesheet";
|
|
1649
|
+
const fontNameUrl = cleanFont.replace(new RegExp("\\s+", "g"), "+");
|
|
1650
|
+
link.href = `https://fonts.googleapis.com/css2?family=${fontNameUrl}:wght@400;500;600;700&display=swap`;
|
|
1651
|
+
document.head.appendChild(link);
|
|
835
1652
|
}
|
|
836
|
-
function
|
|
1653
|
+
function loadAgentExperience() {
|
|
837
1654
|
void (async function() {
|
|
838
|
-
console.log("## ~ ShopPrompter ~ state.service:", service);
|
|
839
1655
|
if (!service) {
|
|
840
|
-
console.warn(
|
|
1656
|
+
console.warn(
|
|
1657
|
+
"Service not initialized yet! Cannot load AgentExperience."
|
|
1658
|
+
);
|
|
841
1659
|
return;
|
|
842
1660
|
}
|
|
843
1661
|
const response = await (service == null ? void 0 : service.getAgentExperience());
|
|
844
|
-
console.log("## ~ ShopPrompter ~ response:", response);
|
|
845
1662
|
setAgentExperience(response);
|
|
846
1663
|
})();
|
|
847
1664
|
}
|
|
848
|
-
|
|
849
|
-
const
|
|
850
|
-
|
|
1665
|
+
function handleFeedback(messageId, messageContent, newFeedback) {
|
|
1666
|
+
const msg = chatMessages.find((m) => m.id === messageId);
|
|
1667
|
+
if (!msg) return;
|
|
1668
|
+
const currentFeedback = msg.feedback;
|
|
1669
|
+
const targetFeedback = currentFeedback === newFeedback ? "clear" : newFeedback;
|
|
1670
|
+
const oldMessages = [...chatMessages];
|
|
1671
|
+
setChatMessages(
|
|
1672
|
+
chatMessages.map((m) => {
|
|
1673
|
+
if (m.id === messageId) {
|
|
1674
|
+
return {
|
|
1675
|
+
...m,
|
|
1676
|
+
feedback: targetFeedback === "clear" ? null : targetFeedback
|
|
1677
|
+
};
|
|
1678
|
+
}
|
|
1679
|
+
return m;
|
|
1680
|
+
})
|
|
1681
|
+
);
|
|
1682
|
+
setError(null);
|
|
1683
|
+
service == null ? void 0 : service.sendFeedback(messageId, messageContent, targetFeedback).catch((err) => {
|
|
1684
|
+
setChatMessages(oldMessages);
|
|
1685
|
+
setError((err == null ? void 0 : err.message) || TRANSLATIONS.feedbackError);
|
|
1686
|
+
});
|
|
1687
|
+
}
|
|
1688
|
+
function canShowFeedback(message) {
|
|
1689
|
+
if (message.role !== "assistant") return false;
|
|
1690
|
+
if (!message.content) return false;
|
|
1691
|
+
const lastMsg = chatMessages[chatMessages.length - 1];
|
|
1692
|
+
if (lastMsg && lastMsg.id === message.id && isLoading) {
|
|
1693
|
+
return false;
|
|
1694
|
+
}
|
|
1695
|
+
return true;
|
|
1696
|
+
}
|
|
1697
|
+
useEffect2(() => {
|
|
1698
|
+
if (typeof window !== "undefined" && !document.getElementById("lottie-player-script")) {
|
|
1699
|
+
const script = document.createElement("script");
|
|
1700
|
+
script.id = "lottie-player-script";
|
|
1701
|
+
script.src = "https://unpkg.com/@lottiefiles/lottie-player@latest/dist/lottie-player";
|
|
1702
|
+
document.head.appendChild(script);
|
|
1703
|
+
}
|
|
1704
|
+
if (themeObj().fontFamily) {
|
|
1705
|
+
loadCustomFont(themeObj().fontFamily);
|
|
1706
|
+
}
|
|
1707
|
+
if (apiConfigObj()) {
|
|
1708
|
+
if (!isConfigInsufficient()) {
|
|
1709
|
+
const apiConfig = {
|
|
1710
|
+
...apiConfigObj(),
|
|
1711
|
+
shopPrompterToken: props.shopPrompterToken || apiConfigObj().shopPrompterToken
|
|
1712
|
+
};
|
|
1713
|
+
const service2 = new ShopPrompterService(apiConfig);
|
|
1714
|
+
setService(service2);
|
|
1715
|
+
const savedMessages = service2.loadMessages();
|
|
1716
|
+
if (savedMessages.length > 0) {
|
|
1717
|
+
setChatMessages(savedMessages);
|
|
1718
|
+
}
|
|
1719
|
+
}
|
|
1720
|
+
} else {
|
|
1721
|
+
console.error("ShopPrompter: apiConfig prop is required!");
|
|
1722
|
+
}
|
|
1723
|
+
if ((props == null ? void 0 : props.chatPosition) === "right-panel" || (props == null ? void 0 : props.chatPosition) === "full-page") {
|
|
1724
|
+
setShowChat(true);
|
|
1725
|
+
}
|
|
1726
|
+
if (typeof window !== "undefined") {
|
|
1727
|
+
document.addEventListener("click", handleTriggerClick);
|
|
1728
|
+
}
|
|
851
1729
|
}, []);
|
|
852
|
-
|
|
1730
|
+
useEffect2(() => {
|
|
853
1731
|
if (service && !agentExperience) {
|
|
854
|
-
|
|
855
|
-
}
|
|
856
|
-
if (agentExperience) {
|
|
857
|
-
console.log("## ~ ShopPrompter ~ agentExperience updated:", {
|
|
858
|
-
greeting: agentExperience.greeting,
|
|
859
|
-
agentLogoUrl: agentExperience.agentLogoUrl
|
|
860
|
-
});
|
|
1732
|
+
loadAgentExperience();
|
|
861
1733
|
}
|
|
862
1734
|
}, [service, agentExperience]);
|
|
863
|
-
|
|
864
|
-
|
|
1735
|
+
useEffect2(() => {
|
|
1736
|
+
if (themeObj().fontFamily) {
|
|
1737
|
+
loadCustomFont(themeObj().fontFamily);
|
|
1738
|
+
}
|
|
1739
|
+
}, [themeObj().fontFamily || ""]);
|
|
1740
|
+
useEffect2(() => {
|
|
1741
|
+
if ((props == null ? void 0 : props.chatPosition) === "right-panel" || (props == null ? void 0 : props.chatPosition) === "full-page") {
|
|
1742
|
+
setShowChat(true);
|
|
1743
|
+
} else if ((props == null ? void 0 : props.chatPosition) === "dialog" || (props == null ? void 0 : props.chatPosition) === "classic-chatbot") {
|
|
1744
|
+
setShowChat(false);
|
|
1745
|
+
setIsClosing(false);
|
|
1746
|
+
setAnimationClass("");
|
|
1747
|
+
setBackdropAnimationClass("");
|
|
1748
|
+
}
|
|
1749
|
+
}, [(props == null ? void 0 : props.chatPosition) || ""]);
|
|
1750
|
+
return /* @__PURE__ */ jsxs4("div", { className: "shopprompter-sdk", children: [
|
|
1751
|
+
/* @__PURE__ */ jsx4("style", { dangerouslySetInnerHTML: { __html: ANIMATION_STYLES } }),
|
|
1752
|
+
/* @__PURE__ */ jsx4(
|
|
1753
|
+
"div",
|
|
1754
|
+
{
|
|
1755
|
+
onClick: (e) => toggleChat(),
|
|
1756
|
+
style: {
|
|
1757
|
+
...styles2.backdrop,
|
|
1758
|
+
display: props.chatPosition === "dialog" && (showChat || isClosing) ? "block" : "none"
|
|
1759
|
+
},
|
|
1760
|
+
className: backdropAnimationClass
|
|
1761
|
+
}
|
|
1762
|
+
),
|
|
1763
|
+
props.chatPosition === "classic-chatbot" ? /* @__PURE__ */ jsx4(Fragment2, { children: !showChat ? /* @__PURE__ */ jsx4(
|
|
865
1764
|
"button",
|
|
866
1765
|
{
|
|
867
|
-
className: "fixed bottom-6 right-6 w-16 h-16 bg-blue-600 hover:bg-blue-700 rounded-full shadow-lg z-50 flex items-center justify-center transition-colors border-none cursor-pointer",
|
|
868
1766
|
onClick: (e) => toggleChat(),
|
|
869
1767
|
style: {
|
|
870
|
-
|
|
1768
|
+
position: "fixed",
|
|
1769
|
+
bottom: "1.5rem",
|
|
1770
|
+
right: "1.5rem",
|
|
1771
|
+
width: "4rem",
|
|
1772
|
+
height: "4rem",
|
|
1773
|
+
backgroundColor: themeObj().actionColor || "#2563eb",
|
|
1774
|
+
borderRadius: "9999px",
|
|
1775
|
+
zIndex: 50,
|
|
1776
|
+
display: "flex",
|
|
1777
|
+
alignItems: "center",
|
|
1778
|
+
justifyContent: "center",
|
|
1779
|
+
transition: "background-color 0.2s",
|
|
1780
|
+
border: "none",
|
|
1781
|
+
cursor: "pointer",
|
|
1782
|
+
boxShadow: themeObj().actionColor ? `0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05), 0 0 0 8px ${themeObj().actionColor}33` : "0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05), 0 0 0 8px rgba(37, 99, 235, 0.2)",
|
|
1783
|
+
fontFamily: themeObj().fontFamily || void 0
|
|
871
1784
|
},
|
|
872
|
-
children: /* @__PURE__ */
|
|
1785
|
+
children: /* @__PURE__ */ jsx4(
|
|
873
1786
|
"img",
|
|
874
1787
|
{
|
|
875
1788
|
alt: "Chat",
|
|
@@ -882,259 +1795,406 @@ function ShopPrompter(props) {
|
|
|
882
1795
|
)
|
|
883
1796
|
}
|
|
884
1797
|
) : null }) : null,
|
|
885
|
-
showChat ? /* @__PURE__ */
|
|
886
|
-
/* @__PURE__ */
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
"path",
|
|
906
|
-
{
|
|
907
|
-
fill: "url(#b)",
|
|
908
|
-
d: "M19.326 0c-3.173 0-5.748 2.6-5.748 5.806v8.444h15.438c1.586 0 2.874 1.3 2.874 2.902v3.924H46V0H19.326Z"
|
|
909
|
-
}
|
|
910
|
-
),
|
|
911
|
-
/* @__PURE__ */ jsx(
|
|
912
|
-
"path",
|
|
913
|
-
{
|
|
914
|
-
fill: "url(#c)",
|
|
915
|
-
d: "M40.252 14.25H29.016c1.586 0 2.874 1.3 2.874 2.902v15.595h-6.751V47h15.117c3.173 0 5.748-2.6 5.748-5.806V20.055c0-3.205-2.575-5.806-5.748-5.806h-.004Z"
|
|
1798
|
+
showChat || isClosing ? /* @__PURE__ */ jsxs4("div", { style: containerStyle(), className: containerClass(), children: [
|
|
1799
|
+
/* @__PURE__ */ jsxs4(
|
|
1800
|
+
"div",
|
|
1801
|
+
{
|
|
1802
|
+
style: {
|
|
1803
|
+
...styles2.header,
|
|
1804
|
+
backgroundColor: themeObj().headerBackgroundColor || "transparent"
|
|
1805
|
+
},
|
|
1806
|
+
children: [
|
|
1807
|
+
themeObj().showAgentName !== false ? /* @__PURE__ */ jsxs4("div", { style: styles2.subHeaderContainer, children: [
|
|
1808
|
+
(agentExperience == null ? void 0 : agentExperience.agentLogoUrl) ? /* @__PURE__ */ jsx4(
|
|
1809
|
+
"img",
|
|
1810
|
+
{
|
|
1811
|
+
src: agentExperience.agentLogoUrl,
|
|
1812
|
+
alt: agentExperience.agentName,
|
|
1813
|
+
style: {
|
|
1814
|
+
width: "24px",
|
|
1815
|
+
height: "24px",
|
|
1816
|
+
borderRadius: "4px",
|
|
1817
|
+
objectFit: "cover"
|
|
916
1818
|
}
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
1819
|
+
}
|
|
1820
|
+
) : null,
|
|
1821
|
+
(agentExperience == null ? void 0 : agentExperience.agentName) ? /* @__PURE__ */ jsx4("span", { style: styles2.headerText, children: agentExperience.agentName }) : null
|
|
1822
|
+
] }) : /* @__PURE__ */ jsx4(Fragment2, { children: /* @__PURE__ */ jsx4("div", { style: styles2.subHeaderContainer }) }),
|
|
1823
|
+
!hasToken() && ((_a = apiConfigObj == null ? void 0 : apiConfigObj()) == null ? void 0 : _a.apiKey) ? /* @__PURE__ */ jsx4("div", { style: styles2.warningBanner, children: "API Key is only for development purposes" }) : null,
|
|
1824
|
+
/* @__PURE__ */ jsxs4("div", { style: styles2.subHeaderContainer, children: [
|
|
1825
|
+
/* @__PURE__ */ jsx4(
|
|
1826
|
+
"button",
|
|
1827
|
+
{
|
|
1828
|
+
className: "sh-header-btn",
|
|
1829
|
+
onClick: (e) => handleNewChat(),
|
|
1830
|
+
style: styles2.headerButton,
|
|
1831
|
+
children: TRANSLATIONS.newChat
|
|
1832
|
+
}
|
|
1833
|
+
),
|
|
1834
|
+
props.chatPosition === "classic-chatbot" || props.chatPosition === "right-panel" || props.chatPosition === "dialog" ? /* @__PURE__ */ jsx4(
|
|
1835
|
+
"button",
|
|
1836
|
+
{
|
|
1837
|
+
onClick: (e) => toggleChat(),
|
|
1838
|
+
style: styles2.ButtonSheetButton,
|
|
1839
|
+
children: "\xD7"
|
|
1840
|
+
}
|
|
1841
|
+
) : null
|
|
1842
|
+
] })
|
|
1843
|
+
]
|
|
1844
|
+
}
|
|
1845
|
+
),
|
|
1846
|
+
isConfigInsufficient() ? /* @__PURE__ */ jsxs4("div", { style: styles2.insufficientConfigContainer, children: [
|
|
1847
|
+
/* @__PURE__ */ jsx4("div", { style: styles2.insufficientConfigIconContainer, children: /* @__PURE__ */ jsxs4(
|
|
1848
|
+
"svg",
|
|
1849
|
+
{
|
|
1850
|
+
width: "48",
|
|
1851
|
+
height: "48",
|
|
1852
|
+
viewBox: "0 0 24 24",
|
|
1853
|
+
fill: "none",
|
|
1854
|
+
stroke: "currentColor",
|
|
1855
|
+
strokeWidth: "2",
|
|
1856
|
+
strokeLinecap: "round",
|
|
1857
|
+
strokeLinejoin: "round",
|
|
1858
|
+
style: {
|
|
1859
|
+
color: "#ef4444"
|
|
1860
|
+
},
|
|
1861
|
+
children: [
|
|
1862
|
+
/* @__PURE__ */ jsx4("rect", { x: "3", y: "11", width: "18", height: "11", rx: "2", ry: "2" }),
|
|
1863
|
+
/* @__PURE__ */ jsx4("path", { d: "M7 11V7a5 5 0 0 1 9.9-1" })
|
|
1864
|
+
]
|
|
1865
|
+
}
|
|
1866
|
+
) }),
|
|
1867
|
+
/* @__PURE__ */ jsx4(
|
|
1868
|
+
"h3",
|
|
1869
|
+
{
|
|
1870
|
+
style: {
|
|
1871
|
+
...styles2.insufficientConfigTitle,
|
|
1872
|
+
fontFamily: themeObj().fontFamily || void 0
|
|
1873
|
+
},
|
|
1874
|
+
children: "Configuration Error"
|
|
1875
|
+
}
|
|
1876
|
+
),
|
|
1877
|
+
/* @__PURE__ */ jsx4(
|
|
1878
|
+
"p",
|
|
1879
|
+
{
|
|
1880
|
+
style: {
|
|
1881
|
+
...styles2.insufficientConfigMessage,
|
|
1882
|
+
fontFamily: themeObj().fontFamily || void 0
|
|
1883
|
+
},
|
|
1884
|
+
children: "ShopPrompter requires a secure token or API key to initialize. Please check your setup."
|
|
1885
|
+
}
|
|
1886
|
+
),
|
|
1887
|
+
/* @__PURE__ */ jsxs4(
|
|
1888
|
+
"div",
|
|
1889
|
+
{
|
|
1890
|
+
style: {
|
|
1891
|
+
...styles2.insufficientConfigDetails,
|
|
1892
|
+
fontFamily: themeObj().fontFamily || void 0
|
|
1893
|
+
},
|
|
1894
|
+
children: [
|
|
1895
|
+
/* @__PURE__ */ jsx4(
|
|
1896
|
+
"div",
|
|
1897
|
+
{
|
|
1898
|
+
style: {
|
|
1899
|
+
fontWeight: 600,
|
|
1900
|
+
marginBottom: "0.25rem"
|
|
1901
|
+
},
|
|
1902
|
+
children: "Missing Parameters:"
|
|
1903
|
+
}
|
|
1904
|
+
),
|
|
1905
|
+
/* @__PURE__ */ jsxs4(
|
|
1906
|
+
"div",
|
|
1907
|
+
{
|
|
1908
|
+
style: {
|
|
1909
|
+
display: "flex",
|
|
1910
|
+
flexDirection: "column",
|
|
1911
|
+
gap: "0.25rem",
|
|
1912
|
+
fontFamily: "monospace",
|
|
1913
|
+
fontSize: "0.75rem"
|
|
1914
|
+
},
|
|
1915
|
+
children: [
|
|
1916
|
+
/* @__PURE__ */ jsx4(
|
|
1917
|
+
"span",
|
|
1918
|
+
{
|
|
1919
|
+
style: {
|
|
1920
|
+
color: "#ef4444"
|
|
1921
|
+
},
|
|
1922
|
+
children: "\u2717 shopPrompterToken (not found)"
|
|
1923
|
+
}
|
|
1924
|
+
),
|
|
1925
|
+
/* @__PURE__ */ jsx4(
|
|
1926
|
+
"span",
|
|
1927
|
+
{
|
|
1928
|
+
style: {
|
|
1929
|
+
color: "#ef4444"
|
|
1930
|
+
},
|
|
1931
|
+
children: "\u2717 apiConfig.apiKey (not found)"
|
|
1932
|
+
}
|
|
1933
|
+
)
|
|
1934
|
+
]
|
|
1935
|
+
}
|
|
1936
|
+
)
|
|
1937
|
+
]
|
|
1938
|
+
}
|
|
1939
|
+
)
|
|
1940
|
+
] }) : null,
|
|
1941
|
+
!isConfigInsufficient() ? /* @__PURE__ */ jsxs4(
|
|
1942
|
+
"div",
|
|
1943
|
+
{
|
|
1944
|
+
style: {
|
|
1945
|
+
display: "flex",
|
|
1946
|
+
flexDirection: "column",
|
|
1947
|
+
flex: 1,
|
|
1948
|
+
overflow: "hidden"
|
|
1949
|
+
},
|
|
1950
|
+
children: [
|
|
1951
|
+
/* @__PURE__ */ jsxs4(
|
|
1952
|
+
"div",
|
|
1953
|
+
{
|
|
1954
|
+
id: "shop-prompter-chat-container",
|
|
1955
|
+
style: {
|
|
1956
|
+
...styles2.chatContainer,
|
|
1957
|
+
backgroundColor: themeObj().mainBackgroundColor || styles2.chatContainer.backgroundColor
|
|
1958
|
+
},
|
|
1959
|
+
children: [
|
|
1960
|
+
showWelcome() ? /* @__PURE__ */ jsxs4("div", { style: styles2.welcomeContainer, children: [
|
|
1961
|
+
/* @__PURE__ */ jsx4(
|
|
1962
|
+
"img",
|
|
1963
|
+
{
|
|
1964
|
+
alt: "ShopPrompter",
|
|
1965
|
+
src: (agentExperience == null ? void 0 : agentExperience.agentLogoUrl) ? agentExperience.agentLogoUrl : ICONS.shopprompter,
|
|
1966
|
+
style: {
|
|
1967
|
+
width: "64px",
|
|
1968
|
+
height: "64px",
|
|
1969
|
+
marginBottom: "24px",
|
|
1970
|
+
borderRadius: "12px",
|
|
1971
|
+
objectFit: "cover"
|
|
1972
|
+
}
|
|
1973
|
+
}
|
|
1974
|
+
),
|
|
1975
|
+
/* @__PURE__ */ jsx4(
|
|
1976
|
+
"h3",
|
|
1977
|
+
{
|
|
1978
|
+
style: {
|
|
1979
|
+
...styles2.welcomeTitle,
|
|
1980
|
+
fontFamily: themeObj().fontFamily || styles2.welcomeTitle.fontFamily
|
|
1981
|
+
},
|
|
1982
|
+
children: ((_b = agentExperience == null ? void 0 : agentExperience.greeting) == null ? void 0 : _b.title) || TRANSLATIONS.welcomeToShopPrompter
|
|
1983
|
+
}
|
|
1984
|
+
),
|
|
1985
|
+
/* @__PURE__ */ jsx4(
|
|
1986
|
+
"p",
|
|
1987
|
+
{
|
|
1988
|
+
style: {
|
|
1989
|
+
...styles2.welcomeDescription,
|
|
1990
|
+
fontFamily: themeObj().fontFamily || styles2.welcomeDescription.fontFamily
|
|
1991
|
+
},
|
|
1992
|
+
children: ((_c = agentExperience == null ? void 0 : agentExperience.greeting) == null ? void 0 : _c.description) || TRANSLATIONS.welcomeDescription
|
|
1993
|
+
}
|
|
1994
|
+
),
|
|
1995
|
+
/* @__PURE__ */ jsx4("div", { style: styles2.buttonContainer, children: (_d = prompts()) == null ? void 0 : _d.map((item) => /* @__PURE__ */ jsx4(
|
|
1996
|
+
"button",
|
|
1997
|
+
{
|
|
1998
|
+
style: styles2.button,
|
|
1999
|
+
onClick: (event) => {
|
|
2000
|
+
setInput(item.prompt);
|
|
2001
|
+
handleSend(item.prompt);
|
|
2002
|
+
},
|
|
2003
|
+
children: item.prompt
|
|
2004
|
+
},
|
|
2005
|
+
item.prompt
|
|
2006
|
+
)) })
|
|
2007
|
+
] }) : null,
|
|
2008
|
+
!showWelcome() ? /* @__PURE__ */ jsx4(
|
|
2009
|
+
"div",
|
|
980
2010
|
{
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
2011
|
+
style: {
|
|
2012
|
+
width: "100%"
|
|
2013
|
+
},
|
|
2014
|
+
children: chatMessages == null ? void 0 : chatMessages.map((message) => /* @__PURE__ */ jsxs4("div", { children: [
|
|
2015
|
+
message.role === "user" ? /* @__PURE__ */ jsx4("div", { style: styles2.messageContainerUser, children: /* @__PURE__ */ jsx4(
|
|
2016
|
+
"div",
|
|
2017
|
+
{
|
|
2018
|
+
style: {
|
|
2019
|
+
...styles2.messageBubbleUser,
|
|
2020
|
+
backgroundColor: themeObj().userMessageBackgroundColor || styles2.messageBubbleUser.backgroundColor
|
|
2021
|
+
},
|
|
2022
|
+
children: message.content
|
|
2023
|
+
}
|
|
2024
|
+
) }) : null,
|
|
2025
|
+
message.role === "assistant" ? /* @__PURE__ */ jsxs4("div", { style: styles2.messageContainerAssistant, children: [
|
|
2026
|
+
/* @__PURE__ */ jsxs4(
|
|
2027
|
+
"div",
|
|
2028
|
+
{
|
|
2029
|
+
style: {
|
|
2030
|
+
...styles2.messageBubbleAssistant,
|
|
2031
|
+
backgroundColor: themeObj().assistantMessageBackgroundColor || styles2.messageBubbleAssistant.backgroundColor
|
|
2032
|
+
},
|
|
2033
|
+
children: [
|
|
2034
|
+
/* @__PURE__ */ jsx4(
|
|
2035
|
+
"div",
|
|
2036
|
+
{
|
|
2037
|
+
dangerouslySetInnerHTML: {
|
|
2038
|
+
__html: parseMarkdown(message.content)
|
|
2039
|
+
}
|
|
2040
|
+
}
|
|
2041
|
+
),
|
|
2042
|
+
!message.content && isLoading ? /* @__PURE__ */ jsx4(Fragment2, { children: (agentExperience == null ? void 0 : agentExperience.loadingIndicatorUrl) ? /* @__PURE__ */ jsx4(
|
|
2043
|
+
"lottie-player",
|
|
2044
|
+
{
|
|
2045
|
+
background: "transparent",
|
|
2046
|
+
speed: "1",
|
|
2047
|
+
src: agentExperience.loadingIndicatorUrl,
|
|
2048
|
+
style: {
|
|
2049
|
+
width: "40px",
|
|
2050
|
+
height: "40px"
|
|
2051
|
+
},
|
|
2052
|
+
loop: true,
|
|
2053
|
+
autoplay: true
|
|
2054
|
+
}
|
|
2055
|
+
) : /* @__PURE__ */ jsx4("div", { style: styles2.thinkingIndicator, children: /* @__PURE__ */ jsxs4(
|
|
2056
|
+
"svg",
|
|
2057
|
+
{
|
|
2058
|
+
width: "24",
|
|
2059
|
+
height: "24",
|
|
2060
|
+
viewBox: "0 0 24 24",
|
|
2061
|
+
fill: "none",
|
|
2062
|
+
stroke: "currentColor",
|
|
2063
|
+
strokeWidth: "2",
|
|
2064
|
+
strokeLinecap: "round",
|
|
2065
|
+
strokeLinejoin: "round",
|
|
2066
|
+
style: {
|
|
2067
|
+
color: "#6b7280"
|
|
2068
|
+
},
|
|
2069
|
+
children: [
|
|
2070
|
+
/* @__PURE__ */ jsx4("path", { d: THINKING_SPINNER }),
|
|
2071
|
+
/* @__PURE__ */ jsx4(
|
|
2072
|
+
"animateTransform",
|
|
2073
|
+
{
|
|
2074
|
+
attributeName: "transform",
|
|
2075
|
+
type: "rotate",
|
|
2076
|
+
from: "0 12 12",
|
|
2077
|
+
to: "360 12 12",
|
|
2078
|
+
dur: "1s",
|
|
2079
|
+
repeatCount: "indefinite"
|
|
2080
|
+
}
|
|
2081
|
+
)
|
|
2082
|
+
]
|
|
2083
|
+
}
|
|
2084
|
+
) }) }) : null
|
|
2085
|
+
]
|
|
2086
|
+
}
|
|
2087
|
+
),
|
|
2088
|
+
canShowFeedback(message) ? /* @__PURE__ */ jsxs4("div", { style: styles2.feedbackRow, children: [
|
|
2089
|
+
/* @__PURE__ */ jsx4(
|
|
2090
|
+
"button",
|
|
2091
|
+
{
|
|
2092
|
+
className: "sh-feedback-btn",
|
|
2093
|
+
onClick: (event) => handleFeedback(
|
|
2094
|
+
message.id,
|
|
2095
|
+
message.content,
|
|
2096
|
+
"upvote"
|
|
2097
|
+
),
|
|
2098
|
+
style: styles2.feedbackButton,
|
|
2099
|
+
children: /* @__PURE__ */ jsx4(
|
|
2100
|
+
thumbs_up_icon_component_default,
|
|
2101
|
+
{
|
|
2102
|
+
fill: message.feedback === "upvote" ? themeObj().actionColor || "#2563eb" : "none",
|
|
2103
|
+
stroke: message.feedback === "upvote" ? themeObj().actionColor || "#2563eb" : "currentColor"
|
|
2104
|
+
}
|
|
2105
|
+
)
|
|
2106
|
+
}
|
|
2107
|
+
),
|
|
2108
|
+
/* @__PURE__ */ jsx4(
|
|
2109
|
+
"button",
|
|
2110
|
+
{
|
|
2111
|
+
className: "sh-feedback-btn",
|
|
2112
|
+
onClick: (event) => handleFeedback(
|
|
2113
|
+
message.id,
|
|
2114
|
+
message.content,
|
|
2115
|
+
"downvote"
|
|
2116
|
+
),
|
|
2117
|
+
style: styles2.feedbackButton,
|
|
2118
|
+
children: /* @__PURE__ */ jsx4(
|
|
2119
|
+
thumbs_down_icon_component_default,
|
|
2120
|
+
{
|
|
2121
|
+
fill: message.feedback === "downvote" ? themeObj().actionColor || "#2563eb" : "none",
|
|
2122
|
+
stroke: message.feedback === "downvote" ? themeObj().actionColor || "#2563eb" : "currentColor"
|
|
2123
|
+
}
|
|
2124
|
+
)
|
|
2125
|
+
}
|
|
2126
|
+
)
|
|
2127
|
+
] }) : null,
|
|
2128
|
+
getShowProducts(message) ? /* @__PURE__ */ jsx4(
|
|
2129
|
+
product_card_list_component_default,
|
|
2130
|
+
{
|
|
2131
|
+
skus: message.productSkus,
|
|
2132
|
+
defaultLocale: props.defaultLocale,
|
|
2133
|
+
showPriceIfEmpty: showPriceIfEmptyVal(),
|
|
2134
|
+
visibleFields: visibleFieldsList()
|
|
2135
|
+
}
|
|
2136
|
+
) : null
|
|
2137
|
+
] }) : null
|
|
2138
|
+
] }, message.id))
|
|
994
2139
|
}
|
|
995
|
-
)
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
] }),
|
|
1002
|
-
/* @__PURE__ */ jsxs("div", { style: styles.subHeaderContainer, children: [
|
|
1003
|
-
/* @__PURE__ */ jsx(
|
|
1004
|
-
"button",
|
|
1005
|
-
{
|
|
1006
|
-
onClick: (e) => handleNewChat(),
|
|
1007
|
-
onMouseEnter: (e) => onHeaderButtonMouseEnter(),
|
|
1008
|
-
onMouseLeave: (e) => onHeaderButtonMouseLeave(),
|
|
1009
|
-
style: {
|
|
1010
|
-
...styles.headerButton,
|
|
1011
|
-
...isHeaderButtonHovered ? styles.headerButton.onHover : {}
|
|
1012
|
-
},
|
|
1013
|
-
children: TRANSLATIONS.newChat
|
|
1014
|
-
}
|
|
1015
|
-
),
|
|
1016
|
-
props.chatPosition === "classic-chatbot" || props.chatPosition === "right-panel" || props.chatPosition === "bottom-sheet" ? /* @__PURE__ */ jsx(
|
|
1017
|
-
"button",
|
|
1018
|
-
{
|
|
1019
|
-
onClick: (e) => toggleChat(),
|
|
1020
|
-
style: styles.ButtonSheetButton,
|
|
1021
|
-
children: "\xD7"
|
|
1022
|
-
}
|
|
1023
|
-
) : null
|
|
1024
|
-
] })
|
|
1025
|
-
] }),
|
|
1026
|
-
/* @__PURE__ */ jsxs("div", { style: styles.chatContainer, children: [
|
|
1027
|
-
showWelcome() ? /* @__PURE__ */ jsxs("div", { style: styles.welcomeContainer, children: [
|
|
1028
|
-
/* @__PURE__ */ jsx(
|
|
1029
|
-
"img",
|
|
1030
|
-
{
|
|
1031
|
-
alt: "ShopPrompter",
|
|
1032
|
-
src: (agentExperience == null ? void 0 : agentExperience.agentLogoUrl) ? agentExperience.agentLogoUrl : ICONS.shopprompter,
|
|
1033
|
-
style: {
|
|
1034
|
-
width: "64px",
|
|
1035
|
-
height: "64px",
|
|
1036
|
-
marginBottom: "24px"
|
|
1037
|
-
}
|
|
1038
|
-
}
|
|
1039
|
-
),
|
|
1040
|
-
/* @__PURE__ */ jsx("h3", { style: styles.welcomeTitle, children: ((_a = agentExperience == null ? void 0 : agentExperience.greeting) == null ? void 0 : _a.title) || TRANSLATIONS.welcomeToShopPrompter }),
|
|
1041
|
-
/* @__PURE__ */ jsx("p", { style: styles.welcomeDescription, children: ((_b = agentExperience == null ? void 0 : agentExperience.greeting) == null ? void 0 : _b.description) || TRANSLATIONS.welcomeDescription }),
|
|
1042
|
-
/* @__PURE__ */ jsxs("div", { style: styles.buttonContainer, children: [
|
|
1043
|
-
/* @__PURE__ */ jsx(
|
|
1044
|
-
"button",
|
|
1045
|
-
{
|
|
1046
|
-
style: styles.button,
|
|
1047
|
-
onClick: (e) => onPopularItemsClick(),
|
|
1048
|
-
children: TRANSLATIONS.showPopularItems
|
|
2140
|
+
) : null,
|
|
2141
|
+
error ? /* @__PURE__ */ jsxs4("div", { style: styles2.errorContainer, children: [
|
|
2142
|
+
"Error: ",
|
|
2143
|
+
error
|
|
2144
|
+
] }) : null
|
|
2145
|
+
]
|
|
1049
2146
|
}
|
|
1050
2147
|
),
|
|
1051
|
-
/* @__PURE__ */
|
|
1052
|
-
"
|
|
2148
|
+
/* @__PURE__ */ jsxs4(
|
|
2149
|
+
"div",
|
|
1053
2150
|
{
|
|
1054
|
-
style:
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
style: message.role === "user" ? styles.messageBubbleUser : styles.messageBubbleAssistant,
|
|
1071
|
-
children: [
|
|
1072
|
-
message.content,
|
|
1073
|
-
!message.content ? /* @__PURE__ */ jsx(Fragment, { children: message.role === "assistant" ? /* @__PURE__ */ jsx(Fragment, { children: isLoading ? /* @__PURE__ */ jsx("div", { style: styles.thinkingIndicator, children: TRANSLATIONS.thinking }) : null }) : null }) : null
|
|
1074
|
-
]
|
|
1075
|
-
}
|
|
1076
|
-
),
|
|
1077
|
-
message.role === "assistant" ? /* @__PURE__ */ jsx("div", { style: styles.productCardsContainer, children: (_a2 = message.safeProductSkus) == null ? void 0 : _a2.map((sku) => /* @__PURE__ */ jsxs("div", { style: styles.productCard, children: [
|
|
1078
|
-
/* @__PURE__ */ jsx("div", { style: styles.productImageContainer, children: /* @__PURE__ */ jsx(
|
|
1079
|
-
"img",
|
|
1080
|
-
{
|
|
1081
|
-
src: getProductImageUrl(sku),
|
|
1082
|
-
alt: sku,
|
|
1083
|
-
style: {
|
|
1084
|
-
maxHeight: "100%",
|
|
1085
|
-
maxWidth: "100%"
|
|
2151
|
+
style: {
|
|
2152
|
+
...styles2.inputSection,
|
|
2153
|
+
backgroundColor: themeObj().mainBackgroundColor || styles2.inputSection.backgroundColor
|
|
2154
|
+
},
|
|
2155
|
+
children: [
|
|
2156
|
+
/* @__PURE__ */ jsxs4("div", { style: styles2.inputWrapper, children: [
|
|
2157
|
+
/* @__PURE__ */ jsx4(
|
|
2158
|
+
"input",
|
|
2159
|
+
{
|
|
2160
|
+
id: "shop-prompter-input",
|
|
2161
|
+
type: "text",
|
|
2162
|
+
style: styles2.input,
|
|
2163
|
+
placeholder: (agentExperience == null ? void 0 : agentExperience.hintText) || TRANSLATIONS.askMeAnything,
|
|
2164
|
+
value: input,
|
|
2165
|
+
onInput: (e) => onInputChange(e),
|
|
2166
|
+
onKeyDown: (e) => onInputKeyDown(e)
|
|
1086
2167
|
}
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
/* @__PURE__ */ jsx("p", { style: styles.productSku, children: sku }),
|
|
1091
|
-
/* @__PURE__ */ jsx(
|
|
1092
|
-
"a",
|
|
2168
|
+
),
|
|
2169
|
+
/* @__PURE__ */ jsx4(
|
|
2170
|
+
"button",
|
|
1093
2171
|
{
|
|
1094
|
-
|
|
1095
|
-
style:
|
|
1096
|
-
|
|
2172
|
+
onClick: (e) => handleSend(),
|
|
2173
|
+
style: {
|
|
2174
|
+
...styles2.formButton,
|
|
2175
|
+
...styles2.sendButton,
|
|
2176
|
+
backgroundColor: themeObj().actionColor || styles2.sendButton.backgroundColor
|
|
2177
|
+
},
|
|
2178
|
+
children: /* @__PURE__ */ jsx4(
|
|
2179
|
+
"img",
|
|
2180
|
+
{
|
|
2181
|
+
alt: "Send",
|
|
2182
|
+
src: ICONS.sendHorizontal,
|
|
2183
|
+
style: {
|
|
2184
|
+
padding: "4px"
|
|
2185
|
+
}
|
|
2186
|
+
}
|
|
2187
|
+
)
|
|
1097
2188
|
}
|
|
1098
2189
|
)
|
|
1099
|
-
] })
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
}
|
|
1106
|
-
|
|
1107
|
-
"Error: ",
|
|
1108
|
-
error
|
|
1109
|
-
] }) : null
|
|
1110
|
-
] }),
|
|
1111
|
-
/* @__PURE__ */ jsxs("div", { style: styles.inputSection, children: [
|
|
1112
|
-
/* @__PURE__ */ jsxs("div", { style: styles.inputWrapper, children: [
|
|
1113
|
-
/* @__PURE__ */ jsx(
|
|
1114
|
-
"input",
|
|
1115
|
-
{
|
|
1116
|
-
type: "text",
|
|
1117
|
-
style: styles.input,
|
|
1118
|
-
placeholder: TRANSLATIONS.askMeAnything,
|
|
1119
|
-
value: input,
|
|
1120
|
-
onInput: (e) => onInputChange(e),
|
|
1121
|
-
onKeyDown: (e) => onInputKeyDown(e)
|
|
1122
|
-
}
|
|
1123
|
-
),
|
|
1124
|
-
/* @__PURE__ */ jsx(
|
|
1125
|
-
"button",
|
|
1126
|
-
{
|
|
1127
|
-
onClick: (e) => handleSend(),
|
|
1128
|
-
style: {
|
|
1129
|
-
...styles.formButton,
|
|
1130
|
-
...styles.sendButton
|
|
1131
|
-
},
|
|
1132
|
-
children: /* @__PURE__ */ jsx("img", { alt: "Send", src: ICONS.sendHorizontal })
|
|
1133
|
-
}
|
|
1134
|
-
)
|
|
1135
|
-
] }),
|
|
1136
|
-
/* @__PURE__ */ jsx("p", { style: styles.disclaimer, children: "AI content may be inaccurate." })
|
|
1137
|
-
] })
|
|
2190
|
+
] }),
|
|
2191
|
+
/* @__PURE__ */ jsx4("p", { style: styles2.disclaimer, children: "AI content may be inaccurate." })
|
|
2192
|
+
]
|
|
2193
|
+
}
|
|
2194
|
+
)
|
|
2195
|
+
]
|
|
2196
|
+
}
|
|
2197
|
+
) : null
|
|
1138
2198
|
] }) : null
|
|
1139
2199
|
] });
|
|
1140
2200
|
}
|