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