@product7/product7-js 0.1.0

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 (58) hide show
  1. package/README.md +1025 -0
  2. package/dist/README.md +1025 -0
  3. package/dist/product7-js.js +14658 -0
  4. package/dist/product7-js.js.map +1 -0
  5. package/dist/product7-js.min.js +2 -0
  6. package/dist/product7-js.min.js.map +1 -0
  7. package/package.json +114 -0
  8. package/src/api/mock-data/index.js +360 -0
  9. package/src/api/services/ChangelogService.js +28 -0
  10. package/src/api/services/FeedbackService.js +44 -0
  11. package/src/api/services/HelpService.js +50 -0
  12. package/src/api/services/MessengerService.js +279 -0
  13. package/src/api/services/SurveyService.js +127 -0
  14. package/src/api/utils/helpers.js +30 -0
  15. package/src/core/APIService.js +303 -0
  16. package/src/core/BaseAPIService.js +298 -0
  17. package/src/core/EventBus.js +54 -0
  18. package/src/core/Product7.js +812 -0
  19. package/src/core/WebSocketService.js +275 -0
  20. package/src/docs/api.md +226 -0
  21. package/src/docs/example.md +461 -0
  22. package/src/docs/framework-integrations.md +714 -0
  23. package/src/docs/installation.md +281 -0
  24. package/src/index.js +894 -0
  25. package/src/styles/base.js +50 -0
  26. package/src/styles/changelog.js +665 -0
  27. package/src/styles/components.js +553 -0
  28. package/src/styles/design-tokens.js +124 -0
  29. package/src/styles/feedback.js +325 -0
  30. package/src/styles/messenger-components.js +632 -0
  31. package/src/styles/messenger-core.js +233 -0
  32. package/src/styles/messenger-features.js +169 -0
  33. package/src/styles/messenger-views.js +877 -0
  34. package/src/styles/messenger.js +17 -0
  35. package/src/styles/messengerCustomStyles.js +114 -0
  36. package/src/styles/styles.js +26 -0
  37. package/src/styles/survey.js +894 -0
  38. package/src/utils/errors.js +142 -0
  39. package/src/utils/helpers.js +219 -0
  40. package/src/widgets/BaseWidget.js +548 -0
  41. package/src/widgets/ButtonWidget.js +104 -0
  42. package/src/widgets/ChangelogWidget.js +615 -0
  43. package/src/widgets/InlineWidget.js +148 -0
  44. package/src/widgets/MessengerWidget.js +979 -0
  45. package/src/widgets/SurveyWidget.js +1325 -0
  46. package/src/widgets/TabWidget.js +45 -0
  47. package/src/widgets/WidgetFactory.js +70 -0
  48. package/src/widgets/messenger/MessengerState.js +323 -0
  49. package/src/widgets/messenger/components/MessengerLauncher.js +124 -0
  50. package/src/widgets/messenger/components/MessengerPanel.js +111 -0
  51. package/src/widgets/messenger/components/NavigationTabs.js +130 -0
  52. package/src/widgets/messenger/views/ChangelogView.js +167 -0
  53. package/src/widgets/messenger/views/ChatView.js +592 -0
  54. package/src/widgets/messenger/views/ConversationsView.js +244 -0
  55. package/src/widgets/messenger/views/HelpView.js +239 -0
  56. package/src/widgets/messenger/views/HomeView.js +300 -0
  57. package/src/widgets/messenger/views/PreChatFormView.js +109 -0
  58. package/types/index.d.ts +341 -0
