@shop-prompter/react 0.1.1 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/index.js +1433 -373
- package/dist/index.mjs +1434 -374
- package/package.json +24 -23
- package/src/api/icons.ts +9 -0
- package/src/api/product-api.ts +121 -0
- package/src/api/session-handler.ts +153 -0
- package/src/api/shop-prompter-api.ts +58 -30
- package/src/api/shop-prompter.types.ts +3 -1
- package/src/product-card-list.component.jsx +271 -0
- package/src/shop-prompter.component.jsx +922 -276
- package/src/shop-prompter.service.ts +60 -18
- package/src/thumbs-down-icon.component.jsx +25 -0
- package/src/thumbs-up-icon.component.jsx +25 -0
package/dist/index.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,297 @@ 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
|
+
productDynamicField: {
|
|
804
|
+
fontSize: "0.6875rem",
|
|
805
|
+
color: "#6b7280",
|
|
806
|
+
margin: 0,
|
|
807
|
+
whiteSpace: "nowrap",
|
|
808
|
+
overflow: "hidden",
|
|
809
|
+
textOverflow: "ellipsis"
|
|
810
|
+
},
|
|
811
|
+
productPrice: {
|
|
812
|
+
fontSize: "0.8125rem",
|
|
813
|
+
fontWeight: 500,
|
|
814
|
+
color: "#4b5563",
|
|
815
|
+
margin: 0
|
|
816
|
+
},
|
|
817
|
+
statusContainer: {
|
|
818
|
+
padding: "0.5rem 0",
|
|
819
|
+
fontSize: "0.75rem",
|
|
820
|
+
color: "#6b7280",
|
|
821
|
+
display: "flex",
|
|
822
|
+
alignItems: "center",
|
|
823
|
+
gap: "0.5rem"
|
|
824
|
+
},
|
|
825
|
+
errorText: {
|
|
826
|
+
color: "#ef4444"
|
|
827
|
+
},
|
|
828
|
+
spinner: {
|
|
829
|
+
color: "#6b7280"
|
|
830
|
+
},
|
|
831
|
+
wrapper: {
|
|
832
|
+
width: "100%",
|
|
833
|
+
maxWidth: "100%",
|
|
834
|
+
boxSizing: "border-box",
|
|
835
|
+
overflow: "hidden"
|
|
836
|
+
}
|
|
837
|
+
};
|
|
838
|
+
function ProductCardList(props) {
|
|
839
|
+
const [products, setProducts] = (0, import_react.useState)(() => []);
|
|
840
|
+
const [loading, setLoading] = (0, import_react.useState)(() => false);
|
|
841
|
+
const [error, setError] = (0, import_react.useState)(() => null);
|
|
842
|
+
function fetchProducts() {
|
|
843
|
+
let skusList = props.skus;
|
|
844
|
+
if (typeof skusList === "string") {
|
|
845
|
+
skusList = skusList.split(",").map((s) => s.trim()).filter(Boolean);
|
|
846
|
+
}
|
|
847
|
+
if (!skusList || skusList.length === 0) {
|
|
848
|
+
setProducts([]);
|
|
849
|
+
setLoading(false);
|
|
850
|
+
return;
|
|
851
|
+
}
|
|
852
|
+
if (productApi.isCached(skusList)) {
|
|
853
|
+
setProducts(productApi.getCached(skusList));
|
|
854
|
+
setLoading(false);
|
|
855
|
+
setError(null);
|
|
856
|
+
return;
|
|
857
|
+
}
|
|
858
|
+
setLoading(true);
|
|
859
|
+
setError(null);
|
|
860
|
+
productApi.getProducts(skusList).then((data) => {
|
|
861
|
+
setProducts(data || []);
|
|
862
|
+
setLoading(false);
|
|
863
|
+
}).catch((err) => {
|
|
864
|
+
console.error("Failed to fetch products:", err);
|
|
865
|
+
setError((err == null ? void 0 : err.message) || "Failed to load products");
|
|
866
|
+
setLoading(false);
|
|
867
|
+
});
|
|
868
|
+
}
|
|
869
|
+
function getProductName(product) {
|
|
870
|
+
var _a;
|
|
871
|
+
const locale = props.defaultLocale || "de";
|
|
872
|
+
const localized = ((_a = product.localization) == null ? void 0 : _a[locale]) || Object.values(product.localization || {})[0];
|
|
873
|
+
return (localized == null ? void 0 : localized.name) || product.sku;
|
|
874
|
+
}
|
|
875
|
+
function showPriceIfEmptyVal() {
|
|
876
|
+
const val = props.showPriceIfEmpty;
|
|
877
|
+
if (typeof val === "string") {
|
|
878
|
+
return val === "true";
|
|
879
|
+
}
|
|
880
|
+
return val != null ? val : false;
|
|
881
|
+
}
|
|
882
|
+
function visibleFieldsList() {
|
|
883
|
+
const val = props.visibleFields;
|
|
884
|
+
if (typeof val === "string") {
|
|
885
|
+
try {
|
|
886
|
+
return JSON.parse(val);
|
|
887
|
+
} catch (e) {
|
|
888
|
+
return val.split(",").map((s) => s.trim()).filter(Boolean);
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
return val || [];
|
|
892
|
+
}
|
|
893
|
+
function getDynamicField(product, field) {
|
|
894
|
+
var _a;
|
|
895
|
+
const locale = props.defaultLocale || "de";
|
|
896
|
+
const localized = ((_a = product.localization) == null ? void 0 : _a[locale]) || Object.values(product.localization || {})[0];
|
|
897
|
+
if (!localized) return void 0;
|
|
898
|
+
const parts = field.split(".");
|
|
899
|
+
let current = localized;
|
|
900
|
+
for (let i = 0; i < parts.length; i++) {
|
|
901
|
+
if (current === void 0 || current === null) return void 0;
|
|
902
|
+
current = current[parts[i]];
|
|
903
|
+
}
|
|
904
|
+
return current;
|
|
905
|
+
}
|
|
906
|
+
function getProductPrice(product) {
|
|
907
|
+
if (!product.pricing) return "";
|
|
908
|
+
const priceVal = product.pricing.gross;
|
|
909
|
+
const currency = product.pricing.currency;
|
|
910
|
+
if (priceVal === void 0 || priceVal === null) return "";
|
|
911
|
+
if (priceVal === 0 && !showPriceIfEmptyVal()) return "";
|
|
912
|
+
return priceVal.toFixed(2) + " " + (currency || "\u20AC");
|
|
913
|
+
}
|
|
914
|
+
function getProductImage(product) {
|
|
915
|
+
var _a;
|
|
916
|
+
return ((_a = product.images) == null ? void 0 : _a[0]) || "https://placehold.co/150x150?text=" + product.sku;
|
|
917
|
+
}
|
|
918
|
+
(0, import_react.useEffect)(() => {
|
|
919
|
+
fetchProducts();
|
|
920
|
+
}, []);
|
|
921
|
+
(0, import_react.useEffect)(() => {
|
|
922
|
+
fetchProducts();
|
|
923
|
+
}, [
|
|
924
|
+
props.skus ? Array.isArray(props.skus) ? props.skus.join(",") : props.skus : ""
|
|
925
|
+
]);
|
|
926
|
+
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: [
|
|
927
|
+
loading ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: styles.statusContainer, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: "Loading products..." }) }) : null,
|
|
928
|
+
!loading && error ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: styles.statusContainer, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { style: styles.errorText, children: [
|
|
929
|
+
"Error: ",
|
|
930
|
+
error
|
|
931
|
+
] }) }) : null,
|
|
932
|
+
!loading && products && products.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: styles.productCardsContainer, children: products == null ? void 0 : products.map((product) => {
|
|
933
|
+
var _a;
|
|
934
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: styles.productCard, children: [
|
|
935
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: styles.productImageContainer, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
936
|
+
"img",
|
|
937
|
+
{
|
|
938
|
+
src: getProductImage(product),
|
|
939
|
+
alt: getProductName(product),
|
|
940
|
+
style: styles.productImage
|
|
941
|
+
}
|
|
942
|
+
) }),
|
|
943
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: styles.productInfo, children: [
|
|
944
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
945
|
+
"p",
|
|
946
|
+
{
|
|
947
|
+
style: styles.productName,
|
|
948
|
+
title: getProductName(product),
|
|
949
|
+
children: getProductName(product)
|
|
950
|
+
}
|
|
951
|
+
),
|
|
952
|
+
(_a = visibleFieldsList()) == null ? void 0 : _a.map(
|
|
953
|
+
(field) => getDynamicField(product, field) !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
954
|
+
"p",
|
|
955
|
+
{
|
|
956
|
+
style: styles.productDynamicField,
|
|
957
|
+
title: String(getDynamicField(product, field)),
|
|
958
|
+
children: String(getDynamicField(product, field))
|
|
959
|
+
}
|
|
960
|
+
) : null
|
|
961
|
+
),
|
|
962
|
+
getProductPrice(product) !== "" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { style: styles.productPrice, children: getProductPrice(product) }) : null
|
|
963
|
+
] })
|
|
964
|
+
] }, product.sku);
|
|
965
|
+
}) }) : null
|
|
966
|
+
] }) }) : null });
|
|
967
|
+
}
|
|
968
|
+
var product_card_list_component_default = ProductCardList;
|
|
969
|
+
|
|
970
|
+
// src/shop-prompter.component.jsx
|
|
971
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
972
|
+
var THINKING_SPINNER = "M21 12a9 9 0 1 1-6.219-8.56";
|
|
973
|
+
var styles2 = {
|
|
478
974
|
header: {
|
|
479
975
|
display: "flex",
|
|
480
976
|
alignItems: "center",
|
|
481
977
|
justifyContent: "space-between",
|
|
482
|
-
padding: "16px"
|
|
978
|
+
padding: "16px",
|
|
979
|
+
borderBottom: "1px solid #e5e7eb"
|
|
483
980
|
},
|
|
484
981
|
subHeaderContainer: {
|
|
485
982
|
display: "flex",
|
|
@@ -495,6 +992,7 @@ var styles = {
|
|
|
495
992
|
border: "none",
|
|
496
993
|
cursor: "pointer",
|
|
497
994
|
transition: "background-color 0.2s, color 0.2s",
|
|
995
|
+
fontFamily: "inherit",
|
|
498
996
|
onHover: {
|
|
499
997
|
backgroundColor: "hsl(220 14% 96%)",
|
|
500
998
|
color: "hsl(220 13% 13%)"
|
|
@@ -515,7 +1013,8 @@ var styles = {
|
|
|
515
1013
|
gap: "0.5rem",
|
|
516
1014
|
cursor: "pointer",
|
|
517
1015
|
fontSize: "0.875rem",
|
|
518
|
-
color: "#09090b"
|
|
1016
|
+
color: "#09090b",
|
|
1017
|
+
fontFamily: "inherit"
|
|
519
1018
|
},
|
|
520
1019
|
ButtonSheetButton: {
|
|
521
1020
|
color: "#6b7280",
|
|
@@ -524,11 +1023,13 @@ var styles = {
|
|
|
524
1023
|
cursor: "pointer",
|
|
525
1024
|
padding: "0.25rem",
|
|
526
1025
|
fontSize: "1.25rem",
|
|
527
|
-
transition: "color 0.2s"
|
|
1026
|
+
transition: "color 0.2s",
|
|
1027
|
+
fontFamily: "inherit"
|
|
528
1028
|
},
|
|
529
1029
|
chatContainer: {
|
|
530
1030
|
flex: 1,
|
|
531
1031
|
overflowY: "auto",
|
|
1032
|
+
overflowX: "hidden",
|
|
532
1033
|
padding: "1rem",
|
|
533
1034
|
backgroundColor: "white"
|
|
534
1035
|
},
|
|
@@ -574,12 +1075,17 @@ var styles = {
|
|
|
574
1075
|
messageContainerUser: {
|
|
575
1076
|
display: "flex",
|
|
576
1077
|
flexDirection: "column",
|
|
577
|
-
alignItems: "flex-end"
|
|
1078
|
+
alignItems: "flex-end",
|
|
1079
|
+
marginBottom: "8px"
|
|
578
1080
|
},
|
|
579
1081
|
messageContainerAssistant: {
|
|
580
1082
|
display: "flex",
|
|
581
1083
|
flexDirection: "column",
|
|
582
|
-
alignItems: "flex-start"
|
|
1084
|
+
alignItems: "flex-start",
|
|
1085
|
+
marginBottom: "8px",
|
|
1086
|
+
width: "100%",
|
|
1087
|
+
maxWidth: "100%",
|
|
1088
|
+
boxSizing: "border-box"
|
|
583
1089
|
},
|
|
584
1090
|
messageBubbleUser: {
|
|
585
1091
|
backgroundColor: "#111827",
|
|
@@ -589,7 +1095,8 @@ var styles = {
|
|
|
589
1095
|
padding: "0.5rem 1rem",
|
|
590
1096
|
fontSize: "0.875rem",
|
|
591
1097
|
boxShadow: "0 1px 2px 0 rgba(0, 0, 0, 0.05)",
|
|
592
|
-
maxWidth: "85%"
|
|
1098
|
+
maxWidth: "85%",
|
|
1099
|
+
textAlign: "left"
|
|
593
1100
|
},
|
|
594
1101
|
messageBubbleAssistant: {
|
|
595
1102
|
backgroundColor: "#f3f4f6",
|
|
@@ -599,7 +1106,8 @@ var styles = {
|
|
|
599
1106
|
padding: "0.5rem 1rem",
|
|
600
1107
|
fontSize: "0.875rem",
|
|
601
1108
|
boxShadow: "0 1px 2px 0 rgba(0, 0, 0, 0.05)",
|
|
602
|
-
maxWidth: "85%"
|
|
1109
|
+
maxWidth: "85%",
|
|
1110
|
+
textAlign: "left"
|
|
603
1111
|
},
|
|
604
1112
|
thinkingIndicator: {
|
|
605
1113
|
display: "flex",
|
|
@@ -681,7 +1189,8 @@ var styles = {
|
|
|
681
1189
|
outline: "none",
|
|
682
1190
|
fontSize: "0.875rem",
|
|
683
1191
|
color: "#111827",
|
|
684
|
-
padding: "0.25rem 0"
|
|
1192
|
+
padding: "0.25rem 0",
|
|
1193
|
+
fontFamily: "inherit"
|
|
685
1194
|
},
|
|
686
1195
|
formButton: {
|
|
687
1196
|
backgroundColor: "transparent",
|
|
@@ -694,7 +1203,8 @@ var styles = {
|
|
|
694
1203
|
fontWeight: "bold",
|
|
695
1204
|
border: "none",
|
|
696
1205
|
cursor: "pointer",
|
|
697
|
-
transition: "background-color 0.2s"
|
|
1206
|
+
transition: "background-color 0.2s",
|
|
1207
|
+
fontFamily: "inherit"
|
|
698
1208
|
},
|
|
699
1209
|
sendButton: {
|
|
700
1210
|
backgroundColor: "#AD59FF1A"
|
|
@@ -704,90 +1214,297 @@ var styles = {
|
|
|
704
1214
|
color: "#9ca3af",
|
|
705
1215
|
textAlign: "center",
|
|
706
1216
|
marginTop: "0.75rem"
|
|
1217
|
+
},
|
|
1218
|
+
backdrop: {
|
|
1219
|
+
position: "fixed",
|
|
1220
|
+
top: 0,
|
|
1221
|
+
left: 0,
|
|
1222
|
+
right: 0,
|
|
1223
|
+
bottom: 0,
|
|
1224
|
+
backgroundColor: "rgba(0, 0, 0, 0.5)",
|
|
1225
|
+
backdropFilter: "blur(4px)",
|
|
1226
|
+
zIndex: 1e3
|
|
1227
|
+
},
|
|
1228
|
+
feedbackRow: {
|
|
1229
|
+
display: "flex",
|
|
1230
|
+
alignItems: "center",
|
|
1231
|
+
gap: "0.5rem",
|
|
1232
|
+
marginTop: "0.5rem",
|
|
1233
|
+
marginLeft: "0.75rem"
|
|
1234
|
+
},
|
|
1235
|
+
feedbackButton: {
|
|
1236
|
+
backgroundColor: "transparent",
|
|
1237
|
+
border: "none",
|
|
1238
|
+
cursor: "pointer",
|
|
1239
|
+
padding: "6px",
|
|
1240
|
+
borderRadius: "6px",
|
|
1241
|
+
display: "flex",
|
|
1242
|
+
alignItems: "center",
|
|
1243
|
+
justifyContent: "center",
|
|
1244
|
+
transition: "background-color 0.2s"
|
|
1245
|
+
},
|
|
1246
|
+
warningBanner: {
|
|
1247
|
+
backgroundColor: "#fffbeb",
|
|
1248
|
+
color: "#b45309",
|
|
1249
|
+
border: "1px solid #fde68a",
|
|
1250
|
+
borderRadius: "0.375rem",
|
|
1251
|
+
padding: "0.25rem 0.5rem",
|
|
1252
|
+
fontSize: "0.6875rem",
|
|
1253
|
+
fontWeight: 500,
|
|
1254
|
+
textAlign: "center",
|
|
1255
|
+
margin: "0 0.5rem",
|
|
1256
|
+
flex: 1,
|
|
1257
|
+
display: "flex",
|
|
1258
|
+
alignItems: "center",
|
|
1259
|
+
justifyContent: "center"
|
|
1260
|
+
},
|
|
1261
|
+
insufficientConfigContainer: {
|
|
1262
|
+
flex: 1,
|
|
1263
|
+
display: "flex",
|
|
1264
|
+
flexDirection: "column",
|
|
1265
|
+
alignItems: "center",
|
|
1266
|
+
justifyContent: "center",
|
|
1267
|
+
padding: "2rem",
|
|
1268
|
+
textAlign: "center",
|
|
1269
|
+
backgroundColor: "#fff5f5",
|
|
1270
|
+
color: "#2d3748"
|
|
1271
|
+
},
|
|
1272
|
+
insufficientConfigIconContainer: {
|
|
1273
|
+
backgroundColor: "#fee2e2",
|
|
1274
|
+
padding: "1rem",
|
|
1275
|
+
borderRadius: "50%",
|
|
1276
|
+
marginBottom: "1rem",
|
|
1277
|
+
display: "flex",
|
|
1278
|
+
alignItems: "center",
|
|
1279
|
+
justifyContent: "center",
|
|
1280
|
+
boxShadow: "0 4px 6px -1px rgba(239, 68, 68, 0.1), 0 2px 4px -1px rgba(239, 68, 68, 0.06)"
|
|
1281
|
+
},
|
|
1282
|
+
insufficientConfigTitle: {
|
|
1283
|
+
fontSize: "1.25rem",
|
|
1284
|
+
fontWeight: 700,
|
|
1285
|
+
color: "#991b1b",
|
|
1286
|
+
marginBottom: "0.5rem"
|
|
1287
|
+
},
|
|
1288
|
+
insufficientConfigMessage: {
|
|
1289
|
+
fontSize: "0.875rem",
|
|
1290
|
+
color: "#7f1d1d",
|
|
1291
|
+
marginBottom: "1.5rem",
|
|
1292
|
+
lineHeight: "1.5",
|
|
1293
|
+
maxWidth: "280px"
|
|
1294
|
+
},
|
|
1295
|
+
insufficientConfigDetails: {
|
|
1296
|
+
backgroundColor: "white",
|
|
1297
|
+
border: "1px solid #fee2e2",
|
|
1298
|
+
borderRadius: "0.5rem",
|
|
1299
|
+
padding: "1rem",
|
|
1300
|
+
textAlign: "left",
|
|
1301
|
+
width: "100%",
|
|
1302
|
+
maxWidth: "300px",
|
|
1303
|
+
boxShadow: "0 1px 3px 0 rgba(0, 0, 0, 0.05)"
|
|
707
1304
|
}
|
|
708
1305
|
};
|
|
1306
|
+
var ANIMATION_STYLES = `
|
|
1307
|
+
@keyframes sh-fade-in {
|
|
1308
|
+
from {
|
|
1309
|
+
opacity: 0;
|
|
1310
|
+
transform: translate(-50%, -48%) scale(0.96);
|
|
1311
|
+
}
|
|
1312
|
+
to {
|
|
1313
|
+
opacity: 1;
|
|
1314
|
+
transform: translate(-50%, -50%) scale(1);
|
|
1315
|
+
}
|
|
1316
|
+
}
|
|
1317
|
+
@keyframes sh-fade-out {
|
|
1318
|
+
from {
|
|
1319
|
+
opacity: 1;
|
|
1320
|
+
transform: translate(-50%, -50%) scale(1);
|
|
1321
|
+
}
|
|
1322
|
+
to {
|
|
1323
|
+
opacity: 0;
|
|
1324
|
+
transform: translate(-50%, -48%) scale(0.96);
|
|
1325
|
+
}
|
|
1326
|
+
}
|
|
1327
|
+
@keyframes sh-backdrop-fade-in {
|
|
1328
|
+
from {
|
|
1329
|
+
opacity: 0;
|
|
1330
|
+
}
|
|
1331
|
+
to {
|
|
1332
|
+
opacity: 1;
|
|
1333
|
+
}
|
|
1334
|
+
}
|
|
1335
|
+
@keyframes sh-backdrop-fade-out {
|
|
1336
|
+
from {
|
|
1337
|
+
opacity: 1;
|
|
1338
|
+
}
|
|
1339
|
+
to {
|
|
1340
|
+
opacity: 0;
|
|
1341
|
+
}
|
|
1342
|
+
}
|
|
1343
|
+
.sh-dialog-animate {
|
|
1344
|
+
animation: sh-fade-in 0.22s cubic-bezier(0.16, 1, 0.3, 1) forwards;
|
|
1345
|
+
}
|
|
1346
|
+
.sh-dialog-animate-out {
|
|
1347
|
+
animation: sh-fade-out 0.2s cubic-bezier(0.16, 1, 0.3, 1) forwards;
|
|
1348
|
+
}
|
|
1349
|
+
.sh-backdrop-animate {
|
|
1350
|
+
animation: sh-backdrop-fade-in 0.18s ease-out forwards;
|
|
1351
|
+
}
|
|
1352
|
+
.sh-backdrop-animate-out {
|
|
1353
|
+
animation: sh-backdrop-fade-out 0.18s ease-out forwards;
|
|
1354
|
+
}
|
|
1355
|
+
.sh-feedback-btn {
|
|
1356
|
+
color: #a1a1aa;
|
|
1357
|
+
border-radius: 4px;
|
|
1358
|
+
transition: color 0.2s, background-color 0.2s;
|
|
1359
|
+
}
|
|
1360
|
+
.sh-feedback-btn:hover {
|
|
1361
|
+
background-color: #f4f4f5 !important;
|
|
1362
|
+
color: #3f3f46 !important;
|
|
1363
|
+
}
|
|
1364
|
+
.sh-header-btn {
|
|
1365
|
+
transition: all 0.2s;
|
|
1366
|
+
}
|
|
1367
|
+
.sh-header-btn:hover {
|
|
1368
|
+
background-color: #f9fafb !important;
|
|
1369
|
+
border-color: #d1d5db !important;
|
|
1370
|
+
}
|
|
1371
|
+
`;
|
|
709
1372
|
var TRANSLATIONS = {
|
|
710
1373
|
newChat: "New Chat",
|
|
711
1374
|
welcomeToShopPrompter: "Welcome to ShopPrompter",
|
|
712
1375
|
welcomeDescription: "I am your personal AI shopping assistant. Ask me anything about our products!",
|
|
713
1376
|
askMeAnything: "Ask me anything...",
|
|
714
1377
|
thinking: "Thinking...",
|
|
715
|
-
|
|
716
|
-
compareProducts: "Compare products",
|
|
717
|
-
findByBudget: "Find by budget"
|
|
1378
|
+
feedbackError: "We are sorry, but we could not process your feedback. Please try again later."
|
|
718
1379
|
};
|
|
719
1380
|
var ICONS = {
|
|
720
1381
|
chat: "https://cdn.jsdelivr.net/gh/lucide-icons/lucide@latest/icons/message-square.svg",
|
|
721
1382
|
shopprompter: "https://cdn.jsdelivr.net/gh/lucide-icons/lucide@latest/icons/bot.svg",
|
|
722
1383
|
popularitems: "https://cdn.jsdelivr.net/gh/lucide-icons/lucide@latest/icons/fire.svg",
|
|
723
1384
|
compareproducts: "https://cdn.jsdelivr.net/gh/lucide-icons/lucide@latest/icons/box.svg",
|
|
724
|
-
findbybudget: "https://cdn.jsdelivr.net/gh/lucide-icons/lucide@latest/icons/foto.svg",
|
|
725
1385
|
sendHorizontal: "https://cdn.jsdelivr.net/gh/lucide-icons/lucide@latest/icons/send-horizontal.svg"
|
|
726
1386
|
};
|
|
727
1387
|
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
|
-
|
|
1388
|
+
var _a, _b, _c, _d;
|
|
1389
|
+
const [input, setInput] = (0, import_react2.useState)(() => "");
|
|
1390
|
+
const [isLoading, setIsLoading] = (0, import_react2.useState)(() => false);
|
|
1391
|
+
const [error, setError] = (0, import_react2.useState)(() => null);
|
|
1392
|
+
const [chatMessages, setChatMessages] = (0, import_react2.useState)(() => []);
|
|
1393
|
+
const [showChat, setShowChat] = (0, import_react2.useState)(() => false);
|
|
1394
|
+
const [isClosing, setIsClosing] = (0, import_react2.useState)(() => false);
|
|
1395
|
+
const [closeTimeout, setCloseTimeout] = (0, import_react2.useState)(() => null);
|
|
1396
|
+
const [service, setService] = (0, import_react2.useState)(() => null);
|
|
1397
|
+
const [agentExperience, setAgentExperience] = (0, import_react2.useState)(() => null);
|
|
1398
|
+
const [animationClass, setAnimationClass] = (0, import_react2.useState)(() => "");
|
|
1399
|
+
const [backdropAnimationClass, setBackdropAnimationClass] = (0, import_react2.useState)(
|
|
1400
|
+
() => ""
|
|
735
1401
|
);
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
()
|
|
739
|
-
|
|
740
|
-
|
|
1402
|
+
function hasToken() {
|
|
1403
|
+
var _a2;
|
|
1404
|
+
const token = props.shopPrompterToken || ((_a2 = apiConfigObj == null ? void 0 : apiConfigObj()) == null ? void 0 : _a2.shopPrompterToken);
|
|
1405
|
+
return !!token;
|
|
1406
|
+
}
|
|
1407
|
+
function isConfigInsufficient() {
|
|
1408
|
+
var _a2, _b2;
|
|
1409
|
+
const token = props.shopPrompterToken || ((_a2 = apiConfigObj == null ? void 0 : apiConfigObj()) == null ? void 0 : _a2.shopPrompterToken);
|
|
1410
|
+
const apiKey = (_b2 = apiConfigObj == null ? void 0 : apiConfigObj()) == null ? void 0 : _b2.apiKey;
|
|
1411
|
+
return !token && !apiKey;
|
|
1412
|
+
}
|
|
1413
|
+
function showPriceIfEmptyVal() {
|
|
1414
|
+
const val = props.showPriceIfEmpty;
|
|
1415
|
+
if (typeof val === "string") {
|
|
1416
|
+
return val === "true";
|
|
1417
|
+
}
|
|
1418
|
+
return val != null ? val : false;
|
|
1419
|
+
}
|
|
1420
|
+
function visibleFieldsList() {
|
|
1421
|
+
const val = props.visibleFields;
|
|
1422
|
+
if (typeof val === "string") {
|
|
1423
|
+
try {
|
|
1424
|
+
return JSON.parse(val);
|
|
1425
|
+
} catch (e) {
|
|
1426
|
+
return val.split(",").map((s) => s.trim()).filter(Boolean);
|
|
1427
|
+
}
|
|
1428
|
+
}
|
|
1429
|
+
return val || [];
|
|
1430
|
+
}
|
|
1431
|
+
function themeObj() {
|
|
1432
|
+
if (typeof props.theme === "string") {
|
|
1433
|
+
try {
|
|
1434
|
+
return JSON.parse(props.theme);
|
|
1435
|
+
} catch (e) {
|
|
1436
|
+
return {};
|
|
1437
|
+
}
|
|
1438
|
+
}
|
|
1439
|
+
return props.theme || {};
|
|
1440
|
+
}
|
|
1441
|
+
function prompts() {
|
|
1442
|
+
return (agentExperience == null ? void 0 : agentExperience.predefinedPrompts) || [];
|
|
1443
|
+
}
|
|
1444
|
+
function apiConfigObj() {
|
|
1445
|
+
if (typeof props.apiConfig === "string") {
|
|
1446
|
+
try {
|
|
1447
|
+
return JSON.parse(props.apiConfig);
|
|
1448
|
+
} catch (e) {
|
|
1449
|
+
return null;
|
|
1450
|
+
}
|
|
1451
|
+
}
|
|
1452
|
+
return props.apiConfig || null;
|
|
1453
|
+
}
|
|
741
1454
|
function containerStyle() {
|
|
742
1455
|
const pos = props.chatPosition || "classic-chatbot";
|
|
743
1456
|
const isFull = pos === "full-page";
|
|
744
|
-
const
|
|
1457
|
+
const isDialog = pos === "dialog";
|
|
745
1458
|
const isClassic = pos === "classic-chatbot";
|
|
746
1459
|
const isRight = pos === "right-panel";
|
|
747
1460
|
return {
|
|
748
1461
|
position: isFull ? "relative" : "fixed",
|
|
749
|
-
bottom: isClassic ? "1rem" :
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
1462
|
+
bottom: isClassic ? "1rem" : isDialog ? "auto" : "0",
|
|
1463
|
+
top: isDialog ? "50%" : "auto",
|
|
1464
|
+
right: isClassic || isRight ? "1rem" : isDialog ? "auto" : "0",
|
|
1465
|
+
left: isDialog ? "50%" : isClassic || isRight || isFull ? "auto" : "0",
|
|
1466
|
+
transform: isDialog ? "translate(-50%, -50%)" : "none",
|
|
1467
|
+
width: isFull ? "100%" : isDialog ? "90%" : "24rem",
|
|
1468
|
+
height: isClassic ? "550px" : isDialog ? "700px" : isFull ? "600px" : "100%",
|
|
1469
|
+
maxWidth: isDialog ? "900px" : "none",
|
|
1470
|
+
maxHeight: isDialog ? "90vh" : "none",
|
|
1471
|
+
zIndex: isDialog ? 1001 : isClassic || isRight ? 1001 : 50,
|
|
1472
|
+
backgroundColor: themeObj().mainBackgroundColor || "white",
|
|
758
1473
|
display: "flex",
|
|
759
1474
|
flexDirection: "column",
|
|
760
1475
|
overflow: "hidden",
|
|
761
1476
|
borderRadius: isFull ? "0" : "0.5rem",
|
|
762
1477
|
border: isFull ? "none" : "1px solid #e5e7eb",
|
|
763
|
-
boxShadow: isFull ? "none" : "0 25px 50px -12px rgba(0, 0, 0, 0.25)"
|
|
1478
|
+
boxShadow: isFull ? "none" : "0 25px 50px -12px rgba(0, 0, 0, 0.25)",
|
|
1479
|
+
fontFamily: themeObj().fontFamily || void 0
|
|
764
1480
|
};
|
|
765
1481
|
}
|
|
766
1482
|
function containerClass() {
|
|
767
1483
|
const pos = props.chatPosition || "classic-chatbot";
|
|
768
1484
|
if (pos === "classic-chatbot") return "sh-classic";
|
|
769
1485
|
if (pos === "right-panel") return "sh-right";
|
|
770
|
-
if (pos === "
|
|
1486
|
+
if (pos === "dialog") {
|
|
1487
|
+
return "sh-dialog " + animationClass;
|
|
1488
|
+
}
|
|
771
1489
|
return "sh-full";
|
|
772
1490
|
}
|
|
773
1491
|
function messages() {
|
|
774
|
-
return chatMessages
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
1492
|
+
return chatMessages;
|
|
1493
|
+
}
|
|
1494
|
+
function parseMarkdown(content) {
|
|
1495
|
+
if (!content) return "";
|
|
1496
|
+
return String(import_marked.marked.parse(content));
|
|
778
1497
|
}
|
|
779
1498
|
function showWelcome() {
|
|
780
1499
|
return chatMessages.length === 0;
|
|
781
1500
|
}
|
|
782
|
-
function
|
|
783
|
-
return
|
|
1501
|
+
function getShowProducts(message) {
|
|
1502
|
+
return message.productSkus && message.productSkus.length > 0;
|
|
784
1503
|
}
|
|
785
|
-
function
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
if (!input.trim() || isLoading) return;
|
|
790
|
-
const userQuery = input;
|
|
1504
|
+
function handleSend(overrideQuery) {
|
|
1505
|
+
const actualQuery = overrideQuery || input;
|
|
1506
|
+
if (!actualQuery.trim() || isLoading) return;
|
|
1507
|
+
const userQuery = actualQuery;
|
|
791
1508
|
setInput("");
|
|
792
1509
|
const userMsg = {
|
|
793
1510
|
id: Date.now().toString() + "-user",
|
|
@@ -795,30 +1512,45 @@ function ShopPrompter(props) {
|
|
|
795
1512
|
content: userQuery,
|
|
796
1513
|
productSkus: []
|
|
797
1514
|
};
|
|
798
|
-
setChatMessages([...chatMessages, userMsg]);
|
|
799
1515
|
const assistantMsg = {
|
|
800
1516
|
id: Date.now().toString() + "-assistant",
|
|
801
1517
|
role: "assistant",
|
|
802
1518
|
content: "",
|
|
803
1519
|
productSkus: []
|
|
804
1520
|
};
|
|
805
|
-
|
|
1521
|
+
let currentMessages = [...chatMessages, userMsg, assistantMsg];
|
|
1522
|
+
setChatMessages(currentMessages);
|
|
1523
|
+
setTimeout(() => {
|
|
1524
|
+
const inputEl = document.getElementById("shop-prompter-input");
|
|
1525
|
+
if (inputEl) {
|
|
1526
|
+
inputEl.value = "";
|
|
1527
|
+
inputEl.focus();
|
|
1528
|
+
}
|
|
1529
|
+
}, 0);
|
|
806
1530
|
service == null ? void 0 : service.sendMessage(
|
|
807
1531
|
userQuery,
|
|
808
1532
|
{
|
|
809
1533
|
onTextUpdate: (text) => {
|
|
810
|
-
const updatedMessages = [...
|
|
1534
|
+
const updatedMessages = [...currentMessages];
|
|
811
1535
|
const lastMsg = updatedMessages[updatedMessages.length - 1];
|
|
812
1536
|
if (lastMsg) {
|
|
813
|
-
|
|
1537
|
+
updatedMessages[updatedMessages.length - 1] = {
|
|
1538
|
+
...lastMsg,
|
|
1539
|
+
content: text
|
|
1540
|
+
};
|
|
1541
|
+
currentMessages = updatedMessages;
|
|
814
1542
|
setChatMessages(updatedMessages);
|
|
815
1543
|
}
|
|
816
1544
|
},
|
|
817
1545
|
onProductSkus: (skus) => {
|
|
818
|
-
const updatedMessages = [...
|
|
1546
|
+
const updatedMessages = [...currentMessages];
|
|
819
1547
|
const lastMsg = updatedMessages[updatedMessages.length - 1];
|
|
820
1548
|
if (lastMsg) {
|
|
821
|
-
|
|
1549
|
+
updatedMessages[updatedMessages.length - 1] = {
|
|
1550
|
+
...lastMsg,
|
|
1551
|
+
productSkus: skus
|
|
1552
|
+
};
|
|
1553
|
+
currentMessages = updatedMessages;
|
|
822
1554
|
setChatMessages(updatedMessages);
|
|
823
1555
|
}
|
|
824
1556
|
},
|
|
@@ -832,29 +1564,63 @@ function ShopPrompter(props) {
|
|
|
832
1564
|
if (props.onCartOperation) {
|
|
833
1565
|
props.onCartOperation(ops);
|
|
834
1566
|
}
|
|
1567
|
+
dispatchCartOperation(ops);
|
|
835
1568
|
}
|
|
836
1569
|
},
|
|
837
1570
|
props.cart || []
|
|
838
1571
|
);
|
|
839
1572
|
}
|
|
1573
|
+
function dispatchCartOperation(ops) {
|
|
1574
|
+
if (typeof window !== "undefined") {
|
|
1575
|
+
const root = typeof self !== "undefined" && self && "dispatchEvent" in self && !(self instanceof Window) ? self : null;
|
|
1576
|
+
if (root) {
|
|
1577
|
+
root.dispatchEvent(
|
|
1578
|
+
new CustomEvent("cartOperation", {
|
|
1579
|
+
detail: ops
|
|
1580
|
+
})
|
|
1581
|
+
);
|
|
1582
|
+
}
|
|
1583
|
+
}
|
|
1584
|
+
}
|
|
840
1585
|
function toggleChat() {
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
1586
|
+
if (showChat) {
|
|
1587
|
+
setIsClosing(true);
|
|
1588
|
+
setAnimationClass("sh-dialog-animate-out");
|
|
1589
|
+
setBackdropAnimationClass("sh-backdrop-animate-out");
|
|
1590
|
+
if (closeTimeout) {
|
|
1591
|
+
clearTimeout(closeTimeout);
|
|
1592
|
+
}
|
|
1593
|
+
setCloseTimeout(
|
|
1594
|
+
setTimeout(() => {
|
|
1595
|
+
setShowChat(false);
|
|
1596
|
+
setIsClosing(false);
|
|
1597
|
+
setAnimationClass("");
|
|
1598
|
+
setBackdropAnimationClass("");
|
|
1599
|
+
setCloseTimeout(null);
|
|
1600
|
+
if (props.onClose) {
|
|
1601
|
+
props.onClose();
|
|
1602
|
+
}
|
|
1603
|
+
}, 200)
|
|
1604
|
+
);
|
|
1605
|
+
} else {
|
|
1606
|
+
if (closeTimeout) {
|
|
1607
|
+
clearTimeout(closeTimeout);
|
|
1608
|
+
setCloseTimeout(null);
|
|
1609
|
+
}
|
|
1610
|
+
setShowChat(true);
|
|
1611
|
+
setIsClosing(false);
|
|
1612
|
+
setAnimationClass("sh-dialog-animate");
|
|
1613
|
+
setBackdropAnimationClass("sh-backdrop-animate");
|
|
1614
|
+
setTimeout(() => {
|
|
1615
|
+
setAnimationClass("");
|
|
1616
|
+
setBackdropAnimationClass("");
|
|
1617
|
+
}, 250);
|
|
844
1618
|
}
|
|
845
1619
|
}
|
|
846
1620
|
function handleNewChat() {
|
|
847
1621
|
setChatMessages([]);
|
|
848
1622
|
service == null ? void 0 : service.resetSession();
|
|
849
1623
|
}
|
|
850
|
-
function onPopularItemsClick() {
|
|
851
|
-
setInput(TRANSLATIONS.showPopularItems);
|
|
852
|
-
handleSend();
|
|
853
|
-
}
|
|
854
|
-
function onCompareProductsClick() {
|
|
855
|
-
setInput(TRANSLATIONS.compareProducts);
|
|
856
|
-
handleSend();
|
|
857
|
-
}
|
|
858
1624
|
function onInputChange(event) {
|
|
859
1625
|
setInput(event.target.value);
|
|
860
1626
|
}
|
|
@@ -863,49 +1629,196 @@ function ShopPrompter(props) {
|
|
|
863
1629
|
handleSend();
|
|
864
1630
|
}
|
|
865
1631
|
}
|
|
866
|
-
function
|
|
867
|
-
|
|
1632
|
+
function handleTriggerClick(e) {
|
|
1633
|
+
if (props.chatPosition !== "dialog") return;
|
|
1634
|
+
if (!props.dialogTrigger) return;
|
|
1635
|
+
const isTargetClicked = typeof props.dialogTrigger === "string" ? e.target.closest(props.dialogTrigger) : (() => {
|
|
1636
|
+
let target = null;
|
|
1637
|
+
if (typeof props.dialogTrigger === "object") {
|
|
1638
|
+
if ("current" in props.dialogTrigger) {
|
|
1639
|
+
target = props.dialogTrigger.current;
|
|
1640
|
+
} else {
|
|
1641
|
+
target = props.dialogTrigger;
|
|
1642
|
+
}
|
|
1643
|
+
}
|
|
1644
|
+
return target && target.contains && target.contains(e.target);
|
|
1645
|
+
})();
|
|
1646
|
+
if (isTargetClicked) {
|
|
1647
|
+
if (closeTimeout) {
|
|
1648
|
+
clearTimeout(closeTimeout);
|
|
1649
|
+
setCloseTimeout(null);
|
|
1650
|
+
}
|
|
1651
|
+
setShowChat(true);
|
|
1652
|
+
setIsClosing(false);
|
|
1653
|
+
setAnimationClass("sh-dialog-animate");
|
|
1654
|
+
setBackdropAnimationClass("sh-backdrop-animate");
|
|
1655
|
+
setTimeout(() => {
|
|
1656
|
+
setAnimationClass("");
|
|
1657
|
+
setBackdropAnimationClass("");
|
|
1658
|
+
}, 250);
|
|
1659
|
+
}
|
|
868
1660
|
}
|
|
869
|
-
function
|
|
870
|
-
|
|
1661
|
+
function loadCustomFont(fontFamily) {
|
|
1662
|
+
if (!fontFamily || typeof window === "undefined") return;
|
|
1663
|
+
const systemFonts = [
|
|
1664
|
+
"sans-serif",
|
|
1665
|
+
"serif",
|
|
1666
|
+
"monospace",
|
|
1667
|
+
"cursive",
|
|
1668
|
+
"fantasy",
|
|
1669
|
+
"system-ui",
|
|
1670
|
+
"-apple-system",
|
|
1671
|
+
"blinkmacsystemfont",
|
|
1672
|
+
"segoe ui",
|
|
1673
|
+
"roboto",
|
|
1674
|
+
"helvetica",
|
|
1675
|
+
"arial",
|
|
1676
|
+
"inherit"
|
|
1677
|
+
];
|
|
1678
|
+
const cleanFont = fontFamily.split(",")[0].trim().replace(new RegExp(`['"]`, "g"), "");
|
|
1679
|
+
if (!cleanFont || systemFonts.includes(cleanFont.toLowerCase())) return;
|
|
1680
|
+
const linkId = `shopprompter-font-${cleanFont.toLowerCase().replace(new RegExp("\\s+", "g"), "-")}`;
|
|
1681
|
+
if (document.getElementById(linkId)) return;
|
|
1682
|
+
const link = document.createElement("link");
|
|
1683
|
+
link.id = linkId;
|
|
1684
|
+
link.rel = "stylesheet";
|
|
1685
|
+
const fontNameUrl = cleanFont.replace(new RegExp("\\s+", "g"), "+");
|
|
1686
|
+
link.href = `https://fonts.googleapis.com/css2?family=${fontNameUrl}:wght@400;500;600;700&display=swap`;
|
|
1687
|
+
document.head.appendChild(link);
|
|
871
1688
|
}
|
|
872
|
-
function
|
|
1689
|
+
function loadAgentExperience() {
|
|
873
1690
|
void (async function() {
|
|
874
|
-
console.log("## ~ ShopPrompter ~ state.service:", service);
|
|
875
1691
|
if (!service) {
|
|
876
|
-
console.warn(
|
|
1692
|
+
console.warn(
|
|
1693
|
+
"Service not initialized yet! Cannot load AgentExperience."
|
|
1694
|
+
);
|
|
877
1695
|
return;
|
|
878
1696
|
}
|
|
879
1697
|
const response = await (service == null ? void 0 : service.getAgentExperience());
|
|
880
|
-
console.log("## ~ ShopPrompter ~ response:", response);
|
|
881
1698
|
setAgentExperience(response);
|
|
882
1699
|
})();
|
|
883
1700
|
}
|
|
884
|
-
(
|
|
885
|
-
const
|
|
886
|
-
|
|
1701
|
+
function handleFeedback(messageId, messageContent, newFeedback) {
|
|
1702
|
+
const msg = chatMessages.find((m) => m.id === messageId);
|
|
1703
|
+
if (!msg) return;
|
|
1704
|
+
const currentFeedback = msg.feedback;
|
|
1705
|
+
const targetFeedback = currentFeedback === newFeedback ? "clear" : newFeedback;
|
|
1706
|
+
const oldMessages = [...chatMessages];
|
|
1707
|
+
setChatMessages(
|
|
1708
|
+
chatMessages.map((m) => {
|
|
1709
|
+
if (m.id === messageId) {
|
|
1710
|
+
return {
|
|
1711
|
+
...m,
|
|
1712
|
+
feedback: targetFeedback === "clear" ? null : targetFeedback
|
|
1713
|
+
};
|
|
1714
|
+
}
|
|
1715
|
+
return m;
|
|
1716
|
+
})
|
|
1717
|
+
);
|
|
1718
|
+
setError(null);
|
|
1719
|
+
service == null ? void 0 : service.sendFeedback(messageId, messageContent, targetFeedback).catch((err) => {
|
|
1720
|
+
setChatMessages(oldMessages);
|
|
1721
|
+
setError((err == null ? void 0 : err.message) || TRANSLATIONS.feedbackError);
|
|
1722
|
+
});
|
|
1723
|
+
}
|
|
1724
|
+
function canShowFeedback(message) {
|
|
1725
|
+
if (message.role !== "assistant") return false;
|
|
1726
|
+
if (!message.content) return false;
|
|
1727
|
+
const lastMsg = chatMessages[chatMessages.length - 1];
|
|
1728
|
+
if (lastMsg && lastMsg.id === message.id && isLoading) {
|
|
1729
|
+
return false;
|
|
1730
|
+
}
|
|
1731
|
+
return true;
|
|
1732
|
+
}
|
|
1733
|
+
(0, import_react2.useEffect)(() => {
|
|
1734
|
+
if (typeof window !== "undefined" && !document.getElementById("lottie-player-script")) {
|
|
1735
|
+
const script = document.createElement("script");
|
|
1736
|
+
script.id = "lottie-player-script";
|
|
1737
|
+
script.src = "https://unpkg.com/@lottiefiles/lottie-player@latest/dist/lottie-player";
|
|
1738
|
+
document.head.appendChild(script);
|
|
1739
|
+
}
|
|
1740
|
+
if (themeObj().fontFamily) {
|
|
1741
|
+
loadCustomFont(themeObj().fontFamily);
|
|
1742
|
+
}
|
|
1743
|
+
if (apiConfigObj()) {
|
|
1744
|
+
if (!isConfigInsufficient()) {
|
|
1745
|
+
const apiConfig = {
|
|
1746
|
+
...apiConfigObj(),
|
|
1747
|
+
shopPrompterToken: props.shopPrompterToken || apiConfigObj().shopPrompterToken
|
|
1748
|
+
};
|
|
1749
|
+
const service2 = new ShopPrompterService(apiConfig);
|
|
1750
|
+
setService(service2);
|
|
1751
|
+
const savedMessages = service2.loadMessages();
|
|
1752
|
+
if (savedMessages.length > 0) {
|
|
1753
|
+
setChatMessages(savedMessages);
|
|
1754
|
+
}
|
|
1755
|
+
}
|
|
1756
|
+
} else {
|
|
1757
|
+
console.error("ShopPrompter: apiConfig prop is required!");
|
|
1758
|
+
}
|
|
1759
|
+
if ((props == null ? void 0 : props.chatPosition) === "right-panel" || (props == null ? void 0 : props.chatPosition) === "full-page") {
|
|
1760
|
+
setShowChat(true);
|
|
1761
|
+
}
|
|
1762
|
+
if (typeof window !== "undefined") {
|
|
1763
|
+
document.addEventListener("click", handleTriggerClick);
|
|
1764
|
+
}
|
|
887
1765
|
}, []);
|
|
888
|
-
(0,
|
|
1766
|
+
(0, import_react2.useEffect)(() => {
|
|
889
1767
|
if (service && !agentExperience) {
|
|
890
|
-
|
|
891
|
-
}
|
|
892
|
-
if (agentExperience) {
|
|
893
|
-
console.log("## ~ ShopPrompter ~ agentExperience updated:", {
|
|
894
|
-
greeting: agentExperience.greeting,
|
|
895
|
-
agentLogoUrl: agentExperience.agentLogoUrl
|
|
896
|
-
});
|
|
1768
|
+
loadAgentExperience();
|
|
897
1769
|
}
|
|
898
1770
|
}, [service, agentExperience]);
|
|
899
|
-
|
|
900
|
-
|
|
1771
|
+
(0, import_react2.useEffect)(() => {
|
|
1772
|
+
if (themeObj().fontFamily) {
|
|
1773
|
+
loadCustomFont(themeObj().fontFamily);
|
|
1774
|
+
}
|
|
1775
|
+
}, [themeObj().fontFamily || ""]);
|
|
1776
|
+
(0, import_react2.useEffect)(() => {
|
|
1777
|
+
if ((props == null ? void 0 : props.chatPosition) === "right-panel" || (props == null ? void 0 : props.chatPosition) === "full-page") {
|
|
1778
|
+
setShowChat(true);
|
|
1779
|
+
} else if ((props == null ? void 0 : props.chatPosition) === "dialog" || (props == null ? void 0 : props.chatPosition) === "classic-chatbot") {
|
|
1780
|
+
setShowChat(false);
|
|
1781
|
+
setIsClosing(false);
|
|
1782
|
+
setAnimationClass("");
|
|
1783
|
+
setBackdropAnimationClass("");
|
|
1784
|
+
}
|
|
1785
|
+
}, [(props == null ? void 0 : props.chatPosition) || ""]);
|
|
1786
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "shopprompter-sdk", children: [
|
|
1787
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("style", { dangerouslySetInnerHTML: { __html: ANIMATION_STYLES } }),
|
|
1788
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1789
|
+
"div",
|
|
1790
|
+
{
|
|
1791
|
+
onClick: (e) => toggleChat(),
|
|
1792
|
+
style: {
|
|
1793
|
+
...styles2.backdrop,
|
|
1794
|
+
display: props.chatPosition === "dialog" && (showChat || isClosing) ? "block" : "none"
|
|
1795
|
+
},
|
|
1796
|
+
className: backdropAnimationClass
|
|
1797
|
+
}
|
|
1798
|
+
),
|
|
1799
|
+
props.chatPosition === "classic-chatbot" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_jsx_runtime4.Fragment, { children: !showChat ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
901
1800
|
"button",
|
|
902
1801
|
{
|
|
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
1802
|
onClick: (e) => toggleChat(),
|
|
905
1803
|
style: {
|
|
906
|
-
|
|
1804
|
+
position: "fixed",
|
|
1805
|
+
bottom: "1.5rem",
|
|
1806
|
+
right: "1.5rem",
|
|
1807
|
+
width: "4rem",
|
|
1808
|
+
height: "4rem",
|
|
1809
|
+
backgroundColor: themeObj().actionColor || "#2563eb",
|
|
1810
|
+
borderRadius: "9999px",
|
|
1811
|
+
zIndex: 50,
|
|
1812
|
+
display: "flex",
|
|
1813
|
+
alignItems: "center",
|
|
1814
|
+
justifyContent: "center",
|
|
1815
|
+
transition: "background-color 0.2s",
|
|
1816
|
+
border: "none",
|
|
1817
|
+
cursor: "pointer",
|
|
1818
|
+
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)",
|
|
1819
|
+
fontFamily: themeObj().fontFamily || void 0
|
|
907
1820
|
},
|
|
908
|
-
children: /* @__PURE__ */ (0,
|
|
1821
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
909
1822
|
"img",
|
|
910
1823
|
{
|
|
911
1824
|
alt: "Chat",
|
|
@@ -918,259 +1831,406 @@ function ShopPrompter(props) {
|
|
|
918
1831
|
)
|
|
919
1832
|
}
|
|
920
1833
|
) : 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"
|
|
1834
|
+
showChat || isClosing ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: containerStyle(), className: containerClass(), children: [
|
|
1835
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
1836
|
+
"div",
|
|
1837
|
+
{
|
|
1838
|
+
style: {
|
|
1839
|
+
...styles2.header,
|
|
1840
|
+
backgroundColor: themeObj().headerBackgroundColor || "transparent"
|
|
1841
|
+
},
|
|
1842
|
+
children: [
|
|
1843
|
+
themeObj().showAgentName !== false ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: styles2.subHeaderContainer, children: [
|
|
1844
|
+
(agentExperience == null ? void 0 : agentExperience.agentLogoUrl) ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1845
|
+
"img",
|
|
1846
|
+
{
|
|
1847
|
+
src: agentExperience.agentLogoUrl,
|
|
1848
|
+
alt: agentExperience.agentName,
|
|
1849
|
+
style: {
|
|
1850
|
+
width: "24px",
|
|
1851
|
+
height: "24px",
|
|
1852
|
+
borderRadius: "4px",
|
|
1853
|
+
objectFit: "cover"
|
|
952
1854
|
}
|
|
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
|
-
|
|
1855
|
+
}
|
|
1856
|
+
) : null,
|
|
1857
|
+
(agentExperience == null ? void 0 : agentExperience.agentName) ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: styles2.headerText, children: agentExperience.agentName }) : null
|
|
1858
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_jsx_runtime4.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: styles2.subHeaderContainer }) }),
|
|
1859
|
+
!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,
|
|
1860
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: styles2.subHeaderContainer, children: [
|
|
1861
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1862
|
+
"button",
|
|
1863
|
+
{
|
|
1864
|
+
className: "sh-header-btn",
|
|
1865
|
+
onClick: (e) => handleNewChat(),
|
|
1866
|
+
style: styles2.headerButton,
|
|
1867
|
+
children: TRANSLATIONS.newChat
|
|
1868
|
+
}
|
|
1869
|
+
),
|
|
1870
|
+
props.chatPosition === "classic-chatbot" || props.chatPosition === "right-panel" || props.chatPosition === "dialog" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1871
|
+
"button",
|
|
1872
|
+
{
|
|
1873
|
+
onClick: (e) => toggleChat(),
|
|
1874
|
+
style: styles2.ButtonSheetButton,
|
|
1875
|
+
children: "\xD7"
|
|
1876
|
+
}
|
|
1877
|
+
) : null
|
|
1878
|
+
] })
|
|
1879
|
+
]
|
|
1880
|
+
}
|
|
1881
|
+
),
|
|
1882
|
+
isConfigInsufficient() ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: styles2.insufficientConfigContainer, children: [
|
|
1883
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: styles2.insufficientConfigIconContainer, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
1884
|
+
"svg",
|
|
1885
|
+
{
|
|
1886
|
+
width: "48",
|
|
1887
|
+
height: "48",
|
|
1888
|
+
viewBox: "0 0 24 24",
|
|
1889
|
+
fill: "none",
|
|
1890
|
+
stroke: "currentColor",
|
|
1891
|
+
strokeWidth: "2",
|
|
1892
|
+
strokeLinecap: "round",
|
|
1893
|
+
strokeLinejoin: "round",
|
|
1894
|
+
style: {
|
|
1895
|
+
color: "#ef4444"
|
|
1896
|
+
},
|
|
1897
|
+
children: [
|
|
1898
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("rect", { x: "3", y: "11", width: "18", height: "11", rx: "2", ry: "2" }),
|
|
1899
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M7 11V7a5 5 0 0 1 9.9-1" })
|
|
1900
|
+
]
|
|
1901
|
+
}
|
|
1902
|
+
) }),
|
|
1903
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1904
|
+
"h3",
|
|
1905
|
+
{
|
|
1906
|
+
style: {
|
|
1907
|
+
...styles2.insufficientConfigTitle,
|
|
1908
|
+
fontFamily: themeObj().fontFamily || void 0
|
|
1909
|
+
},
|
|
1910
|
+
children: "Configuration Error"
|
|
1911
|
+
}
|
|
1912
|
+
),
|
|
1913
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1914
|
+
"p",
|
|
1915
|
+
{
|
|
1916
|
+
style: {
|
|
1917
|
+
...styles2.insufficientConfigMessage,
|
|
1918
|
+
fontFamily: themeObj().fontFamily || void 0
|
|
1919
|
+
},
|
|
1920
|
+
children: "ShopPrompter requires a secure token or API key to initialize. Please check your setup."
|
|
1921
|
+
}
|
|
1922
|
+
),
|
|
1923
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
1924
|
+
"div",
|
|
1925
|
+
{
|
|
1926
|
+
style: {
|
|
1927
|
+
...styles2.insufficientConfigDetails,
|
|
1928
|
+
fontFamily: themeObj().fontFamily || void 0
|
|
1929
|
+
},
|
|
1930
|
+
children: [
|
|
1931
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1932
|
+
"div",
|
|
1933
|
+
{
|
|
1934
|
+
style: {
|
|
1935
|
+
fontWeight: 600,
|
|
1936
|
+
marginBottom: "0.25rem"
|
|
1937
|
+
},
|
|
1938
|
+
children: "Missing Parameters:"
|
|
1939
|
+
}
|
|
1940
|
+
),
|
|
1941
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
1942
|
+
"div",
|
|
1943
|
+
{
|
|
1944
|
+
style: {
|
|
1945
|
+
display: "flex",
|
|
1946
|
+
flexDirection: "column",
|
|
1947
|
+
gap: "0.25rem",
|
|
1948
|
+
fontFamily: "monospace",
|
|
1949
|
+
fontSize: "0.75rem"
|
|
1950
|
+
},
|
|
1951
|
+
children: [
|
|
1952
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1953
|
+
"span",
|
|
1954
|
+
{
|
|
1955
|
+
style: {
|
|
1956
|
+
color: "#ef4444"
|
|
1957
|
+
},
|
|
1958
|
+
children: "\u2717 shopPrompterToken (not found)"
|
|
1959
|
+
}
|
|
1960
|
+
),
|
|
1961
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1962
|
+
"span",
|
|
1963
|
+
{
|
|
1964
|
+
style: {
|
|
1965
|
+
color: "#ef4444"
|
|
1966
|
+
},
|
|
1967
|
+
children: "\u2717 apiConfig.apiKey (not found)"
|
|
1968
|
+
}
|
|
1969
|
+
)
|
|
1970
|
+
]
|
|
1971
|
+
}
|
|
1972
|
+
)
|
|
1973
|
+
]
|
|
1974
|
+
}
|
|
1975
|
+
)
|
|
1976
|
+
] }) : null,
|
|
1977
|
+
!isConfigInsufficient() ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
1978
|
+
"div",
|
|
1979
|
+
{
|
|
1980
|
+
style: {
|
|
1981
|
+
display: "flex",
|
|
1982
|
+
flexDirection: "column",
|
|
1983
|
+
flex: 1,
|
|
1984
|
+
overflow: "hidden"
|
|
1985
|
+
},
|
|
1986
|
+
children: [
|
|
1987
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
1988
|
+
"div",
|
|
1989
|
+
{
|
|
1990
|
+
id: "shop-prompter-chat-container",
|
|
1991
|
+
style: {
|
|
1992
|
+
...styles2.chatContainer,
|
|
1993
|
+
backgroundColor: themeObj().mainBackgroundColor || styles2.chatContainer.backgroundColor
|
|
1994
|
+
},
|
|
1995
|
+
children: [
|
|
1996
|
+
showWelcome() ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: styles2.welcomeContainer, children: [
|
|
1997
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1998
|
+
"img",
|
|
1999
|
+
{
|
|
2000
|
+
alt: "ShopPrompter",
|
|
2001
|
+
src: (agentExperience == null ? void 0 : agentExperience.agentLogoUrl) ? agentExperience.agentLogoUrl : ICONS.shopprompter,
|
|
2002
|
+
style: {
|
|
2003
|
+
width: "64px",
|
|
2004
|
+
height: "64px",
|
|
2005
|
+
marginBottom: "24px",
|
|
2006
|
+
borderRadius: "12px",
|
|
2007
|
+
objectFit: "cover"
|
|
2008
|
+
}
|
|
2009
|
+
}
|
|
2010
|
+
),
|
|
2011
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
2012
|
+
"h3",
|
|
2013
|
+
{
|
|
2014
|
+
style: {
|
|
2015
|
+
...styles2.welcomeTitle,
|
|
2016
|
+
fontFamily: themeObj().fontFamily || styles2.welcomeTitle.fontFamily
|
|
2017
|
+
},
|
|
2018
|
+
children: ((_b = agentExperience == null ? void 0 : agentExperience.greeting) == null ? void 0 : _b.title) || TRANSLATIONS.welcomeToShopPrompter
|
|
2019
|
+
}
|
|
2020
|
+
),
|
|
2021
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
2022
|
+
"p",
|
|
2023
|
+
{
|
|
2024
|
+
style: {
|
|
2025
|
+
...styles2.welcomeDescription,
|
|
2026
|
+
fontFamily: themeObj().fontFamily || styles2.welcomeDescription.fontFamily
|
|
2027
|
+
},
|
|
2028
|
+
children: ((_c = agentExperience == null ? void 0 : agentExperience.greeting) == null ? void 0 : _c.description) || TRANSLATIONS.welcomeDescription
|
|
2029
|
+
}
|
|
2030
|
+
),
|
|
2031
|
+
/* @__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)(
|
|
2032
|
+
"button",
|
|
2033
|
+
{
|
|
2034
|
+
style: styles2.button,
|
|
2035
|
+
onClick: (event) => {
|
|
2036
|
+
setInput(item.prompt);
|
|
2037
|
+
handleSend(item.prompt);
|
|
2038
|
+
},
|
|
2039
|
+
children: item.prompt
|
|
2040
|
+
},
|
|
2041
|
+
item.prompt
|
|
2042
|
+
)) })
|
|
2043
|
+
] }) : null,
|
|
2044
|
+
!showWelcome() ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
2045
|
+
"div",
|
|
1016
2046
|
{
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
2047
|
+
style: {
|
|
2048
|
+
width: "100%"
|
|
2049
|
+
},
|
|
2050
|
+
children: chatMessages == null ? void 0 : chatMessages.map((message) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { children: [
|
|
2051
|
+
message.role === "user" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: styles2.messageContainerUser, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
2052
|
+
"div",
|
|
2053
|
+
{
|
|
2054
|
+
style: {
|
|
2055
|
+
...styles2.messageBubbleUser,
|
|
2056
|
+
backgroundColor: themeObj().userMessageBackgroundColor || styles2.messageBubbleUser.backgroundColor
|
|
2057
|
+
},
|
|
2058
|
+
children: message.content
|
|
2059
|
+
}
|
|
2060
|
+
) }) : null,
|
|
2061
|
+
message.role === "assistant" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: styles2.messageContainerAssistant, children: [
|
|
2062
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
2063
|
+
"div",
|
|
2064
|
+
{
|
|
2065
|
+
style: {
|
|
2066
|
+
...styles2.messageBubbleAssistant,
|
|
2067
|
+
backgroundColor: themeObj().assistantMessageBackgroundColor || styles2.messageBubbleAssistant.backgroundColor
|
|
2068
|
+
},
|
|
2069
|
+
children: [
|
|
2070
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
2071
|
+
"div",
|
|
2072
|
+
{
|
|
2073
|
+
dangerouslySetInnerHTML: {
|
|
2074
|
+
__html: parseMarkdown(message.content)
|
|
2075
|
+
}
|
|
2076
|
+
}
|
|
2077
|
+
),
|
|
2078
|
+
!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)(
|
|
2079
|
+
"lottie-player",
|
|
2080
|
+
{
|
|
2081
|
+
background: "transparent",
|
|
2082
|
+
speed: "1",
|
|
2083
|
+
src: agentExperience.loadingIndicatorUrl,
|
|
2084
|
+
style: {
|
|
2085
|
+
width: "40px",
|
|
2086
|
+
height: "40px"
|
|
2087
|
+
},
|
|
2088
|
+
loop: true,
|
|
2089
|
+
autoplay: true
|
|
2090
|
+
}
|
|
2091
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: styles2.thinkingIndicator, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
2092
|
+
"svg",
|
|
2093
|
+
{
|
|
2094
|
+
width: "24",
|
|
2095
|
+
height: "24",
|
|
2096
|
+
viewBox: "0 0 24 24",
|
|
2097
|
+
fill: "none",
|
|
2098
|
+
stroke: "currentColor",
|
|
2099
|
+
strokeWidth: "2",
|
|
2100
|
+
strokeLinecap: "round",
|
|
2101
|
+
strokeLinejoin: "round",
|
|
2102
|
+
style: {
|
|
2103
|
+
color: "#6b7280"
|
|
2104
|
+
},
|
|
2105
|
+
children: [
|
|
2106
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: THINKING_SPINNER }),
|
|
2107
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
2108
|
+
"animateTransform",
|
|
2109
|
+
{
|
|
2110
|
+
attributeName: "transform",
|
|
2111
|
+
type: "rotate",
|
|
2112
|
+
from: "0 12 12",
|
|
2113
|
+
to: "360 12 12",
|
|
2114
|
+
dur: "1s",
|
|
2115
|
+
repeatCount: "indefinite"
|
|
2116
|
+
}
|
|
2117
|
+
)
|
|
2118
|
+
]
|
|
2119
|
+
}
|
|
2120
|
+
) }) }) : null
|
|
2121
|
+
]
|
|
2122
|
+
}
|
|
2123
|
+
),
|
|
2124
|
+
canShowFeedback(message) ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: styles2.feedbackRow, children: [
|
|
2125
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
2126
|
+
"button",
|
|
2127
|
+
{
|
|
2128
|
+
className: "sh-feedback-btn",
|
|
2129
|
+
onClick: (event) => handleFeedback(
|
|
2130
|
+
message.id,
|
|
2131
|
+
message.content,
|
|
2132
|
+
"upvote"
|
|
2133
|
+
),
|
|
2134
|
+
style: styles2.feedbackButton,
|
|
2135
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
2136
|
+
thumbs_up_icon_component_default,
|
|
2137
|
+
{
|
|
2138
|
+
fill: message.feedback === "upvote" ? themeObj().actionColor || "#2563eb" : "none",
|
|
2139
|
+
stroke: message.feedback === "upvote" ? themeObj().actionColor || "#2563eb" : "currentColor"
|
|
2140
|
+
}
|
|
2141
|
+
)
|
|
2142
|
+
}
|
|
2143
|
+
),
|
|
2144
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
2145
|
+
"button",
|
|
2146
|
+
{
|
|
2147
|
+
className: "sh-feedback-btn",
|
|
2148
|
+
onClick: (event) => handleFeedback(
|
|
2149
|
+
message.id,
|
|
2150
|
+
message.content,
|
|
2151
|
+
"downvote"
|
|
2152
|
+
),
|
|
2153
|
+
style: styles2.feedbackButton,
|
|
2154
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
2155
|
+
thumbs_down_icon_component_default,
|
|
2156
|
+
{
|
|
2157
|
+
fill: message.feedback === "downvote" ? themeObj().actionColor || "#2563eb" : "none",
|
|
2158
|
+
stroke: message.feedback === "downvote" ? themeObj().actionColor || "#2563eb" : "currentColor"
|
|
2159
|
+
}
|
|
2160
|
+
)
|
|
2161
|
+
}
|
|
2162
|
+
)
|
|
2163
|
+
] }) : null,
|
|
2164
|
+
getShowProducts(message) ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
2165
|
+
product_card_list_component_default,
|
|
2166
|
+
{
|
|
2167
|
+
skus: message.productSkus,
|
|
2168
|
+
defaultLocale: props.defaultLocale,
|
|
2169
|
+
showPriceIfEmpty: showPriceIfEmptyVal(),
|
|
2170
|
+
visibleFields: visibleFieldsList()
|
|
2171
|
+
}
|
|
2172
|
+
) : null
|
|
2173
|
+
] }) : null
|
|
2174
|
+
] }, message.id))
|
|
1030
2175
|
}
|
|
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
|
|
2176
|
+
) : null,
|
|
2177
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: styles2.errorContainer, children: [
|
|
2178
|
+
"Error: ",
|
|
2179
|
+
error
|
|
2180
|
+
] }) : null
|
|
2181
|
+
]
|
|
1085
2182
|
}
|
|
1086
2183
|
),
|
|
1087
|
-
/* @__PURE__ */ (0,
|
|
1088
|
-
"
|
|
2184
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
2185
|
+
"div",
|
|
1089
2186
|
{
|
|
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%"
|
|
2187
|
+
style: {
|
|
2188
|
+
...styles2.inputSection,
|
|
2189
|
+
backgroundColor: themeObj().mainBackgroundColor || styles2.inputSection.backgroundColor
|
|
2190
|
+
},
|
|
2191
|
+
children: [
|
|
2192
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: styles2.inputWrapper, children: [
|
|
2193
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
2194
|
+
"input",
|
|
2195
|
+
{
|
|
2196
|
+
id: "shop-prompter-input",
|
|
2197
|
+
type: "text",
|
|
2198
|
+
style: styles2.input,
|
|
2199
|
+
placeholder: (agentExperience == null ? void 0 : agentExperience.hintText) || TRANSLATIONS.askMeAnything,
|
|
2200
|
+
value: input,
|
|
2201
|
+
onInput: (e) => onInputChange(e),
|
|
2202
|
+
onKeyDown: (e) => onInputKeyDown(e)
|
|
1122
2203
|
}
|
|
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",
|
|
2204
|
+
),
|
|
2205
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
2206
|
+
"button",
|
|
1129
2207
|
{
|
|
1130
|
-
|
|
1131
|
-
style:
|
|
1132
|
-
|
|
2208
|
+
onClick: (e) => handleSend(),
|
|
2209
|
+
style: {
|
|
2210
|
+
...styles2.formButton,
|
|
2211
|
+
...styles2.sendButton,
|
|
2212
|
+
backgroundColor: themeObj().actionColor || styles2.sendButton.backgroundColor
|
|
2213
|
+
},
|
|
2214
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
2215
|
+
"img",
|
|
2216
|
+
{
|
|
2217
|
+
alt: "Send",
|
|
2218
|
+
src: ICONS.sendHorizontal,
|
|
2219
|
+
style: {
|
|
2220
|
+
padding: "4px"
|
|
2221
|
+
}
|
|
2222
|
+
}
|
|
2223
|
+
)
|
|
1133
2224
|
}
|
|
1134
2225
|
)
|
|
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
|
-
] })
|
|
2226
|
+
] }),
|
|
2227
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { style: styles2.disclaimer, children: "AI content may be inaccurate." })
|
|
2228
|
+
]
|
|
2229
|
+
}
|
|
2230
|
+
)
|
|
2231
|
+
]
|
|
2232
|
+
}
|
|
2233
|
+
) : null
|
|
1174
2234
|
] }) : null
|
|
1175
2235
|
] });
|
|
1176
2236
|
}
|