@shop-prompter/react 0.1.1 → 1.0.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 +6 -0
- package/dist/index.js +1361 -372
- package/dist/index.mjs +1362 -373
- package/package.json +24 -23
- package/src/api/icons.ts +9 -0
- package/src/api/product-api.ts +120 -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 +212 -0
- package/src/shop-prompter.component.jsx +897 -273
- 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,244 @@ 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
|
+
productPrice: {
|
|
768
|
+
fontSize: "0.8125rem",
|
|
769
|
+
fontWeight: 500,
|
|
770
|
+
color: "#4b5563",
|
|
771
|
+
margin: 0
|
|
772
|
+
},
|
|
773
|
+
statusContainer: {
|
|
774
|
+
padding: "0.5rem 0",
|
|
775
|
+
fontSize: "0.75rem",
|
|
776
|
+
color: "#6b7280",
|
|
777
|
+
display: "flex",
|
|
778
|
+
alignItems: "center",
|
|
779
|
+
gap: "0.5rem"
|
|
780
|
+
},
|
|
781
|
+
errorText: {
|
|
782
|
+
color: "#ef4444"
|
|
783
|
+
},
|
|
784
|
+
spinner: {
|
|
785
|
+
color: "#6b7280"
|
|
786
|
+
},
|
|
787
|
+
wrapper: {
|
|
788
|
+
width: "100%",
|
|
789
|
+
maxWidth: "100%",
|
|
790
|
+
boxSizing: "border-box",
|
|
791
|
+
overflow: "hidden"
|
|
792
|
+
}
|
|
793
|
+
};
|
|
794
|
+
function ProductCardList(props) {
|
|
795
|
+
const [products, setProducts] = useState(() => []);
|
|
796
|
+
const [loading, setLoading] = useState(() => false);
|
|
797
|
+
const [error, setError] = useState(() => null);
|
|
798
|
+
function fetchProducts() {
|
|
799
|
+
let skusList = props.skus;
|
|
800
|
+
if (typeof skusList === "string") {
|
|
801
|
+
skusList = skusList.split(",").map((s) => s.trim()).filter(Boolean);
|
|
802
|
+
}
|
|
803
|
+
if (!skusList || skusList.length === 0) {
|
|
804
|
+
setProducts([]);
|
|
805
|
+
setLoading(false);
|
|
806
|
+
return;
|
|
807
|
+
}
|
|
808
|
+
if (productApi.isCached(skusList)) {
|
|
809
|
+
setProducts(productApi.getCached(skusList));
|
|
810
|
+
setLoading(false);
|
|
811
|
+
setError(null);
|
|
812
|
+
return;
|
|
813
|
+
}
|
|
814
|
+
setLoading(true);
|
|
815
|
+
setError(null);
|
|
816
|
+
productApi.getProducts(skusList).then((data) => {
|
|
817
|
+
setProducts(data || []);
|
|
818
|
+
setLoading(false);
|
|
819
|
+
}).catch((err) => {
|
|
820
|
+
console.error("Failed to fetch products:", err);
|
|
821
|
+
setError((err == null ? void 0 : err.message) || "Failed to load products");
|
|
822
|
+
setLoading(false);
|
|
823
|
+
});
|
|
824
|
+
}
|
|
825
|
+
function getProductName(product) {
|
|
826
|
+
var _a;
|
|
827
|
+
const locale = props.defaultLocale || "de";
|
|
828
|
+
const localized = ((_a = product.localization) == null ? void 0 : _a[locale]) || Object.values(product.localization || {})[0];
|
|
829
|
+
return (localized == null ? void 0 : localized.name) || product.sku;
|
|
830
|
+
}
|
|
831
|
+
function getProductPrice(product) {
|
|
832
|
+
if (!product.pricing) return "";
|
|
833
|
+
const priceVal = product.pricing.gross;
|
|
834
|
+
const currency = product.pricing.currency;
|
|
835
|
+
if (priceVal === void 0 || priceVal === null) return "";
|
|
836
|
+
return priceVal.toFixed(2) + " " + (currency || "\u20AC");
|
|
837
|
+
}
|
|
838
|
+
function getProductImage(product) {
|
|
839
|
+
var _a;
|
|
840
|
+
return ((_a = product.images) == null ? void 0 : _a[0]) || "https://placehold.co/150x150?text=" + product.sku;
|
|
841
|
+
}
|
|
842
|
+
useEffect(() => {
|
|
843
|
+
fetchProducts();
|
|
844
|
+
}, []);
|
|
845
|
+
useEffect(() => {
|
|
846
|
+
fetchProducts();
|
|
847
|
+
}, [
|
|
848
|
+
props.skus ? Array.isArray(props.skus) ? props.skus.join(",") : props.skus : ""
|
|
849
|
+
]);
|
|
850
|
+
return /* @__PURE__ */ jsx3(Fragment, { children: props.skus && props.skus.length > 0 ? /* @__PURE__ */ jsx3(Fragment, { children: /* @__PURE__ */ jsxs3("div", { style: styles.wrapper, children: [
|
|
851
|
+
loading ? /* @__PURE__ */ jsx3("div", { style: styles.statusContainer, children: /* @__PURE__ */ jsx3("span", { children: "Loading products..." }) }) : null,
|
|
852
|
+
!loading && error ? /* @__PURE__ */ jsx3("div", { style: styles.statusContainer, children: /* @__PURE__ */ jsxs3("span", { style: styles.errorText, children: [
|
|
853
|
+
"Error: ",
|
|
854
|
+
error
|
|
855
|
+
] }) }) : null,
|
|
856
|
+
!loading && products && products.length > 0 ? /* @__PURE__ */ jsx3("div", { style: styles.productCardsContainer, children: products == null ? void 0 : products.map((product) => /* @__PURE__ */ jsxs3("div", { style: styles.productCard, children: [
|
|
857
|
+
/* @__PURE__ */ jsx3("div", { style: styles.productImageContainer, children: /* @__PURE__ */ jsx3(
|
|
858
|
+
"img",
|
|
859
|
+
{
|
|
860
|
+
src: getProductImage(product),
|
|
861
|
+
alt: getProductName(product),
|
|
862
|
+
style: styles.productImage
|
|
863
|
+
}
|
|
864
|
+
) }),
|
|
865
|
+
/* @__PURE__ */ jsxs3("div", { style: styles.productInfo, children: [
|
|
866
|
+
/* @__PURE__ */ jsx3(
|
|
867
|
+
"p",
|
|
868
|
+
{
|
|
869
|
+
style: styles.productName,
|
|
870
|
+
title: getProductName(product),
|
|
871
|
+
children: getProductName(product)
|
|
872
|
+
}
|
|
873
|
+
),
|
|
874
|
+
/* @__PURE__ */ jsx3("p", { style: styles.productPrice, children: getProductPrice(product) })
|
|
875
|
+
] })
|
|
876
|
+
] }, product.sku)) }) : null
|
|
877
|
+
] }) }) : null });
|
|
878
|
+
}
|
|
879
|
+
var product_card_list_component_default = ProductCardList;
|
|
880
|
+
|
|
881
|
+
// src/shop-prompter.component.jsx
|
|
882
|
+
import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
883
|
+
var THINKING_SPINNER = "M21 12a9 9 0 1 1-6.219-8.56";
|
|
884
|
+
var styles2 = {
|
|
442
885
|
header: {
|
|
443
886
|
display: "flex",
|
|
444
887
|
alignItems: "center",
|
|
445
888
|
justifyContent: "space-between",
|
|
446
|
-
padding: "16px"
|
|
889
|
+
padding: "16px",
|
|
890
|
+
borderBottom: "1px solid #e5e7eb"
|
|
447
891
|
},
|
|
448
892
|
subHeaderContainer: {
|
|
449
893
|
display: "flex",
|
|
@@ -459,6 +903,7 @@ var styles = {
|
|
|
459
903
|
border: "none",
|
|
460
904
|
cursor: "pointer",
|
|
461
905
|
transition: "background-color 0.2s, color 0.2s",
|
|
906
|
+
fontFamily: "inherit",
|
|
462
907
|
onHover: {
|
|
463
908
|
backgroundColor: "hsl(220 14% 96%)",
|
|
464
909
|
color: "hsl(220 13% 13%)"
|
|
@@ -479,7 +924,8 @@ var styles = {
|
|
|
479
924
|
gap: "0.5rem",
|
|
480
925
|
cursor: "pointer",
|
|
481
926
|
fontSize: "0.875rem",
|
|
482
|
-
color: "#09090b"
|
|
927
|
+
color: "#09090b",
|
|
928
|
+
fontFamily: "inherit"
|
|
483
929
|
},
|
|
484
930
|
ButtonSheetButton: {
|
|
485
931
|
color: "#6b7280",
|
|
@@ -488,11 +934,13 @@ var styles = {
|
|
|
488
934
|
cursor: "pointer",
|
|
489
935
|
padding: "0.25rem",
|
|
490
936
|
fontSize: "1.25rem",
|
|
491
|
-
transition: "color 0.2s"
|
|
937
|
+
transition: "color 0.2s",
|
|
938
|
+
fontFamily: "inherit"
|
|
492
939
|
},
|
|
493
940
|
chatContainer: {
|
|
494
941
|
flex: 1,
|
|
495
942
|
overflowY: "auto",
|
|
943
|
+
overflowX: "hidden",
|
|
496
944
|
padding: "1rem",
|
|
497
945
|
backgroundColor: "white"
|
|
498
946
|
},
|
|
@@ -538,12 +986,17 @@ var styles = {
|
|
|
538
986
|
messageContainerUser: {
|
|
539
987
|
display: "flex",
|
|
540
988
|
flexDirection: "column",
|
|
541
|
-
alignItems: "flex-end"
|
|
989
|
+
alignItems: "flex-end",
|
|
990
|
+
marginBottom: "8px"
|
|
542
991
|
},
|
|
543
992
|
messageContainerAssistant: {
|
|
544
993
|
display: "flex",
|
|
545
994
|
flexDirection: "column",
|
|
546
|
-
alignItems: "flex-start"
|
|
995
|
+
alignItems: "flex-start",
|
|
996
|
+
marginBottom: "8px",
|
|
997
|
+
width: "100%",
|
|
998
|
+
maxWidth: "100%",
|
|
999
|
+
boxSizing: "border-box"
|
|
547
1000
|
},
|
|
548
1001
|
messageBubbleUser: {
|
|
549
1002
|
backgroundColor: "#111827",
|
|
@@ -553,7 +1006,8 @@ var styles = {
|
|
|
553
1006
|
padding: "0.5rem 1rem",
|
|
554
1007
|
fontSize: "0.875rem",
|
|
555
1008
|
boxShadow: "0 1px 2px 0 rgba(0, 0, 0, 0.05)",
|
|
556
|
-
maxWidth: "85%"
|
|
1009
|
+
maxWidth: "85%",
|
|
1010
|
+
textAlign: "left"
|
|
557
1011
|
},
|
|
558
1012
|
messageBubbleAssistant: {
|
|
559
1013
|
backgroundColor: "#f3f4f6",
|
|
@@ -563,7 +1017,8 @@ var styles = {
|
|
|
563
1017
|
padding: "0.5rem 1rem",
|
|
564
1018
|
fontSize: "0.875rem",
|
|
565
1019
|
boxShadow: "0 1px 2px 0 rgba(0, 0, 0, 0.05)",
|
|
566
|
-
maxWidth: "85%"
|
|
1020
|
+
maxWidth: "85%",
|
|
1021
|
+
textAlign: "left"
|
|
567
1022
|
},
|
|
568
1023
|
thinkingIndicator: {
|
|
569
1024
|
display: "flex",
|
|
@@ -645,7 +1100,8 @@ var styles = {
|
|
|
645
1100
|
outline: "none",
|
|
646
1101
|
fontSize: "0.875rem",
|
|
647
1102
|
color: "#111827",
|
|
648
|
-
padding: "0.25rem 0"
|
|
1103
|
+
padding: "0.25rem 0",
|
|
1104
|
+
fontFamily: "inherit"
|
|
649
1105
|
},
|
|
650
1106
|
formButton: {
|
|
651
1107
|
backgroundColor: "transparent",
|
|
@@ -658,7 +1114,8 @@ var styles = {
|
|
|
658
1114
|
fontWeight: "bold",
|
|
659
1115
|
border: "none",
|
|
660
1116
|
cursor: "pointer",
|
|
661
|
-
transition: "background-color 0.2s"
|
|
1117
|
+
transition: "background-color 0.2s",
|
|
1118
|
+
fontFamily: "inherit"
|
|
662
1119
|
},
|
|
663
1120
|
sendButton: {
|
|
664
1121
|
backgroundColor: "#AD59FF1A"
|
|
@@ -668,17 +1125,169 @@ var styles = {
|
|
|
668
1125
|
color: "#9ca3af",
|
|
669
1126
|
textAlign: "center",
|
|
670
1127
|
marginTop: "0.75rem"
|
|
1128
|
+
},
|
|
1129
|
+
backdrop: {
|
|
1130
|
+
position: "fixed",
|
|
1131
|
+
top: 0,
|
|
1132
|
+
left: 0,
|
|
1133
|
+
right: 0,
|
|
1134
|
+
bottom: 0,
|
|
1135
|
+
backgroundColor: "rgba(0, 0, 0, 0.5)",
|
|
1136
|
+
backdropFilter: "blur(4px)",
|
|
1137
|
+
zIndex: 1e3
|
|
1138
|
+
},
|
|
1139
|
+
feedbackRow: {
|
|
1140
|
+
display: "flex",
|
|
1141
|
+
alignItems: "center",
|
|
1142
|
+
gap: "0.5rem",
|
|
1143
|
+
marginTop: "0.5rem",
|
|
1144
|
+
marginLeft: "0.75rem"
|
|
1145
|
+
},
|
|
1146
|
+
feedbackButton: {
|
|
1147
|
+
backgroundColor: "transparent",
|
|
1148
|
+
border: "none",
|
|
1149
|
+
cursor: "pointer",
|
|
1150
|
+
padding: "6px",
|
|
1151
|
+
borderRadius: "6px",
|
|
1152
|
+
display: "flex",
|
|
1153
|
+
alignItems: "center",
|
|
1154
|
+
justifyContent: "center",
|
|
1155
|
+
transition: "background-color 0.2s"
|
|
1156
|
+
},
|
|
1157
|
+
warningBanner: {
|
|
1158
|
+
backgroundColor: "#fffbeb",
|
|
1159
|
+
color: "#b45309",
|
|
1160
|
+
border: "1px solid #fde68a",
|
|
1161
|
+
borderRadius: "0.375rem",
|
|
1162
|
+
padding: "0.25rem 0.5rem",
|
|
1163
|
+
fontSize: "0.6875rem",
|
|
1164
|
+
fontWeight: 500,
|
|
1165
|
+
textAlign: "center",
|
|
1166
|
+
margin: "0 0.5rem",
|
|
1167
|
+
flex: 1,
|
|
1168
|
+
display: "flex",
|
|
1169
|
+
alignItems: "center",
|
|
1170
|
+
justifyContent: "center"
|
|
1171
|
+
},
|
|
1172
|
+
insufficientConfigContainer: {
|
|
1173
|
+
flex: 1,
|
|
1174
|
+
display: "flex",
|
|
1175
|
+
flexDirection: "column",
|
|
1176
|
+
alignItems: "center",
|
|
1177
|
+
justifyContent: "center",
|
|
1178
|
+
padding: "2rem",
|
|
1179
|
+
textAlign: "center",
|
|
1180
|
+
backgroundColor: "#fff5f5",
|
|
1181
|
+
color: "#2d3748"
|
|
1182
|
+
},
|
|
1183
|
+
insufficientConfigIconContainer: {
|
|
1184
|
+
backgroundColor: "#fee2e2",
|
|
1185
|
+
padding: "1rem",
|
|
1186
|
+
borderRadius: "50%",
|
|
1187
|
+
marginBottom: "1rem",
|
|
1188
|
+
display: "flex",
|
|
1189
|
+
alignItems: "center",
|
|
1190
|
+
justifyContent: "center",
|
|
1191
|
+
boxShadow: "0 4px 6px -1px rgba(239, 68, 68, 0.1), 0 2px 4px -1px rgba(239, 68, 68, 0.06)"
|
|
1192
|
+
},
|
|
1193
|
+
insufficientConfigTitle: {
|
|
1194
|
+
fontSize: "1.25rem",
|
|
1195
|
+
fontWeight: 700,
|
|
1196
|
+
color: "#991b1b",
|
|
1197
|
+
marginBottom: "0.5rem"
|
|
1198
|
+
},
|
|
1199
|
+
insufficientConfigMessage: {
|
|
1200
|
+
fontSize: "0.875rem",
|
|
1201
|
+
color: "#7f1d1d",
|
|
1202
|
+
marginBottom: "1.5rem",
|
|
1203
|
+
lineHeight: "1.5",
|
|
1204
|
+
maxWidth: "280px"
|
|
1205
|
+
},
|
|
1206
|
+
insufficientConfigDetails: {
|
|
1207
|
+
backgroundColor: "white",
|
|
1208
|
+
border: "1px solid #fee2e2",
|
|
1209
|
+
borderRadius: "0.5rem",
|
|
1210
|
+
padding: "1rem",
|
|
1211
|
+
textAlign: "left",
|
|
1212
|
+
width: "100%",
|
|
1213
|
+
maxWidth: "300px",
|
|
1214
|
+
boxShadow: "0 1px 3px 0 rgba(0, 0, 0, 0.05)"
|
|
671
1215
|
}
|
|
672
1216
|
};
|
|
1217
|
+
var ANIMATION_STYLES = `
|
|
1218
|
+
@keyframes sh-fade-in {
|
|
1219
|
+
from {
|
|
1220
|
+
opacity: 0;
|
|
1221
|
+
transform: translate(-50%, -48%) scale(0.96);
|
|
1222
|
+
}
|
|
1223
|
+
to {
|
|
1224
|
+
opacity: 1;
|
|
1225
|
+
transform: translate(-50%, -50%) scale(1);
|
|
1226
|
+
}
|
|
1227
|
+
}
|
|
1228
|
+
@keyframes sh-fade-out {
|
|
1229
|
+
from {
|
|
1230
|
+
opacity: 1;
|
|
1231
|
+
transform: translate(-50%, -50%) scale(1);
|
|
1232
|
+
}
|
|
1233
|
+
to {
|
|
1234
|
+
opacity: 0;
|
|
1235
|
+
transform: translate(-50%, -48%) scale(0.96);
|
|
1236
|
+
}
|
|
1237
|
+
}
|
|
1238
|
+
@keyframes sh-backdrop-fade-in {
|
|
1239
|
+
from {
|
|
1240
|
+
opacity: 0;
|
|
1241
|
+
}
|
|
1242
|
+
to {
|
|
1243
|
+
opacity: 1;
|
|
1244
|
+
}
|
|
1245
|
+
}
|
|
1246
|
+
@keyframes sh-backdrop-fade-out {
|
|
1247
|
+
from {
|
|
1248
|
+
opacity: 1;
|
|
1249
|
+
}
|
|
1250
|
+
to {
|
|
1251
|
+
opacity: 0;
|
|
1252
|
+
}
|
|
1253
|
+
}
|
|
1254
|
+
.sh-dialog-animate {
|
|
1255
|
+
animation: sh-fade-in 0.22s cubic-bezier(0.16, 1, 0.3, 1) forwards;
|
|
1256
|
+
}
|
|
1257
|
+
.sh-dialog-animate-out {
|
|
1258
|
+
animation: sh-fade-out 0.2s cubic-bezier(0.16, 1, 0.3, 1) forwards;
|
|
1259
|
+
}
|
|
1260
|
+
.sh-backdrop-animate {
|
|
1261
|
+
animation: sh-backdrop-fade-in 0.18s ease-out forwards;
|
|
1262
|
+
}
|
|
1263
|
+
.sh-backdrop-animate-out {
|
|
1264
|
+
animation: sh-backdrop-fade-out 0.18s ease-out forwards;
|
|
1265
|
+
}
|
|
1266
|
+
.sh-feedback-btn {
|
|
1267
|
+
color: #a1a1aa;
|
|
1268
|
+
border-radius: 4px;
|
|
1269
|
+
transition: color 0.2s, background-color 0.2s;
|
|
1270
|
+
}
|
|
1271
|
+
.sh-feedback-btn:hover {
|
|
1272
|
+
background-color: #f4f4f5 !important;
|
|
1273
|
+
color: #3f3f46 !important;
|
|
1274
|
+
}
|
|
1275
|
+
.sh-header-btn {
|
|
1276
|
+
transition: all 0.2s;
|
|
1277
|
+
}
|
|
1278
|
+
.sh-header-btn:hover {
|
|
1279
|
+
background-color: #f9fafb !important;
|
|
1280
|
+
border-color: #d1d5db !important;
|
|
1281
|
+
}
|
|
1282
|
+
`;
|
|
673
1283
|
var TRANSLATIONS = {
|
|
674
1284
|
newChat: "New Chat",
|
|
675
1285
|
welcomeToShopPrompter: "Welcome to ShopPrompter",
|
|
676
1286
|
welcomeDescription: "I am your personal AI shopping assistant. Ask me anything about our products!",
|
|
677
1287
|
askMeAnything: "Ask me anything...",
|
|
678
1288
|
thinking: "Thinking...",
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
findByBudget: "Find by budget"
|
|
1289
|
+
findByBudget: "Find by budget",
|
|
1290
|
+
feedbackError: "We are sorry, but we could not process your feedback. Please try again later."
|
|
682
1291
|
};
|
|
683
1292
|
var ICONS = {
|
|
684
1293
|
chat: "https://cdn.jsdelivr.net/gh/lucide-icons/lucide@latest/icons/message-square.svg",
|
|
@@ -689,69 +1298,108 @@ var ICONS = {
|
|
|
689
1298
|
sendHorizontal: "https://cdn.jsdelivr.net/gh/lucide-icons/lucide@latest/icons/send-horizontal.svg"
|
|
690
1299
|
};
|
|
691
1300
|
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
|
-
|
|
699
|
-
);
|
|
700
|
-
const [service, setService] =
|
|
701
|
-
const [
|
|
702
|
-
|
|
1301
|
+
var _a, _b, _c, _d;
|
|
1302
|
+
const [input, setInput] = useState2(() => "");
|
|
1303
|
+
const [isLoading, setIsLoading] = useState2(() => false);
|
|
1304
|
+
const [error, setError] = useState2(() => null);
|
|
1305
|
+
const [chatMessages, setChatMessages] = useState2(() => []);
|
|
1306
|
+
const [showChat, setShowChat] = useState2(() => false);
|
|
1307
|
+
const [isClosing, setIsClosing] = useState2(() => false);
|
|
1308
|
+
const [closeTimeout, setCloseTimeout] = useState2(() => null);
|
|
1309
|
+
const [service, setService] = useState2(() => null);
|
|
1310
|
+
const [agentExperience, setAgentExperience] = useState2(() => null);
|
|
1311
|
+
const [animationClass, setAnimationClass] = useState2(() => "");
|
|
1312
|
+
const [backdropAnimationClass, setBackdropAnimationClass] = useState2(
|
|
1313
|
+
() => ""
|
|
703
1314
|
);
|
|
704
|
-
|
|
1315
|
+
function hasToken() {
|
|
1316
|
+
var _a2;
|
|
1317
|
+
const token = props.shopPrompterToken || ((_a2 = apiConfigObj == null ? void 0 : apiConfigObj()) == null ? void 0 : _a2.shopPrompterToken);
|
|
1318
|
+
return !!token;
|
|
1319
|
+
}
|
|
1320
|
+
function isConfigInsufficient() {
|
|
1321
|
+
var _a2, _b2;
|
|
1322
|
+
const token = props.shopPrompterToken || ((_a2 = apiConfigObj == null ? void 0 : apiConfigObj()) == null ? void 0 : _a2.shopPrompterToken);
|
|
1323
|
+
const apiKey = (_b2 = apiConfigObj == null ? void 0 : apiConfigObj()) == null ? void 0 : _b2.apiKey;
|
|
1324
|
+
return !token && !apiKey;
|
|
1325
|
+
}
|
|
1326
|
+
function themeObj() {
|
|
1327
|
+
if (typeof props.theme === "string") {
|
|
1328
|
+
try {
|
|
1329
|
+
return JSON.parse(props.theme);
|
|
1330
|
+
} catch (e) {
|
|
1331
|
+
return {};
|
|
1332
|
+
}
|
|
1333
|
+
}
|
|
1334
|
+
return props.theme || {};
|
|
1335
|
+
}
|
|
1336
|
+
function prompts() {
|
|
1337
|
+
return (agentExperience == null ? void 0 : agentExperience.predefinedPrompts) || [];
|
|
1338
|
+
}
|
|
1339
|
+
function apiConfigObj() {
|
|
1340
|
+
if (typeof props.apiConfig === "string") {
|
|
1341
|
+
try {
|
|
1342
|
+
return JSON.parse(props.apiConfig);
|
|
1343
|
+
} catch (e) {
|
|
1344
|
+
return null;
|
|
1345
|
+
}
|
|
1346
|
+
}
|
|
1347
|
+
return props.apiConfig || null;
|
|
1348
|
+
}
|
|
705
1349
|
function containerStyle() {
|
|
706
1350
|
const pos = props.chatPosition || "classic-chatbot";
|
|
707
1351
|
const isFull = pos === "full-page";
|
|
708
|
-
const
|
|
1352
|
+
const isDialog = pos === "dialog";
|
|
709
1353
|
const isClassic = pos === "classic-chatbot";
|
|
710
1354
|
const isRight = pos === "right-panel";
|
|
711
1355
|
return {
|
|
712
1356
|
position: isFull ? "relative" : "fixed",
|
|
713
|
-
bottom: isClassic ? "1rem" :
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
1357
|
+
bottom: isClassic ? "1rem" : isDialog ? "auto" : "0",
|
|
1358
|
+
top: isDialog ? "50%" : "auto",
|
|
1359
|
+
right: isClassic || isRight ? "1rem" : isDialog ? "auto" : "0",
|
|
1360
|
+
left: isDialog ? "50%" : isClassic || isRight || isFull ? "auto" : "0",
|
|
1361
|
+
transform: isDialog ? "translate(-50%, -50%)" : "none",
|
|
1362
|
+
width: isFull ? "100%" : isDialog ? "90%" : "24rem",
|
|
1363
|
+
height: isClassic ? "550px" : isDialog ? "700px" : isFull ? "600px" : "100%",
|
|
1364
|
+
maxWidth: isDialog ? "900px" : "none",
|
|
1365
|
+
maxHeight: isDialog ? "90vh" : "none",
|
|
1366
|
+
zIndex: isDialog ? 1001 : isClassic || isRight ? 1001 : 50,
|
|
1367
|
+
backgroundColor: themeObj().mainBackgroundColor || "white",
|
|
722
1368
|
display: "flex",
|
|
723
1369
|
flexDirection: "column",
|
|
724
1370
|
overflow: "hidden",
|
|
725
1371
|
borderRadius: isFull ? "0" : "0.5rem",
|
|
726
1372
|
border: isFull ? "none" : "1px solid #e5e7eb",
|
|
727
|
-
boxShadow: isFull ? "none" : "0 25px 50px -12px rgba(0, 0, 0, 0.25)"
|
|
1373
|
+
boxShadow: isFull ? "none" : "0 25px 50px -12px rgba(0, 0, 0, 0.25)",
|
|
1374
|
+
fontFamily: themeObj().fontFamily || void 0
|
|
728
1375
|
};
|
|
729
1376
|
}
|
|
730
1377
|
function containerClass() {
|
|
731
1378
|
const pos = props.chatPosition || "classic-chatbot";
|
|
732
1379
|
if (pos === "classic-chatbot") return "sh-classic";
|
|
733
1380
|
if (pos === "right-panel") return "sh-right";
|
|
734
|
-
if (pos === "
|
|
1381
|
+
if (pos === "dialog") {
|
|
1382
|
+
return "sh-dialog " + animationClass;
|
|
1383
|
+
}
|
|
735
1384
|
return "sh-full";
|
|
736
1385
|
}
|
|
737
1386
|
function messages() {
|
|
738
|
-
return chatMessages
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
1387
|
+
return chatMessages;
|
|
1388
|
+
}
|
|
1389
|
+
function parseMarkdown(content) {
|
|
1390
|
+
if (!content) return "";
|
|
1391
|
+
return String(marked.parse(content));
|
|
742
1392
|
}
|
|
743
1393
|
function showWelcome() {
|
|
744
1394
|
return chatMessages.length === 0;
|
|
745
1395
|
}
|
|
746
|
-
function
|
|
747
|
-
return
|
|
1396
|
+
function getShowProducts(message) {
|
|
1397
|
+
return message.productSkus && message.productSkus.length > 0;
|
|
748
1398
|
}
|
|
749
|
-
function
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
if (!input.trim() || isLoading) return;
|
|
754
|
-
const userQuery = input;
|
|
1399
|
+
function handleSend(overrideQuery) {
|
|
1400
|
+
const actualQuery = overrideQuery || input;
|
|
1401
|
+
if (!actualQuery.trim() || isLoading) return;
|
|
1402
|
+
const userQuery = actualQuery;
|
|
755
1403
|
setInput("");
|
|
756
1404
|
const userMsg = {
|
|
757
1405
|
id: Date.now().toString() + "-user",
|
|
@@ -759,30 +1407,45 @@ function ShopPrompter(props) {
|
|
|
759
1407
|
content: userQuery,
|
|
760
1408
|
productSkus: []
|
|
761
1409
|
};
|
|
762
|
-
setChatMessages([...chatMessages, userMsg]);
|
|
763
1410
|
const assistantMsg = {
|
|
764
1411
|
id: Date.now().toString() + "-assistant",
|
|
765
1412
|
role: "assistant",
|
|
766
1413
|
content: "",
|
|
767
1414
|
productSkus: []
|
|
768
1415
|
};
|
|
769
|
-
|
|
1416
|
+
let currentMessages = [...chatMessages, userMsg, assistantMsg];
|
|
1417
|
+
setChatMessages(currentMessages);
|
|
1418
|
+
setTimeout(() => {
|
|
1419
|
+
const inputEl = document.getElementById("shop-prompter-input");
|
|
1420
|
+
if (inputEl) {
|
|
1421
|
+
inputEl.value = "";
|
|
1422
|
+
inputEl.focus();
|
|
1423
|
+
}
|
|
1424
|
+
}, 0);
|
|
770
1425
|
service == null ? void 0 : service.sendMessage(
|
|
771
1426
|
userQuery,
|
|
772
1427
|
{
|
|
773
1428
|
onTextUpdate: (text) => {
|
|
774
|
-
const updatedMessages = [...
|
|
1429
|
+
const updatedMessages = [...currentMessages];
|
|
775
1430
|
const lastMsg = updatedMessages[updatedMessages.length - 1];
|
|
776
1431
|
if (lastMsg) {
|
|
777
|
-
|
|
1432
|
+
updatedMessages[updatedMessages.length - 1] = {
|
|
1433
|
+
...lastMsg,
|
|
1434
|
+
content: text
|
|
1435
|
+
};
|
|
1436
|
+
currentMessages = updatedMessages;
|
|
778
1437
|
setChatMessages(updatedMessages);
|
|
779
1438
|
}
|
|
780
1439
|
},
|
|
781
1440
|
onProductSkus: (skus) => {
|
|
782
|
-
const updatedMessages = [...
|
|
1441
|
+
const updatedMessages = [...currentMessages];
|
|
783
1442
|
const lastMsg = updatedMessages[updatedMessages.length - 1];
|
|
784
1443
|
if (lastMsg) {
|
|
785
|
-
|
|
1444
|
+
updatedMessages[updatedMessages.length - 1] = {
|
|
1445
|
+
...lastMsg,
|
|
1446
|
+
productSkus: skus
|
|
1447
|
+
};
|
|
1448
|
+
currentMessages = updatedMessages;
|
|
786
1449
|
setChatMessages(updatedMessages);
|
|
787
1450
|
}
|
|
788
1451
|
},
|
|
@@ -796,29 +1459,63 @@ function ShopPrompter(props) {
|
|
|
796
1459
|
if (props.onCartOperation) {
|
|
797
1460
|
props.onCartOperation(ops);
|
|
798
1461
|
}
|
|
1462
|
+
dispatchCartOperation(ops);
|
|
799
1463
|
}
|
|
800
1464
|
},
|
|
801
1465
|
props.cart || []
|
|
802
1466
|
);
|
|
803
1467
|
}
|
|
1468
|
+
function dispatchCartOperation(ops) {
|
|
1469
|
+
if (typeof window !== "undefined") {
|
|
1470
|
+
const root = typeof self !== "undefined" && self && "dispatchEvent" in self && !(self instanceof Window) ? self : null;
|
|
1471
|
+
if (root) {
|
|
1472
|
+
root.dispatchEvent(
|
|
1473
|
+
new CustomEvent("cartOperation", {
|
|
1474
|
+
detail: ops
|
|
1475
|
+
})
|
|
1476
|
+
);
|
|
1477
|
+
}
|
|
1478
|
+
}
|
|
1479
|
+
}
|
|
804
1480
|
function toggleChat() {
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
1481
|
+
if (showChat) {
|
|
1482
|
+
setIsClosing(true);
|
|
1483
|
+
setAnimationClass("sh-dialog-animate-out");
|
|
1484
|
+
setBackdropAnimationClass("sh-backdrop-animate-out");
|
|
1485
|
+
if (closeTimeout) {
|
|
1486
|
+
clearTimeout(closeTimeout);
|
|
1487
|
+
}
|
|
1488
|
+
setCloseTimeout(
|
|
1489
|
+
setTimeout(() => {
|
|
1490
|
+
setShowChat(false);
|
|
1491
|
+
setIsClosing(false);
|
|
1492
|
+
setAnimationClass("");
|
|
1493
|
+
setBackdropAnimationClass("");
|
|
1494
|
+
setCloseTimeout(null);
|
|
1495
|
+
if (props.onClose) {
|
|
1496
|
+
props.onClose();
|
|
1497
|
+
}
|
|
1498
|
+
}, 200)
|
|
1499
|
+
);
|
|
1500
|
+
} else {
|
|
1501
|
+
if (closeTimeout) {
|
|
1502
|
+
clearTimeout(closeTimeout);
|
|
1503
|
+
setCloseTimeout(null);
|
|
1504
|
+
}
|
|
1505
|
+
setShowChat(true);
|
|
1506
|
+
setIsClosing(false);
|
|
1507
|
+
setAnimationClass("sh-dialog-animate");
|
|
1508
|
+
setBackdropAnimationClass("sh-backdrop-animate");
|
|
1509
|
+
setTimeout(() => {
|
|
1510
|
+
setAnimationClass("");
|
|
1511
|
+
setBackdropAnimationClass("");
|
|
1512
|
+
}, 250);
|
|
808
1513
|
}
|
|
809
1514
|
}
|
|
810
1515
|
function handleNewChat() {
|
|
811
1516
|
setChatMessages([]);
|
|
812
1517
|
service == null ? void 0 : service.resetSession();
|
|
813
1518
|
}
|
|
814
|
-
function onPopularItemsClick() {
|
|
815
|
-
setInput(TRANSLATIONS.showPopularItems);
|
|
816
|
-
handleSend();
|
|
817
|
-
}
|
|
818
|
-
function onCompareProductsClick() {
|
|
819
|
-
setInput(TRANSLATIONS.compareProducts);
|
|
820
|
-
handleSend();
|
|
821
|
-
}
|
|
822
1519
|
function onInputChange(event) {
|
|
823
1520
|
setInput(event.target.value);
|
|
824
1521
|
}
|
|
@@ -827,49 +1524,196 @@ function ShopPrompter(props) {
|
|
|
827
1524
|
handleSend();
|
|
828
1525
|
}
|
|
829
1526
|
}
|
|
830
|
-
function
|
|
831
|
-
|
|
1527
|
+
function handleTriggerClick(e) {
|
|
1528
|
+
if (props.chatPosition !== "dialog") return;
|
|
1529
|
+
if (!props.dialogTrigger) return;
|
|
1530
|
+
const isTargetClicked = typeof props.dialogTrigger === "string" ? e.target.closest(props.dialogTrigger) : (() => {
|
|
1531
|
+
let target = null;
|
|
1532
|
+
if (typeof props.dialogTrigger === "object") {
|
|
1533
|
+
if ("current" in props.dialogTrigger) {
|
|
1534
|
+
target = props.dialogTrigger.current;
|
|
1535
|
+
} else {
|
|
1536
|
+
target = props.dialogTrigger;
|
|
1537
|
+
}
|
|
1538
|
+
}
|
|
1539
|
+
return target && target.contains && target.contains(e.target);
|
|
1540
|
+
})();
|
|
1541
|
+
if (isTargetClicked) {
|
|
1542
|
+
if (closeTimeout) {
|
|
1543
|
+
clearTimeout(closeTimeout);
|
|
1544
|
+
setCloseTimeout(null);
|
|
1545
|
+
}
|
|
1546
|
+
setShowChat(true);
|
|
1547
|
+
setIsClosing(false);
|
|
1548
|
+
setAnimationClass("sh-dialog-animate");
|
|
1549
|
+
setBackdropAnimationClass("sh-backdrop-animate");
|
|
1550
|
+
setTimeout(() => {
|
|
1551
|
+
setAnimationClass("");
|
|
1552
|
+
setBackdropAnimationClass("");
|
|
1553
|
+
}, 250);
|
|
1554
|
+
}
|
|
832
1555
|
}
|
|
833
|
-
function
|
|
834
|
-
|
|
1556
|
+
function loadCustomFont(fontFamily) {
|
|
1557
|
+
if (!fontFamily || typeof window === "undefined") return;
|
|
1558
|
+
const systemFonts = [
|
|
1559
|
+
"sans-serif",
|
|
1560
|
+
"serif",
|
|
1561
|
+
"monospace",
|
|
1562
|
+
"cursive",
|
|
1563
|
+
"fantasy",
|
|
1564
|
+
"system-ui",
|
|
1565
|
+
"-apple-system",
|
|
1566
|
+
"blinkmacsystemfont",
|
|
1567
|
+
"segoe ui",
|
|
1568
|
+
"roboto",
|
|
1569
|
+
"helvetica",
|
|
1570
|
+
"arial",
|
|
1571
|
+
"inherit"
|
|
1572
|
+
];
|
|
1573
|
+
const cleanFont = fontFamily.split(",")[0].trim().replace(new RegExp(`['"]`, "g"), "");
|
|
1574
|
+
if (!cleanFont || systemFonts.includes(cleanFont.toLowerCase())) return;
|
|
1575
|
+
const linkId = `shopprompter-font-${cleanFont.toLowerCase().replace(new RegExp("\\s+", "g"), "-")}`;
|
|
1576
|
+
if (document.getElementById(linkId)) return;
|
|
1577
|
+
const link = document.createElement("link");
|
|
1578
|
+
link.id = linkId;
|
|
1579
|
+
link.rel = "stylesheet";
|
|
1580
|
+
const fontNameUrl = cleanFont.replace(new RegExp("\\s+", "g"), "+");
|
|
1581
|
+
link.href = `https://fonts.googleapis.com/css2?family=${fontNameUrl}:wght@400;500;600;700&display=swap`;
|
|
1582
|
+
document.head.appendChild(link);
|
|
835
1583
|
}
|
|
836
|
-
function
|
|
1584
|
+
function loadAgentExperience() {
|
|
837
1585
|
void (async function() {
|
|
838
|
-
console.log("## ~ ShopPrompter ~ state.service:", service);
|
|
839
1586
|
if (!service) {
|
|
840
|
-
console.warn(
|
|
1587
|
+
console.warn(
|
|
1588
|
+
"Service not initialized yet! Cannot load AgentExperience."
|
|
1589
|
+
);
|
|
841
1590
|
return;
|
|
842
1591
|
}
|
|
843
1592
|
const response = await (service == null ? void 0 : service.getAgentExperience());
|
|
844
|
-
console.log("## ~ ShopPrompter ~ response:", response);
|
|
845
1593
|
setAgentExperience(response);
|
|
846
1594
|
})();
|
|
847
1595
|
}
|
|
848
|
-
|
|
849
|
-
const
|
|
850
|
-
|
|
1596
|
+
function handleFeedback(messageId, messageContent, newFeedback) {
|
|
1597
|
+
const msg = chatMessages.find((m) => m.id === messageId);
|
|
1598
|
+
if (!msg) return;
|
|
1599
|
+
const currentFeedback = msg.feedback;
|
|
1600
|
+
const targetFeedback = currentFeedback === newFeedback ? "clear" : newFeedback;
|
|
1601
|
+
const oldMessages = [...chatMessages];
|
|
1602
|
+
setChatMessages(
|
|
1603
|
+
chatMessages.map((m) => {
|
|
1604
|
+
if (m.id === messageId) {
|
|
1605
|
+
return {
|
|
1606
|
+
...m,
|
|
1607
|
+
feedback: targetFeedback === "clear" ? null : targetFeedback
|
|
1608
|
+
};
|
|
1609
|
+
}
|
|
1610
|
+
return m;
|
|
1611
|
+
})
|
|
1612
|
+
);
|
|
1613
|
+
setError(null);
|
|
1614
|
+
service == null ? void 0 : service.sendFeedback(messageId, messageContent, targetFeedback).catch((err) => {
|
|
1615
|
+
setChatMessages(oldMessages);
|
|
1616
|
+
setError((err == null ? void 0 : err.message) || TRANSLATIONS.feedbackError);
|
|
1617
|
+
});
|
|
1618
|
+
}
|
|
1619
|
+
function canShowFeedback(message) {
|
|
1620
|
+
if (message.role !== "assistant") return false;
|
|
1621
|
+
if (!message.content) return false;
|
|
1622
|
+
const lastMsg = chatMessages[chatMessages.length - 1];
|
|
1623
|
+
if (lastMsg && lastMsg.id === message.id && isLoading) {
|
|
1624
|
+
return false;
|
|
1625
|
+
}
|
|
1626
|
+
return true;
|
|
1627
|
+
}
|
|
1628
|
+
useEffect2(() => {
|
|
1629
|
+
if (typeof window !== "undefined" && !document.getElementById("lottie-player-script")) {
|
|
1630
|
+
const script = document.createElement("script");
|
|
1631
|
+
script.id = "lottie-player-script";
|
|
1632
|
+
script.src = "https://unpkg.com/@lottiefiles/lottie-player@latest/dist/lottie-player";
|
|
1633
|
+
document.head.appendChild(script);
|
|
1634
|
+
}
|
|
1635
|
+
if (themeObj().fontFamily) {
|
|
1636
|
+
loadCustomFont(themeObj().fontFamily);
|
|
1637
|
+
}
|
|
1638
|
+
if (apiConfigObj()) {
|
|
1639
|
+
if (!isConfigInsufficient()) {
|
|
1640
|
+
const apiConfig = {
|
|
1641
|
+
...apiConfigObj(),
|
|
1642
|
+
shopPrompterToken: props.shopPrompterToken || apiConfigObj().shopPrompterToken
|
|
1643
|
+
};
|
|
1644
|
+
const service2 = new ShopPrompterService(apiConfig);
|
|
1645
|
+
setService(service2);
|
|
1646
|
+
const savedMessages = service2.loadMessages();
|
|
1647
|
+
if (savedMessages.length > 0) {
|
|
1648
|
+
setChatMessages(savedMessages);
|
|
1649
|
+
}
|
|
1650
|
+
}
|
|
1651
|
+
} else {
|
|
1652
|
+
console.error("ShopPrompter: apiConfig prop is required!");
|
|
1653
|
+
}
|
|
1654
|
+
if ((props == null ? void 0 : props.chatPosition) === "right-panel" || (props == null ? void 0 : props.chatPosition) === "full-page") {
|
|
1655
|
+
setShowChat(true);
|
|
1656
|
+
}
|
|
1657
|
+
if (typeof window !== "undefined") {
|
|
1658
|
+
document.addEventListener("click", handleTriggerClick);
|
|
1659
|
+
}
|
|
851
1660
|
}, []);
|
|
852
|
-
|
|
1661
|
+
useEffect2(() => {
|
|
853
1662
|
if (service && !agentExperience) {
|
|
854
|
-
|
|
855
|
-
}
|
|
856
|
-
if (agentExperience) {
|
|
857
|
-
console.log("## ~ ShopPrompter ~ agentExperience updated:", {
|
|
858
|
-
greeting: agentExperience.greeting,
|
|
859
|
-
agentLogoUrl: agentExperience.agentLogoUrl
|
|
860
|
-
});
|
|
1663
|
+
loadAgentExperience();
|
|
861
1664
|
}
|
|
862
1665
|
}, [service, agentExperience]);
|
|
863
|
-
|
|
864
|
-
|
|
1666
|
+
useEffect2(() => {
|
|
1667
|
+
if (themeObj().fontFamily) {
|
|
1668
|
+
loadCustomFont(themeObj().fontFamily);
|
|
1669
|
+
}
|
|
1670
|
+
}, [themeObj().fontFamily || ""]);
|
|
1671
|
+
useEffect2(() => {
|
|
1672
|
+
if ((props == null ? void 0 : props.chatPosition) === "right-panel" || (props == null ? void 0 : props.chatPosition) === "full-page") {
|
|
1673
|
+
setShowChat(true);
|
|
1674
|
+
} else if ((props == null ? void 0 : props.chatPosition) === "dialog" || (props == null ? void 0 : props.chatPosition) === "classic-chatbot") {
|
|
1675
|
+
setShowChat(false);
|
|
1676
|
+
setIsClosing(false);
|
|
1677
|
+
setAnimationClass("");
|
|
1678
|
+
setBackdropAnimationClass("");
|
|
1679
|
+
}
|
|
1680
|
+
}, [(props == null ? void 0 : props.chatPosition) || ""]);
|
|
1681
|
+
return /* @__PURE__ */ jsxs4("div", { className: "shopprompter-sdk", children: [
|
|
1682
|
+
/* @__PURE__ */ jsx4("style", { dangerouslySetInnerHTML: { __html: ANIMATION_STYLES } }),
|
|
1683
|
+
/* @__PURE__ */ jsx4(
|
|
1684
|
+
"div",
|
|
1685
|
+
{
|
|
1686
|
+
onClick: (e) => toggleChat(),
|
|
1687
|
+
style: {
|
|
1688
|
+
...styles2.backdrop,
|
|
1689
|
+
display: props.chatPosition === "dialog" && (showChat || isClosing) ? "block" : "none"
|
|
1690
|
+
},
|
|
1691
|
+
className: backdropAnimationClass
|
|
1692
|
+
}
|
|
1693
|
+
),
|
|
1694
|
+
props.chatPosition === "classic-chatbot" ? /* @__PURE__ */ jsx4(Fragment2, { children: !showChat ? /* @__PURE__ */ jsx4(
|
|
865
1695
|
"button",
|
|
866
1696
|
{
|
|
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
1697
|
onClick: (e) => toggleChat(),
|
|
869
1698
|
style: {
|
|
870
|
-
|
|
1699
|
+
position: "fixed",
|
|
1700
|
+
bottom: "1.5rem",
|
|
1701
|
+
right: "1.5rem",
|
|
1702
|
+
width: "4rem",
|
|
1703
|
+
height: "4rem",
|
|
1704
|
+
backgroundColor: themeObj().actionColor || "#2563eb",
|
|
1705
|
+
borderRadius: "9999px",
|
|
1706
|
+
zIndex: 50,
|
|
1707
|
+
display: "flex",
|
|
1708
|
+
alignItems: "center",
|
|
1709
|
+
justifyContent: "center",
|
|
1710
|
+
transition: "background-color 0.2s",
|
|
1711
|
+
border: "none",
|
|
1712
|
+
cursor: "pointer",
|
|
1713
|
+
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)",
|
|
1714
|
+
fontFamily: themeObj().fontFamily || void 0
|
|
871
1715
|
},
|
|
872
|
-
children: /* @__PURE__ */
|
|
1716
|
+
children: /* @__PURE__ */ jsx4(
|
|
873
1717
|
"img",
|
|
874
1718
|
{
|
|
875
1719
|
alt: "Chat",
|
|
@@ -882,259 +1726,404 @@ function ShopPrompter(props) {
|
|
|
882
1726
|
)
|
|
883
1727
|
}
|
|
884
1728
|
) : 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"
|
|
1729
|
+
showChat || isClosing ? /* @__PURE__ */ jsxs4("div", { style: containerStyle(), className: containerClass(), children: [
|
|
1730
|
+
/* @__PURE__ */ jsxs4(
|
|
1731
|
+
"div",
|
|
1732
|
+
{
|
|
1733
|
+
style: {
|
|
1734
|
+
...styles2.header,
|
|
1735
|
+
backgroundColor: themeObj().headerBackgroundColor || "transparent"
|
|
1736
|
+
},
|
|
1737
|
+
children: [
|
|
1738
|
+
themeObj().showAgentName !== false ? /* @__PURE__ */ jsxs4("div", { style: styles2.subHeaderContainer, children: [
|
|
1739
|
+
(agentExperience == null ? void 0 : agentExperience.agentLogoUrl) ? /* @__PURE__ */ jsx4(
|
|
1740
|
+
"img",
|
|
1741
|
+
{
|
|
1742
|
+
src: agentExperience.agentLogoUrl,
|
|
1743
|
+
alt: agentExperience.agentName,
|
|
1744
|
+
style: {
|
|
1745
|
+
width: "24px",
|
|
1746
|
+
height: "24px",
|
|
1747
|
+
borderRadius: "4px",
|
|
1748
|
+
objectFit: "cover"
|
|
916
1749
|
}
|
|
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
|
-
|
|
1750
|
+
}
|
|
1751
|
+
) : null,
|
|
1752
|
+
(agentExperience == null ? void 0 : agentExperience.agentName) ? /* @__PURE__ */ jsx4("span", { style: styles2.headerText, children: agentExperience.agentName }) : null
|
|
1753
|
+
] }) : /* @__PURE__ */ jsx4(Fragment2, { children: /* @__PURE__ */ jsx4("div", { style: styles2.subHeaderContainer }) }),
|
|
1754
|
+
!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,
|
|
1755
|
+
/* @__PURE__ */ jsxs4("div", { style: styles2.subHeaderContainer, children: [
|
|
1756
|
+
/* @__PURE__ */ jsx4(
|
|
1757
|
+
"button",
|
|
1758
|
+
{
|
|
1759
|
+
className: "sh-header-btn",
|
|
1760
|
+
onClick: (e) => handleNewChat(),
|
|
1761
|
+
style: styles2.headerButton,
|
|
1762
|
+
children: TRANSLATIONS.newChat
|
|
1763
|
+
}
|
|
1764
|
+
),
|
|
1765
|
+
props.chatPosition === "classic-chatbot" || props.chatPosition === "right-panel" || props.chatPosition === "dialog" ? /* @__PURE__ */ jsx4(
|
|
1766
|
+
"button",
|
|
1767
|
+
{
|
|
1768
|
+
onClick: (e) => toggleChat(),
|
|
1769
|
+
style: styles2.ButtonSheetButton,
|
|
1770
|
+
children: "\xD7"
|
|
1771
|
+
}
|
|
1772
|
+
) : null
|
|
1773
|
+
] })
|
|
1774
|
+
]
|
|
1775
|
+
}
|
|
1776
|
+
),
|
|
1777
|
+
isConfigInsufficient() ? /* @__PURE__ */ jsxs4("div", { style: styles2.insufficientConfigContainer, children: [
|
|
1778
|
+
/* @__PURE__ */ jsx4("div", { style: styles2.insufficientConfigIconContainer, children: /* @__PURE__ */ jsxs4(
|
|
1779
|
+
"svg",
|
|
1780
|
+
{
|
|
1781
|
+
width: "48",
|
|
1782
|
+
height: "48",
|
|
1783
|
+
viewBox: "0 0 24 24",
|
|
1784
|
+
fill: "none",
|
|
1785
|
+
stroke: "currentColor",
|
|
1786
|
+
strokeWidth: "2",
|
|
1787
|
+
strokeLinecap: "round",
|
|
1788
|
+
strokeLinejoin: "round",
|
|
1789
|
+
style: {
|
|
1790
|
+
color: "#ef4444"
|
|
1791
|
+
},
|
|
1792
|
+
children: [
|
|
1793
|
+
/* @__PURE__ */ jsx4("rect", { x: "3", y: "11", width: "18", height: "11", rx: "2", ry: "2" }),
|
|
1794
|
+
/* @__PURE__ */ jsx4("path", { d: "M7 11V7a5 5 0 0 1 9.9-1" })
|
|
1795
|
+
]
|
|
1796
|
+
}
|
|
1797
|
+
) }),
|
|
1798
|
+
/* @__PURE__ */ jsx4(
|
|
1799
|
+
"h3",
|
|
1800
|
+
{
|
|
1801
|
+
style: {
|
|
1802
|
+
...styles2.insufficientConfigTitle,
|
|
1803
|
+
fontFamily: themeObj().fontFamily || void 0
|
|
1804
|
+
},
|
|
1805
|
+
children: "Configuration Error"
|
|
1806
|
+
}
|
|
1807
|
+
),
|
|
1808
|
+
/* @__PURE__ */ jsx4(
|
|
1809
|
+
"p",
|
|
1810
|
+
{
|
|
1811
|
+
style: {
|
|
1812
|
+
...styles2.insufficientConfigMessage,
|
|
1813
|
+
fontFamily: themeObj().fontFamily || void 0
|
|
1814
|
+
},
|
|
1815
|
+
children: "ShopPrompter requires a secure token or API key to initialize. Please check your setup."
|
|
1816
|
+
}
|
|
1817
|
+
),
|
|
1818
|
+
/* @__PURE__ */ jsxs4(
|
|
1819
|
+
"div",
|
|
1820
|
+
{
|
|
1821
|
+
style: {
|
|
1822
|
+
...styles2.insufficientConfigDetails,
|
|
1823
|
+
fontFamily: themeObj().fontFamily || void 0
|
|
1824
|
+
},
|
|
1825
|
+
children: [
|
|
1826
|
+
/* @__PURE__ */ jsx4(
|
|
1827
|
+
"div",
|
|
1828
|
+
{
|
|
1829
|
+
style: {
|
|
1830
|
+
fontWeight: 600,
|
|
1831
|
+
marginBottom: "0.25rem"
|
|
1832
|
+
},
|
|
1833
|
+
children: "Missing Parameters:"
|
|
1834
|
+
}
|
|
1835
|
+
),
|
|
1836
|
+
/* @__PURE__ */ jsxs4(
|
|
1837
|
+
"div",
|
|
1838
|
+
{
|
|
1839
|
+
style: {
|
|
1840
|
+
display: "flex",
|
|
1841
|
+
flexDirection: "column",
|
|
1842
|
+
gap: "0.25rem",
|
|
1843
|
+
fontFamily: "monospace",
|
|
1844
|
+
fontSize: "0.75rem"
|
|
1845
|
+
},
|
|
1846
|
+
children: [
|
|
1847
|
+
/* @__PURE__ */ jsx4(
|
|
1848
|
+
"span",
|
|
1849
|
+
{
|
|
1850
|
+
style: {
|
|
1851
|
+
color: "#ef4444"
|
|
1852
|
+
},
|
|
1853
|
+
children: "\u2717 shopPrompterToken (not found)"
|
|
1854
|
+
}
|
|
1855
|
+
),
|
|
1856
|
+
/* @__PURE__ */ jsx4(
|
|
1857
|
+
"span",
|
|
1858
|
+
{
|
|
1859
|
+
style: {
|
|
1860
|
+
color: "#ef4444"
|
|
1861
|
+
},
|
|
1862
|
+
children: "\u2717 apiConfig.apiKey (not found)"
|
|
1863
|
+
}
|
|
1864
|
+
)
|
|
1865
|
+
]
|
|
1866
|
+
}
|
|
1867
|
+
)
|
|
1868
|
+
]
|
|
1869
|
+
}
|
|
1870
|
+
)
|
|
1871
|
+
] }) : null,
|
|
1872
|
+
!isConfigInsufficient() ? /* @__PURE__ */ jsxs4(
|
|
1873
|
+
"div",
|
|
1874
|
+
{
|
|
1875
|
+
style: {
|
|
1876
|
+
display: "flex",
|
|
1877
|
+
flexDirection: "column",
|
|
1878
|
+
flex: 1,
|
|
1879
|
+
overflow: "hidden"
|
|
1880
|
+
},
|
|
1881
|
+
children: [
|
|
1882
|
+
/* @__PURE__ */ jsxs4(
|
|
1883
|
+
"div",
|
|
1884
|
+
{
|
|
1885
|
+
id: "shop-prompter-chat-container",
|
|
1886
|
+
style: {
|
|
1887
|
+
...styles2.chatContainer,
|
|
1888
|
+
backgroundColor: themeObj().mainBackgroundColor || styles2.chatContainer.backgroundColor
|
|
1889
|
+
},
|
|
1890
|
+
children: [
|
|
1891
|
+
showWelcome() ? /* @__PURE__ */ jsxs4("div", { style: styles2.welcomeContainer, children: [
|
|
1892
|
+
/* @__PURE__ */ jsx4(
|
|
1893
|
+
"img",
|
|
1894
|
+
{
|
|
1895
|
+
alt: "ShopPrompter",
|
|
1896
|
+
src: (agentExperience == null ? void 0 : agentExperience.agentLogoUrl) ? agentExperience.agentLogoUrl : ICONS.shopprompter,
|
|
1897
|
+
style: {
|
|
1898
|
+
width: "64px",
|
|
1899
|
+
height: "64px",
|
|
1900
|
+
marginBottom: "24px",
|
|
1901
|
+
borderRadius: "12px",
|
|
1902
|
+
objectFit: "cover"
|
|
1903
|
+
}
|
|
1904
|
+
}
|
|
1905
|
+
),
|
|
1906
|
+
/* @__PURE__ */ jsx4(
|
|
1907
|
+
"h3",
|
|
1908
|
+
{
|
|
1909
|
+
style: {
|
|
1910
|
+
...styles2.welcomeTitle,
|
|
1911
|
+
fontFamily: themeObj().fontFamily || styles2.welcomeTitle.fontFamily
|
|
1912
|
+
},
|
|
1913
|
+
children: ((_b = agentExperience == null ? void 0 : agentExperience.greeting) == null ? void 0 : _b.title) || TRANSLATIONS.welcomeToShopPrompter
|
|
1914
|
+
}
|
|
1915
|
+
),
|
|
1916
|
+
/* @__PURE__ */ jsx4(
|
|
1917
|
+
"p",
|
|
1918
|
+
{
|
|
1919
|
+
style: {
|
|
1920
|
+
...styles2.welcomeDescription,
|
|
1921
|
+
fontFamily: themeObj().fontFamily || styles2.welcomeDescription.fontFamily
|
|
1922
|
+
},
|
|
1923
|
+
children: ((_c = agentExperience == null ? void 0 : agentExperience.greeting) == null ? void 0 : _c.description) || TRANSLATIONS.welcomeDescription
|
|
1924
|
+
}
|
|
1925
|
+
),
|
|
1926
|
+
/* @__PURE__ */ jsx4("div", { style: styles2.buttonContainer, children: (_d = prompts()) == null ? void 0 : _d.map((item) => /* @__PURE__ */ jsx4(
|
|
1927
|
+
"button",
|
|
1928
|
+
{
|
|
1929
|
+
style: styles2.button,
|
|
1930
|
+
onClick: (event) => {
|
|
1931
|
+
setInput(item.prompt);
|
|
1932
|
+
handleSend(item.prompt);
|
|
1933
|
+
},
|
|
1934
|
+
children: item.prompt
|
|
1935
|
+
},
|
|
1936
|
+
item.prompt
|
|
1937
|
+
)) })
|
|
1938
|
+
] }) : null,
|
|
1939
|
+
!showWelcome() ? /* @__PURE__ */ jsx4(
|
|
1940
|
+
"div",
|
|
980
1941
|
{
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
1942
|
+
style: {
|
|
1943
|
+
width: "100%"
|
|
1944
|
+
},
|
|
1945
|
+
children: chatMessages == null ? void 0 : chatMessages.map((message) => /* @__PURE__ */ jsxs4("div", { children: [
|
|
1946
|
+
message.role === "user" ? /* @__PURE__ */ jsx4("div", { style: styles2.messageContainerUser, children: /* @__PURE__ */ jsx4(
|
|
1947
|
+
"div",
|
|
1948
|
+
{
|
|
1949
|
+
style: {
|
|
1950
|
+
...styles2.messageBubbleUser,
|
|
1951
|
+
backgroundColor: themeObj().userMessageBackgroundColor || styles2.messageBubbleUser.backgroundColor
|
|
1952
|
+
},
|
|
1953
|
+
children: message.content
|
|
1954
|
+
}
|
|
1955
|
+
) }) : null,
|
|
1956
|
+
message.role === "assistant" ? /* @__PURE__ */ jsxs4("div", { style: styles2.messageContainerAssistant, children: [
|
|
1957
|
+
/* @__PURE__ */ jsxs4(
|
|
1958
|
+
"div",
|
|
1959
|
+
{
|
|
1960
|
+
style: {
|
|
1961
|
+
...styles2.messageBubbleAssistant,
|
|
1962
|
+
backgroundColor: themeObj().assistantMessageBackgroundColor || styles2.messageBubbleAssistant.backgroundColor
|
|
1963
|
+
},
|
|
1964
|
+
children: [
|
|
1965
|
+
/* @__PURE__ */ jsx4(
|
|
1966
|
+
"div",
|
|
1967
|
+
{
|
|
1968
|
+
dangerouslySetInnerHTML: {
|
|
1969
|
+
__html: parseMarkdown(message.content)
|
|
1970
|
+
}
|
|
1971
|
+
}
|
|
1972
|
+
),
|
|
1973
|
+
!message.content && isLoading ? /* @__PURE__ */ jsx4(Fragment2, { children: (agentExperience == null ? void 0 : agentExperience.loadingIndicatorUrl) ? /* @__PURE__ */ jsx4(
|
|
1974
|
+
"lottie-player",
|
|
1975
|
+
{
|
|
1976
|
+
background: "transparent",
|
|
1977
|
+
speed: "1",
|
|
1978
|
+
src: agentExperience.loadingIndicatorUrl,
|
|
1979
|
+
style: {
|
|
1980
|
+
width: "40px",
|
|
1981
|
+
height: "40px"
|
|
1982
|
+
},
|
|
1983
|
+
loop: true,
|
|
1984
|
+
autoplay: true
|
|
1985
|
+
}
|
|
1986
|
+
) : /* @__PURE__ */ jsx4("div", { style: styles2.thinkingIndicator, children: /* @__PURE__ */ jsxs4(
|
|
1987
|
+
"svg",
|
|
1988
|
+
{
|
|
1989
|
+
width: "24",
|
|
1990
|
+
height: "24",
|
|
1991
|
+
viewBox: "0 0 24 24",
|
|
1992
|
+
fill: "none",
|
|
1993
|
+
stroke: "currentColor",
|
|
1994
|
+
strokeWidth: "2",
|
|
1995
|
+
strokeLinecap: "round",
|
|
1996
|
+
strokeLinejoin: "round",
|
|
1997
|
+
style: {
|
|
1998
|
+
color: "#6b7280"
|
|
1999
|
+
},
|
|
2000
|
+
children: [
|
|
2001
|
+
/* @__PURE__ */ jsx4("path", { d: THINKING_SPINNER }),
|
|
2002
|
+
/* @__PURE__ */ jsx4(
|
|
2003
|
+
"animateTransform",
|
|
2004
|
+
{
|
|
2005
|
+
attributeName: "transform",
|
|
2006
|
+
type: "rotate",
|
|
2007
|
+
from: "0 12 12",
|
|
2008
|
+
to: "360 12 12",
|
|
2009
|
+
dur: "1s",
|
|
2010
|
+
repeatCount: "indefinite"
|
|
2011
|
+
}
|
|
2012
|
+
)
|
|
2013
|
+
]
|
|
2014
|
+
}
|
|
2015
|
+
) }) }) : null
|
|
2016
|
+
]
|
|
2017
|
+
}
|
|
2018
|
+
),
|
|
2019
|
+
canShowFeedback(message) ? /* @__PURE__ */ jsxs4("div", { style: styles2.feedbackRow, children: [
|
|
2020
|
+
/* @__PURE__ */ jsx4(
|
|
2021
|
+
"button",
|
|
2022
|
+
{
|
|
2023
|
+
className: "sh-feedback-btn",
|
|
2024
|
+
onClick: (event) => handleFeedback(
|
|
2025
|
+
message.id,
|
|
2026
|
+
message.content,
|
|
2027
|
+
"upvote"
|
|
2028
|
+
),
|
|
2029
|
+
style: styles2.feedbackButton,
|
|
2030
|
+
children: /* @__PURE__ */ jsx4(
|
|
2031
|
+
thumbs_up_icon_component_default,
|
|
2032
|
+
{
|
|
2033
|
+
fill: message.feedback === "upvote" ? themeObj().actionColor || "#2563eb" : "none",
|
|
2034
|
+
stroke: message.feedback === "upvote" ? themeObj().actionColor || "#2563eb" : "currentColor"
|
|
2035
|
+
}
|
|
2036
|
+
)
|
|
2037
|
+
}
|
|
2038
|
+
),
|
|
2039
|
+
/* @__PURE__ */ jsx4(
|
|
2040
|
+
"button",
|
|
2041
|
+
{
|
|
2042
|
+
className: "sh-feedback-btn",
|
|
2043
|
+
onClick: (event) => handleFeedback(
|
|
2044
|
+
message.id,
|
|
2045
|
+
message.content,
|
|
2046
|
+
"downvote"
|
|
2047
|
+
),
|
|
2048
|
+
style: styles2.feedbackButton,
|
|
2049
|
+
children: /* @__PURE__ */ jsx4(
|
|
2050
|
+
thumbs_down_icon_component_default,
|
|
2051
|
+
{
|
|
2052
|
+
fill: message.feedback === "downvote" ? themeObj().actionColor || "#2563eb" : "none",
|
|
2053
|
+
stroke: message.feedback === "downvote" ? themeObj().actionColor || "#2563eb" : "currentColor"
|
|
2054
|
+
}
|
|
2055
|
+
)
|
|
2056
|
+
}
|
|
2057
|
+
)
|
|
2058
|
+
] }) : null,
|
|
2059
|
+
getShowProducts(message) ? /* @__PURE__ */ jsx4(
|
|
2060
|
+
product_card_list_component_default,
|
|
2061
|
+
{
|
|
2062
|
+
skus: message.productSkus,
|
|
2063
|
+
defaultLocale: props.defaultLocale
|
|
2064
|
+
}
|
|
2065
|
+
) : null
|
|
2066
|
+
] }) : null
|
|
2067
|
+
] }, message.id))
|
|
994
2068
|
}
|
|
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
|
|
2069
|
+
) : null,
|
|
2070
|
+
error ? /* @__PURE__ */ jsxs4("div", { style: styles2.errorContainer, children: [
|
|
2071
|
+
"Error: ",
|
|
2072
|
+
error
|
|
2073
|
+
] }) : null
|
|
2074
|
+
]
|
|
1049
2075
|
}
|
|
1050
2076
|
),
|
|
1051
|
-
/* @__PURE__ */
|
|
1052
|
-
"
|
|
2077
|
+
/* @__PURE__ */ jsxs4(
|
|
2078
|
+
"div",
|
|
1053
2079
|
{
|
|
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%"
|
|
2080
|
+
style: {
|
|
2081
|
+
...styles2.inputSection,
|
|
2082
|
+
backgroundColor: themeObj().mainBackgroundColor || styles2.inputSection.backgroundColor
|
|
2083
|
+
},
|
|
2084
|
+
children: [
|
|
2085
|
+
/* @__PURE__ */ jsxs4("div", { style: styles2.inputWrapper, children: [
|
|
2086
|
+
/* @__PURE__ */ jsx4(
|
|
2087
|
+
"input",
|
|
2088
|
+
{
|
|
2089
|
+
id: "shop-prompter-input",
|
|
2090
|
+
type: "text",
|
|
2091
|
+
style: styles2.input,
|
|
2092
|
+
placeholder: (agentExperience == null ? void 0 : agentExperience.hintText) || TRANSLATIONS.askMeAnything,
|
|
2093
|
+
value: input,
|
|
2094
|
+
onInput: (e) => onInputChange(e),
|
|
2095
|
+
onKeyDown: (e) => onInputKeyDown(e)
|
|
1086
2096
|
}
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
/* @__PURE__ */ jsx("p", { style: styles.productSku, children: sku }),
|
|
1091
|
-
/* @__PURE__ */ jsx(
|
|
1092
|
-
"a",
|
|
2097
|
+
),
|
|
2098
|
+
/* @__PURE__ */ jsx4(
|
|
2099
|
+
"button",
|
|
1093
2100
|
{
|
|
1094
|
-
|
|
1095
|
-
style:
|
|
1096
|
-
|
|
2101
|
+
onClick: (e) => handleSend(),
|
|
2102
|
+
style: {
|
|
2103
|
+
...styles2.formButton,
|
|
2104
|
+
...styles2.sendButton,
|
|
2105
|
+
backgroundColor: themeObj().actionColor || styles2.sendButton.backgroundColor
|
|
2106
|
+
},
|
|
2107
|
+
children: /* @__PURE__ */ jsx4(
|
|
2108
|
+
"img",
|
|
2109
|
+
{
|
|
2110
|
+
alt: "Send",
|
|
2111
|
+
src: ICONS.sendHorizontal,
|
|
2112
|
+
style: {
|
|
2113
|
+
padding: "4px"
|
|
2114
|
+
}
|
|
2115
|
+
}
|
|
2116
|
+
)
|
|
1097
2117
|
}
|
|
1098
2118
|
)
|
|
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
|
-
] })
|
|
2119
|
+
] }),
|
|
2120
|
+
/* @__PURE__ */ jsx4("p", { style: styles2.disclaimer, children: "AI content may be inaccurate." })
|
|
2121
|
+
]
|
|
2122
|
+
}
|
|
2123
|
+
)
|
|
2124
|
+
]
|
|
2125
|
+
}
|
|
2126
|
+
) : null
|
|
1138
2127
|
] }) : null
|
|
1139
2128
|
] });
|
|
1140
2129
|
}
|