@shop-prompter/react 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs ADDED
@@ -0,0 +1,1144 @@
1
+ // src/shop-prompter.component.jsx
2
+ import * as React from "react";
3
+ import { useState, useEffect } from "react";
4
+
5
+ // src/api/shop-prompter-api.ts
6
+ var DefaultShopPrompterApi = class {
7
+ constructor() {
8
+ this.config = null;
9
+ }
10
+ setApiConfig(config) {
11
+ this.config = config;
12
+ }
13
+ async execute(prompt, userId, sessionId) {
14
+ if (!this.config) {
15
+ throw new Error("API configuration not set. Call setApiConfig first.");
16
+ }
17
+ const response = await fetch(`${this.config.baseUrl}/interaction`, {
18
+ method: "POST",
19
+ headers: {
20
+ "Content-Type": "application/json",
21
+ "X-Api-Key": this.config.apiKey
22
+ },
23
+ body: JSON.stringify({
24
+ prompt,
25
+ userId,
26
+ sessionId
27
+ })
28
+ });
29
+ if (!response.ok) {
30
+ throw new Error(`API error: ${response.status}`);
31
+ }
32
+ return response.json();
33
+ }
34
+ async executeStream(prompt, userId, sessionId, onEvent, cartContext) {
35
+ var _a;
36
+ if (!this.config) {
37
+ throw new Error("API configuration not set. Call setApiConfig first.");
38
+ }
39
+ const url = `${this.config.baseUrl}/interaction/stream`;
40
+ console.log("ShopPrompter Request:", {
41
+ url,
42
+ prompt,
43
+ userId,
44
+ sessionId,
45
+ cartContext
46
+ });
47
+ let response;
48
+ try {
49
+ response = await fetch(url, {
50
+ method: "POST",
51
+ headers: {
52
+ "Content-Type": "application/json",
53
+ "X-Api-Key": this.config.apiKey,
54
+ Accept: "text/event-stream",
55
+ "Cache-Control": "no-cache"
56
+ },
57
+ body: JSON.stringify({
58
+ prompt,
59
+ userId,
60
+ sessionId,
61
+ cart: cartContext
62
+ })
63
+ });
64
+ } catch (fetchError) {
65
+ console.error("ShopPrompter Fetch Error:", fetchError);
66
+ onEvent({
67
+ type: "error",
68
+ reason: `Failed to fetch: ${fetchError instanceof Error ? fetchError.message : "Network error"}`
69
+ });
70
+ return;
71
+ }
72
+ console.log("ShopPrompter Response:", response.status);
73
+ if (!response.ok) {
74
+ const errorText = await response.text().catch(() => "");
75
+ console.error("ShopPrompter API Error:", response.status, errorText);
76
+ onEvent({
77
+ type: "error",
78
+ reason: `API error: ${response.status} - ${errorText}`
79
+ });
80
+ return;
81
+ }
82
+ const reader = (_a = response.body) == null ? void 0 : _a.getReader();
83
+ if (!reader) {
84
+ onEvent({ type: "error", reason: "No response body" });
85
+ return;
86
+ }
87
+ const decoder = new TextDecoder();
88
+ let buffer = "";
89
+ try {
90
+ while (true) {
91
+ const { done, value } = await reader.read();
92
+ if (done) {
93
+ console.log("ShopPrompter Stream done");
94
+ onEvent({ type: "close" });
95
+ break;
96
+ }
97
+ const chunk = decoder.decode(value, { stream: true });
98
+ console.log("ShopPrompter Raw chunk:", chunk);
99
+ buffer += chunk;
100
+ const lines = buffer.split("\n");
101
+ buffer = lines.pop() || "";
102
+ let currentEventType = "";
103
+ for (const line of lines) {
104
+ console.log("ShopPrompter Line:", line);
105
+ if (line.startsWith("event:")) {
106
+ currentEventType = line.slice(6).trim();
107
+ console.log("ShopPrompter Event type:", currentEventType);
108
+ if (currentEventType === "error") {
109
+ onEvent({
110
+ type: "error",
111
+ reason: "Server returned an error event. Check backend configuration."
112
+ });
113
+ }
114
+ } else if (line.startsWith("data:")) {
115
+ const data = line.slice(5).trim();
116
+ console.log("ShopPrompter Data:", data);
117
+ if (data) {
118
+ if (currentEventType === "error") {
119
+ try {
120
+ const errorData = JSON.parse(data);
121
+ onEvent({
122
+ type: "error",
123
+ reason: errorData.message || errorData.error || "Unknown server error"
124
+ });
125
+ } catch {
126
+ onEvent({
127
+ type: "error",
128
+ reason: data || "Unknown server error"
129
+ });
130
+ }
131
+ } else {
132
+ const event = this.parseEvent(data);
133
+ console.log("ShopPrompter Parsed event:", event);
134
+ if (event) {
135
+ onEvent(event);
136
+ }
137
+ }
138
+ }
139
+ currentEventType = "";
140
+ }
141
+ }
142
+ }
143
+ } catch (error) {
144
+ console.error("ShopPrompter Stream error:", error);
145
+ onEvent({
146
+ type: "error",
147
+ reason: error instanceof Error ? error.message : "Unknown error"
148
+ });
149
+ }
150
+ }
151
+ async getAgentExperience() {
152
+ if (!this.config) {
153
+ console.warn("API configuration not set. Call setApiConfig first.");
154
+ return null;
155
+ }
156
+ try {
157
+ const response = await fetch(`${this.config.baseUrl}/agent-experience`, {
158
+ method: "GET",
159
+ headers: {
160
+ "Content-Type": "application/json",
161
+ "X-Api-Key": this.config.apiKey
162
+ }
163
+ });
164
+ if (!response.ok) {
165
+ console.error(`Failed to fetch agent experience: ${response.status}`);
166
+ return null;
167
+ }
168
+ const data = await response.json();
169
+ console.log(
170
+ "## ~ DefaultShopPrompterApi ~ getAgentExperience ~ data:",
171
+ data
172
+ );
173
+ return data;
174
+ } catch (error) {
175
+ console.error("Error fetching agent experience:", error);
176
+ return null;
177
+ }
178
+ }
179
+ parseEvent(data) {
180
+ try {
181
+ const json = JSON.parse(data);
182
+ if (json.token !== void 0) {
183
+ if (json.token === "close") {
184
+ return { type: "close" };
185
+ }
186
+ return {
187
+ type: "text",
188
+ text: json.token
189
+ };
190
+ }
191
+ if (json.text !== void 0) {
192
+ return {
193
+ type: "text",
194
+ text: json.text
195
+ };
196
+ }
197
+ if (json.skus !== void 0) {
198
+ return {
199
+ type: "productSkus",
200
+ skus: json.skus
201
+ };
202
+ }
203
+ if (json.products !== void 0 && Array.isArray(json.products)) {
204
+ const skus = json.products.map((p) => p.sku).filter(Boolean);
205
+ if (skus.length > 0) {
206
+ return {
207
+ type: "productSkus",
208
+ skus
209
+ };
210
+ }
211
+ }
212
+ if (json.productSkus !== void 0) {
213
+ return {
214
+ type: "productSkus",
215
+ skus: json.productSkus
216
+ };
217
+ }
218
+ if (json.output !== void 0 && Array.isArray(json.output)) {
219
+ for (const item of json.output) {
220
+ if (item.type === "product" && item.data && Array.isArray(item.data)) {
221
+ const skus = item.data.filter((p) => p !== null).map((p) => typeof p === "string" ? p : p == null ? void 0 : p.sku).filter(Boolean);
222
+ if (skus.length > 0) {
223
+ return {
224
+ type: "productSkus",
225
+ skus
226
+ };
227
+ }
228
+ }
229
+ if (item.type === "product" && item.skus && Array.isArray(item.skus)) {
230
+ return {
231
+ type: "productSkus",
232
+ skus: item.skus
233
+ };
234
+ }
235
+ }
236
+ }
237
+ if (json.navigation !== void 0) {
238
+ return {
239
+ type: "navigation",
240
+ navigationOperations: json.navigation.map((nav) => ({
241
+ name: nav.name,
242
+ route: nav.path || nav.route,
243
+ description: nav.description
244
+ }))
245
+ };
246
+ }
247
+ if (json.cart !== void 0) {
248
+ return {
249
+ type: "cart",
250
+ operations: json.cart.map((op) => ({
251
+ sku: op.sku,
252
+ action: op.action,
253
+ quantity: op.quantity || 1
254
+ }))
255
+ };
256
+ }
257
+ if (json.output !== void 0 && Array.isArray(json.output)) {
258
+ for (const item of json.output) {
259
+ if (item.type === "cart" && item.data) {
260
+ return {
261
+ type: "cart",
262
+ operations: (Array.isArray(item.data) ? item.data : [item.data]).map((op) => ({
263
+ sku: op.sku,
264
+ action: op.action || "add",
265
+ quantity: op.quantity || 1
266
+ }))
267
+ };
268
+ }
269
+ }
270
+ }
271
+ if (json.close !== void 0 || json.type === "close") {
272
+ return { type: "close" };
273
+ }
274
+ return null;
275
+ } catch {
276
+ if (data && typeof data === "string") {
277
+ return {
278
+ type: "text",
279
+ text: data
280
+ };
281
+ }
282
+ return null;
283
+ }
284
+ }
285
+ };
286
+ var shopPrompterApi = new DefaultShopPrompterApi();
287
+
288
+ // src/api/session-handler.ts
289
+ import { v4 as uuidv4 } from "uuid";
290
+ var SESSION_KEY = "shopprompter_sessionId";
291
+ var USER_KEY = "shopprompter_userId";
292
+ var DefaultSessionHandler = class {
293
+ constructor() {
294
+ this.sessionId = "";
295
+ this.userId = "";
296
+ }
297
+ initialize(userIdentifier) {
298
+ this.userId = userIdentifier || this.getPersistedUserId() || uuidv4();
299
+ this.persistUserId(this.userId);
300
+ this.sessionId = this.getPersistedSessionId() || this.userId;
301
+ this.persistSessionId(this.sessionId);
302
+ }
303
+ regenerate() {
304
+ this.sessionId = uuidv4();
305
+ this.persistSessionId(this.sessionId);
306
+ }
307
+ getSessionId() {
308
+ if (!this.sessionId) {
309
+ this.initialize();
310
+ }
311
+ return this.sessionId;
312
+ }
313
+ getUserId() {
314
+ if (!this.userId) {
315
+ this.initialize();
316
+ }
317
+ return this.userId;
318
+ }
319
+ getPersistedSessionId() {
320
+ try {
321
+ return localStorage.getItem(SESSION_KEY);
322
+ } catch {
323
+ return null;
324
+ }
325
+ }
326
+ persistSessionId(sessionId) {
327
+ try {
328
+ localStorage.setItem(SESSION_KEY, sessionId);
329
+ } catch {
330
+ }
331
+ }
332
+ getPersistedUserId() {
333
+ try {
334
+ return localStorage.getItem(USER_KEY);
335
+ } catch {
336
+ return null;
337
+ }
338
+ }
339
+ persistUserId(userId) {
340
+ try {
341
+ localStorage.setItem(USER_KEY, userId);
342
+ } catch {
343
+ }
344
+ }
345
+ };
346
+ var sessionHandler = new DefaultSessionHandler();
347
+
348
+ // src/shop-prompter.service.ts
349
+ var SHOP_PROMPTER_CONFIG = {
350
+ baseUrl: "https://demo.dev.shop-prompter.com/touch-points-api",
351
+ apiKey: "864c87266ef52c079c09b3248d86b4b5ef430bf9e5a4188476124c93ee2f6dda380f337986837b30b60f73e6aceefe7a0e0f778b3d21a7fa7698cf8546afc709"
352
+ };
353
+ var ShopPrompterService = class {
354
+ constructor() {
355
+ this.isLoading = false;
356
+ this.error = null;
357
+ this.streamingText = "";
358
+ shopPrompterApi.setApiConfig(SHOP_PROMPTER_CONFIG);
359
+ sessionHandler.initialize();
360
+ }
361
+ async sendMessage(prompt, callbacks, cartContext) {
362
+ var _a, _b, _c;
363
+ this.isLoading = true;
364
+ (_a = callbacks.onLoadingChange) == null ? void 0 : _a.call(callbacks, true);
365
+ this.error = null;
366
+ this.streamingText = "";
367
+ const userId = sessionHandler.getUserId();
368
+ const sessionId = sessionHandler.getSessionId();
369
+ let accumulatedText = "";
370
+ try {
371
+ await shopPrompterApi.executeStream(
372
+ prompt,
373
+ userId,
374
+ sessionId,
375
+ (event) => {
376
+ var _a2, _b2, _c2, _d, _e, _f, _g;
377
+ switch (event.type) {
378
+ case "text":
379
+ accumulatedText += event.text;
380
+ this.streamingText = accumulatedText;
381
+ (_a2 = callbacks.onTextUpdate) == null ? void 0 : _a2.call(callbacks, accumulatedText);
382
+ break;
383
+ case "productSkus":
384
+ (_b2 = callbacks.onProductSkus) == null ? void 0 : _b2.call(callbacks, event.skus);
385
+ break;
386
+ case "navigation":
387
+ console.log("Navigation event:", event.navigationOperations);
388
+ break;
389
+ case "cart":
390
+ (_c2 = callbacks.onCartOperation) == null ? void 0 : _c2.call(callbacks, event.operations);
391
+ break;
392
+ case "close":
393
+ this.isLoading = false;
394
+ (_d = callbacks.onLoadingChange) == null ? void 0 : _d.call(callbacks, false);
395
+ (_e = callbacks.onComplete) == null ? void 0 : _e.call(callbacks);
396
+ break;
397
+ case "error":
398
+ this.error = event.reason;
399
+ this.isLoading = false;
400
+ (_f = callbacks.onLoadingChange) == null ? void 0 : _f.call(callbacks, false);
401
+ (_g = callbacks.onError) == null ? void 0 : _g.call(callbacks, event.reason);
402
+ break;
403
+ }
404
+ },
405
+ cartContext
406
+ );
407
+ } catch (err) {
408
+ const errorMessage = err instanceof Error ? err.message : "Unknown error";
409
+ this.error = errorMessage;
410
+ this.isLoading = false;
411
+ (_b = callbacks.onLoadingChange) == null ? void 0 : _b.call(callbacks, false);
412
+ (_c = callbacks.onError) == null ? void 0 : _c.call(callbacks, errorMessage);
413
+ }
414
+ return accumulatedText;
415
+ }
416
+ async getAgentExperience() {
417
+ console.log(
418
+ "## ~ ShopPrompterService ~ getAgentExperience ~ getAgentExperience:"
419
+ );
420
+ try {
421
+ return await shopPrompterApi.getAgentExperience();
422
+ } catch (err) {
423
+ console.error("Failed to fetch agent experience:", err);
424
+ throw err;
425
+ }
426
+ }
427
+ resetSession() {
428
+ sessionHandler.regenerate();
429
+ }
430
+ getStatus() {
431
+ return {
432
+ isLoading: this.isLoading,
433
+ error: this.error,
434
+ streamingText: this.streamingText
435
+ };
436
+ }
437
+ };
438
+
439
+ // src/shop-prompter.component.jsx
440
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
441
+ var styles = {
442
+ header: {
443
+ display: "flex",
444
+ alignItems: "center",
445
+ justifyContent: "space-between",
446
+ padding: "16px"
447
+ },
448
+ subHeaderContainer: {
449
+ display: "flex",
450
+ alignItems: "center",
451
+ gap: "0.5rem"
452
+ },
453
+ headerButton: {
454
+ fontSize: "0.75rem",
455
+ color: "#71717a",
456
+ padding: "0.25rem 0.5rem",
457
+ borderRadius: "0.25rem",
458
+ backgroundColor: "transparent",
459
+ border: "none",
460
+ cursor: "pointer",
461
+ transition: "background-color 0.2s, color 0.2s",
462
+ onHover: {
463
+ backgroundColor: "hsl(220 14% 96%)",
464
+ color: "hsl(220 13% 13%)"
465
+ }
466
+ },
467
+ headerText: {
468
+ color: "hsl(220 13% 13%)",
469
+ fontWeight: 600
470
+ },
471
+ button: {
472
+ padding: "0.625rem 1rem",
473
+ border: "1px solid #e5e7eb",
474
+ borderRadius: "0.75rem",
475
+ backgroundColor: "transparent",
476
+ transition: "background-color 0.2s, color 0.2s",
477
+ display: "flex",
478
+ alignItems: "center",
479
+ gap: "0.5rem",
480
+ cursor: "pointer",
481
+ fontSize: "0.875rem",
482
+ color: "#09090b"
483
+ },
484
+ ButtonSheetButton: {
485
+ color: "#6b7280",
486
+ backgroundColor: "transparent",
487
+ border: "none",
488
+ cursor: "pointer",
489
+ padding: "0.25rem",
490
+ fontSize: "1.25rem",
491
+ transition: "color 0.2s"
492
+ },
493
+ chatContainer: {
494
+ flex: 1,
495
+ overflowY: "auto",
496
+ padding: "1rem",
497
+ backgroundColor: "white"
498
+ },
499
+ welcomeContainer: {
500
+ textAlign: "center",
501
+ paddingTop: "3rem",
502
+ paddingBottom: "3rem",
503
+ display: "flex",
504
+ flexDirection: "column",
505
+ alignItems: "center"
506
+ },
507
+ welcomeTitle: {
508
+ color: "#111827",
509
+ marginBottom: "0.5rem",
510
+ fontFamily: 'var(--font-space-grotesk), "Space Grotesk", sans-serif',
511
+ fontWeight: 500,
512
+ fontStyle: "Medium",
513
+ fontSize: "32px",
514
+ leadingTrim: "NONE",
515
+ lineHeight: "100%",
516
+ letterSpacing: "0%",
517
+ textAlign: "center"
518
+ },
519
+ welcomeDescription: {
520
+ color: "#4b5563",
521
+ maxWidth: "20rem",
522
+ fontFamily: 'var(--font-space-grotesk), "Space Grotesk", sans-serif',
523
+ fontWeight: 400,
524
+ fontStyle: "Regular",
525
+ fontSize: "16px",
526
+ leadingTrim: "NONE",
527
+ lineHeight: "100%",
528
+ letterSpacing: "0%",
529
+ textAlign: "center"
530
+ },
531
+ buttonContainer: {
532
+ marginTop: "2rem",
533
+ display: "flex",
534
+ flexWrap: "wrap",
535
+ justifyContent: "center",
536
+ gap: "0.5rem"
537
+ },
538
+ messageContainerUser: {
539
+ display: "flex",
540
+ flexDirection: "column",
541
+ alignItems: "flex-end"
542
+ },
543
+ messageContainerAssistant: {
544
+ display: "flex",
545
+ flexDirection: "column",
546
+ alignItems: "flex-start"
547
+ },
548
+ messageBubbleUser: {
549
+ backgroundColor: "#111827",
550
+ color: "white",
551
+ borderRadius: "1rem",
552
+ borderTopRightRadius: "0",
553
+ padding: "0.5rem 1rem",
554
+ fontSize: "0.875rem",
555
+ boxShadow: "0 1px 2px 0 rgba(0, 0, 0, 0.05)",
556
+ maxWidth: "85%"
557
+ },
558
+ messageBubbleAssistant: {
559
+ backgroundColor: "#f3f4f6",
560
+ color: "#1f2937",
561
+ borderRadius: "1rem",
562
+ borderTopLeftRadius: "0",
563
+ padding: "0.5rem 1rem",
564
+ fontSize: "0.875rem",
565
+ boxShadow: "0 1px 2px 0 rgba(0, 0, 0, 0.05)",
566
+ maxWidth: "85%"
567
+ },
568
+ thinkingIndicator: {
569
+ display: "flex",
570
+ alignItems: "center",
571
+ gap: "0.5rem",
572
+ fontStyle: "italic",
573
+ color: "#6b7280"
574
+ },
575
+ productCardsContainer: {
576
+ marginTop: "1rem",
577
+ display: "flex",
578
+ gap: "0.75rem",
579
+ overflowX: "auto",
580
+ width: "100%",
581
+ paddingBottom: "0.5rem"
582
+ },
583
+ productCard: {
584
+ minWidth: "8rem",
585
+ backgroundColor: "white",
586
+ border: "1px solid #e5e7eb",
587
+ borderRadius: "0.75rem",
588
+ overflow: "hidden",
589
+ boxShadow: "0 1px 2px 0 rgba(0, 0, 0, 0.05)",
590
+ display: "flex",
591
+ flexDirection: "column"
592
+ },
593
+ productImageContainer: {
594
+ height: "6rem",
595
+ backgroundColor: "#f9fafb",
596
+ display: "flex",
597
+ alignItems: "center",
598
+ justifyContent: "center",
599
+ padding: "0.5rem"
600
+ },
601
+ productInfo: {
602
+ padding: "0.5rem"
603
+ },
604
+ productSku: {
605
+ fontSize: "0.75rem",
606
+ fontWeight: 600,
607
+ overflow: "hidden",
608
+ textOverflow: "ellipsis",
609
+ whiteSpace: "nowrap",
610
+ color: "#111827"
611
+ },
612
+ productLink: {
613
+ fontSize: "0.625rem",
614
+ color: "#2563eb",
615
+ fontWeight: "bold",
616
+ textDecoration: "none"
617
+ },
618
+ errorContainer: {
619
+ padding: "0.75rem",
620
+ backgroundColor: "#fef2f2",
621
+ border: "1px solid #fecaca",
622
+ color: "#dc2626",
623
+ fontSize: "0.75rem",
624
+ borderRadius: "0.5rem"
625
+ },
626
+ inputSection: {
627
+ padding: "1rem",
628
+ borderTop: "1px solid #e5e7eb",
629
+ backgroundColor: "#f9fafb"
630
+ },
631
+ inputWrapper: {
632
+ display: "flex",
633
+ alignItems: "center",
634
+ gap: "0.5rem",
635
+ backgroundColor: "white",
636
+ border: "1px solid #d1d5db",
637
+ borderRadius: "0.75rem",
638
+ padding: "0.5rem 1rem",
639
+ transition: "all 0.2s"
640
+ },
641
+ input: {
642
+ flex: 1,
643
+ backgroundColor: "transparent",
644
+ border: "none",
645
+ outline: "none",
646
+ fontSize: "0.875rem",
647
+ color: "#111827",
648
+ padding: "0.25rem 0"
649
+ },
650
+ formButton: {
651
+ backgroundColor: "transparent",
652
+ color: "white",
653
+ width: "32px",
654
+ height: "32px",
655
+ borderRadius: "0.5rem",
656
+ padding: 0,
657
+ fontSize: "0.75rem",
658
+ fontWeight: "bold",
659
+ border: "none",
660
+ cursor: "pointer",
661
+ transition: "background-color 0.2s"
662
+ },
663
+ sendButton: {
664
+ backgroundColor: "#AD59FF1A"
665
+ },
666
+ disclaimer: {
667
+ fontSize: "0.625rem",
668
+ color: "#9ca3af",
669
+ textAlign: "center",
670
+ marginTop: "0.75rem"
671
+ }
672
+ };
673
+ var TRANSLATIONS = {
674
+ newChat: "New Chat",
675
+ welcomeToShopPrompter: "Welcome to ShopPrompter",
676
+ welcomeDescription: "I am your personal AI shopping assistant. Ask me anything about our products!",
677
+ askMeAnything: "Ask me anything...",
678
+ thinking: "Thinking...",
679
+ showPopularItems: "Show popular items",
680
+ compareProducts: "Compare products",
681
+ findByBudget: "Find by budget"
682
+ };
683
+ var ICONS = {
684
+ chat: "https://cdn.jsdelivr.net/gh/lucide-icons/lucide@latest/icons/message-square.svg",
685
+ shopprompter: "https://cdn.jsdelivr.net/gh/lucide-icons/lucide@latest/icons/bot.svg",
686
+ popularitems: "https://cdn.jsdelivr.net/gh/lucide-icons/lucide@latest/icons/fire.svg",
687
+ compareproducts: "https://cdn.jsdelivr.net/gh/lucide-icons/lucide@latest/icons/box.svg",
688
+ findbybudget: "https://cdn.jsdelivr.net/gh/lucide-icons/lucide@latest/icons/foto.svg",
689
+ sendHorizontal: "https://cdn.jsdelivr.net/gh/lucide-icons/lucide@latest/icons/send-horizontal.svg"
690
+ };
691
+ function ShopPrompter(props) {
692
+ var _a, _b, _c;
693
+ const [input, setInput] = useState(() => "");
694
+ const [isLoading, setIsLoading] = useState(() => false);
695
+ const [error, setError] = useState(() => null);
696
+ const [chatMessages, setChatMessages] = useState(() => []);
697
+ const [showChat, setShowChat] = useState(
698
+ () => props.chatPosition === "right-panel" || props.chatPosition === "full-page"
699
+ );
700
+ const [service, setService] = useState(() => null);
701
+ const [isHeaderButtonHovered, setIsHeaderButtonHovered] = useState(
702
+ () => false
703
+ );
704
+ const [agentExperience, setAgentExperience] = useState(() => null);
705
+ function containerStyle() {
706
+ const pos = props.chatPosition || "classic-chatbot";
707
+ const isFull = pos === "full-page";
708
+ const isBottom = pos === "bottom-sheet";
709
+ const isClassic = pos === "classic-chatbot";
710
+ const isRight = pos === "right-panel";
711
+ return {
712
+ position: isFull ? "relative" : "fixed",
713
+ bottom: isClassic ? "1rem" : isBottom ? "2rem" : "0",
714
+ right: isClassic || isRight ? "1rem" : "0",
715
+ width: isFull ? "100%" : isBottom ? "90%" : "24rem",
716
+ height: isClassic ? "550px" : isBottom ? "700px" : "100%",
717
+ maxWidth: isBottom ? "900px" : "none",
718
+ left: isBottom ? "50%" : "auto",
719
+ transform: isBottom ? "translateX(-50%)" : "none",
720
+ zIndex: 50,
721
+ backgroundColor: "white",
722
+ display: "flex",
723
+ flexDirection: "column",
724
+ overflow: "hidden",
725
+ borderRadius: isFull ? "0" : "0.5rem",
726
+ border: isFull ? "none" : "1px solid #e5e7eb",
727
+ boxShadow: isFull ? "none" : "0 25px 50px -12px rgba(0, 0, 0, 0.25)"
728
+ };
729
+ }
730
+ function containerClass() {
731
+ const pos = props.chatPosition || "classic-chatbot";
732
+ if (pos === "classic-chatbot") return "sh-classic";
733
+ if (pos === "right-panel") return "sh-right";
734
+ if (pos === "bottom-sheet") return "sh-bottom";
735
+ return "sh-full";
736
+ }
737
+ function messages() {
738
+ return chatMessages.map((msg) => ({
739
+ ...msg,
740
+ safeProductSkus: msg.productSkus || []
741
+ }));
742
+ }
743
+ function showWelcome() {
744
+ return chatMessages.length === 0;
745
+ }
746
+ function getProductImageUrl(sku) {
747
+ return "https://placehold.co/100x100?text=" + sku;
748
+ }
749
+ function getProductLink(sku) {
750
+ return "/product/" + sku;
751
+ }
752
+ function handleSend() {
753
+ if (!input.trim() || isLoading) return;
754
+ const userQuery = input;
755
+ setInput("");
756
+ const userMsg = {
757
+ id: Date.now().toString() + "-user",
758
+ role: "user",
759
+ content: userQuery,
760
+ productSkus: []
761
+ };
762
+ setChatMessages([...chatMessages, userMsg]);
763
+ const assistantMsg = {
764
+ id: Date.now().toString() + "-assistant",
765
+ role: "assistant",
766
+ content: "",
767
+ productSkus: []
768
+ };
769
+ setChatMessages([...chatMessages, assistantMsg]);
770
+ service == null ? void 0 : service.sendMessage(
771
+ userQuery,
772
+ {
773
+ onTextUpdate: (text) => {
774
+ const updatedMessages = [...chatMessages];
775
+ const lastMsg = updatedMessages[updatedMessages.length - 1];
776
+ if (lastMsg) {
777
+ lastMsg.content = text;
778
+ setChatMessages(updatedMessages);
779
+ }
780
+ },
781
+ onProductSkus: (skus) => {
782
+ const updatedMessages = [...chatMessages];
783
+ const lastMsg = updatedMessages[updatedMessages.length - 1];
784
+ if (lastMsg) {
785
+ lastMsg.productSkus = skus;
786
+ setChatMessages(updatedMessages);
787
+ }
788
+ },
789
+ onLoadingChange: (loading) => {
790
+ setIsLoading(loading);
791
+ },
792
+ onError: (err) => {
793
+ setError(err);
794
+ },
795
+ onCartOperation: (ops) => {
796
+ if (props.onCartOperation) {
797
+ props.onCartOperation(ops);
798
+ }
799
+ }
800
+ },
801
+ props.cart || []
802
+ );
803
+ }
804
+ function toggleChat() {
805
+ setShowChat(!showChat);
806
+ if (!showChat && props.onClose) {
807
+ props.onClose();
808
+ }
809
+ }
810
+ function handleNewChat() {
811
+ setChatMessages([]);
812
+ service == null ? void 0 : service.resetSession();
813
+ }
814
+ function onPopularItemsClick() {
815
+ setInput(TRANSLATIONS.showPopularItems);
816
+ handleSend();
817
+ }
818
+ function onCompareProductsClick() {
819
+ setInput(TRANSLATIONS.compareProducts);
820
+ handleSend();
821
+ }
822
+ function onInputChange(event) {
823
+ setInput(event.target.value);
824
+ }
825
+ function onInputKeyDown(event) {
826
+ if (event.key === "Enter") {
827
+ handleSend();
828
+ }
829
+ }
830
+ function onHeaderButtonMouseEnter() {
831
+ setIsHeaderButtonHovered(true);
832
+ }
833
+ function onHeaderButtonMouseLeave() {
834
+ setIsHeaderButtonHovered(false);
835
+ }
836
+ function doSomethingAsync() {
837
+ void (async function() {
838
+ console.log("## ~ ShopPrompter ~ state.service:", service);
839
+ if (!service) {
840
+ console.warn("Service not initialized yet");
841
+ return;
842
+ }
843
+ const response = await (service == null ? void 0 : service.getAgentExperience());
844
+ console.log("## ~ ShopPrompter ~ response:", response);
845
+ setAgentExperience(response);
846
+ })();
847
+ }
848
+ useEffect(() => {
849
+ const shopPrompterService = new ShopPrompterService();
850
+ setService(shopPrompterService);
851
+ }, []);
852
+ useEffect(() => {
853
+ if (service && !agentExperience) {
854
+ doSomethingAsync();
855
+ }
856
+ if (agentExperience) {
857
+ console.log("## ~ ShopPrompter ~ agentExperience updated:", {
858
+ greeting: agentExperience.greeting,
859
+ agentLogoUrl: agentExperience.agentLogoUrl
860
+ });
861
+ }
862
+ }, [service, agentExperience]);
863
+ return /* @__PURE__ */ jsxs("div", { className: "shopprompter-sdk", children: [
864
+ props.chatPosition === "classic-chatbot" ? /* @__PURE__ */ jsx(Fragment, { children: !showChat ? /* @__PURE__ */ jsx(
865
+ "button",
866
+ {
867
+ className: "fixed bottom-6 right-6 w-16 h-16 bg-blue-600 hover:bg-blue-700 rounded-full shadow-lg z-50 flex items-center justify-center transition-colors border-none cursor-pointer",
868
+ onClick: (e) => toggleChat(),
869
+ style: {
870
+ boxShadow: "0 0 0 8px rgba(37, 99, 235, 0.2)"
871
+ },
872
+ children: /* @__PURE__ */ jsx(
873
+ "img",
874
+ {
875
+ alt: "Chat",
876
+ src: ICONS.chat,
877
+ style: {
878
+ width: "28px",
879
+ height: "28px"
880
+ }
881
+ }
882
+ )
883
+ }
884
+ ) : null }) : null,
885
+ showChat ? /* @__PURE__ */ jsxs("div", { style: containerStyle(), className: containerClass(), children: [
886
+ /* @__PURE__ */ jsxs("div", { style: styles.header, children: [
887
+ /* @__PURE__ */ jsxs("div", { style: styles.subHeaderContainer, children: [
888
+ /* @__PURE__ */ jsxs(
889
+ "svg",
890
+ {
891
+ xmlns: "http://www.w3.org/2000/svg",
892
+ viewBox: "0 0 46 47",
893
+ width: "24",
894
+ height: "24",
895
+ fill: "none",
896
+ children: [
897
+ /* @__PURE__ */ jsx(
898
+ "path",
899
+ {
900
+ fill: "url(#a)",
901
+ d: "M16.452 32.747c-1.587 0-2.874-1.3-2.874-2.903V14.25h5.259V0H5.747C2.576 0 0 2.6 0 5.806v21.139c0 3.208 2.575 5.805 5.748 5.805h10.704v-.003Z"
902
+ }
903
+ ),
904
+ /* @__PURE__ */ jsx(
905
+ "path",
906
+ {
907
+ fill: "url(#b)",
908
+ d: "M19.326 0c-3.173 0-5.748 2.6-5.748 5.806v8.444h15.438c1.586 0 2.874 1.3 2.874 2.902v3.924H46V0H19.326Z"
909
+ }
910
+ ),
911
+ /* @__PURE__ */ jsx(
912
+ "path",
913
+ {
914
+ fill: "url(#c)",
915
+ d: "M40.252 14.25H29.016c1.586 0 2.874 1.3 2.874 2.902v15.595h-6.751V47h15.117c3.173 0 5.748-2.6 5.748-5.806V20.055c0-3.205-2.575-5.806-5.748-5.806h-.004Z"
916
+ }
917
+ ),
918
+ /* @__PURE__ */ jsx(
919
+ "path",
920
+ {
921
+ fill: "url(#d)",
922
+ d: "M8.669 32.75H5.751c-3.173 0-5.747-2.6-5.747-5.805V47h26.142c3.172 0 5.747-2.6 5.747-5.806V32.75H8.67Z"
923
+ }
924
+ ),
925
+ /* @__PURE__ */ jsxs("defs", { children: [
926
+ /* @__PURE__ */ jsxs(
927
+ "linearGradient",
928
+ {
929
+ id: "a",
930
+ x1: "14.3",
931
+ x2: "3.322",
932
+ y1: "22.494",
933
+ y2: "4.382",
934
+ gradientUnits: "userSpaceOnUse",
935
+ children: [
936
+ /* @__PURE__ */ jsx("stop", { stopColor: "#B0145C" }),
937
+ /* @__PURE__ */ jsx("stop", { offset: ".37", stopColor: "#AE2E9A" }),
938
+ /* @__PURE__ */ jsx("stop", { offset: "1", stopColor: "#AD59FF" })
939
+ ]
940
+ }
941
+ ),
942
+ /* @__PURE__ */ jsxs(
943
+ "linearGradient",
944
+ {
945
+ id: "b",
946
+ x1: "21.156",
947
+ x2: "40.431",
948
+ y1: "21.216",
949
+ y2: "1.624",
950
+ gradientUnits: "userSpaceOnUse",
951
+ children: [
952
+ /* @__PURE__ */ jsx("stop", { offset: ".08", stopColor: "#E7A2FF" }),
953
+ /* @__PURE__ */ jsx("stop", { offset: ".37", stopColor: "#E983CD" }),
954
+ /* @__PURE__ */ jsx("stop", { offset: ".99", stopColor: "#F03A58" })
955
+ ]
956
+ }
957
+ ),
958
+ /* @__PURE__ */ jsxs(
959
+ "linearGradient",
960
+ {
961
+ id: "c",
962
+ x1: "30.464",
963
+ x2: "46.567",
964
+ y1: "27.405",
965
+ y2: "42.472",
966
+ gradientUnits: "userSpaceOnUse",
967
+ children: [
968
+ /* @__PURE__ */ jsx("stop", { stopColor: "#B0145C" }),
969
+ /* @__PURE__ */ jsx("stop", { offset: ".02", stopColor: "#B11861" }),
970
+ /* @__PURE__ */ jsx("stop", { offset: ".27", stopColor: "#C44999" }),
971
+ /* @__PURE__ */ jsx("stop", { offset: ".5", stopColor: "#D36FC5" }),
972
+ /* @__PURE__ */ jsx("stop", { offset: ".71", stopColor: "#DE8BE4" }),
973
+ /* @__PURE__ */ jsx("stop", { offset: ".88", stopColor: "#E49BF8" }),
974
+ /* @__PURE__ */ jsx("stop", { offset: "1", stopColor: "#E7A2FF" })
975
+ ]
976
+ }
977
+ ),
978
+ /* @__PURE__ */ jsxs(
979
+ "linearGradient",
980
+ {
981
+ id: "d",
982
+ x1: "23.356",
983
+ x2: "-.618",
984
+ y1: "44.082",
985
+ y2: "30.739",
986
+ gradientUnits: "userSpaceOnUse",
987
+ children: [
988
+ /* @__PURE__ */ jsx("stop", { stopColor: "#AD59FF" }),
989
+ /* @__PURE__ */ jsx("stop", { offset: ".1", stopColor: "#B455EB" }),
990
+ /* @__PURE__ */ jsx("stop", { offset: ".54", stopColor: "#D4469C" }),
991
+ /* @__PURE__ */ jsx("stop", { offset: ".85", stopColor: "#E83D6B" }),
992
+ /* @__PURE__ */ jsx("stop", { offset: "1", stopColor: "#F03A58" })
993
+ ]
994
+ }
995
+ )
996
+ ] })
997
+ ]
998
+ }
999
+ ),
1000
+ /* @__PURE__ */ jsx("span", { style: styles.headerText, children: "ShopPrompter\xAE" })
1001
+ ] }),
1002
+ /* @__PURE__ */ jsxs("div", { style: styles.subHeaderContainer, children: [
1003
+ /* @__PURE__ */ jsx(
1004
+ "button",
1005
+ {
1006
+ onClick: (e) => handleNewChat(),
1007
+ onMouseEnter: (e) => onHeaderButtonMouseEnter(),
1008
+ onMouseLeave: (e) => onHeaderButtonMouseLeave(),
1009
+ style: {
1010
+ ...styles.headerButton,
1011
+ ...isHeaderButtonHovered ? styles.headerButton.onHover : {}
1012
+ },
1013
+ children: TRANSLATIONS.newChat
1014
+ }
1015
+ ),
1016
+ props.chatPosition === "classic-chatbot" || props.chatPosition === "right-panel" || props.chatPosition === "bottom-sheet" ? /* @__PURE__ */ jsx(
1017
+ "button",
1018
+ {
1019
+ onClick: (e) => toggleChat(),
1020
+ style: styles.ButtonSheetButton,
1021
+ children: "\xD7"
1022
+ }
1023
+ ) : null
1024
+ ] })
1025
+ ] }),
1026
+ /* @__PURE__ */ jsxs("div", { style: styles.chatContainer, children: [
1027
+ showWelcome() ? /* @__PURE__ */ jsxs("div", { style: styles.welcomeContainer, children: [
1028
+ /* @__PURE__ */ jsx(
1029
+ "img",
1030
+ {
1031
+ alt: "ShopPrompter",
1032
+ src: (agentExperience == null ? void 0 : agentExperience.agentLogoUrl) ? agentExperience.agentLogoUrl : ICONS.shopprompter,
1033
+ style: {
1034
+ width: "64px",
1035
+ height: "64px",
1036
+ marginBottom: "24px"
1037
+ }
1038
+ }
1039
+ ),
1040
+ /* @__PURE__ */ jsx("h3", { style: styles.welcomeTitle, children: ((_a = agentExperience == null ? void 0 : agentExperience.greeting) == null ? void 0 : _a.title) || TRANSLATIONS.welcomeToShopPrompter }),
1041
+ /* @__PURE__ */ jsx("p", { style: styles.welcomeDescription, children: ((_b = agentExperience == null ? void 0 : agentExperience.greeting) == null ? void 0 : _b.description) || TRANSLATIONS.welcomeDescription }),
1042
+ /* @__PURE__ */ jsxs("div", { style: styles.buttonContainer, children: [
1043
+ /* @__PURE__ */ jsx(
1044
+ "button",
1045
+ {
1046
+ style: styles.button,
1047
+ onClick: (e) => onPopularItemsClick(),
1048
+ children: TRANSLATIONS.showPopularItems
1049
+ }
1050
+ ),
1051
+ /* @__PURE__ */ jsx(
1052
+ "button",
1053
+ {
1054
+ style: styles.button,
1055
+ onClick: (e) => onCompareProductsClick(),
1056
+ children: TRANSLATIONS.compareProducts
1057
+ }
1058
+ )
1059
+ ] })
1060
+ ] }) : /* @__PURE__ */ jsx(Fragment, { children: (_c = messages()) == null ? void 0 : _c.map((message) => {
1061
+ var _a2;
1062
+ return /* @__PURE__ */ jsxs(
1063
+ "div",
1064
+ {
1065
+ style: message.role === "user" ? styles.messageContainerUser : styles.messageContainerAssistant,
1066
+ children: [
1067
+ /* @__PURE__ */ jsxs(
1068
+ "div",
1069
+ {
1070
+ style: message.role === "user" ? styles.messageBubbleUser : styles.messageBubbleAssistant,
1071
+ children: [
1072
+ message.content,
1073
+ !message.content ? /* @__PURE__ */ jsx(Fragment, { children: message.role === "assistant" ? /* @__PURE__ */ jsx(Fragment, { children: isLoading ? /* @__PURE__ */ jsx("div", { style: styles.thinkingIndicator, children: TRANSLATIONS.thinking }) : null }) : null }) : null
1074
+ ]
1075
+ }
1076
+ ),
1077
+ message.role === "assistant" ? /* @__PURE__ */ jsx("div", { style: styles.productCardsContainer, children: (_a2 = message.safeProductSkus) == null ? void 0 : _a2.map((sku) => /* @__PURE__ */ jsxs("div", { style: styles.productCard, children: [
1078
+ /* @__PURE__ */ jsx("div", { style: styles.productImageContainer, children: /* @__PURE__ */ jsx(
1079
+ "img",
1080
+ {
1081
+ src: getProductImageUrl(sku),
1082
+ alt: sku,
1083
+ style: {
1084
+ maxHeight: "100%",
1085
+ maxWidth: "100%"
1086
+ }
1087
+ }
1088
+ ) }),
1089
+ /* @__PURE__ */ jsxs("div", { style: styles.productInfo, children: [
1090
+ /* @__PURE__ */ jsx("p", { style: styles.productSku, children: sku }),
1091
+ /* @__PURE__ */ jsx(
1092
+ "a",
1093
+ {
1094
+ href: getProductLink(sku),
1095
+ style: styles.productLink,
1096
+ children: "VIEW DETAILS"
1097
+ }
1098
+ )
1099
+ ] })
1100
+ ] }, sku)) }) : null
1101
+ ]
1102
+ },
1103
+ message.id
1104
+ );
1105
+ }) }),
1106
+ error ? /* @__PURE__ */ jsxs("div", { style: styles.errorContainer, children: [
1107
+ "Error: ",
1108
+ error
1109
+ ] }) : null
1110
+ ] }),
1111
+ /* @__PURE__ */ jsxs("div", { style: styles.inputSection, children: [
1112
+ /* @__PURE__ */ jsxs("div", { style: styles.inputWrapper, children: [
1113
+ /* @__PURE__ */ jsx(
1114
+ "input",
1115
+ {
1116
+ type: "text",
1117
+ style: styles.input,
1118
+ placeholder: TRANSLATIONS.askMeAnything,
1119
+ value: input,
1120
+ onInput: (e) => onInputChange(e),
1121
+ onKeyDown: (e) => onInputKeyDown(e)
1122
+ }
1123
+ ),
1124
+ /* @__PURE__ */ jsx(
1125
+ "button",
1126
+ {
1127
+ onClick: (e) => handleSend(),
1128
+ style: {
1129
+ ...styles.formButton,
1130
+ ...styles.sendButton
1131
+ },
1132
+ children: /* @__PURE__ */ jsx("img", { alt: "Send", src: ICONS.sendHorizontal })
1133
+ }
1134
+ )
1135
+ ] }),
1136
+ /* @__PURE__ */ jsx("p", { style: styles.disclaimer, children: "AI content may be inaccurate." })
1137
+ ] })
1138
+ ] }) : null
1139
+ ] });
1140
+ }
1141
+ var shop_prompter_component_default = ShopPrompter;
1142
+ export {
1143
+ shop_prompter_component_default as ShopPrompter
1144
+ };