@product7/product7-js 0.6.7 → 0.6.8

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.
@@ -4282,10 +4282,173 @@
4282
4282
  opacity: 0.7;
4283
4283
  cursor: not-allowed;
4284
4284
  }
4285
+
4286
+ /* ========================================
4287
+ FEEDBACK FORM VIEW
4288
+ ======================================== */
4289
+
4290
+ .liveChat-feedback-view {
4291
+ display: flex;
4292
+ flex-direction: column;
4293
+ height: 100%;
4294
+ overflow: hidden;
4295
+ }
4296
+
4297
+ .liveChat-feedback-header {
4298
+ display: flex;
4299
+ align-items: center;
4300
+ gap: var(--spacing-3);
4301
+ padding: var(--spacing-4) var(--spacing-4);
4302
+ border-bottom: 1px solid var(--border-color);
4303
+ flex-shrink: 0;
4304
+ }
4305
+
4306
+ .liveChat-feedback-title {
4307
+ font-size: var(--font-size-base);
4308
+ font-weight: var(--font-weight-semibold);
4309
+ color: var(--text-primary);
4310
+ }
4311
+
4312
+ .liveChat-feedback-body {
4313
+ display: flex;
4314
+ flex-direction: column;
4315
+ gap: var(--spacing-4);
4316
+ padding: var(--spacing-5) var(--spacing-4);
4317
+ flex: 1;
4318
+ overflow-y: auto;
4319
+ }
4320
+
4321
+ .liveChat-feedback-prompt {
4322
+ margin: 0;
4323
+ font-size: var(--font-size-sm);
4324
+ color: var(--text-secondary);
4325
+ }
4326
+
4327
+
4328
+ .liveChat-feedback-input {
4329
+ width: 100%;
4330
+ border: 1px solid var(--border-color);
4331
+ border-radius: var(--radius-md);
4332
+ padding: var(--spacing-3);
4333
+ font-size: var(--font-size-sm);
4334
+ font-family: inherit;
4335
+ color: var(--text-primary);
4336
+ background: var(--msg-bg);
4337
+ box-sizing: border-box;
4338
+ transition: border-color var(--transition-fast);
4339
+ }
4340
+
4341
+ .liveChat-feedback-input::placeholder {
4342
+ color: var(--msg-text-secondary);
4343
+ }
4344
+
4345
+ .liveChat-feedback-input:focus {
4346
+ outline: none;
4347
+ border-color: var(--color-primary);
4348
+ }
4349
+
4350
+ .liveChat-feedback-textarea {
4351
+ width: 100%;
4352
+ resize: none;
4353
+ border: 1px solid var(--border-color);
4354
+ border-radius: var(--radius-md);
4355
+ padding: var(--spacing-3);
4356
+ font-size: var(--font-size-sm);
4357
+ font-family: inherit;
4358
+ color: var(--text-primary);
4359
+ background: var(--msg-bg);
4360
+ box-sizing: border-box;
4361
+ transition: border-color var(--transition-fast);
4362
+ }
4363
+
4364
+ .liveChat-feedback-textarea::placeholder {
4365
+ color: var(--msg-text-secondary);
4366
+ }
4367
+
4368
+ .liveChat-feedback-textarea:focus {
4369
+ outline: none;
4370
+ border-color: var(--color-primary);
4371
+ }
4372
+
4373
+ .liveChat-feedback-submit {
4374
+ display: flex;
4375
+ align-items: center;
4376
+ justify-content: center;
4377
+ padding: var(--spacing-3);
4378
+ border-radius: var(--radius-md);
4379
+ font-size: var(--font-size-sm);
4380
+ font-weight: var(--font-weight-medium);
4381
+ font-family: inherit;
4382
+ cursor: pointer;
4383
+ border: none;
4384
+ background: var(--color-primary);
4385
+ color: #ffffff;
4386
+ transition: all var(--transition-fast);
4387
+ }
4388
+
4389
+ .liveChat-feedback-submit:hover:not(:disabled) {
4390
+ background: var(--color-primary-hover);
4391
+ }
4392
+
4393
+ .liveChat-feedback-submit:disabled {
4394
+ opacity: 0.5;
4395
+ cursor: not-allowed;
4396
+ }
4397
+
4398
+ .liveChat-feedback-thankyou {
4399
+ display: flex;
4400
+ flex-direction: column;
4401
+ align-items: center;
4402
+ justify-content: center;
4403
+ flex: 1;
4404
+ padding: var(--spacing-6) var(--spacing-4);
4405
+ text-align: center;
4406
+ gap: var(--spacing-3);
4407
+ }
4408
+
4409
+ .liveChat-feedback-thankyou-emoji {
4410
+ font-size: 48px;
4411
+ line-height: 1;
4412
+ }
4413
+
4414
+ .liveChat-feedback-thankyou h3 {
4415
+ margin: 0;
4416
+ font-size: var(--font-size-lg);
4417
+ font-weight: var(--font-weight-semibold);
4418
+ color: var(--text-primary);
4419
+ }
4420
+
4421
+ .liveChat-feedback-thankyou p {
4422
+ margin: 0;
4423
+ font-size: var(--font-size-sm);
4424
+ color: var(--text-secondary);
4425
+ }
4426
+
4427
+ .liveChat-feedback-done-btn {
4428
+ margin-top: var(--spacing-2);
4429
+ padding: var(--spacing-2) var(--spacing-5);
4430
+ border-radius: var(--radius-md);
4431
+ font-size: var(--font-size-sm);
4432
+ font-weight: var(--font-weight-medium);
4433
+ font-family: inherit;
4434
+ cursor: pointer;
4435
+ border: 1px solid var(--border-color);
4436
+ background: transparent;
4437
+ color: var(--text-primary);
4438
+ transition: all var(--transition-fast);
4439
+ }
4440
+
4441
+ .liveChat-feedback-done-btn:hover {
4442
+ background: var(--bg-secondary);
4443
+ }
4285
4444
  `;
4286
4445
 
4287
4446
  const liveChatCoreStyles = `
