@product7/feedback-sdk 1.3.7 → 1.3.9

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 (39) hide show
  1. package/dist/feedback-sdk.js +3006 -2817
  2. package/dist/feedback-sdk.js.map +1 -1
  3. package/dist/feedback-sdk.min.js +1 -1
  4. package/dist/feedback-sdk.min.js.map +1 -1
  5. package/package.json +1 -1
  6. package/src/api/services/MessengerService.js +8 -2
  7. package/src/core/APIService.js +33 -14
  8. package/src/index.js +1 -1
  9. package/src/styles/base.js +1 -1
  10. package/src/styles/changelog.js +58 -40
  11. package/src/styles/components.js +19 -2
  12. package/src/styles/design-tokens.js +4 -4
  13. package/src/styles/feedback.js +3 -8
  14. package/src/styles/messenger-components.js +473 -0
  15. package/src/styles/messenger-core.js +37 -268
  16. package/src/styles/messenger-features.js +89 -267
  17. package/src/styles/messenger-views.js +391 -325
  18. package/src/styles/messenger.js +17 -558
  19. package/src/styles/styles.js +21 -24
  20. package/src/styles/{surveys.js → survey.js} +55 -20
  21. package/src/widgets/BaseWidget.js +1 -1
  22. package/src/widgets/ButtonWidget.js +1 -1
  23. package/src/widgets/ChangelogWidget.js +1 -1
  24. package/src/widgets/InlineWidget.js +1 -1
  25. package/src/widgets/MessengerWidget.js +74 -84
  26. package/src/widgets/SurveyWidget.js +1 -1
  27. package/src/widgets/TabWidget.js +1 -1
  28. package/src/widgets/messenger/MessengerState.js +50 -119
  29. package/src/widgets/messenger/components/MessengerLauncher.js +22 -18
  30. package/src/widgets/messenger/components/MessengerPanel.js +1 -1
  31. package/src/widgets/messenger/components/NavigationTabs.js +36 -15
  32. package/src/widgets/messenger/views/ChangelogView.js +8 -32
  33. package/src/widgets/messenger/views/ChatView.js +83 -219
  34. package/src/widgets/messenger/views/ConversationsView.js +67 -45
  35. package/src/widgets/messenger/views/HelpView.js +22 -32
  36. package/src/widgets/messenger/views/HomeView.js +58 -40
  37. package/src/widgets/messenger/views/PreChatFormView.js +47 -51
  38. package/src/styles/messenger-help.js +0 -298
  39. package/src/styles/messenger-themes.js +0 -500
@@ -14,6 +14,10 @@ export const surveyStyles = `
14
14
  animation: fadeIn var(--transition-slow);
15
15
  }
16
16
 
17
+ /* ========================================
18
+ SURVEY CARD
19
+ ======================================== */
20
+
17
21
  .feedback-survey {
18
22
  position: fixed;
19
23
  z-index: var(--z-modal);
@@ -56,16 +60,15 @@ export const surveyStyles = `
56
60
  right: var(--spacing-3);
57
61
  background: none;
58
62
  border: none;
59
- font-size: 20px;
60
63
  cursor: pointer;
61
64
  color: var(--color-neutral-500);
62
- line-height: 1;
65
+ padding: 0;
63
66
  width: 28px;
64
67
  height: 28px;
65
68
  display: flex;
66
69
  align-items: center;
67
70
  justify-content: center;
68
- border-radius: var(--radius-sm);
71
+ border-radius: var(--radius-md);
69
72
  transition: all var(--transition-base);
70
73
  }
71
74
 
@@ -77,7 +80,7 @@ export const surveyStyles = `
77
80
  .feedback-survey-title {
78
81
  margin: 0 0 var(--spacing-2) 0;
79
82
  font-size: var(--font-size-xl);
80
- font-weight: var(--font-weight-semibold);
83
+ font-weight: var(--font-weight-bold);
81
84
  padding-right: var(--spacing-6);
82
85
  color: var(--color-text-primary);
83
86
  }
@@ -93,6 +96,10 @@ export const surveyStyles = `
93
96
  margin-bottom: var(--spacing-4);
94
97
  }
95
98
 
