@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
|
@@ -36,7 +36,7 @@ export class HomeView {
|
|
|
36
36
|
${this.options.logoUrl ? `<img src="${this.options.logoUrl}" alt="${this.state.teamName}" />` : ''}
|
|
37
37
|
</div>
|
|
38
38
|
<div class="messenger-home-avatars">${avatarsHtml}</div>
|
|
39
|
-
<button class="
|
|
39
|
+
<button class="sdk-close-btn" aria-label="Close">
|
|
40
40
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="#000000" viewBox="0 0 256 256">
|
|
41
41
|
<path d="M205.66,194.34a8,8,0,0,1-11.32,11.32L128,139.31,61.66,205.66a8,8,0,0,1-11.32-11.32L116.69,128,50.34,61.66A8,8,0,0,1,61.66,50.34L128,116.69l66.34-66.35a8,8,0,0,1,11.32,11.32L139.31,128Z"></path>
|
|
42
42
|
</svg>
|
|
@@ -66,30 +66,25 @@ export class HomeView {
|
|
|
66
66
|
if (!avatars || avatars.length === 0) {
|
|
67
67
|
return `
|
|
68
68
|
<div class="messenger-avatar-stack">
|
|
69
|
-
<div class="
|
|
70
|
-
<div class="
|
|
69
|
+
<div class="sdk-avatar sdk-avatar-md">S</div>
|
|
70
|
+
<div class="sdk-avatar sdk-avatar-md">T</div>
|
|
71
71
|
</div>
|
|
72
72
|
`;
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
const avatarItems = avatars
|
|
76
76
|
.slice(0, 3)
|
|
77
|
-
.map((avatar
|
|
77
|
+
.map((avatar) => {
|
|
78
78
|
if (typeof avatar === 'string' && avatar.startsWith('http')) {
|
|
79
|
-
return `<
|
|
79
|
+
return `<div class="sdk-avatar sdk-avatar-md"><img src="${avatar}" alt="Team member" /></div>`;
|
|
80
80
|
}
|
|
81
|
-
return `<div class="
|
|
81
|
+
return `<div class="sdk-avatar sdk-avatar-md">${avatar.charAt(0).toUpperCase()}</div>`;
|
|
82
82
|
})
|
|
83
83
|
.join('');
|
|
84
84
|
|
|
85
85
|
return `<div class="messenger-avatar-stack">${avatarItems}</div>`;
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
-
_getAvatarColor(index) {
|
|
89
|
-
const colors = ['#5856d6', '#007aff', '#34c759', '#ff9500', '#ff3b30'];
|
|
90
|
-
return colors[index % colors.length];
|
|
91
|
-
}
|
|
92
|
-
|
|
93
88
|
_renderAvailabilityStatus() {
|
|
94
89
|
const isOnline = this.state.agentsOnline;
|
|
95
90
|
const responseTime =
|
|
@@ -130,7 +125,7 @@ export class HomeView {
|
|
|
130
125
|
<span class="messenger-home-continue-label">Continue conversation</span>
|
|
131
126
|
<span class="messenger-home-continue-preview">${preview}</span>
|
|
132
127
|
</div>
|
|
133
|
-
<i class="ph ph-arrow-right"
|
|
128
|
+
<i class="ph ph-arrow-right"></i>
|
|
134
129
|
</button>
|
|
135
130
|
`;
|
|
136
131
|
}
|
|
@@ -138,7 +133,7 @@ export class HomeView {
|
|
|
138
133
|
return `
|
|
139
134
|
<button class="messenger-home-message-btn">
|
|
140
135
|
<span>Send us a message</span>
|
|
141
|
-
<i class="ph ph-arrow-right"
|
|
136
|
+
<i class="ph ph-arrow-right"></i>
|
|
142
137
|
</button>
|
|
143
138
|
`;
|
|
144
139
|
}
|
|
@@ -158,7 +153,7 @@ export class HomeView {
|
|
|
158
153
|
<h3>${title}</h3>
|
|
159
154
|
<p>${description}</p>
|
|
160
155
|
</div>
|
|
161
|
-
${action ? `<button class="messenger-home-featured-btn" data-action="${action.type}" data-value="${action.value}">${action.label}</button>` : ''}
|
|
156
|
+
${action ? `<button class="sdk-btn sdk-btn-primary messenger-home-featured-btn" data-action="${action.type}" data-value="${action.value}">${action.label}</button>` : ''}
|
|
162
157
|
</div>
|
|
163
158
|
`;
|
|
164
159
|
}
|
|
@@ -213,7 +208,7 @@ export class HomeView {
|
|
|
213
208
|
|
|
214
209
|
_attachEvents() {
|
|
215
210
|
this.element
|
|
216
|
-
.querySelector('.
|
|
211
|
+
.querySelector('.sdk-close-btn')
|
|
217
212
|
.addEventListener('click', () => {
|
|
218
213
|
this.state.setOpen(false);
|
|
219
214
|
});
|
|
@@ -279,4 +274,4 @@ export class HomeView {
|
|
|
279
274
|
this.element.parentNode.removeChild(this.element);
|
|
280
275
|
}
|
|
281
276
|
}
|
|
282
|
-
}
|
|
277
|
+
}
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* PreChatFormView - Collects user info after the first message
|
|
3
|
-
*/
|
|
4
1
|
export class PreChatFormView {
|
|
5
2
|
constructor(state, options = {}) {
|
|
6
3
|
this.state = state;
|
|
@@ -19,16 +16,15 @@ export class PreChatFormView {
|
|
|
19
16
|
}
|
|
20
17
|
|
|
21
18
|
_updateContent() {
|
|
22
|
-
// Pre-fill from userContext if available
|
|
23
19
|
const existingName = this.state.userContext?.name || '';
|
|
24
20
|
const existingEmail = this.state.userContext?.email || '';
|
|
25
21
|
|
|
26
22
|
this.element.innerHTML = `
|
|
27
23
|
<div class="messenger-prechat-overlay">
|
|
28
24
|
<div class="messenger-prechat-card">
|
|
29
|
-
<h4>Get notified when we reply</h4>
|
|
30
|
-
<form class="
|
|
31
|
-
<div class="
|
|
25
|
+
<h4 class="messenger-prechat-title">Get notified when we reply</h4>
|
|
26
|
+
<form class="sdk-form-group" novalidate>
|
|
27
|
+
<div class="sdk-form-group">
|
|
32
28
|
<input
|
|
33
29
|
type="text"
|
|
34
30
|
id="messenger-prechat-name"
|
|
@@ -36,8 +32,10 @@ export class PreChatFormView {
|
|
|
36
32
|
placeholder="Name (optional)"
|
|
37
33
|
value="${this._escapeHtml(existingName)}"
|
|
38
34
|
autocomplete="name"
|
|
39
|
-
class="
|
|
35
|
+
class="sdk-input"
|
|
40
36
|
/>
|
|
37
|
+
</div>
|
|
38
|
+
<div class="sdk-form-group">
|
|
41
39
|
<input
|
|
42
40
|
type="email"
|
|
43
41
|
id="messenger-prechat-email"
|
|
@@ -46,16 +44,16 @@ export class PreChatFormView {
|
|
|
46
44
|
value="${this._escapeHtml(existingEmail)}"
|
|
47
45
|
required
|
|
48
46
|
autocomplete="email"
|
|
49
|
-
class="
|
|
47
|
+
class="sdk-input"
|
|
50
48
|
/>
|
|
49
|
+
<span class="messenger-prechat-error" id="messenger-email-error"></span>
|
|
51
50
|
</div>
|
|
52
|
-
<span class="messenger-prechat-error" id="messenger-email-error"></span>
|
|
53
51
|
<div class="messenger-prechat-actions">
|
|
54
|
-
<button type="button" class="messenger-prechat-skip">Skip</button>
|
|
55
|
-
<button type="submit" class="messenger-prechat-submit" disabled>
|
|
52
|
+
<button type="button" class="sdk-btn sdk-btn-secondary messenger-prechat-skip">Skip</button>
|
|
53
|
+
<button type="submit" class="sdk-btn sdk-btn-primary sdk-btn-block messenger-prechat-submit" disabled>
|
|
56
54
|
<span class="messenger-prechat-submit-text">Continue</span>
|
|
57
|
-
<span class="messenger-prechat-submit-loading"
|
|
58
|
-
<i class="ph ph-spinner"
|
|
55
|
+
<span class="messenger-prechat-submit-loading">
|
|
56
|
+
<i class="ph ph-spinner"></i>
|
|
59
57
|
</span>
|
|
60
58
|
</button>
|
|
61
59
|
</div>
|
|
@@ -72,20 +70,19 @@ export class PreChatFormView {
|
|
|
72
70
|
if (!avatars || avatars.length === 0) {
|
|
73
71
|
return `
|
|
74
72
|
<div class="messenger-avatar-stack">
|
|
75
|
-
<div class="
|
|
76
|
-
<div class="
|
|
73
|
+
<div class="sdk-avatar sdk-avatar-md">S</div>
|
|
74
|
+
<div class="sdk-avatar sdk-avatar-md">T</div>
|
|
77
75
|
</div>
|
|
78
76
|
`;
|
|
79
77
|
}
|
|
80
78
|
|
|
81
|
-
const colors = ['#5856d6', '#007aff', '#34c759', '#ff9500', '#ff3b30'];
|
|
82
79
|
const avatarItems = avatars
|
|
83
80
|
.slice(0, 3)
|
|
84
|
-
.map((avatar
|
|
81
|
+
.map((avatar) => {
|
|
85
82
|
if (typeof avatar === 'string' && avatar.startsWith('http')) {
|
|
86
|
-
return `<
|
|
83
|
+
return `<div class="sdk-avatar sdk-avatar-md"><img src="${avatar}" alt="Team member" /></div>`;
|
|
87
84
|
}
|
|
88
|
-
return `<div class="
|
|
85
|
+
return `<div class="sdk-avatar sdk-avatar-md">${avatar.charAt(0).toUpperCase()}</div>`;
|
|
89
86
|
})
|
|
90
87
|
.join('');
|
|
91
88
|
|
|
@@ -103,7 +100,7 @@ export class PreChatFormView {
|
|
|
103
100
|
|
|
104
101
|
_attachEvents() {
|
|
105
102
|
// Form validation
|
|
106
|
-
const form = this.element.querySelector('
|
|
103
|
+
const form = this.element.querySelector('form');
|
|
107
104
|
const emailInput = this.element.querySelector('#messenger-prechat-email');
|
|
108
105
|
const submitBtn = this.element.querySelector('.messenger-prechat-submit');
|
|
109
106
|
const skipBtn = this.element.querySelector('.messenger-prechat-skip');
|
|
@@ -127,12 +124,10 @@ export class PreChatFormView {
|
|
|
127
124
|
}
|
|
128
125
|
});
|
|
129
126
|
|
|
130
|
-
// Skip button - go back to chat without collecting info
|
|
131
127
|
skipBtn.addEventListener('click', () => {
|
|
132
128
|
this.state.setView('chat');
|
|
133
129
|
});
|
|
134
130
|
|
|
135
|
-
// Form submission
|
|
136
131
|
form.addEventListener('submit', async (e) => {
|
|
137
132
|
e.preventDefault();
|
|
138
133
|
if (this._isSubmitting) return;
|
|
@@ -143,10 +138,8 @@ export class PreChatFormView {
|
|
|
143
138
|
await this._handleSubmit();
|
|
144
139
|
});
|
|
145
140
|
|
|
146
|
-
// Set initial button state
|
|
147
141
|
validateForm();
|
|
148
142
|
|
|
149
|
-
// Focus email input
|
|
150
143
|
setTimeout(() => emailInput.focus(), 100);
|
|
151
144
|
}
|
|
152
145
|
|
|
@@ -181,19 +174,16 @@ export class PreChatFormView {
|
|
|
181
174
|
const name = nameInput.value.trim();
|
|
182
175
|
const email = emailInput.value.trim();
|
|
183
176
|
|
|
184
|
-
// Show loading state
|
|
185
177
|
this._isSubmitting = true;
|
|
186
178
|
submitBtn.disabled = true;
|
|
187
179
|
submitText.style.display = 'none';
|
|
188
180
|
submitLoading.style.display = 'inline-flex';
|
|
189
181
|
|
|
190
182
|
try {
|
|
191
|
-
// First, identify the contact with collected info
|
|
192
183
|
if (this.options.onIdentifyContact) {
|
|
193
184
|
await this.options.onIdentifyContact({ name, email });
|
|
194
185
|
}
|
|
195
186
|
|
|
196
|
-
// Update state with user info
|
|
197
187
|
if (!this.state.userContext) {
|
|
198
188
|
this.state.userContext = {};
|
|
199
189
|
}
|
|
@@ -202,13 +192,11 @@ export class PreChatFormView {
|
|
|
202
192
|
|
|
203
193
|
this._isSubmitting = false;
|
|
204
194
|
|
|
205
|
-
// Go to chat after collecting contact info
|
|
206
195
|
this.state.setView('chat');
|
|
207
196
|
} catch (error) {
|
|
208
197
|
console.error('[PreChatFormView] Error submitting form:', error);
|
|
209
198
|
this._showError('messenger-email-error', 'Something went wrong. Please try again.');
|
|
210
199
|
|
|
211
|
-
// Reset button state
|
|
212
200
|
this._isSubmitting = false;
|
|
213
201
|
submitBtn.disabled = false;
|
|
214
202
|
submitText.style.display = 'inline';
|