package/package.json ADDED
@@ -0,0 +1,114 @@
1
+ {
2
+ "name": "@product7/product7-js",
3
+ "version": "0.1.0",
4
+ "description": "JavaScript SDK for integrating Product7 feedback widgets into any website",
5
+ "main": "dist/product7-js.js",
6
+ "module": "src/index.js",
7
+ "browser": "dist/product7-js.min.js",
8
+ "types": "types/index.d.ts",
9
+ "files": [
10
+ "dist/",
11
+ "src/",
12
+ "types/",
13
+ "README.md"
14
+ ],
15
+ "scripts": {
16
+ "build": "npm run build:dev && npm run build:prod",
17
+ "build:dev": "rollup -c rollup.config.js --environment NODE_ENV:development",
18
+ "build:prod": "rollup -c rollup.config.js --environment NODE_ENV:production",
19
+ "dev": "rollup -c rollup.config.js --environment NODE_ENV:development --watch",
20
+ "serve": "http-server . -p 8080 -c-1",
21
+ "localstack": "npm run build:dev && echo 'Open http://localhost:8080/test.html?env=localstack' && http-server . -p 8080 -c-1",
22
+ "dev:test": "npm run build:dev && npm run serve",
23
+ "test": "jest",
24
+ "test:watch": "jest --watch",
25
+ "test:coverage": "jest --coverage",
26
+ "lint": "eslint src/ --ext .js",
27
+ "lint:fix": "eslint src/ --ext .js --fix",
28
+ "typecheck": "tsc --noEmit",
29
+ "docs": "jsdoc -c jsdoc.config.json",
30
+ "size": "bundlesize",
31
+ "precommit": "npm run lint && npm run test",
32
+ "prepublishOnly": "npm run build && npm run test"
33
+ },
34
+ "keywords": [
35
+ "feedback",
36
+ "widget",
37
+ "sdk",
38
+ "javascript",
39
+ "product7",
40
+ "customer-feedback",
41
+ "user-feedback",
42
+ "embeddable",
43
+ "modal",
44
+ "form"
45
+ ],
46
+ "author": "Product7 Team",
47
+ "license": "MIT",
48
+ "homepage": "https://github.com/product7/product7-js#readme",
49
+ "repository": {
50
+ "type": "git",
51
+ "url": "git+https://github.com/product7/product7-js.git"
52
+ },
53
+ "bugs": {
54
+ "url": "https://github.com/product7/product7-js/issues"
55
+ },
56
+ "engines": {
57
+ "node": ">=14.0.0"
58
+ },
59
+ "browserslist": [
60
+ "> 1%",
61
+ "last 2 versions",
62
+ "not dead",
63
+ "not ie 11"
64
+ ],
65
+ "type": "module",
66
+ "devDependencies": {
67
+ "@babel/core": "^7.28.3",
68
+ "@babel/preset-env": "^7.28.3",
69
+ "@rollup/plugin-babel": "^6.0.4",
70
+ "@rollup/plugin-commonjs": "^28.0.6",
71
+ "@rollup/plugin-node-resolve": "^16.0.1",
72
+ "@rollup/plugin-terser": "^0.4.4",
73
+ "bundlesize": "^0.18.2",
74
+ "eslint": "^8.57.1",
75
+ "eslint-config-standard": "^17.1.0",
76
+ "http-server": "^14.1.1",
77
+ "jest": "^30.1.1",
78
+ "jest-environment-jsdom": "^30.1.1",
79
+ "jsdoc": "^4.0.4",
80
+ "prettier": "^3.6.2",
81
+ "prettier-plugin-organize-imports": "^4.2.0",
82
+ "rollup": "^4.49.0",
83
+ "rollup-plugin-copy": "^3.5.0",
84
+ "rollup-plugin-livereload": "^2.0.5",
85
+ "rollup-plugin-serve": "^3.0.0",
86
+ "typescript": "^5.9.2"
87
+ },
88
+ "bundlesize": [
89
+ {
90
+ "path": "./dist/product7-js.min.js",
91
+ "maxSize": "25kb"
92
+ }
93
+ ],
94
+ "jest": {
95
+ "testEnvironment": "jsdom",
96
+ "testMatch": [
97
+ "**/tests/**/*.test.js",
98
+ "**/src/**/*.test.js"
99
+ ],
100
+ "collectCoverageFrom": [
101
+ "src/**/*.js",
102
+ "!src/**/*.test.js",
103
+ "!src/index.js"
104
+ ],
105
+ "coverageThreshold": {
106
+ "global": {
107
+ "branches": 80,
108
+ "functions": 80,
109
+ "lines": 80,
110
+ "statements": 80
111
+ }
112
+ }
113
+ }
114
+ }
@@ -0,0 +1,360 @@
1
+ export const MOCK_CHANGELOGS = [
2
+ {
3
+ id: 'changelog_1',
4
+ title:
5
+ 'Feature prioritization, multiple roadmaps, and feature request analytics.',
6
+ excerpt:
7
+ 'We are super excited to bring you the long-waited feature prioritization together with many quality updates!',
8
+ description:
9
+ 'We are super excited to bring you the long-waited feature prioritization together with many quality updates!',
10
+ cover_image:
11
+ 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDAwIiBoZWlnaHQ9IjI1MCIgdmlld0JveD0iMCAwIDQwMCAyNTAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHJlY3Qgd2lkdGg9IjQwMCIgaGVpZ2h0PSIyNTAiIGZpbGw9IiNEQkVBRkUiLz48cmVjdCB4PSIyMCIgeT0iMjAiIHdpZHRoPSIzNjAiIGhlaWdodD0iMjEwIiByeD0iOCIgZmlsbD0id2hpdGUiIHN0cm9rZT0iIzE1NUVFRiIgc3Ryb2tlLXdpZHRoPSIyIi8+PHJlY3QgeD0iMzAiIHk9IjQwIiB3aWR0aD0iODAiIGhlaWdodD0iOCIgcng9IjQiIGZpbGw9IiNFNUU3RUIiLz48cmVjdCB4PSIzMCIgeT0iNjAiIHdpZHRoPSIxNDAiIGhlaWdodD0iNDAiIHJ4PSI0IiBmaWxsPSIjRjNGNEY2Ii8+PHRleHQgeD0iNDAiIHk9Ijg1IiBmb250LWZhbWlseT0ic3lzdGVtLXVpIiBmb250LXNpemU9IjE2IiBmb250LXdlaWdodD0iNjAwIiBmaWxsPSIjMUYyOTM3Ij4yMDA8L3RleHQ+PHRleHQgeD0iNDAiIHk9Ijk1IiBmb250LWZhbWlseT0ic3lzdGVtLXVpIiBmb250LXNpemU9IjgiIGZpbGw9IiM2QjcyODAiPlBvc3RzPC90ZXh0PjxyZWN0IHg9IjE4MCIgeT0iNjAiIHdpZHRoPSI4MCIgaGVpZ2h0PSI0MCIgcng9IjQiIGZpbGw9IiNGM0Y0RjYiLz48cmVjdCB4PSIyNzAiIHk9IjYwIiB3aWR0aD0iODAiIGhlaWdodD0iNDAiIHJ4PSI0IiBmaWxsPSIjRjNGNEY2Ii8+PHBhdGggZD0iTTMwIDEzMEgzNzBNMzAgMTUwSDM3ME0zMCAxNzBIMzcwTTMwIDE5MEgzNzAiIHN0cm9rZT0iI0U1RTdFQiIgc3Ryb2tlLXdpZHRoPSIxIi8+PHBhdGggZD0iTTUwIDE2MEwxMDAgMTQwTDE1MCAxNTBMMjAwIDEzMEwyNTAgMTM1TDMwMCAxMjBMMzUwIDEyNSIgc3Ryb2tlPSIjMTU1RUVGIiBzdHJva2Utd2lkdGg9IjIiIGZpbGw9Im5vbmUiLz48L3N2Zz4=',
12
+ slug: 'feature-prioritization-roadmaps-analytics',
13
+ published_at: '2025-03-15T10:00:00Z',
14
+ labels: [
15
+ { name: 'New Feature', color: '#10B981' },
16
+ { name: 'Analytics', color: '#6366F1' },
17
+ ],
18
+ status: 'published',
19
+ },
20
+ {
21
+ id: 'changelog_2',
22
+ title: 'Dark mode support and UI improvements',
23
+ excerpt:
24
+ 'You asked for it, we delivered! Dark mode is now available across all pages.',
25
+ description:
26
+ 'You asked for it, we delivered! Dark mode is now available across all pages.',
27
+ cover_image:
28
+ 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDAwIiBoZWlnaHQ9IjI1MCIgdmlld0JveD0iMCAwIDQwMCAyNTAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHJlY3Qgd2lkdGg9IjQwMCIgaGVpZ2h0PSIyNTAiIGZpbGw9IiMxRjI5MzciLz48cmVjdCB4PSIyMCIgeT0iMjAiIHdpZHRoPSIzNjAiIGhlaWdodD0iMjEwIiByeD0iOCIgZmlsbD0iIzM3NDE1MSIgc3Ryb2tlPSIjNEI1NTYzIiBzdHJva2Utd2lkdGg9IjEiLz48Y2lyY2xlIGN4PSIyMDAiIGN5PSIxMjUiIHI9IjQwIiBmaWxsPSIjRkJCRjI0Ii8+PHBhdGggZD0iTTIyMCAxMjVDMjIwIDEzNiAyMTEgMTQ1IDIwMCAxNDVDMTg5IDE0NSAxODAgMTM2IDE4MCAxMjVDMTgwIDExNCAxODkgMTA1IDIwMCAxMDVDMjExIDEwNSAyMjAgMTE0IDIyMCAxMjVaIiBmaWxsPSIjMUYyOTM3Ii8+PC9zdmc+',
29
+ slug: 'dark-mode-ui-improvements',
30
+ published_at: '2025-03-01T10:00:00Z',
31
+ labels: [{ name: 'Enhancement', color: '#8B5CF6' }],
32
+ status: 'published',
33
+ },
34
+ {
35
+ id: 'changelog_3',
36
+ title: 'Performance improvements and bug fixes',
37
+ excerpt:
38
+ 'This release includes major performance improvements and several bug fixes.',
39
+ description:
40
+ 'This release includes major performance improvements and several bug fixes.',
41
+ slug: 'performance-improvements-bug-fixes',
42
+ published_at: '2025-02-15T10:00:00Z',
43
+ labels: [
44
+ { name: 'Bug Fix', color: '#EF4444' },
45
+ { name: 'Performance', color: '#F59E0B' },
46
+ ],
47
+ status: 'published',
48
+ },
49
+ ];
50
+
51
+ export const MOCK_CONVERSATIONS = [
52
+ {
53
+ id: 'conv_1',
54
+ subject: 'Question about pricing',
55
+ status: 'open',
56
+ last_message_at: new Date(Date.now() - 49 * 60 * 1000).toISOString(),
57
+ created_at: new Date(Date.now() - 2 * 24 * 60 * 60 * 1000).toISOString(),
58
+ unread: 1,
59
+ assigned_user: {
60
+ id: 'user_1',
61
+ name: 'Sarah',
62
+ avatar: null,
63
+ },
64
+ },
65
+ {
66
+ id: 'conv_2',
67
+ subject: 'Feature request',
68
+ status: 'open',
69
+ last_message_at: new Date(
70
+ Date.now() - 6 * 24 * 60 * 60 * 1000
71
+ ).toISOString(),
72
+ created_at: new Date(Date.now() - 10 * 24 * 60 * 60 * 1000).toISOString(),
73
+ unread: 0,
74
+ assigned_user: {
75
+ id: 'user_2',
76
+ name: 'Tom',
77
+ avatar: null,
78
+ },
79
+ },
80
+ ];
81
+
82
+ export const MOCK_MESSAGES = {
83
+ conv_1: [
84
+ {
85
+ id: 'msg_1',
86
+ content: "Hi there! 👋 I'm Sarah. How can I help you today?",
87
+ sender_type: 'agent',
88
+ sender_name: 'Sarah',
89
+ sender_avatar: null,
90
+ created_at: new Date(Date.now() - 50 * 60 * 1000).toISOString(),
91
+ },
92
+ {
93
+ id: 'msg_2',
94
+ content: 'Hi! I have a question about your enterprise pricing.',
95
+ sender_type: 'customer',
96
+ created_at: new Date(Date.now() - 49 * 60 * 1000).toISOString(),
97
+ },
98
+ ],
99
+ conv_2: [
100
+ {
101
+ id: 'msg_3',
102
+ content: "Hello! I'm Tom from the product team.",
103
+ sender_type: 'agent',
104
+ sender_name: 'Tom',
105
+ sender_avatar: null,
106
+ created_at: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString(),
107
+ },
108
+ {
109
+ id: 'msg_4',
110
+ content: 'I would love to see a dark mode feature!',
111
+ sender_type: 'customer',
112
+ created_at: new Date(
113
+ Date.now() - 6 * 24 * 60 * 60 * 1000 - 30 * 60 * 1000
114
+ ).toISOString(),
115
+ },
116
+ {
117
+ id: 'msg_5',
118
+ content:
119
+ "Great suggestion! That feature will be available next week. I'll let you know when it's ready.",
120
+ sender_type: 'agent',
121
+ sender_name: 'Tom',
122
+ sender_avatar: null,
123
+ created_at: new Date(Date.now() - 6 * 24 * 60 * 60 * 1000).toISOString(),
124
+ },
125
+ ],
126
+ };
127
+
128
+ export const MOCK_HELP_COLLECTIONS = [
129
+ {
130
+ id: 'collection_1',
131
+ title: 'Product Overview',
132
+ description: 'See how your AI-first customer service solution works.',
133
+ articleCount: 24,
134
+ icon: 'ph-book-open',
135
+ url: '#',
136
+ },
137
+ {
138
+ id: 'collection_2',
139
+ title: 'Getting Started',
140
+ description: 'Everything you need to know to get started with Product7.',
141
+ articleCount: 30,
142
+ icon: 'ph-rocket',
143
+ url: '#',
144
+ },
145
+ {
146
+ id: 'collection_3',
147
+ title: 'AI Agent',
148
+ description:
149
+ 'Resolving customer questions instantly and accurately—from live chat to email.',
150
+ articleCount: 82,
151
+ icon: 'ph-robot',
152
+ url: '#',
153
+ },
154
+ {
155
+ id: 'collection_4',
156
+ title: 'Channels',
157
+ description:
158
+ 'Enabling the channels you use to communicate with customers, all from the Inbox.',
159
+ articleCount: 45,
160
+ icon: 'ph-chat-circle',
161
+ url: '#',
162
+ },
163
+ {
164
+ id: 'collection_5',
165
+ title: 'Billing & Payments',
166
+ description: 'Manage your subscription, invoices, and payment methods.',
167
+ articleCount: 12,
168
+ icon: 'ph-credit-card',
169
+ url: '#',
170
+ },
171
+ ];
172
+
173
+ export const MOCK_SURVEYS = [
174
+ {
175
+ id: 'mock_nps_survey',
176
+ name: 'NPS Score',
177
+ slug: 'nps',
178
+ status: 'active',
179
+ trigger_type: 'manual',
180
+ pages: [
181
+ {
182
+ id: 'nps-page-1',
183
+ type: 'rating',
184
+ title: 'How likely are you to recommend us to a friend?',
185
+ description: '',
186
+ placeholder: '',
187
+ rating_config: {
188
+ scale: 11,
189
+ low_label: 'Very unlikely',
190
+ high_label: 'Very likely',
191
+ survey_type: 'nps',
192
+ },
193
+ multiple_choice_config: null,
194
+ link_config: null,
195
+ after_this_page: { default: 'end_survey', conditions: [] },
196
+ required: true,
197
+ },
198
+ ],
199
+ },
200
+ {
201
+ id: 'mock_csat_survey',
202
+ name: 'CSAT Survey',
203
+ slug: 'csat',
204
+ status: 'active',
205
+ trigger_type: 'manual',
206
+ pages: [
207
+ {
208
+ id: 'csat-page-1',
209
+ type: 'rating',
210
+ title: 'How satisfied are you with our service?',
211
+ description: '',
212
+ placeholder: '',
213
+ rating_config: {
214
+ scale: 5,
215
+ low_label: 'Very dissatisfied',
216
+ high_label: 'Very satisfied',
217
+ survey_type: 'emoji',
218
+ },
219
+ multiple_choice_config: null,
220
+ link_config: null,
221
+ after_this_page: { default: 'end_survey', conditions: [] },
222
+ required: true,
223
+ },
224
+ ],
225
+ },
226
+ {
227
+ id: 'mock_ces_survey',
228
+ name: 'Customer Effort Score',
229
+ slug: 'ces',
230
+ status: 'active',
231
+ trigger_type: 'manual',
232
+ pages: [
233
+ {
234
+ id: 'ces-page-1',
235
+ type: 'rating',
236
+ title: 'How easy was it to use our product?',
237
+ description: '',
238
+ placeholder: '',
239
+ rating_config: {
240
+ scale: 5,
241
+ low_label: 'Very difficult',
242
+ high_label: 'Very easy',
243
+ survey_type: 'ces',
244
+ },
245
+ multiple_choice_config: null,
246
+ link_config: null,
247
+ after_this_page: { default: 'end_survey', conditions: [] },
248
+ required: true,
249
+ },
250
+ ],
251
+ },
252
+ {
253
+ id: 'mock_open_question_survey',
254
+ name: 'Open Question',
255
+ slug: 'open-question',
256
+ status: 'active',
257
+ trigger_type: 'manual',
258
+ pages: [
259
+ {
260
+ id: 'open-page-1',
261
+ type: 'text',
262
+ title: 'What could we do better?',
263
+ description:
264
+ 'Is there anything we could do to make our product better for you?',
265
+ placeholder: 'Type your answer here',
266
+ rating_config: null,
267
+ multiple_choice_config: null,
268
+ link_config: null,
269
+ after_this_page: { default: 'end_survey', conditions: [] },
270
+ required: true,
271
+ },
272
+ ],
273
+ },
274
+ {
275
+ id: 'mock_product_idea_poll_survey',
276
+ name: 'Product Idea Poll',
277
+ slug: 'product-idea-poll',
278
+ status: 'active',
279
+ trigger_type: 'manual',
280
+ pages: [
281
+ {
282
+ id: 'poll-page-1',
283
+ type: 'multiple_choice',
284
+ title: 'Which feature should we add next?',
285
+ description: 'Vote on the feature you would like to see next.',
286
+ placeholder: '',
287
+ rating_config: null,
288
+ multiple_choice_config: {
289
+ allow_multiple_selection: false,
290
+ survey_type: 'regular',
291
+ options: [
292
+ { id: 'opt1', label: 'Better reporting' },
293
+ { id: 'opt2', label: 'Mobile app' },
294
+ { id: 'opt3', label: 'Integrations' },
295
+ { id: 'opt4', label: 'AI features' },
296
+ ],
297
+ },
298
+ link_config: null,
299
+ after_this_page: { default: 'end_survey', conditions: [] },
300
+ required: true,
301
+ },
302
+ ],
303
+ },
304
+ {
305
+ id: 'mock_pmf_survey',
306
+ name: 'Product Market Fit (PMF)',
307
+ slug: 'pmf',
308
+ status: 'active',
309
+ trigger_type: 'manual',
310
+ pages: [
311
+ {
312
+ id: 'pmf-page-1',
313
+ type: 'multiple_choice',
314
+ title: 'How would you feel if you could no longer use our product?',
315
+ description: '',
316
+ placeholder: '',
317
+ rating_config: null,
318
+ multiple_choice_config: {
319
+ allow_multiple_selection: false,
320
+ survey_type: 'regular',
321
+ options: [
322
+ { id: 'very_disappointed', label: 'Very disappointed' },
323
+ { id: 'somewhat_disappointed', label: 'Somewhat disappointed' },
324
+ { id: 'not_disappointed', label: 'Not disappointed' },
325
+ ],
326
+ },
327
+ link_config: null,
328
+ after_this_page: { default: 'end_survey', conditions: [] },
329
+ required: true,
330
+ },
331
+ ],
332
+ },
333
+ {
334
+ id: 'mock_user_interview_survey',
335
+ name: 'User Interview Request',
336
+ slug: 'user-interview',
337
+ status: 'active',
338
+ trigger_type: 'manual',
339
+ pages: [
340
+ {
341
+ id: 'interview-page-1',
342
+ type: 'link',
343
+ title: 'Would you like to hop on a quick demo?',
344
+ description:
345
+ 'We would love to hear your thoughts and answer any questions you have.',
346
+ placeholder: '',
347
+ rating_config: null,
348
+ multiple_choice_config: null,
349
+ link_config: {
350
+ button_text: 'Book a demo',
351
+ link_text: '',
352
+ redirect_url: 'https://example.com',
353
+ open_in: 'new_tab',
354
+ },
355
+ after_this_page: { default: 'end_survey', conditions: [] },
356
+ required: true,
357
+ },
358
+ ],
359
+ },
360
+ ];
@@ -0,0 +1,28 @@
1
+ import { MOCK_CHANGELOGS } from '../mock-data/index.js';
2
+ import { delay } from '../utils/helpers.js';
3
+
4
+ export class ChangelogService {
5
+ constructor(baseAPI) {
6
+ this.api = baseAPI;
7
+ }
8
+
9
+ async getChangelogs(options = {}) {
10
+ await this.api._ensureSession();
11
+
12
+ if (this.api.mock) {
13
+ await delay(300);
14
+ return { success: true, data: MOCK_CHANGELOGS };
15
+ }
16
+
17
+ return this.api._handleAuthRetry(async () => {
18
+ const endpoint = this.api._getEndpointWithParams(
19
+ '/widget/changelogs',
20
+ options
21
+ );
22
+ return await this.api._makeRequest(endpoint, {
23
+ method: 'GET',
24
+ headers: { Authorization: `Bearer ${this.api.sessionToken}` },
25
+ });
26
+ });
27
+ }
28
+ }
@@ -0,0 +1,44 @@
1
+ import { delay } from '../utils/helpers.js';
2
+
3
+ export class FeedbackService {
4
+ constructor(baseAPI) {
5
+ this.api = baseAPI;
6
+ }
7
+
8
+ async submitFeedback(feedbackData) {
9
+ await this.api._ensureSession();
10
+
11
+ if (this.api.mock) {
12
+ await delay(500);
13
+ return {
14
+ success: true,
15
+ data: {
16
+ id: 'mock_post_' + Date.now(),
17
+ title: feedbackData.title,
18
+ content: feedbackData.content,
19
+ },
20
+ message: 'Feedback submitted successfully!',
21
+ };
22
+ }
23
+
24
+ const payload = {
25
+ board:
26
+ feedbackData.board_id || feedbackData.board || feedbackData.boardName,
27
+ title: feedbackData.title,
28
+ content: feedbackData.content,
29
+ attachments: feedbackData.attachments || [],
30
+ };
31
+
32
+ return this.api._handleAuthRetry(async () => {
33
+ const response = await this.api._makeRequest('/widget/feedback', {
34
+ method: 'POST',
35
+ body: JSON.stringify(payload),
36
+ headers: {
37
+ 'Content-Type': 'application/json',
38
+ Authorization: `Bearer ${this.api.sessionToken}`,
39
+ },
40
+ });
41
+ return response;
42
+ });
43
+ }
44
+ }
@@ -0,0 +1,50 @@
1
+ import { MOCK_HELP_COLLECTIONS } from '../mock-data/index.js';
2
+ import { delay } from '../utils/helpers.js';
3
+
4
+ export class HelpService {
5
+ constructor(baseAPI) {
6
+ this.api = baseAPI;
7
+ }
8
+
9
+ async getHelpCollections(options = {}) {
10
+ await this.api._ensureSession();
11
+
12
+ if (this.api.mock) {
13
+ await delay(200);
14
+ return { status: true, data: MOCK_HELP_COLLECTIONS };
15
+ }
16
+
17
+ const endpoint = this.api._getEndpointWithParams(
18
+ '/widget/help/collections',
19
+ options
20
+ );
21
+ return this.api._makeRequest(endpoint, {
22
+ method: 'GET',
23
+ headers: { Authorization: `Bearer ${this.api.sessionToken}` },
24
+ });
25
+ }
26
+
27
+ async searchHelpArticles(query, options = {}) {
28
+ await this.api._ensureSession();
29
+
30
+ if (this.api.mock) {
31
+ await delay(200);
32
+ const filtered = MOCK_HELP_COLLECTIONS.filter(
33
+ (c) =>
34
+ c.title.toLowerCase().includes(query.toLowerCase()) ||
35
+ c.description.toLowerCase().includes(query.toLowerCase())
36
+ );
37
+ return { status: true, data: filtered };
38
+ }
39
+
40
+ const params = { q: query, ...options };
41
+ const endpoint = this.api._getEndpointWithParams(
42
+ '/widget/help/search',
43
+ params
44
+ );
45
+ return this.api._makeRequest(endpoint, {
46
+ method: 'GET',
47
+ headers: { Authorization: `Bearer ${this.api.sessionToken}` },
48
+ });
49
+ }
50
+ }