99
+ /* ========================================
100
+ NPS
101
+ ======================================== */
102
+
96
103
  .feedback-survey-nps {
97
104
  display: flex;
98
105
  justify-content: space-between;
@@ -103,10 +110,11 @@ export const surveyStyles = `
103
110
  width: 28px;
104
111
  height: 36px;
105
112
  border: 1px solid var(--color-border);
106
- border-radius: var(--radius-sm);
113
+ border-radius: var(--radius-md);
107
114
  background: var(--color-surface);
108
115
  cursor: pointer;
109
116
  font-size: var(--font-size-sm);
117
+ font-weight: var(--font-weight-medium);
110
118
  color: var(--color-text-primary);
111
119
  transition: all var(--transition-fast);
112
120
  font-family: inherit;
@@ -123,6 +131,10 @@ export const surveyStyles = `
123
131
  color: var(--color-white);
124
132
  }
125
133
 
134
+ /* ========================================
135
+ CSAT
136
+ ======================================== */
137
+
126
138
  .feedback-survey-csat {
127
139
  display: flex;
128
140
  justify-content: center;
@@ -146,6 +158,10 @@ export const surveyStyles = `
146
158
  transform: scale(1.2);
147
159
  }
148
160
 
161
+ /* ========================================
162
+ CES
163
+ ======================================== */
164
+
149
165
  .feedback-survey-ces {
150
166
  display: flex;
151
167
  justify-content: space-between;
@@ -160,6 +176,7 @@ export const surveyStyles = `
160
176
  background: var(--color-surface);
161
177
  cursor: pointer;
162
178
  font-size: var(--font-size-xs);
179
+ font-weight: var(--font-weight-medium);
163
180
  color: var(--color-text-primary);
164
181
  transition: all var(--transition-fast);
165
182
  font-family: inherit;
@@ -182,9 +199,13 @@ export const surveyStyles = `
182
199
  justify-content: space-between;
183
200
  margin-top: var(--spacing-2);
184
201
  font-size: var(--font-size-xs);
185
- color: var(--color-text-secondary);
202
+ color: var(--color-text-tertiary);
186
203
  }
187
204
 
205
+ /* ========================================
206
+ FREQUENCY
207
+ ======================================== */
208
+
188
209
  .feedback-survey-frequency {
189
210
  display: flex;
190
211
  gap: var(--spacing-2);
@@ -192,12 +213,13 @@ export const surveyStyles = `
192
213
 
193
214
  .feedback-survey-freq-btn {
194
215
  flex: 1;
195
- padding: 10px;
216
+ padding: var(--spacing-3);
196
217
  border: 1px solid var(--color-border);
197
218
  border-radius: var(--radius-md);
198
219
  background: var(--color-surface);
199
220
  cursor: pointer;
200
221
  font-size: var(--font-size-sm);
222
+ font-weight: var(--font-weight-medium);
201
223
  color: var(--color-text-primary);
202
224
  transition: all var(--transition-fast);
203
225
  font-family: inherit;
@@ -214,13 +236,17 @@ export const surveyStyles = `
214
236
  color: var(--color-white);
215
237
  }
216
238
 
239
+ /* ========================================
240
+ FORM INPUTS
241
+ ======================================== */
242
+
217
243
  .feedback-survey-feedback {
218
244
  margin-top: var(--spacing-4);
219
245
  }
220
246
 
221
247
  .feedback-survey-textarea {
222
248
  width: 100%;
223
- padding: var(--spacing-3) 14px;
249
+ padding: var(--spacing-3);
224
250
  border: 1px solid var(--color-border);
225
251
  border-radius: var(--radius-md);
226
252
  font-size: var(--font-size-base);
@@ -230,7 +256,7 @@ export const surveyStyles = `
230
256
  color: var(--color-text-primary);
231
257
  font-family: inherit;
232
258
  box-sizing: border-box;
233
- transition: all var(--transition-base);
259
+ transition: border-color var(--transition-base);
234
260
  outline: none;
235
261
  }
236
262
 
@@ -245,7 +271,7 @@ export const surveyStyles = `
245
271
 
246
272
  .feedback-survey-select {
247
273
  width: 100%;
248
- padding: 10px 14px;
274
+ padding: var(--spacing-3);
249
275
  border: 1px solid var(--color-border);
250
276
  border-radius: var(--radius-md);
251
277
  font-size: var(--font-size-base);
@@ -253,7 +279,7 @@ export const surveyStyles = `
253
279
  color: var(--color-text-primary);
254
280
  font-family: inherit;
255
281
  cursor: pointer;
256
- transition: all var(--transition-base);
282
+ transition: border-color var(--transition-base);
257
283
  outline: none;
258
284
  }
