@blotoutio/providers-shop-gpt-sdk 1.4.0 → 1.6.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.
Files changed (4) hide show
  1. package/index.cjs.js +426 -13
  2. package/index.js +426 -13
  3. package/index.mjs +426 -13
  4. package/package.json +1 -1
package/index.mjs CHANGED
@@ -297,9 +297,73 @@ const isoCountries = new Map([
297
297
  ['ZM', 'Zambia'],
298
298
  ['ZW', 'Zimbabwe'],
299
299
  ]);
300
- new Set(isoCountries.keys());
300
+ /**
301
+ * ISO-3166 US state ISO codes
302
+ * @see https://en.wikipedia.org/wiki/ISO_3166-2:US
303
+ * */
304
+ const usStates = new Map([
305
+ ['US-AL', 'Alabama'],
306
+ ['US-AK', 'Alaska'],
307
+ ['US-AZ', 'Arizona'],
308
+ ['US-AR', 'Arkansas'],
309
+ ['US-CA', 'California'],
310
+ ['US-CO', 'Colorado'],
311
+ ['US-CT', 'Connecticut'],
312
+ ['US-DE', 'Delaware'],
313
+ ['US-FL', 'Florida'],
314
+ ['US-GA', 'Georgia'],
315
+ ['US-HI', 'Hawaii'],
316
+ ['US-ID', 'Idaho'],
317
+ ['US-IL', 'Illinois'],
318
+ ['US-IN', 'Indiana'],
319
+ ['US-IA', 'Iowa'],
320
+ ['US-KS', 'Kansas'],
321
+ ['US-KY', 'Kentucky'],
322
+ ['US-LA', 'Louisiana'],
323
+ ['US-ME', 'Maine'],
324
+ ['US-MD', 'Maryland'],
325
+ ['US-MA', 'Massachusetts'],
326
+ ['US-MI', 'Michigan'],
327
+ ['US-MN', 'Minnesota'],
328
+ ['US-MS', 'Mississippi'],
329
+ ['US-MO', 'Missouri'],
330
+ ['US-MT', 'Montana'],
331
+ ['US-NE', 'Nebraska'],
332
+ ['US-NV', 'Nevada'],
333
+ ['US-NH', 'New Hampshire'],
334
+ ['US-NJ', 'New Jersey'],
335
+ ['US-NM', 'New Mexico'],
336
+ ['US-NY', 'New York'],
337
+ ['US-NC', 'North Carolina'],
338
+ ['US-ND', 'North Dakota'],
339
+ ['US-OH', 'Ohio'],
340
+ ['US-OK', 'Oklahoma'],
341
+ ['US-OR', 'Oregon'],
342
+ ['US-PA', 'Pennsylvania'],
343
+ ['US-RI', 'Rhode Island'],
344
+ ['US-SC', 'South Carolina'],
345
+ ['US-SD', 'South Dakota'],
346
+ ['US-TN', 'Tennessee'],
347
+ ['US-TX', 'Texas'],
348
+ ['US-UT', 'Utah'],
349
+ ['US-VT', 'Vermont'],
350
+ ['US-VA', 'Virginia'],
351
+ ['US-WA', 'Washington'],
352
+ ['US-WV', 'West Virginia'],
353
+ ['US-WI', 'Wisconsin'],
354
+ ['US-WY', 'Wyoming'],
355
+ ['US-DC', 'District of Columbia'],
356
+ ['US-AS', 'American Samoa'],
357
+ ['US-GU', 'Guam'],
358
+ ['US-MP', 'Northern Mariana Islands'],
359
+ ['US-PR', 'Puerto Rico'],
360
+ ['US-UM', 'United States Minor Outlying Islands'],
361
+ ['US-VI', 'Virgin Islands, U.S.'],
362
+ ]);
363
+ new Set([...isoCountries.keys(), ...usStates.keys()]);
301
364
 