4288
4447
 
4448
+ .liveChat-widget * {
4449
+ font-weight: 500;
4450
+ }
4451
+
4289
4452
  .liveChat-launcher {
4290
4453
  position: fixed;
4291
4454
  z-index: var(--z-modal);
@@ -9490,11 +9653,12 @@
9490
9653
  </div>`;
9491
9654
  }
9492
9655
 
9493
- // Hide nav in chat and prechat views
9656
+ // Hide nav in chat, prechat and feedback views
9494
9657
  if (navContainer) {
9495
9658
  const hideNav =
9496
9659
  this.state.currentView === 'chat' ||
9497
- this.state.currentView === 'prechat';
9660
+ this.state.currentView === 'prechat' ||
9661
+ this.state.currentView === 'feedback';
9498
9662
  navContainer.style.display = hideNav ? 'none' : '';
9499
9663
  }
9500
9664
  }
@@ -11232,8 +11396,11 @@
11232
11396
  const sendIcon = `<iconify-icon icon="ph:paper-plane-right" width="20" height="20" style="flex-shrink: 0;"></iconify-icon>`;
11233
11397
  const caretIcon = `<iconify-icon icon="ph:caret-right" width="20" height="20" style="flex-shrink: 0;"></iconify-icon>`;
11234
11398
 
11235
- const responseTime =
11236
- this.state.responseTime || 'We typically reply within a few minutes';
11399
+ const isUnavailable = this.state.businessHoursState === 'offline' || this.state.businessHoursState === 'away';
11400
+ const buttonLabel = isUnavailable ? 'Leave us a message' : this.state.startButtonText;
11401
+ const buttonSubtext = isUnavailable
11402
+ ? "We'll get back to you when we're back"
11403
+ : (this.state.responseTime || 'We typically reply within a few minutes');
11237
11404
 
11238
11405
  const recentCardHtml = openConversation
11239
11406
  ? this._renderRecentMessageCard(openConversation)
@@ -11243,8 +11410,8 @@
11243
11410
  ${recentCardHtml}
11244
11411
  <button class="liveChat-home-message-btn">
11245
11412
  <div class="liveChat-home-continue-info">
11246
- <span class="liveChat-home-continue-label">${this.state.startButtonText}</span>
11247
- <span class="liveChat-home-message-subtext">${responseTime}</span>
11413
+ <span class="liveChat-home-continue-label">${buttonLabel}</span>
11414
+ <span class="liveChat-home-message-subtext">${buttonSubtext}</span>
11248
11415
  </div>
11249
11416
  ${sendIcon}
11250
11417
  </button>
@@ -11408,12 +11575,7 @@
11408
11575
  const feedbackBtn = this.element.querySelector('.liveChat-feedback-btn');
11409
11576
  if (feedbackBtn) {
11410
11577
  feedbackBtn.addEventListener('click', () => {
11411
- if (this.options.onFeedbackClick) {
11412
- this.state.setOpen(false);
11413
- this.options.onFeedbackClick();
11414
- } else if (this.state.urls?.feedback) {
11415
- window.open(this.state.urls.feedback, '_blank');
11416
- }
11578
+ this.state.setView('feedback');
11417
11579
  });
11418
11580
  }
11419
11581
 
@@ -11467,6 +11629,111 @@
11467
11629
  }
11468
11630
  }
11469
11631
 
11632
+ class FeedbackFormView {
11633
+ constructor(state, options = {}) {
11634
+ this.state = state;
11635
+ this.options = options;
11636
+ this.element = null;
11637
+ this._isSubmitting = false;
11638
+ this._selectedRating = null;
11639
+ }
11640
+
11641
+ render() {
11642
+ this.element = document.createElement('div');
11643
+ this.element.className = 'liveChat-view liveChat-feedback-view';
11644
+ this._renderForm();
11645
+ return this.element;
11646
+ }
11647
+
11648
+ _renderForm() {
11649
+ this.element.innerHTML = `
11650
+ <div class="liveChat-feedback-header">
11651
+ <button class="sdk-btn-icon liveChat-feedback-back-btn">
11652
+ <iconify-icon icon="ph:arrow-left" width="20" height="20"></iconify-icon>
11653
+ </button>
11654
+ <span class="liveChat-feedback-title">Leave us feedback</span>
11655
+ </div>
11656
+ <div class="liveChat-feedback-body">
11657
+ <p class="liveChat-feedback-prompt">Share your thoughts with us. We read every message.</p>
11658
+ <input
11659
+ type="text"
11660
+ class="liveChat-feedback-input"
11661
+ placeholder="Title"
11662
+ />
11663
+ <textarea
11664
+ class="liveChat-feedback-textarea"
11665
+ placeholder="Your feedback..."
11666
+ rows="5"
11667
+ ></textarea>
11668
+ <button class="liveChat-feedback-submit">Send feedback</button>
11669
+ </div>
11670
+ `;
11671
+ this._attachEvents();
11672
+ }
11673
+
11674
+ _renderThankYou() {
11675
+ this.element.innerHTML = `
11676
+ <div class="liveChat-feedback-header">
11677
+ <button class="sdk-btn-icon liveChat-feedback-back-btn">
11678
+ <iconify-icon icon="ph:arrow-left" width="20" height="20"></iconify-icon>
11679
+ </button>
11680
+ <span class="liveChat-feedback-title">Leave us feedback</span>
11681
+ </div>
11682
+ <div class="liveChat-feedback-thankyou">
11683
+ <span class="liveChat-feedback-thankyou-emoji">🙏</span>
11684
+ <h3>Thanks for your feedback!</h3>
11685
+ <p>We appreciate you taking the time to share your thoughts.</p>
11686
+ <button class="liveChat-feedback-done-btn">Done</button>
11687
+ </div>
11688
+ `;
11689
+ this.element.querySelector('.liveChat-feedback-back-btn').addEventListener('click', () => {
11690
+ this.state.setView('home');
11691
+ });
11692
+ this.element.querySelector('.liveChat-feedback-done-btn').addEventListener('click', () => {
11693
+ this.state.setView('home');
11694
+ });
11695
+ }
11696
+
11697
+ _attachEvents() {
11698
+ this.element.querySelector('.liveChat-feedback-back-btn').addEventListener('click', () => {
11699
+ this.state.setView('home');
11700
+ });
11701
+
11702
+ const submitBtn = this.element.querySelector('.liveChat-feedback-submit');
11703
+ submitBtn.addEventListener('click', async () => {
11704
+ if (this._isSubmitting) return;
11705
+ const title = this.element.querySelector('.liveChat-feedback-input').value.trim();
11706
+ const message = this.element.querySelector('.liveChat-feedback-textarea').value.trim();
11707
+ await this._submit(title, message);
11708
+ });
11709
+ }
11710
+
11711
+ async _submit(title, message) {
11712
+ this._isSubmitting = true;
11713
+ const submitBtn = this.element.querySelector('.liveChat-feedback-submit');
11714
+ if (submitBtn) {
11715
+ submitBtn.disabled = true;
11716
+ submitBtn.textContent = 'Sending...';
11717
+ }
11718
+
11719
+ try {
11720
+ if (this.options.onSubmitFeedback) {
11721
+ await this.options.onSubmitFeedback({ title, message });
11722
+ }
11723
+ } catch (e) {
11724
+ console.warn('[FeedbackFormView] Submit error:', e);
11725
+ }
11726
+
11727
+ this._renderThankYou();
11728
+ }
11729
+
11730
+ destroy() {
11731
+ if (this.element && this.element.parentNode) {
11732
+ this.element.parentNode.removeChild(this.element);
11733
+ }
11734
+ }
11735
+ }
11736
+
11470
11737
  class PreChatFormView {
11471
11738
  constructor(state, options = {}) {
11472
11739
  this.state = state;
@@ -11785,6 +12052,7 @@
11785
12052
  this.panel.registerView('messages', ConversationsView);
11786
12053
  this.panel.registerView('chat', ChatView);
11787
12054
  this.panel.registerView('prechat', PreChatFormView);
12055
+ this.panel.registerView('feedback', FeedbackFormView);
11788
12056
  this.panel.registerView('help', HelpView);
11789
12057
  this.panel.registerView('changelog', ChangelogView);
11790
12058