@product7/feedback-sdk 1.6.0 → 1.6.3

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.
@@ -28,20 +28,24 @@ export class HelpView {
28
28
  <div class="messenger-help-header">
29
29
  <div class="messenger-help-header-top">
30
30
  <h2>Help</h2>
31
- <button class="sdk-close-btn" aria-label="Close">
31
+ <button class="sdk-close-btn messenger-help-close-btn" aria-label="Close">
32
32
  <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" viewBox="0 0 256 256">
33
33
  <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>
34
34
  </svg>
35
35
  </button>
36
36
  </div>
37
- <input
38
- type="text"
39
- class="messenger-help-search-input"
40
- placeholder="Search for help..."
41
- value="${searchQuery}"
42
- />
37
+ <div class="messenger-help-search-wrap">
38
+ <span class="messenger-help-search-icon">
39
+ <iconify-icon icon="ph:magnifying-glass-duotone" width="16" height="16"></iconify-icon>
40
+ </span>
41
+ <input
42
+ type="text"
43
+ class="messenger-help-search-input"
44
+ placeholder="Search for help..."
45
+ value="${searchQuery}"
46
+ />
47
+ </div>
43
48
  </div>
44
-
45
49
  <div class="messenger-help-body">
46
50
  <div class="messenger-help-collections"></div>
47
51
  </div>
@@ -52,13 +56,11 @@ export class HelpView {
52
56
  }
53
57
 
54
58
  _updateCollectionsList() {
55
- const collectionsContainer = this.element.querySelector(
56
- '.messenger-help-collections'
57
- );
59
+ const container = this.element.querySelector('.messenger-help-collections');
58
60
  const collections = this.state.helpArticles || [];
59
61
  const searchQuery = (this.state.helpSearchQuery || '').toLowerCase();
60
62
 
61
- const filteredCollections = searchQuery
63
+ const filtered = searchQuery
62
64
  ? collections.filter(
63
65
  (c) =>
64
66
  c.title.toLowerCase().includes(searchQuery) ||
@@ -66,51 +68,104 @@ export class HelpView {
66
68
  )
67
69
  : collections;
68
70
 
69
- const headerEl = this.element.querySelector(
70
- '.messenger-help-collections-header'
71
- );
72
- if (headerEl) {
73
- headerEl.textContent = `${filteredCollections.length} collections`;
71
+ if (filtered.length === 0) {
72
+ container.innerHTML = this._renderEmptyState();
73
+ return;
74
74
  }
75
75
 
76
- if (filteredCollections.length === 0) {
77
- collectionsContainer.innerHTML = this._renderEmptyState();
78
- return;
76
+ container.innerHTML = filtered.map((c) => this._renderCollectionItem(c)).join('');
77
+ this._attachCollectionEvents();
78
+ }
79
+
80
+ _avatarColors = [
81
+ { bg: '#EF4444', text: '#FFFFFF' },
82
+ { bg: '#F97316', text: '#FFFFFF' },
83
+ { bg: '#F59E0B', text: '#FFFFFF' },
84
+ { bg: '#10B981', text: '#FFFFFF' },
85
+ { bg: '#06B6D4', text: '#FFFFFF' },
86
+ { bg: '#3B82F6', text: '#FFFFFF' },
87
+ { bg: '#8B5CF6', text: '#FFFFFF' },
88
+ { bg: '#EC4899', text: '#FFFFFF' },
89
+ ];
90
+
91
+ _getAvatarColor(id) {
92
+ const hash = id.split('').reduce((acc, char) => acc + char.charCodeAt(0), 0);
93
+ return this._avatarColors[hash % this._avatarColors.length];
94
+ }
95
+
96
+ _getInitials(name) {
97
+ if (!name) return 'A';
98
+ return name.split(' ').map((n) => n[0]).join('').toUpperCase().slice(0, 2);
99
+ }
100
+
101
+ _renderAuthorAvatar(collection) {
102
+ if (collection.author?.picture) {
103
+ return `<img
104
+ src="${collection.author.picture}"
105
+ alt="${collection.author.name || ''}"
106
+ class="messenger-help-collection-avatar"
107
+ title="${collection.author.name || ''}"
108
+ />`;
79
109
  }
80
110
 
81
- collectionsContainer.innerHTML = filteredCollections
82
- .map((collection) => this._renderCollectionItem(collection))
83
- .join('');
111
+ const { bg, text } = this._getAvatarColor(collection.id);
112
+ const initials = collection.author?.name ? this._getInitials(collection.author.name) : 'A';
84
113
 
85
- this._attachCollectionEvents();
114
+ return `<span
115
+ class="messenger-help-collection-avatar messenger-help-collection-avatar--initials"
116
+ style="background-color: ${bg}; color: ${text};"
117
+ title="${collection.author?.name || 'Author'}"
118
+ >${initials}</span>`;
119
+ }
120
+
121
+ _resolveCollectionIcon(icon) {
122
+ if (!icon) return this._defaultCollectionIcon();
123
+
124
+ if (icon.trimStart().startsWith('<')) {
125
+ return `<span class="messenger-help-collection-icon">${icon}</span>`;
126
+ }
127
+
128
+ if (icon.startsWith('ph:')) {
129
+ return `<span class="messenger-help-collection-icon">
130
+ <iconify-icon icon="${icon}" width="18" height="18"></iconify-icon>
131
+ </span>`;
132
+ }
133
+
134
+ return this._defaultCollectionIcon();
135
+ }
136
+
137
+ _defaultCollectionIcon() {
138
+ return `<span class="messenger-help-collection-icon">
139
+ <iconify-icon icon="ph:book-open-duotone" width="18" height="18"></iconify-icon>
140
+ </span>`;
86
141
  }
87
142
 
88
143
  _renderCollectionItem(collection) {
89
144
  const articleCount = collection.articleCount || 0;
145
+
90
146
  return `
91
147
  <div class="messenger-help-collection" data-collection-id="${collection.id}">
148
+ ${this._resolveCollectionIcon(collection.icon)}
92
149
  <div class="messenger-help-collection-content">
93
- <h3 class="messenger-help-collection-title">${collection.title}</h3>
94
- <p class="messenger-help-collection-desc">${collection.description || ''}</p>
95
- <span class="messenger-help-collection-count">${articleCount} articles</span>
150
+ <div class="messenger-help-collection-title">${collection.title}</div>
151
+ ${collection.description ? `<p class="messenger-help-collection-desc">${collection.description}</p>` : ''}
152
+ <div class="messenger-help-collection-meta">
153
+ ${this._renderAuthorAvatar(collection)}
154
+ <span class="messenger-help-collection-count">
155
+ ${articleCount} ${articleCount === 1 ? 'article' : 'articles'}
156
+ </span>
157
+ </div>
96
158
  </div>
97
- <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="#000000" viewBox="0 0 256 256" class="messenger-help-collection-arrow">
98
- <path d="M181.66,133.66l-80,80a8,8,0,0,1-11.32-11.32L164.69,128,90.34,53.66a8,8,0,0,1,11.32-11.32l80,80A8,8,0,0,1,181.66,133.66Z"></path>
99
- </svg>
100
159
  </div>
101
160
  `;
102
161
  }
103
162
 
104
163
  _renderEmptyState() {
105
- const isSearching = this.state.helpSearchQuery;
106
-
107
- if (isSearching) {
164
+ if (this.state.helpSearchQuery) {
108
165
  return `
109
166
  <div class="messenger-empty-state">
110
167
  <div class="messenger-empty-state-icon">
111
- <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" fill="currentColor" viewBox="0 0 256 256">
112
- <path d="M229.66,218.34l-50.07-50.06a88.11,88.11,0,1,0-11.31,11.31l50.06,50.07a8,8,0,0,0,11.32-11.32ZM40,112a72,72,0,1,1,72,72A72.08,72.08,0,0,1,40,112Z"></path>
113
- </svg>
168
+ <iconify-icon icon="ph:magnifying-glass-duotone" width="48" height="48"></iconify-icon>
114
169
  </div>
115
170
  <h3>No results found</h3>
116
171
  <p>Try a different search term</p>
@@ -121,9 +176,7 @@ export class HelpView {
121
176
  return `
122
177
  <div class="messenger-empty-state">
123
178
  <div class="messenger-empty-state-icon">
124
- <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" fill="currentColor" viewBox="0 0 256 256">
125
- <path d="M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm0,192a88,88,0,1,1,88-88A88.1,88.1,0,0,1,128,216Zm16-40a8,8,0,0,1-8,8,16,16,0,0,1-16-16V128a8,8,0,0,1,0-16,16,16,0,0,1,16,16v40A8,8,0,0,1,144,176ZM112,84a12,12,0,1,1,12,12A12,12,0,0,1,112,84Z"></path>
126
- </svg>
179
+ <iconify-icon icon="ph:books-duotone" width="48" height="48"></iconify-icon>
127
180
  </div>
128
181
  <h3>Help collections</h3>
129
182
  <p>No collections available yet</p>
@@ -132,15 +185,11 @@ export class HelpView {
132
185
  }
133
186
 
134
187
  _attachEvents() {
135
- this.element
136
- .querySelector('.sdk-close-btn')
137
- .addEventListener('click', () => {
138
- this.state.setOpen(false);
139
- });
188
+ this.element.querySelector('.messenger-help-close-btn').addEventListener('click', () => {
189
+ this.state.setOpen(false);
190
+ });
140
191
 
141
- const searchInput = this.element.querySelector(
142
- '.messenger-help-search-input'
143
- );
192
+ const searchInput = this.element.querySelector('.messenger-help-search-input');
144
193
  let searchTimeout;
145
194
  searchInput.addEventListener('input', (e) => {
146
195
  clearTimeout(searchTimeout);
@@ -153,29 +202,22 @@ export class HelpView {
153
202
  }
154
203
 
155
204
  _attachCollectionEvents() {
156
- this.element
157
- .querySelectorAll('.messenger-help-collection')
158
- .forEach((item) => {
159
- item.addEventListener('click', () => {
160
- const collectionId = item.dataset.collectionId;
161
- const collection = this.state.helpArticles.find(
162
- (c) => c.id === collectionId
163
- );
164
- if (collection && collection.url) {
165
- window.open(collection.url, '_blank');
166
- } else if (this.options.onArticleClick) {
167
- this.options.onArticleClick(collection);
168
- }
169
- });
205
+ this.element.querySelectorAll('.messenger-help-collection').forEach((item) => {
206
+ item.addEventListener('click', () => {
207
+ const collection = this.state.helpArticles.find(
208
+ (c) => c.id === item.dataset.collectionId
209
+ );
210
+ if (collection?.url) {
211
+ window.open(collection.url, '_blank');
212
+ } else if (this.options.onArticleClick) {
213
+ this.options.onArticleClick(collection);
214
+ }
170
215
  });
216
+ });
171
217
  }
172
218
 
173
219
  destroy() {
174
- if (this._unsubscribe) {
175
- this._unsubscribe();
176
- }
177
- if (this.element && this.element.parentNode) {
178
- this.element.parentNode.removeChild(this.element);
179
- }
220
+ if (this._unsubscribe) this._unsubscribe();
221
+ if (this.element?.parentNode) this.element.parentNode.removeChild(this.element);
180
222
  }
181
- }
223
+ }