259
285
 
@@ -264,7 +290,7 @@ export const surveyStyles = `
264
290
 
265
291
  .feedback-survey-input {
266
292
  width: 100%;
267
- padding: 10px 14px;
293
+ padding: var(--spacing-3);
268
294
  border: 1px solid var(--color-border);
269
295
  border-radius: var(--radius-md);
270
296
  font-size: var(--font-size-base);
@@ -272,7 +298,7 @@ export const surveyStyles = `
272
298
  color: var(--color-text-primary);
273
299
  font-family: inherit;
274
300
  box-sizing: border-box;
275
- transition: all var(--transition-base);
301
+ transition: border-color var(--transition-base);
276
302
  outline: none;
277
303
  }
278
304
 
@@ -285,16 +311,20 @@ export const surveyStyles = `
285
311
  box-shadow: 0 0 0 3px var(--color-primary-light);
286
312
  }
287
313
 
314
+ /* ========================================
315
+ SUBMIT & FEEDBACK
316
+ ======================================== */
317
+
288
318
  .feedback-survey-submit {
289
319
  width: 100%;
290
320
  margin-top: var(--spacing-3);
291
321
  padding: var(--spacing-3);
292
322
  background: var(--color-primary);
293
323
  color: var(--color-white);
294
- border: none;
324
+ border: 1px solid var(--color-primary);
295
325
  border-radius: var(--radius-md);
296
326
  font-size: var(--font-size-base);
297
- font-weight: var(--font-weight-medium);
327
+ font-weight: var(--font-weight-semibold);
298
328
  cursor: pointer;
299
329
  font-family: inherit;
300
330
  transition: all var(--transition-base);
@@ -302,6 +332,7 @@ export const surveyStyles = `
302
332
 
303
333
  .feedback-survey-submit:hover {
304
334
  background: var(--color-primary-hover);
335
+ border-color: var(--color-primary-hover);
305
336
  }
306
337
 
307
338
  .feedback-survey-error {
@@ -317,7 +348,7 @@ export const surveyStyles = `
317
348
  right: var(--spacing-6);
318
349
  background: var(--color-success);
319
350
  color: var(--color-white);
320
- padding: var(--spacing-4) var(--spacing-6);
351
+ padding: var(--spacing-3) var(--spacing-5);
321
352
  border-radius: var(--radius-xl);
322
353
  font-size: var(--font-size-base);
323
354
  font-weight: var(--font-weight-medium);
@@ -332,23 +363,27 @@ export const surveyStyles = `
332
363
  gap: var(--spacing-2);
333
364
  }
334
365
 
366
+ /* ========================================
367
+ RESPONSIVE
368
+ ======================================== */
369
+
335
370
  @media (max-width: 768px) {
336
371
  .feedback-survey {
337
372
  min-width: 300px;
338
373
  }
339
-
374
+
340
375
  .feedback-survey-bottom {
341
376
  padding: var(--spacing-5);
342
377
  }
343
-
378
+
344
379
  .feedback-survey-nps-btn {
345
380
  width: 24px;
346
381
  height: 32px;
347
382
  font-size: var(--font-size-xs);
348
383
  }
349
-
384
+
350
385
  .feedback-survey-csat-btn {
351
386
  font-size: 32px;
352
387
  }
353
388
  }
354
- `;
389
+ `;
@@ -510,4 +510,4 @@ export class BaseWidget {
510
510
  closeModal() {
511
511
  this.closePanel();
512
512
  }
513
- }
513
+ }
@@ -98,4 +98,4 @@ export class ButtonWidget extends BaseWidget {
98
98
  );
99
99
  }
