@product7/feedback-sdk 1.3.3 → 1.3.5
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/feedback-sdk.js +2441 -3240
- package/dist/feedback-sdk.js.map +1 -1
- package/dist/feedback-sdk.min.js +1 -1
- package/dist/feedback-sdk.min.js.map +1 -1
- package/package.json +1 -1
- package/src/api/services/MessengerService.js +76 -0
- package/src/core/BaseAPIService.js +4 -0
- package/src/index.js +2 -3
- package/src/styles/base.js +27 -52
- package/src/styles/changelog.js +152 -269
- package/src/styles/components.js +489 -0
- package/src/styles/design-tokens.js +104 -0
- package/src/styles/feedback.js +59 -369
- package/src/styles/messenger-core.js +390 -0
- package/src/styles/messenger-features.js +347 -0
- package/src/styles/messenger-help.js +298 -0
- package/src/styles/messenger-themes.js +500 -0
- package/src/styles/messenger-views.js +618 -0
- package/src/styles/messenger.js +558 -0
- package/src/styles/styles.js +24 -2
- package/src/styles/surveys.js +354 -0
- package/src/widgets/BaseWidget.js +25 -58
- package/src/widgets/ButtonWidget.js +3 -18
- package/src/widgets/ChangelogWidget.js +7 -48
- package/src/widgets/InlineWidget.js +16 -13
- package/src/widgets/MessengerWidget.js +37 -51
- package/src/widgets/SurveyWidget.js +42 -146
- package/src/widgets/TabWidget.js +2 -22
- package/src/widgets/messenger/MessengerState.js +49 -46
- package/src/widgets/messenger/components/MessengerLauncher.js +10 -5
- package/src/widgets/messenger/components/MessengerPanel.js +5 -27
- package/src/widgets/messenger/components/NavigationTabs.js +5 -14
- package/src/widgets/messenger/views/ChangelogView.js +13 -14
- package/src/widgets/messenger/views/ChatView.js +43 -36
- package/src/widgets/messenger/views/ConversationsView.js +16 -21
- package/src/widgets/messenger/views/HelpView.js +10 -10
- package/src/widgets/messenger/views/HomeView.js +11 -16
- package/src/widgets/messenger/views/PreChatFormView.js +18 -30
- package/src/styles/messengerStyles.js +0 -2328
|
@@ -12,7 +12,7 @@ export class ChangelogWidget extends BaseWidget {
|
|
|
12
12
|
|
|
13
13
|
_render() {
|
|
14
14
|
const trigger = document.createElement('div');
|
|
15
|
-
trigger.className = `
|
|
15
|
+
trigger.className = `changelog-widget position-${this.options.position}`;
|
|
16
16
|
trigger.innerHTML = `
|
|
17
17
|
<button class="changelog-trigger-btn" type="button" aria-label="View Updates">
|
|
18
18
|
<svg class="changelog-icon" width="18" height="18" viewBox="0 0 24 24" fill="currentColor">
|
|
@@ -33,29 +33,17 @@ export class ChangelogWidget extends BaseWidget {
|
|
|
33
33
|
|
|
34
34
|
_attachEvents() {
|
|
35
35
|
const button = this.element.querySelector('.changelog-trigger-btn');
|
|
36
|
-
|
|
37
36
|
button.addEventListener('click', () => {
|
|
38
37
|
this.openSidebar();
|
|
39
38
|
});
|
|
40
|
-
|
|
41
|
-
button.addEventListener('mouseenter', () => {
|
|
42
|
-
button.style.transform = 'translateY(-2px)';
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
button.addEventListener('mouseleave', () => {
|
|
46
|
-
button.style.transform = 'translateY(0)';
|
|
47
|
-
});
|
|
48
39
|
}
|
|
49
40
|
|
|
50
|
-
// ==================== POPUP MODAL ====================
|
|
51
|
-
|
|
52
41
|
async openModal() {
|
|
53
42
|
if (this.modalElement) return;
|
|
54
43
|
|
|
55
44
|
this.state.isOpen = true;
|
|
56
45
|
this._createModal();
|
|
57
46
|
|
|
58
|
-
// Load changelogs if not already loaded
|
|
59
47
|
if (this.changelogs.length === 0) {
|
|
60
48
|
await this._loadChangelogs();
|
|
61
49
|
}
|
|
@@ -63,7 +51,6 @@ export class ChangelogWidget extends BaseWidget {
|
|
|
63
51
|
this.currentIndex = 0;
|
|
64
52
|
this._renderCurrentChangelog();
|
|
65
53
|
|
|
66
|
-
// Prevent body scroll
|
|
67
54
|
document.body.style.overflow = 'hidden';
|
|
68
55
|
|
|
69
56
|
requestAnimationFrame(() => {
|
|
@@ -77,7 +64,6 @@ export class ChangelogWidget extends BaseWidget {
|
|
|
77
64
|
}
|
|
78
65
|
|
|
79
66
|
closeModal() {
|
|
80
|
-
// Restore body scroll
|
|
81
67
|
document.body.style.overflow = '';
|
|
82
68
|
|
|
83
69
|
if (this.modalElement) {
|
|
@@ -101,21 +87,19 @@ export class ChangelogWidget extends BaseWidget {
|
|
|
101
87
|
}
|
|
102
88
|
|
|
103
89
|
_createModal() {
|
|
104
|
-
// Create backdrop
|
|
105
90
|
this.backdropElement = document.createElement('div');
|
|
106
91
|
this.backdropElement.className = 'changelog-modal-backdrop';
|
|
107
92
|
document.body.appendChild(this.backdropElement);
|
|
108
93
|
this.backdropElement.addEventListener('click', () => this.closeModal());
|
|
109
94
|
|
|
110
|
-
// Create modal
|
|
111
95
|
this.modalElement = document.createElement('div');
|
|
112
|
-
this.modalElement.className =
|
|
96
|
+
this.modalElement.className = 'changelog-modal';
|
|
113
97
|
this.modalElement.innerHTML = `
|
|
114
98
|
<div class="changelog-modal-container">
|
|
115
99
|
<button class="changelog-modal-close" type="button" aria-label="Close">×</button>
|
|
116
100
|
<div class="changelog-modal-content">
|
|
117
101
|
<div class="changelog-loading">
|
|
118
|
-
<div class="
|
|
102
|
+
<div class="sdk-spinner"></div>
|
|
119
103
|
</div>
|
|
120
104
|
</div>
|
|
121
105
|
</div>
|
|
@@ -123,19 +107,16 @@ export class ChangelogWidget extends BaseWidget {
|
|
|
123
107
|
|
|
124
108
|
document.body.appendChild(this.modalElement);
|
|
125
109
|
|
|
126
|
-
// Prevent clicks inside modal from closing it
|
|
127
110
|
this.modalElement
|
|
128
111
|
.querySelector('.changelog-modal-container')
|
|
129
112
|
.addEventListener('click', (e) => {
|
|
130
113
|
e.stopPropagation();
|
|
131
114
|
});
|
|
132
115
|
|
|
133
|
-
// Attach close button event
|
|
134
116
|
this.modalElement
|
|
135
117
|
.querySelector('.changelog-modal-close')
|
|
136
118
|
.addEventListener('click', () => this.closeModal());
|
|
137
119
|
|
|
138
|
-
// Handle escape key
|
|
139
120
|
this._escapeHandler = (e) => {
|
|
140
121
|
if (e.key === 'Escape') {
|
|
141
122
|
this.closeModal();
|
|
@@ -144,12 +125,9 @@ export class ChangelogWidget extends BaseWidget {
|
|
|
144
125
|
document.addEventListener('keydown', this._escapeHandler);
|
|
145
126
|
}
|
|
146
127
|
|
|
147
|
-
// ==================== LIST MODAL ====================
|
|
148
|
-
|
|
149
128
|
async openSidebar() {
|
|
150
129
|
if (this.listModalElement) return;
|
|
151
130
|
|
|
152
|
-
// Close popup modal if open
|
|
153
131
|
if (this.modalElement) {
|
|
154
132
|
this.closeModal();
|
|
155
133
|
await new Promise((resolve) => setTimeout(resolve, 350));
|
|
@@ -158,20 +136,17 @@ export class ChangelogWidget extends BaseWidget {
|
|
|
158
136
|
this.state.isOpen = true;
|
|
159
137
|
this._createListModal();
|
|
160
138
|
|
|
161
|
-
// Load changelogs if not already loaded
|
|
162
139
|
if (this.changelogs.length === 0) {
|
|
163
140
|
await this._loadChangelogs();
|
|
164
141
|
}
|
|
165
142
|
|
|
166
143
|
this._renderChangelogList();
|
|
167
144
|
|
|
168
|
-
// Prevent body scroll
|
|
169
145
|
document.body.style.overflow = 'hidden';
|
|
170
146
|
|
|
171
147
|
requestAnimationFrame(() => {
|
|
172
148
|
if (this.listModalElement) {
|
|
173
149
|
this.listModalElement.classList.add('open');
|
|
174
|
-
// Trigger confetti animation
|
|
175
150
|
this._showConfetti();
|
|
176
151
|
}
|
|
177
152
|
if (this.listModalBackdropElement) {
|
|
@@ -205,7 +180,6 @@ export class ChangelogWidget extends BaseWidget {
|
|
|
205
180
|
confetti.style.animationDelay = Math.random() * 0.5 + 's';
|
|
206
181
|
confetti.style.animationDuration = Math.random() * 1 + 1.5 + 's';
|
|
207
182
|
|
|
208
|
-
// Random shapes
|
|
209
183
|
const shapes = ['circle', 'square', 'rectangle'];
|
|
210
184
|
const shape = shapes[Math.floor(Math.random() * shapes.length)];
|
|
211
185
|
if (shape === 'circle') {
|
|
@@ -223,7 +197,6 @@ export class ChangelogWidget extends BaseWidget {
|
|
|
223
197
|
container.appendChild(confetti);
|
|
224
198
|
}
|
|
225
199
|
|
|
226
|
-
// Remove confetti after animation
|
|
227
200
|
setTimeout(() => {
|
|
228
201
|
if (container.parentNode) {
|
|
229
202
|
container.parentNode.removeChild(container);
|
|
@@ -232,7 +205,6 @@ export class ChangelogWidget extends BaseWidget {
|
|
|
232
205
|
}
|
|
233
206
|
|
|
234
207
|
closeSidebar() {
|
|
235
|
-
// Restore body scroll
|
|
236
208
|
document.body.style.overflow = '';
|
|
237
209
|
|
|
238
210
|
if (this.listModalElement) {
|
|
@@ -264,7 +236,6 @@ export class ChangelogWidget extends BaseWidget {
|
|
|
264
236
|
}
|
|
265
237
|
|
|
266
238
|
_createListModal() {
|
|
267
|
-
// Create backdrop
|
|
268
239
|
this.listModalBackdropElement = document.createElement('div');
|
|
269
240
|
this.listModalBackdropElement.className = 'changelog-list-modal-backdrop';
|
|
270
241
|
document.body.appendChild(this.listModalBackdropElement);
|
|
@@ -272,9 +243,8 @@ export class ChangelogWidget extends BaseWidget {
|
|
|
272
243
|
this.closeSidebar()
|
|
273
244
|
);
|
|
274
245
|
|
|
275
|
-
// Create list modal
|
|
276
246
|
this.listModalElement = document.createElement('div');
|
|
277
|
-
this.listModalElement.className =
|
|
247
|
+
this.listModalElement.className = 'changelog-list-modal';
|
|
278
248
|
this.listModalElement.innerHTML = `
|
|
279
249
|
<div class="changelog-list-modal-container">
|
|
280
250
|
<div class="changelog-list-modal-header">
|
|
@@ -283,7 +253,7 @@ export class ChangelogWidget extends BaseWidget {
|
|
|
283
253
|
</div>
|
|
284
254
|
<div class="changelog-list-modal-body">
|
|
285
255
|
<div class="changelog-loading">
|
|
286
|
-
<div class="
|
|
256
|
+
<div class="sdk-spinner"></div>
|
|
287
257
|
</div>
|
|
288
258
|
</div>
|
|
289
259
|
</div>
|
|
@@ -291,19 +261,16 @@ export class ChangelogWidget extends BaseWidget {
|
|
|
291
261
|
|
|
292
262
|
document.body.appendChild(this.listModalElement);
|
|
293
263
|
|
|
294
|
-
// Prevent clicks inside modal from closing it
|
|
295
264
|
this.listModalElement
|
|
296
265
|
.querySelector('.changelog-list-modal-container')
|
|
297
266
|
.addEventListener('click', (e) => {
|
|
298
267
|
e.stopPropagation();
|
|
299
268
|
});
|
|
300
269
|
|
|
301
|
-
// Attach close button event
|
|
302
270
|
this.listModalElement
|
|
303
271
|
.querySelector('.changelog-list-modal-close')
|
|
304
272
|
.addEventListener('click', () => this.closeSidebar());
|
|
305
273
|
|
|
306
|
-
// Handle escape key
|
|
307
274
|
this._listModalEscapeHandler = (e) => {
|
|
308
275
|
if (e.key === 'Escape') {
|
|
309
276
|
this.closeSidebar();
|
|
@@ -340,7 +307,6 @@ export class ChangelogWidget extends BaseWidget {
|
|
|
340
307
|
</div>
|
|
341
308
|
`;
|
|
342
309
|
|
|
343
|
-
// Attach click events to items
|
|
344
310
|
body.querySelectorAll('.changelog-list-item').forEach((item, index) => {
|
|
345
311
|
item.addEventListener('click', () => {
|
|
346
312
|
const changelog = this.changelogs[index];
|
|
@@ -420,7 +386,7 @@ export class ChangelogWidget extends BaseWidget {
|
|
|
420
386
|
const content = this.modalElement.querySelector('.changelog-modal-content');
|
|
421
387
|
|
|
422
388
|
if (this.isLoading) {
|
|
423
|
-
return;
|
|
389
|
+
return;
|
|
424
390
|
}
|
|
425
391
|
|
|
426
392
|
if (this.changelogs.length === 0) {
|
|
@@ -491,14 +457,12 @@ export class ChangelogWidget extends BaseWidget {
|
|
|
491
457
|
</div>
|
|
492
458
|
`;
|
|
493
459
|
|
|
494
|
-
// Attach view button event
|
|
495
460
|
content
|
|
496
461
|
.querySelector('.changelog-popup-btn')
|
|
497
462
|
.addEventListener('click', () => {
|
|
498
463
|
this._handleViewUpdate(changelog);
|
|
499
464
|
});
|
|
500
465
|
|
|
501
|
-
// Attach view all button event
|
|
502
466
|
content
|
|
503
467
|
.querySelector('.changelog-view-all-btn')
|
|
504
468
|
.addEventListener('click', () => {
|
|
@@ -506,7 +470,6 @@ export class ChangelogWidget extends BaseWidget {
|
|
|
506
470
|
setTimeout(() => this.openSidebar(), 350);
|
|
507
471
|
});
|
|
508
472
|
|
|
509
|
-
// Attach dot navigation events
|
|
510
473
|
if (hasMultiple) {
|
|
511
474
|
content.querySelectorAll('.changelog-dot').forEach((dot) => {
|
|
512
475
|
dot.addEventListener('click', (e) => {
|
|
@@ -521,7 +484,6 @@ export class ChangelogWidget extends BaseWidget {
|
|
|
521
484
|
_handleViewUpdate(changelog) {
|
|
522
485
|
this.sdk.eventBus.emit('changelog:view', { changelog });
|
|
523
486
|
|
|
524
|
-
// If there's a URL, open it
|
|
525
487
|
if (changelog.url || changelog.slug) {
|
|
526
488
|
const url =
|
|
527
489
|
changelog.url ||
|
|
@@ -533,7 +495,6 @@ export class ChangelogWidget extends BaseWidget {
|
|
|
533
495
|
}
|
|
534
496
|
}
|
|
535
497
|
|
|
536
|
-
// Custom callback if provided
|
|
537
498
|
if (typeof this.options.onViewUpdate === 'function') {
|
|
538
499
|
this.options.onViewUpdate(changelog);
|
|
539
500
|
}
|
|
@@ -546,12 +507,10 @@ export class ChangelogWidget extends BaseWidget {
|
|
|
546
507
|
}
|
|
547
508
|
|
|
548
509
|
_getContrastColor(hexColor) {
|
|
549
|
-
// Remove # if present
|
|
550
510
|
const hex = hexColor.replace('#', '');
|
|
551
511
|
const r = parseInt(hex.substr(0, 2), 16);
|
|
552
512
|
const g = parseInt(hex.substr(2, 2), 16);
|
|
553
513
|
const b = parseInt(hex.substr(4, 2), 16);
|
|
554
|
-
// Calculate luminance
|
|
555
514
|
const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
|
|
556
515
|
return luminance > 0.5 ? '#1F2937' : '#FFFFFF';
|
|
557
516
|
}
|
|
@@ -611,4 +570,4 @@ export class ChangelogWidget extends BaseWidget {
|
|
|
611
570
|
this.closeSidebar();
|
|
612
571
|
super.destroy();
|
|
613
572
|
}
|
|
614
|
-
}
|
|
573
|
+
}
|
|
@@ -7,38 +7,41 @@ export class InlineWidget extends BaseWidget {
|
|
|
7
7
|
|
|
8
8
|
_render() {
|
|
9
9
|
const widget = document.createElement('div');
|
|
10
|
-
widget.className =
|
|
10
|
+
widget.className = 'feedback-widget feedback-widget-inline';
|
|
11
11
|
widget.innerHTML = `
|
|
12
12
|
<div class="feedback-inline-content">
|
|
13
13
|
<h3>Send us your feedback</h3>
|
|
14
14
|
<form class="feedback-inline-form">
|
|
15
|
-
<div class="
|
|
15
|
+
<div class="sdk-form-group">
|
|
16
16
|
<input
|
|
17
17
|
type="text"
|
|
18
18
|
name="title"
|
|
19
|
+
class="sdk-input"
|
|
19
20
|
placeholder="Title (optional)"
|
|
20
21
|
value="${this.state.title}"
|
|
21
22
|
/>
|
|
22
23
|
</div>
|
|
23
|
-
<div class="
|
|
24
|
+
<div class="sdk-form-group">
|
|
24
25
|
<textarea
|
|
25
26
|
name="content"
|
|
27
|
+
class="sdk-textarea"
|
|
26
28
|
placeholder="Your feedback..."
|
|
27
29
|
required
|
|
28
30
|
>${this.state.content}</textarea>
|
|
29
31
|
</div>
|
|
30
|
-
<div class="
|
|
32
|
+
<div class="sdk-form-group">
|
|
31
33
|
<input
|
|
32
34
|
type="email"
|
|
33
35
|
name="email"
|
|
36
|
+
class="sdk-input"
|
|
34
37
|
placeholder="Email (optional)"
|
|
35
38
|
value="${this.state.email}"
|
|
36
39
|
/>
|
|
37
40
|
</div>
|
|
38
|
-
<button type="submit" class="
|
|
41
|
+
<button type="submit" class="sdk-btn-primary sdk-btn-block">
|
|
39
42
|
Send Feedback
|
|
40
43
|
</button>
|
|
41
|
-
<div class="feedback-error"
|
|
44
|
+
<div class="feedback-error"></div>
|
|
42
45
|
</form>
|
|
43
46
|
</div>
|
|
44
47
|
`;
|
|
@@ -90,14 +93,14 @@ export class InlineWidget extends BaseWidget {
|
|
|
90
93
|
|
|
91
94
|
widget.innerHTML = `
|
|
92
95
|
<div class="feedback-success">
|
|
93
|
-
<div class="
|
|
96
|
+
<div class="sdk-notification-icon">✓</div>
|
|
94
97
|
<h3>Thank you!</h3>
|
|
95
98
|
<p>Your feedback has been submitted successfully.</p>
|
|
96
|
-
<button class="
|
|
99
|
+
<button class="sdk-btn-primary">Send Another</button>
|
|
97
100
|
</div>
|
|
98
101
|
`;
|
|
99
102
|
|
|
100
|
-
const resetBtn = widget.querySelector('.
|
|
103
|
+
const resetBtn = widget.querySelector('.sdk-btn-primary');
|
|
101
104
|
resetBtn.addEventListener('click', () => {
|
|
102
105
|
widget.innerHTML = originalContent;
|
|
103
106
|
this._attachEvents();
|
|
@@ -109,18 +112,18 @@ export class InlineWidget extends BaseWidget {
|
|
|
109
112
|
const errorElement = this.element.querySelector('.feedback-error');
|
|
110
113
|
if (errorElement) {
|
|
111
114
|
errorElement.textContent = message;
|
|
112
|
-
errorElement.
|
|
115
|
+
errorElement.classList.add('show');
|
|
113
116
|
|
|
114
117
|
setTimeout(() => {
|
|
115
118
|
if (errorElement) {
|
|
116
|
-
errorElement.
|
|
119
|
+
errorElement.classList.remove('show');
|
|
117
120
|
}
|
|
118
121
|
}, 5000);
|
|
119
122
|
}
|
|
120
123
|
}
|
|
121
124
|
|
|
122
125
|
_updateSubmitButton() {
|
|
123
|
-
const submitBtn = this.element.querySelector('.
|
|
126
|
+
const submitBtn = this.element.querySelector('.sdk-btn-primary');
|
|
124
127
|
if (submitBtn) {
|
|
125
128
|
submitBtn.textContent = this.state.isSubmitting
|
|
126
129
|
? 'Sending...'
|
|
@@ -142,4 +145,4 @@ export class InlineWidget extends BaseWidget {
|
|
|
142
145
|
input.placeholder = placeholder;
|
|
143
146
|
}
|
|
144
147
|
}
|
|
145
|
-
}
|
|
148
|
+
}
|
|
@@ -134,25 +134,9 @@ export class MessengerWidget extends BaseWidget {
|
|
|
134
134
|
|
|
135
135
|
async _handleStartConversation(messageContent, pendingAttachments) {
|
|
136
136
|
try {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
// If user is authenticated, silently identify them first
|
|
141
|
-
if (isAuthenticated) {
|
|
142
|
-
try {
|
|
143
|
-
await this.apiService.identifyContact({
|
|
144
|
-
name: userContext.name,
|
|
145
|
-
email: userContext.email,
|
|
146
|
-
});
|
|
147
|
-
console.log('[MessengerWidget] User auto-identified for conversation');
|
|
148
|
-
} catch (error) {
|
|
149
|
-
// If identification fails with a non-critical error, continue anyway
|
|
150
|
-
if (error?.code !== 'ALREADY_IDENTIFIED') {
|
|
151
|
-
console.warn('[MessengerWidget] Auto-identification failed:', error);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
} else {
|
|
155
|
-
// Unauthenticated user - show pre-chat form
|
|
137
|
+
// Check if already identified
|
|
138
|
+
if (!this.messengerState.isIdentified) {
|
|
139
|
+
// Not identified - show pre-chat form
|
|
156
140
|
this.messengerState.pendingMessage = {
|
|
157
141
|
content: messageContent,
|
|
158
142
|
attachments: pendingAttachments,
|
|
@@ -161,7 +145,7 @@ async _handleStartConversation(messageContent, pendingAttachments) {
|
|
|
161
145
|
return null;
|
|
162
146
|
}
|
|
163
147
|
|
|
164
|
-
//
|
|
148
|
+
// Already identified - proceed with conversation
|
|
165
149
|
const openConversation = this.messengerState.conversations.find(
|
|
166
150
|
(c) => c.status === 'open'
|
|
167
151
|
);
|
|
@@ -210,42 +194,44 @@ async _handleStartConversation(messageContent, pendingAttachments) {
|
|
|
210
194
|
}
|
|
211
195
|
}
|
|
212
196
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
if (response.status) {
|
|
221
|
-
console.log('[MessengerWidget] Contact identified:', contactData.email);
|
|
222
|
-
|
|
223
|
-
if (!this.messengerState.userContext) {
|
|
224
|
-
this.messengerState.userContext = {};
|
|
225
|
-
}
|
|
226
|
-
this.messengerState.userContext.name = contactData.name;
|
|
227
|
-
this.messengerState.userContext.email = contactData.email;
|
|
197
|
+
async _handleIdentifyContact(contactData) {
|
|
198
|
+
try {
|
|
199
|
+
const response = await this.apiService.identifyContact({
|
|
200
|
+
name: contactData.name,
|
|
201
|
+
email: contactData.email,
|
|
202
|
+
});
|
|
228
203
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
this.messengerState.pendingMessage = null;
|
|
204
|
+
if (response.status) {
|
|
205
|
+
console.log('[MessengerWidget] Contact identified:', response.data.contact_id);
|
|
232
206
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
207
|
+
// Update state
|
|
208
|
+
if (!this.messengerState.userContext) {
|
|
209
|
+
this.messengerState.userContext = {};
|
|
210
|
+
}
|
|
211
|
+
this.messengerState.userContext.name = contactData.name;
|
|
212
|
+
this.messengerState.userContext.email = contactData.email;
|
|
213
|
+
this.messengerState.isIdentified = true; // ADD THIS LINE
|
|
214
|
+
|
|
215
|
+
// Process pending message
|
|
216
|
+
const pendingMessage = this.messengerState.pendingMessage;
|
|
217
|
+
if (pendingMessage) {
|
|
218
|
+
this.messengerState.pendingMessage = null;
|
|
219
|
+
await this.startNewConversation(
|
|
220
|
+
pendingMessage.content,
|
|
221
|
+
'',
|
|
222
|
+
pendingMessage.attachments
|
|
223
|
+
);
|
|
224
|
+
} else {
|
|
225
|
+
this.messengerState.setView('chat');
|
|
241
226
|
}
|
|
242
|
-
|
|
243
|
-
return response;
|
|
244
|
-
} catch (error) {
|
|
245
|
-
console.error('[MessengerWidget] Failed to identify contact:', error);
|
|
246
|
-
throw error;
|
|
247
227
|
}
|
|
228
|
+
|
|
229
|
+
return response;
|
|
230
|
+
} catch (error) {
|
|
231
|
+
console.error('[MessengerWidget] Failed to identify contact:', error);
|
|
232
|
+
throw error;
|
|
248
233
|
}
|
|
234
|
+
}
|
|
249
235
|
|
|
250
236
|
async _handleUploadFile(base64Data, filename) {
|
|
251
237
|
try {
|