302
365
  const packageName = 'shopGPT';
366
+ const DEFAULT_MAX_THREAD_AGE = 14;
303
367
  const previewKeyName = 'previewShopGPT';
304
368
 
305
369
  const canLog = () => {
@@ -379,6 +443,7 @@ const createShopGPTAPI = ({ fetch: fetchImpl = window.fetch, baseURL, userId, st
379
443
  }
380
444
  const data = (await response.json());
381
445
  return {
446
+ messageId: data.messageId,
382
447
  message: data.message,
383
448
  products: (_a = data.products) === null || _a === void 0 ? void 0 : _a.filter((item) => !!item).map((item) => ({ ...item, quantity: 1 })),
384
449
  chatTitle: data.chatTitle,
@@ -449,6 +514,20 @@ const createShopGPTAPI = ({ fetch: fetchImpl = window.fetch, baseURL, userId, st
449
514
  throw new Error(`Failed to delete all chat threads - ${response.status}: ${await response.text()}`);
450
515
  }
451
516
  };
517
+ const saveFeedback = async (messageId, feedback) => {
518
+ const response = await fetchImpl(getURL('/feedback'), {
519
+ method: 'POST',
520
+ headers: getHeaders(),
521
+ credentials: 'include',
522
+ body: JSON.stringify({
523
+ messageId,
524
+ feedback,
525
+ }),
526
+ });
527
+ if (!response.ok) {
528
+ throw new Error(`Failed to save feedback - ${response.status}: ${await response.text()}`);
529
+ }
530
+ };
452
531
  return {
453
532
  processQuery,
454
533
  fetchChatHistory,
@@ -456,6 +535,7 @@ const createShopGPTAPI = ({ fetch: fetchImpl = window.fetch, baseURL, userId, st
456
535
  createChatThread,
457
536
  deleteSingleThread,
458
537
  deleteAllThreads,
538
+ saveFeedback,
459
539
  };
460
540
  };
461
541
 
@@ -489,7 +569,7 @@ const init = (params) => {
489
569
  // exit if not in top window
490
570
  return;
491
571
  }
492
- const { enabled, devMode, merchantUrl, profiles, productHandles, targetPath, uiMode, brandName, quickPrompts, merchantImage, } = (_c = params.manifest.variables) !== null && _c !== void 0 ? _c : {};
572
+ const { enabled, devMode, merchantUrl, profiles, productHandles, targetPath, uiMode, brandName, quickPrompts, merchantImage, latestThreadLoad, } = (_c = params.manifest.variables) !== null && _c !== void 0 ? _c : {};
493
573
  let shouldShowUI = enabled;
494
574
  if (!enabled && hasPreviewKey()) {
495
575
  logger.log('Enabling UI in preview mode');
@@ -518,6 +598,7 @@ const init = (params) => {
518
598
  brandName,
519
599
  quickPrompts,
520
600
  merchantImage,
601
+ latestThreadLoad: latestThreadLoad !== null && latestThreadLoad !== void 0 ? latestThreadLoad : DEFAULT_MAX_THREAD_AGE,
521
602
  });
522
603
  }
523
604
  };
@@ -1579,14 +1660,18 @@ class ProductsList extends r$2 {
1579
1660
  super(...arguments);
1580
1661
  this.showButtons = true;
1581
1662
  this.updateButtonsState = () => {
1582
- if (!this.leftBtnEle || !this.productsEle || !this.rightBtnEle) {
1663
+ if (!this.productsEle) {
1583
1664
  return;
1584
1665
  }
1585
1666
  const { scrollWidth, clientWidth } = this.productsEle;
1586
1667
  this.showButtons = scrollWidth > clientWidth;
1587
- this.leftBtnEle.classList.toggle('disabled', this.productsEle.scrollLeft === 0);
1668
+ if (this.leftBtnEle) {
1669
+ this.leftBtnEle.classList.toggle('disabled', this.productsEle.scrollLeft === 0);
1670
+ }
1588
1671
  const maxScroll = this.productsEle.scrollWidth - this.productsEle.clientWidth;
1589
- this.rightBtnEle.classList.toggle('disabled', this.productsEle.scrollLeft >= maxScroll - 1);
1672
+ if (this.rightBtnEle) {
1673
+ this.rightBtnEle.classList.toggle('disabled', this.productsEle.scrollLeft >= maxScroll - 1);
1674
+ }
1590
1675
  };
1591
1676
  }
1592
1677
  connectedCallback() {
@@ -1994,6 +2079,26 @@ const chatSectionStyles = i$4 `
1994
2079
  }
1995
2080
  }
1996
2081
 
2082
+ .bot-response-actions {
2083
+ display: flex;
2084
+ margin-left: 12px;
2085
+ margin-top: -10px;
2086
+
2087
+ button {
2088
+ display: flex;
2089
+ align-items: center;
2090
+ justify-content: center;
2091
+ padding: 8px;
2092
+ background: none;
2093
+ color: rgb(140, 137, 156);
2094
+ border-radius: 50%;
2095
+
2096
+ &:hover {
2097
+ background-color: rgba(47, 43, 61, 0.08);
2098
+ }
2099
+ }
2100
+ }
2101
+
1997
2102
  .bot-icon {
1998
2103
  display: flex;
1999
2104
  padding: 8px 11px;
@@ -2253,6 +2358,18 @@ const timerBtn = b `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="2
2253
2358
  const crossBtn = b `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none">
2254
2359
  <path d="M18 7.05L16.95 6L12 10.95L7.05 6L6 7.05L10.95 12L6 16.95L7.05 18L12 13.05L16.95 18L18 16.95L13.05 12L18 7.05Z" fill="white"/>
2255
2360
  </svg>`;
2361
+ const thumbsUpBtn = b `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--tabler" font-size="1.375rem" width="1em" height="1em" viewBox="0 0 24 24">
2362
+ <path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M7 11v8a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1v-7a1 1 0 0 1 1-1h3a4 4 0 0 0 4-4V6a2 2 0 0 1 4 0v5h3a2 2 0 0 1 2 2l-1 5a2 3 0 0 1-2 2h-7a3 3 0 0 1-3-3"></path>
2363
+ </svg>`;
2364
+ const thumbsUpFilledBtn = b `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--tabler" font-size="1.375rem" width="1em" height="1em" viewBox="0 0 24 24">
2365
+ <path fill="currentColor" d="M13 3a3 3 0 0 1 2.995 2.824L16 6v4h2a3 3 0 0 1 2.98 2.65l.015.174L21 13l-.02.196l-1.006 5.032c-.381 1.626-1.502 2.796-2.81 2.78L17 21H9a1 1 0 0 1-.993-.883L8 20l.001-9.536a1 1 0 0 1 .5-.865a3 3 0 0 0 1.492-2.397L10 7V6a3 3 0 0 1 3-3m-8 7a1 1 0 0 1 .993.883L6 11v9a1 1 0 0 1-.883.993L5 21H4a2 2 0 0 1-1.995-1.85L2 19v-7a2 2 0 0 1 1.85-1.995L4 10z"></path>
2366
+ </svg>`;
2367
+ const thumbsDownBtn = b `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--tabler" font-size="1.375rem" width="1em" height="1em" viewBox="0 0 24 24">
2368
+ <path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M7 13V5a1 1 0 0 0-1-1H4a1 1 0 0 0-1 1v7a1 1 0 0 0 1 1h3a4 4 0 0 1 4 4v1a2 2 0 0 0 4 0v-5h3a2 2 0 0 0 2-2l-1-5a2 3 0 0 0-2-2h-7a3 3 0 0 0-3 3"></path>
2369
+ </svg>`;
2370
+ const thumbsDownFilledBtn = b `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--tabler" font-size="1.375rem" width="1em" height="1em" viewBox="0 0 24 24">
2371
+ <path fill="currentColor" d="M13 21.008a3 3 0 0 0 2.995-2.823l.005-.177v-4h2a3 3 0 0 0 2.98-2.65l.015-.173l.005-.177l-.02-.196l-1.006-5.032c-.381-1.625-1.502-2.796-2.81-2.78L17 3.008H9a1 1 0 0 0-.993.884L8 4.008l.001 9.536a1 1 0 0 0 .5.866a3 3 0 0 1 1.492 2.396l.007.202v1a3 3 0 0 0 3 3m-8-7a1 1 0 0 0 .993-.883L6 13.008v-9a1 1 0 0 0-.883-.993L5 3.008H4A2 2 0 0 0 2.005 4.86L2 5.01v7a2 2 0 0 0 1.85 1.994l.15.005h1z"></path>
2372
+ </svg>`;
2256
2373
 
2257
2374
  const personalizeDialogStyles = i$4 `
2258
2375
  :host {
@@ -3156,6 +3273,212 @@ if (!customElements.get('confirm-dialog')) {
3156
3273
  customElements.define('confirm-dialog', ConfirmDialog);
3157
3274
  }
3158
3275
 
3276
+ const feedbackDialogStyles = i$4 `
3277
+ :host {
3278
+ font-family: 'Inter', sans-serif;
3279
+ font-size: 16px;
3280
+ line-height: 24px;
3281
+ font-weight: 400;
3282
+
3283
+ display: flex;
3284
+ position: absolute;
3285
+ top: 0;
3286
+ left: 0;
3287
+ width: 100%;
3288
+ height: 100%;
3289
+ background: #00000050;
3290
+ }
3291
+
3292
+ .modal {
3293
+ width: 75%;
3294
+ max-width: 400px;
3295
+ background: #fff;
3296
+ padding: 24px;
3297
+ margin: auto;
3298
+
3299
+ border-radius: 8px;
3300
+ box-shadow: rgba(47, 43, 61, 0.28) 0px 8px 23px 0px;
3301
+
3302
+ z-index: 2000;
3303
+ }
3304
+
3305
+ .header {
3306
+ display: flex;
3307
+ justify-content: space-between;
3308
+ align-items: center;
3309
+ margin-bottom: 16px;
3310
+ }
3311
+
3312
+ .close {
3313
+ display: flex;
3314
+ justify-content: center;
3315
+ align-items: center;
3316
+ cursor: pointer;
3317
+ }
3318
+
3319
+ h3 {
3320
+ margin: 0;
3321
+ font-size: 20px;
3322
+ font-weight: 700;
3323
+ color: #172a41;
3324
+ line-height: 24px;
3325
+ }
3326
+
3327
+ form {
3328
+ display: flex;
3329
+ flex-direction: column;
3330
+ gap: 12px;
3331
+ margin: 0;
3332
+ }
3333
+
3334
+ textarea {
3335
+ padding: 16px;
3336
+ border: 1px solid #2f2b3d28;
3337
+ border-radius: 10px;
3338
+ font-size: 16px;
3339
+ resize: none;
3340
+ min-height: 104px;
3341
+ box-sizing: border-box;
3342
+ font-family: inherit;
3343
+ color: #4e647f;
3344
+ font-weight: 500;
3345
+ line-height: 24px;
3346
+
3347
+ &:focus {
3348
+ outline: none;
3349
+ box-shadow: rgba(57, 123, 244, 0.5) 0px 0px 4px;
3350
+ }
3351
+
3352
+ &::placeholder {
3353
+ font-style: italic;
3354
+ color: #8799af80;
3355
+ }
3356
+ }
3357
+
3358
+ .btns-container {
3359
+ display: flex;
3360
+ gap: 0 8px;
3361
+ margin-left: auto;
3362
+ margin-top: 10px;
3363
+ }
3364
+
3365
+ button {
3366
+ padding: 9px 20px;
3367
+ border: none;
3368
+ border-radius: 5px;
3369
+ cursor: pointer;
3370
+ }
3371
+
3372
+ .btn-skip {
3373
+ background-color: #dbe2eb;
3374
+ color: #172a41;
3375
+ font-weight: 500;
3376
+
3377
+ &:hover {
3378
+ background-color: rgb(219, 226, 235);
3379
+ }
3380
+ }
3381
+
3382
+ .btn-submit-feedback {
3383
+ background-color: rgb(23, 42, 65);
3384
+ color: #ffffff;
3385
+ font-weight: 500;
3386
+
3387
+ &:hover {
3388
+ background-color: rgb(9, 22, 39);
3389
+ }
3390
+
3391
+ &:disabled {
3392
+ background-color: #e0e0e0;
3393
+ cursor: not-allowed;
3394
+ }
3395
+ }
3396
+ `;
3397
+
3398
+ class FeedbackDialog extends r$2 {
3399
+ dispatchFeedbackEvent(feedback) {
3400
+ this.dispatchEvent(new CustomEvent('submit-feedback', {
3401
+ detail: {
3402
+ messageId: this.messageId,
3403
+ feedback,
3404
+ },
3405
+ composed: true,
3406
+ bubbles: true,
3407
+ }));
3408
+ }
3409
+ handleSubmit(e) {
3410
+ var _a;
3411
+ e.preventDefault();
3412
+ const form = e.target;
3413
+ const data = new FormData(form);
3414
+ this.dispatchFeedbackEvent({
3415
+ rating: 'bad',
3416
+ comment: (_a = data.get('comment')) === null || _a === void 0 ? void 0 : _a.toString().trim(),
3417
+ });
3418
+ form.reset();
3419
+ }
3420
+ handleSkipComment(e) {
3421
+ e.preventDefault();
3422
+ this.comment = '';
3423
+ this.dispatchFeedbackEvent({ rating: 'bad', comment: null });
3424
+ }
3425
+ close(e) {
3426
+ e.preventDefault();
3427
+ this.dispatchEvent(new CustomEvent('close', {
3428
+ composed: true,
3429
+ bubbles: true,
3430
+ }));
3431
+ }
3432
+ render() {
3433
+ return x `
3434
+ <div class="modal">
3435
+ <div class="header">
3436
+ <h3>Provide Additional Feedback</h3>
3437
+ <div class="close" @click=${this.close}>${closeBtn}</div>
3438
+ </div>
3439
+ <form @submit=${this.handleSubmit}>
3440
+ <textarea
3441
+ name="comment"
3442
+ @input=${(e) => { var _a; return (this.comment = (_a = e.target) === null || _a === void 0 ? void 0 : _a.value); }}
3443
+ placeholder="Share your feedback"
3444
+ required
3445
+ >
3446
+ ${this.comment ? this.comment : E}</textarea
3447
+ >
3448
+ <div class="btns-container">
3449
+ <button
3450
+ type="button"
3451
+ class="btn btn-skip"
3452
+ @click=${this.handleSkipComment}
3453
+ >
3454
+ Skip
3455
+ </button>
3456
+ <button
3457
+ type="submit"
3458
+ class="btn btn-submit-feedback"
3459
+ ?disabled=${!this.comment}
3460
+ >
3461
+ Submit
3462
+ </button>
3463
+ </div>
3464
+ </form>
3465
+ </div>
3466
+ `;
3467
+ }
3468
+ }
3469
+ FeedbackDialog.styles = [feedbackDialogStyles];
3470
+ __decorate([
3471
+ n({ type: String }),
3472
+ __metadata("design:type", Object)
3473
+ ], FeedbackDialog.prototype, "messageId", void 0);
3474
+ __decorate([
3475
+ n({ type: String }),
3476
+ __metadata("design:type", Object)
3477
+ ], FeedbackDialog.prototype, "comment", void 0);
3478
+ if (!customElements.get('feedback-dialog')) {
3479
+ customElements.define('feedback-dialog', FeedbackDialog);
3480
+ }
3481
+
3159
3482
  class ChatSection extends r$2 {
3160
3483
  constructor() {
3161
3484
  super(...arguments);
@@ -3203,6 +3526,23 @@ class ChatSection extends r$2 {
3203
3526
  }));
3204
3527
  this.deleteThreadId = '';
3205
3528
  }
3529
+ handleFeedback(rating, messageId, comment) {
3530
+ if (rating === 'bad') {
3531
+ this.feedbackDetails = { messageId, comment };
3532
+ return;
3533
+ }
3534
+ this.dispatchEvent(new CustomEvent('submit-feedback', {
3535
+ detail: {
3536
+ messageId: messageId,
3537
+ feedback: {
3538
+ rating,
3539
+ comment: null,
3540
+ },
3541
+ },
3542
+ composed: true,
3543
+ bubbles: true,
3544
+ }));
3545
+ }
3206
3546
  typingIndicator() {
3207
3547
  return x ` <div class="typing-dots">
3208
3548
  <div class="dot"></div>
@@ -3211,7 +3551,7 @@ class ChatSection extends r$2 {
3211
3551
  </div>`;
3212
3552
  }
3213
3553
  botMessage(message) {
3214
- var _a;
3554
+ var _a, _b, _c, _d, _e;
3215
3555
  return x `
3216
3556
  <div class="message-wrapper">
3217
3557
  <div class="message bot">
@@ -3242,6 +3582,26 @@ class ChatSection extends r$2 {
3242
3582
  .viewType=${this.viewType}
3243
3583
  ></products-list>`
3244
3584
  : E}
3585
+ ${message.messageId
3586
+ ? x `<div class="bot-response-actions">
3587
+ <button
3588
+ type="button"
3589
+ @click=${this.handleFeedback.bind(this, 'good', message.messageId, (_b = message.feedback) === null || _b === void 0 ? void 0 : _b.comment)}
3590
+ >
3591
+ ${((_c = message.feedback) === null || _c === void 0 ? void 0 : _c.rating) === 'good'
3592
+ ? thumbsUpFilledBtn
3593
+ : thumbsUpBtn}
3594
+ </button>
3595
+ <button
3596
+ type="button"
3597
+ @click=${this.handleFeedback.bind(this, 'bad', message.messageId, (_d = message.feedback) === null || _d === void 0 ? void 0 : _d.comment)}
3598
+ >
3599
+ ${((_e = message.feedback) === null || _e === void 0 ? void 0 : _e.rating) === 'bad'
3600
+ ? thumbsDownFilledBtn
3601
+ : thumbsDownBtn}
3602
+ </button>
3603
+ </div>`
3604
+ : E}
3245
3605
  </div>
3246
3606
  `;
3247
3607
  }
@@ -3262,10 +3622,19 @@ class ChatSection extends r$2 {
3262
3622
  </div>`
3263
3623
  : ''}
3264
3624
  ${this.isFailed
3265
- ? this.botMessage({
3266
- sender: 'bot',
3267
- message: "Uh-oh! Looks like I tripped over some alpha-stage wires. Things are still a bit wobbly here, buy hey, that's what testing is for, Let's try that again; or feel free to throw another challenge my way!",
3268
- })
3625
+ ? x `<div class="message bot">
3626
+ <div>
3627
+ <div class="bot-icon">${botIcon}</div>
3628
+ </div>
3629
+ <div>
3630
+ <p>
3631
+ Uh-oh! Looks like I tripped over some alpha-stage wires.
3632
+ Things are still a bit wobbly here, buy hey, that's what
3633
+ testing is for, Let's try that again; or feel free to throw
3634
+ another challenge my way!
3635
+ </p>
3636
+ </div>
3637
+ </div>`
3269
3638
  : E}
3270
3639
  ${this.messages.map((message) => {
3271
3640
  if (message.sender === 'bot') {
@@ -3297,7 +3666,7 @@ class ChatSection extends r$2 {
3297
3666
  ? this.messages[0].welcomePrompts
3298
3667
  : this.prompts
3299
3668
  ? this.prompts.split(',').map((prompt) => prompt.trim())
3300
- : ['Best Selling Items', 'Hot Sales'];
3669
+ : ['Best Sellers'];
3301
3670
  if (!prompts) {
3302
3671
  return E;
3303
3672
  }
@@ -3609,6 +3978,21 @@ class ChatSection extends r$2 {
3609
3978
  </confirm-dialog>
3610
3979
  `
3611
3980
  : E}
3981
+ ${this.feedbackDetails
3982
+ ? x `
3983
+ <feedback-dialog
3984
+ .messageId=${this.feedbackDetails.messageId}
3985
+ .comment=${this.feedbackDetails.comment}
3986
+ @submit-feedback=${() => {
3987
+ this.feedbackDetails = undefined;
3988
+ }}
3989
+ @close=${(e) => {
3990
+ e.stopPropagation();
3991
+ this.feedbackDetails = undefined;
3992
+ }}
3993
+ ></feedback-dialog>
3994
+ `
3995
+ : E}
3612
3996
  `;
3613
3997
  }
3614
3998
  }
@@ -3693,6 +4077,10 @@ __decorate([
3693
4077
  e$3('personalize-dialog'),
3694
4078
  __metadata("design:type", Object)
3695
4079
  ], ChatSection.prototype, "personalizeDialogElement", void 0);
4080
+ __decorate([
4081
+ r(),
4082
+ __metadata("design:type", Object)
4083
+ ], ChatSection.prototype, "feedbackDetails", void 0);
3696
4084
  __decorate([
3697
4085
  n({ type: String }),
3698
4086
  __metadata("design:type", Object)
@@ -3702,11 +4090,11 @@ if (!customElements.get('chat-section')) {
3702
4090
  }
3703
4091
 
3704
4092
  const DIALOG_DELAY = 1000;
3705
- const LATEST_THREAD_LOAD_DAYS = 14;
3706
4093
  const normalizePath = (path) => path.replace(/\/$/, '');
3707
4094
  class ShopGPT extends r$2 {
3708
4095
  constructor() {
3709
4096
  super(...arguments);
4097
+ this.latestThreadLoad = DEFAULT_MAX_THREAD_AGE;
3710
4098
  this.modalState = 'close';
3711
4099
  this.isLoadingHistory = false;
3712
4100
  this.isLoadingThreads = false;
@@ -3813,6 +4201,7 @@ class ShopGPT extends r$2 {
3813
4201
  }
3814
4202
  this.messages = [
3815
4203
  {
4204
+ messageId: reply.messageId,
3816
4205
  sender: 'bot',
3817
4206
  message: reply.message,
3818
4207
  products: reply.products,
@@ -3844,7 +4233,7 @@ class ShopGPT extends r$2 {
3844
4233
  }
3845
4234
  }
3846
4235
  selectLatestThread() {
3847
- const cutoffTime = Date.now() - LATEST_THREAD_LOAD_DAYS * 24 * 60 * 60 * 1000;
4236
+ const cutoffTime = Date.now() - this.latestThreadLoad * 24 * 60 * 60 * 1000;
3848
4237
  // If the latest thread is not older than cutoff we should load the thread
3849
4238
  let latestThread;
3850
4239
  for (const thread of this.chatThreads.values()) {
@@ -3880,10 +4269,12 @@ class ShopGPT extends r$2 {
3880
4269
  latestAvailableProducts = products;
3881
4270
  }
3882
4271
  return {
4272
+ messageId: message.messageId,
3883
4273
  message: message.message,
3884
4274
  sender: message.sender,
3885
4275
  products,
3886
4276
  welcomePrompts: message.welcomePrompts,
4277
+ feedback: message.feedback,
3887
4278
  };
3888
4279
  });
3889
4280
  this.products = latestAvailableProducts;
@@ -3964,6 +4355,7 @@ class ShopGPT extends r$2 {
3964
4355
  }
3965
4356
  this.messages = [
3966
4357
  {
4358
+ messageId: reply.messageId,
3967
4359
  sender: 'bot',
3968
4360
  message: reply.message,
3969
4361
  products: reply.products,
@@ -3983,6 +4375,20 @@ class ShopGPT extends r$2 {
3983
4375
  this.isTyping = false;
3984
4376
  }
3985
4377
  }
4378
+ submitFeedback(e) {
4379
+ e.stopPropagation();
4380
+ this.shopGPTAPI
4381
+ .saveFeedback(e.detail.messageId, e.detail.feedback)
4382
+ .then(() => {
4383
+ const messages = this.messages;
4384
+ const messageIndex = messages.findIndex(({ messageId }) => messageId === e.detail.messageId);
4385
+ messages[messageIndex] = {
4386
+ ...messages[messageIndex],
4387
+ feedback: e.detail.feedback,
4388
+ };
4389
+ this.messages = [...messages];
4390
+ });
4391
+ }
3986
4392
  getSiteCurrency() {
3987
4393
  return this.storeAPI.getSiteCurrency();
3988
4394
  }
@@ -3999,6 +4405,7 @@ class ShopGPT extends r$2 {
3999
4405
  id="shop-gpt-dialog-overlay"
4000
4406
  @delete-thread=${this.handleThreadDelete}
4001
4407
  @delete-all-threads=${this.handleAllThreadsDelete}
4408
+ @submit-feedback=${this.submitFeedback}
4002
4409
  >
4003
4410
  <div class="mobile-version">
4004
4411
  Please switch to the desktop version for the best experience.
@@ -4063,6 +4470,7 @@ class ShopGPT extends r$2 {
4063
4470
  id="shop-gpt-modal"
4064
4471
  @delete-thread=${this.handleThreadDelete}
4065
4472
  @delete-all-threads=${this.handleAllThreadsDelete}
4473
+ @submit-feedback=${this.submitFeedback}
4066
4474
  >
4067
4475
  <chat-section
4068
4476
  .prompts=${this.quickPrompts}
@@ -4090,6 +4498,10 @@ class ShopGPT extends r$2 {
4090
4498
  }
4091
4499
  }
4092
4500
  ShopGPT.styles = [shopGPTStyles];
4501
+ __decorate([
4502
+ n({ type: Number }),
4503
+ __metadata("design:type", Number)
4504
+ ], ShopGPT.prototype, "latestThreadLoad", void 0);
4093
4505
  __decorate([
4094
4506
  e$3('#shop-gpt-dialog-overlay'),
4095
4507
  __metadata("design:type", Object)
@@ -4156,6 +4568,7 @@ if (typeof window != 'undefined' && typeof document != 'undefined') {
4156
4568
  shopGPT.brandName = params.brandName;
4157
4569
  shopGPT.quickPrompts = params.quickPrompts;
4158
4570
  shopGPT.merchantImage = params.merchantImage;
4571
+ shopGPT.latestThreadLoad = params.latestThreadLoad;
4159
4572
  document.body.append(shopGPT);
4160
4573
  },
4161
4574
  destroy() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blotoutio/providers-shop-gpt-sdk",
3
- "version": "1.4.0",
3
+ "version": "1.6.0",
4
4
  "description": "Shop GPT SDK for EdgeTag",
5
5
  "author": "Blotout",
6
6
  "license": "MIT",