100
100
  }
101
- }
101
+ }
@@ -570,4 +570,4 @@ export class ChangelogWidget extends BaseWidget {
570
570
  this.closeSidebar();
571
571
  super.destroy();
572
572
  }
573
- }
573
+ }
@@ -145,4 +145,4 @@ export class InlineWidget extends BaseWidget {
145
145
  input.placeholder = placeholder;
146
146
  }
147
147
  }
148
- }
148
+ }
@@ -1,4 +1,4 @@
1
-
1
+ import { WebSocketService } from '../core/WebSocketService.js';
2
2
  import { BaseWidget } from './BaseWidget.js';
3
3
  import { MessengerState } from './messenger/MessengerState.js';
4
4
  import { MessengerLauncher } from './messenger/components/MessengerLauncher.js';
@@ -9,7 +9,6 @@ import { ConversationsView } from './messenger/views/ConversationsView.js';
9
9
  import { HelpView } from './messenger/views/HelpView.js';
10
10
  import { HomeView } from './messenger/views/HomeView.js';
11
11
  import { PreChatFormView } from './messenger/views/PreChatFormView.js';
12
- import { WebSocketService } from '../core/WebSocketService.js';
13
12
 
14
13
  export class MessengerWidget extends BaseWidget {
15
14
  constructor(options) {
@@ -132,44 +131,41 @@ export class MessengerWidget extends BaseWidget {
132
131
  }
133
132
  }
134
133
 
135
- async _handleStartConversation(messageContent, pendingAttachments) {
136
- try {
137
- // Check if already identified
138
- if (!this.messengerState.isIdentified) {
139
- // Not identified - show pre-chat form
140
- this.messengerState.pendingMessage = {
141
- content: messageContent,
142
- attachments: pendingAttachments,
143
- };
144
- this.messengerState.setView('prechat');
145
- return null;
146
- }
134
+ async _handleStartConversation(messageContent, pendingAttachments) {
135
+ try {
136
+ if (!this.messengerState.isIdentified) {
137
+ this.messengerState.pendingMessage = {
138
+ content: messageContent,
139
+ attachments: pendingAttachments,
140
+ };
141
+ this.messengerState.setView('prechat');
142
+ return null;
143
+ }
147
144
 
148
- // Already identified - proceed with conversation
149
- const openConversation = this.messengerState.conversations.find(
150
- (c) => c.status === 'open'
151
- );
145
+ const openConversation = this.messengerState.conversations.find(
146
+ (c) => c.status === 'open'
147
+ );
152
148
 
153
- if (openConversation) {
154
- this.messengerState.setActiveConversation(openConversation.id);
155
- await this._handleSendMessage(
156
- openConversation.id,
157
- { content: messageContent },
149
+ if (openConversation) {
150
+ this.messengerState.setActiveConversation(openConversation.id);
151
+ await this._handleSendMessage(
152
+ openConversation.id,
153
+ { content: messageContent },
154
+ pendingAttachments
155
+ );
156
+ return openConversation;
157
+ }
158
+
159
+ return await this.startNewConversation(
160
+ messageContent,
161
+ '',
158
162
  pendingAttachments
159
163
  );
160
- return openConversation;
164
+ } catch (error) {
165
+ console.error('[MessengerWidget] Failed to start conversation:', error);
166
+ return null;
161
167
  }
162
-
163
- return await this.startNewConversation(
164
- messageContent,
165
- '',
166
- pendingAttachments
167
- );
168
- } catch (error) {
169
- console.error('[MessengerWidget] Failed to start conversation:', error);
170
- return null;
171
168
  }
172
- }
173
169
 
174
170
  async _handleSelectConversation(conversationId) {
175
171
  try {
@@ -194,31 +190,35 @@ async _handleStartConversation(messageContent, pendingAttachments) {
194
190
  }
195
191
  }
196
192
 
197
- async _handleIdentifyContact(contactData) {
198
- try {
199
- const response = await this.apiService.identifyContact({
200
- name: contactData.name,
201
- email: contactData.email,
202
- });
203
-
204
- if (response.status) {
205
- console.log('[MessengerWidget] Contact identified:', response.data.contact_id);
193
+ async _handleIdentifyContact(contactData) {
194
+ try {
195
+ const response = await this.apiService.identifyContact({
196
+ name: contactData.name,
197
+ email: contactData.email,
198
+ });
206
199
 
207
- // Update state
208
- if (!this.messengerState.userContext) {
209
- this.messengerState.userContext = {};
200
+ if (response.status) {
201
+ console.log(
202
+ '[MessengerWidget] Contact identified:',
203
+ response.data.contact_id
204
+ );
205
+ this.messengerState.setIdentified(true, {
206
+ name: contactData.name,
207
+ email: contactData.email,
208
+ });
210
209
  }
211
- this.messengerState.userContext.name = contactData.name;
212
- this.messengerState.userContext.email = contactData.email;
213
- this.messengerState.isIdentified = true;
210
+
211
+ return response;
212
+ } catch (error) {
213
+ console.error('[MessengerWidget] Failed to identify contact:', error);
214
+ throw error;
214
215
  }
216
+ }
215
217
 
216
- return response;
217
- } catch (error) {
218
- console.error('[MessengerWidget] Failed to identify contact:', error);
219
- throw error;
218
+ markAsIdentified(name, email) {
219
+ this.messengerState.setIdentified(true, { name, email });
220
+ console.log('[MessengerWidget] Marked as identified:', email);
220
221
  }
221
- }
222
222
 
223
223
  async _handleUploadFile(base64Data, filename) {
224
224
  try {
@@ -353,7 +353,9 @@ async _handleIdentifyContact(contactData) {
353
353
  data?.conversation_id || data?.id || data?.conversation?.id;
354
354
  if (!conversationId) return;
355
355
 
356
- this.messengerState.updateConversation(conversationId, { status: 'closed' });
356
+ this.messengerState.updateConversation(conversationId, {
357
+ status: 'closed',
358
+ });
357
359
  }
358
360
 
359
361
  async _updateUnreadCount() {
@@ -595,25 +597,12 @@ async _handleIdentifyContact(contactData) {
595
597
  const uploadedAttachments =
596
598
  await this._uploadPendingAttachments(pendingAttachments);
597
599
 
598
- console.log('[MessengerWidget] Starting conversation...', {
599
- message,
600
- attachmentCount: uploadedAttachments.length,
601
- hasSession: this.apiService.isSessionValid(),
602
- sessionToken: this.apiService.sessionToken
603
- ? this.apiService.sessionToken.substring(0, 10) + '...'
604
- : null,
605
- baseURL: this.apiService.baseURL,
606
- mock: this.apiService.mock,
607
- });
608
-
609
600
  const response = await this.apiService.startConversation({
610
601
  message,
611
602
  subject,
612
603
  attachments: uploadedAttachments,
613
604
  });
614
605
 
615
- console.log('[MessengerWidget] Conversation response:', response);
616
-
617
606
  if (response.status && response.data) {
618
607
  const conv = response.data;
619
608
  const newConversation = {
@@ -691,7 +680,8 @@ async _handleIdentifyContact(contactData) {
691
680
  description:
692
681
  'Connect with more tools you love and streamline your workflow.',
693
682
  tags: ['Integration'],
694
- coverImage: 'https://feedback-sdk.product7.io/700x400__5_.png',
683
+ coverImage:
684
+ 'https://images.unsplash.com/photo-1674027444485-cec3da58eef4?w=500&auto=format&fit=crop&q=60&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxzZWFyY2h8M3x8YWl8ZW58MHx8MHx8fDA%3D',
695
685
  coverText: null,
696
686
  publishedAt: new Date(
697
687
  Date.now() - 14 * 24 * 60 * 60 * 1000
@@ -705,7 +695,7 @@ async _handleIdentifyContact(contactData) {
705
695
  'We announced Fin Insights, a groundbreaking, AI-powered product that gives you complete visibility into every customer conversation.',
706
696
  tags: ['New feature', 'AI'],
707
697
  coverImage:
708
- 'https://feedback-sdk.product7.io/Intercom_Messenger__1_.jpg',
698
+ 'https://images.unsplash.com/photo-1666875753105-c63a6f3bdc86?w=500&auto=format&fit=crop&q=60&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MTJ8fGluc2lnaHRzfGVufDB8fDB8fHww',
709
699
  coverText: 'Watch our major product launch on-demand',
710
700
  publishedAt: new Date(
711
701
  Date.now() - 5 * 24 * 60 * 60 * 1000
@@ -719,7 +709,7 @@ async _handleIdentifyContact(contactData) {
719
709
  'Learn how AI has transformed customer service from the ground up—rewriting its economics and reshaping expectations.',
720
710
  tags: ['Report'],
721
711
  coverImage:
722
- 'https://feedback-sdk.product7.io/Main_Report_Email_Header.png',
712
+ 'https://images.unsplash.com/photo-1762330467475-a565d04e1808?w=500&auto=format&fit=crop&q=60&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxzZWFyY2h8N3x8YWklMjBjdXN0b21lciUyMHNlcnZpY2V8ZW58MHx8MHx8fDA%3D',
723
713
  coverText: 'Customer service trends as we know them are dead.',
724
714
  publishedAt: new Date(
725
715
  Date.now() - 2 * 24 * 60 * 60 * 1000
@@ -735,7 +725,7 @@ async _handleIdentifyContact(contactData) {
735
725
  'Get deeper insights into your customer conversations with our new analytics dashboard.',
736
726
  tags: ['Analytics'],
737
727
  coverImage:
738
- 'https://feedback-sdk.product7.io/cgangelog-Frame%202087334450.jpg',
728
+ 'https://images.unsplash.com/photo-1523961131990-5ea7c61b2107?w=500&auto=format&fit=crop&q=60&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MTJ8fGFuYWx5dGljc3xlbnwwfHwwfHx8MA%3D%3D',
739
729
  coverText: null,
740
730
  publishedAt: new Date(
741
731
  Date.now() - 10 * 24 * 60 * 60 * 1000
@@ -749,7 +739,7 @@ async _handleIdentifyContact(contactData) {
749
739
  'New AI-powered escalation guidance helps your team handle complex customer issues more effectively.',
750
740
  tags: ['New feature', 'AI'],
751
741
  coverImage:
752
- 'https://feedback-sdk.product7.io/cgangelog-image-escalation-guidance-event@2x.png',
742
+ 'https://images.unsplash.com/photo-1764773516703-b246ac2ad5ef?w=500&auto=format&fit=crop&q=60&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxzZWFyY2h8M3x8Y29tcGxleCUyMGlzc3Vlc3xlbnwwfHwwfHx8MA%3D%3D',
753
743
  coverText: null,
754
744
  publishedAt: new Date(
755
745
  Date.now() - 7 * 24 * 60 * 60 * 1000
@@ -780,19 +770,19 @@ async _handleIdentifyContact(contactData) {
780
770
  };
781
771
  }
782
772
 
783
- async onMount() {
784
- this.loadInitialData();
785
-
786
- if (this.apiService?.sessionToken) {
787
- this._initWebSocket();
788
- }
773
+ async onMount() {
774
+ this.loadInitialData();
789
775
 
790
- this.checkAgentAvailability();
776
+ if (this.apiService?.sessionToken) {
777
+ this._initWebSocket();
778
+ }
791
779
 
792
- this._availabilityInterval = setInterval(() => {
793
780
  this.checkAgentAvailability();
794
- }, 60000);
795
- }
781
+
782
+ this._availabilityInterval = setInterval(() => {
783
+ this.checkAgentAvailability();
784
+ }, 60000);
785
+ }
796
786
 
797
787
  onDestroy() {
798
788
  if (this._stateUnsubscribe) {
@@ -821,4 +811,4 @@ async onMount() {
821
811
  this.onDestroy();
822
812
  super.destroy();
823
813
  }
824
- }
814
+ }
@@ -508,4 +508,4 @@ export class SurveyWidget extends BaseWidget {
508
508
  this._closeSurvey();
509
509
  super.destroy();
510
510
  }
511
- }
511
+ }
@@ -42,4 +42,4 @@ export class TabWidget extends BaseWidget {
42
42
  );
43
43
  }
44
44
  }
45
- }
45
+ }