@encatch/web-sdk 0.0.35 → 1.0.0-beta.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 (33) hide show
  1. package/README.md +140 -638
  2. package/dist/encatch.es.js +2 -0
  3. package/dist/encatch.es.js.map +1 -0
  4. package/dist/encatch.iife.js +2 -0
  5. package/dist/encatch.iife.js.map +1 -0
  6. package/dist/index.d.ts +191 -0
  7. package/package.json +32 -50
  8. package/dist-sdk/plugin/sdk/core-wrapper-BMvOyc0u.js +0 -22926
  9. package/dist-sdk/plugin/sdk/module-DC2Edddk.js +0 -481
  10. package/dist-sdk/plugin/sdk/module.js +0 -5
  11. package/dist-sdk/plugin/sdk/preview-sdk.html +0 -1182
  12. package/dist-sdk/plugin/sdk/vite.svg +0 -15
  13. package/dist-sdk/plugin/sdk/web-form-engine-core.css +0 -1
  14. package/index.d.ts +0 -207
  15. package/src/@types/encatch-type.ts +0 -111
  16. package/src/encatch-instance.ts +0 -161
  17. package/src/feedback-api-types.ts +0 -18
  18. package/src/hooks/useDevice.ts +0 -30
  19. package/src/hooks/useFeedbackInterval.ts +0 -71
  20. package/src/hooks/useFeedbackTriggers.ts +0 -342
  21. package/src/hooks/useFetchElligibleFeedbackConfiguration.ts +0 -363
  22. package/src/hooks/useFetchFeedbackConfigurationDetails.ts +0 -92
  23. package/src/hooks/usePageChangeTracker.ts +0 -88
  24. package/src/hooks/usePrepopulatedAnswers.ts +0 -123
  25. package/src/hooks/useRefineTextForm.ts +0 -55
  26. package/src/hooks/useSubmitFeedbackForm.ts +0 -134
  27. package/src/hooks/useUserSession.ts +0 -53
  28. package/src/module.tsx +0 -428
  29. package/src/store/formResponses.ts +0 -211
  30. package/src/utils/browser-details.ts +0 -36
  31. package/src/utils/duration-utils.ts +0 -158
  32. package/src/utils/feedback-frequency-storage.ts +0 -214
  33. package/src/utils/feedback-storage.ts +0 -166
@@ -1,1182 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
- <title>Encatch SDK Preview</title>
7
- <!-- Load the custom element script -->
8
- <!-- <script type="module" src="./embedded.js"></script> -->
9
- <link rel="stylesheet" href="preview-sdk.css" />
10
- <style>
11
- body {
12
- font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI",
13
- Roboto, sans-serif;
14
- margin: 0;
15
- padding: 20px;
16
- background: black;
17
- min-height: 100vh;
18
- overflow-x: hidden;
19
- overflow-y: auto;
20
- }
21
-
22
- .container {
23
- max-width: 1400px;
24
- margin: 0 auto;
25
- padding-bottom: 2rem;
26
- }
27
-
28
- .header {
29
- text-align: center;
30
- color: white;
31
- margin-bottom: 2rem;
32
- }
33
-
34
- .header h1 {
35
- font-size: 2.5rem;
36
- margin: 0;
37
- text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
38
- }
39
-
40
- .header p {
41
- font-size: 1.2rem;
42
- opacity: 0.9;
43
- margin: 0.5rem 0;
44
- }
45
-
46
- .controls {
47
- display: grid;
48
- grid-template-columns: 1fr 1fr 1fr;
49
- gap: 2rem;
50
- margin-bottom: 2rem;
51
- }
52
-
53
- .card {
54
- background: rgba(255, 255, 255, 0.95);
55
- backdrop-filter: blur(10px);
56
- border-radius: 12px;
57
- padding: 1.5rem;
58
- box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
59
- border: 1px solid rgba(255, 255, 255, 0.2);
60
- }
61
-
62
- .card h3 {
63
- margin: 0 0 1rem 0;
64
- color: #333;
65
- font-size: 1.3rem;
66
- border-bottom: 2px solid #667eea;
67
- padding-bottom: 0.5rem;
68
- }
69
-
70
- .column {
71
- display: flex;
72
- flex-direction: column;
73
- gap: 1rem;
74
- }
75
-
76
- select,
77
- input,
78
- textarea {
79
- padding: 0.75rem 1rem;
80
- border: 2px solid #e1e5e9;
81
- border-radius: 8px;
82
- font-size: 0.95rem;
83
- background: white;
84
- color: #333;
85
- transition: all 0.3s ease;
86
- width: 100%;
87
- box-sizing: border-box;
88
- }
89
-
90
- select:focus,
91
- input:focus,
92
- textarea:focus {
93
- outline: none;
94
- border-color: #667eea;
95
- box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
96
- }
97
-
98
- button {
99
- padding: 0.75rem 1.5rem;
100
- border: none;
101
- border-radius: 8px;
102
- font-size: 1rem;
103
- font-weight: 600;
104
- cursor: pointer;
105
- background: black;
106
- color: white;
107
- transition: all 0.3s ease;
108
- width: 100%;
109
- text-transform: uppercase;
110
- letter-spacing: 0.5px;
111
- }
112
-
113
- button:hover {
114
- transform: translateY(-2px);
115
- box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);
116
- }
117
-
118
- button:active {
119
- transform: translateY(0);
120
- }
121
-
122
- .examples {
123
- background: rgba(255, 255, 255, 0.95);
124
- backdrop-filter: blur(10px);
125
- border-radius: 12px;
126
- padding: 1.5rem;
127
- box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
128
- border: 1px solid rgba(255, 255, 255, 0.2);
129
- margin-top: 2rem;
130
- }
131
-
132
- .examples h3 {
133
- margin: 0 0 1rem 0;
134
- color: #333;
135
- font-size: 1.3rem;
136
- border-bottom: 2px solid #667eea;
137
- padding-bottom: 0.5rem;
138
- }
139
-
140
- .example-grid {
141
- display: grid;
142
- grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
143
- gap: 1rem;
144
- }
145
-
146
- .example-item {
147
- background: #f8f9fa;
148
- border-radius: 8px;
149
- padding: 1rem;
150
- border: 1px solid #e9ecef;
151
- }
152
-
153
- .example-item h4 {
154
- margin: 0 0 0.5rem 0;
155
- color: #495057;
156
- font-size: 0.9rem;
157
- font-weight: 600;
158
- }
159
-
160
- .example-code {
161
- background: #2d3748;
162
- color: #e2e8f0;
163
- padding: 0.75rem;
164
- border-radius: 6px;
165
- font-family: "Monaco", "Menlo", monospace;
166
- font-size: 0.85rem;
167
- overflow-x: auto;
168
- cursor: pointer;
169
- transition: all 0.2s ease;
170
- }
171
-
172
- .example-code:hover {
173
- background: #4a5568;
174
- }
175
-
176
- .copy-btn {
177
- background: #28a745;
178
- color: white;
179
- border: none;
180
- padding: 0.25rem 0.5rem;
181
- border-radius: 4px;
182
- font-size: 0.75rem;
183
- cursor: pointer;
184
- margin-top: 0.5rem;
185
- width: auto;
186
- text-transform: none;
187
- letter-spacing: normal;
188
- }
189
-
190
- .copy-btn:hover {
191
- background: #218838;
192
- transform: none;
193
- box-shadow: none;
194
- }
195
-
196
- .tabs {
197
- display: flex;
198
- background: rgba(255, 255, 255, 0.1);
199
- border-radius: 8px;
200
- padding: 4px;
201
- margin-bottom: 1rem;
202
- }
203
-
204
- .tab {
205
- flex: 1;
206
- background: transparent;
207
- border: none;
208
- padding: 0.5rem 1rem;
209
- border-radius: 6px;
210
- color: rgba(255, 255, 255, 0.7);
211
- cursor: pointer;
212
- transition: all 0.3s ease;
213
- font-weight: 500;
214
- text-transform: none;
215
- letter-spacing: normal;
216
- }
217
-
218
- .tab.active {
219
- background: white;
220
- color: #333;
221
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
222
- }
223
-
224
- .tab-content {
225
- display: none;
226
- }
227
-
228
- .tab-content.active {
229
- display: block;
230
- }
231
-
232
- @media (max-width: 1200px) {
233
- .controls {
234
- grid-template-columns: 1fr 1fr;
235
- }
236
- }
237
-
238
- @media (max-width: 768px) {
239
- .controls {
240
- grid-template-columns: 1fr;
241
- }
242
-
243
- .example-grid {
244
- grid-template-columns: 1fr;
245
- }
246
- }
247
- </style>
248
- </head>
249
- <body>
250
- <div class="container">
251
- <div class="header">
252
- <h1>🚀 Encatch SDK Testing Console</h1>
253
- <p>Test feedback triggers, user identification, and event tracking</p>
254
- </div>
255
-
256
- <div class="controls">
257
- <!-- Feedback Controls Card -->
258
- <div class="card">
259
- <h3>📝 Feedback Controls</h3>
260
- <div class="column">
261
- <select id="languageSelect">
262
- <option value="en">đŸ‡ē🇸 English</option>
263
- <option value="es">đŸ‡Ē🇸 Spanish</option>
264
- <option value="fr">đŸ‡Ģ🇷 French</option>
265
- <option value="de">🇩đŸ‡Ē German</option>
266
- <option value="zh">đŸ‡¨đŸ‡ŗ Chinese</option>
267
- <option value="hi">đŸ‡ŽđŸ‡ŗ Hindi</option>
268
- </select>
269
- <select id="themeSelect">
270
- <option value="light">â˜€ī¸ Light Theme</option>
271
- <option value="dark">🌙 Dark Theme</option>
272
- </select>
273
- <input
274
- type="text"
275
- id="feedbackId"
276
- placeholder="Feedback ID"
277
- value="019865a4-d7f5-79a0-9183-bb1416143b5e"
278
- />
279
- <input
280
- type="text"
281
- id="feedbackName"
282
- placeholder="Feedback Name"
283
- value="Long and Short answer Test"
284
- />
285
- <textarea
286
- id="customPropertiesTextarea"
287
- placeholder="Custom Properties (JSON)"
288
- rows="4"
289
- style="resize: vertical; font-family: monospace"
290
- ></textarea>
291
- <textarea
292
- id="prepopulatedAnswersTextarea"
293
- placeholder="Prepopulated Answers (JSON)"
294
- rows="4"
295
- style="resize: vertical; font-family: monospace"
296
- ></textarea>
297
- <button id="openPopupById">Open by ID</button>
298
- <button id="openPopupByName">Open by Name</button>
299
- </div>
300
- </div>
301
-
302
- <!-- SDK Control-->
303
- <div class="card">
304
- <h3>🔗 SDK Control</h3>
305
- <div class="column">
306
- <div style="background: #f8f9fa; padding: 1rem; border-radius: 6px; margin-bottom: 1rem;">
307
- <strong>Current Session ID:</strong>
308
- <div id="sessionStatus" style="font-family: monospace; color: #666; margin-top: 0.5rem; word-break: break-all;">
309
- No session active
310
- </div>
311
- </div>
312
- <button id="startSessionBtn">🚀 Start SDK (Enable AutoStart)</button>
313
- <button id="stopSessionBtn">âšī¸ Stop SDK</button>
314
- <button id="resetSessionBtn">🔄 Make User Anonymous</button>
315
- <button id="checkSessionBtn">🔍 Check Session Status</button>
316
- </div>
317
- </div>
318
-
319
- <!-- Event Tracking Card -->
320
- <div class="card">
321
- <h3>📊 Event Tracking</h3>
322
- <div class="column">
323
- <input
324
- type="text"
325
- id="eventName"
326
- placeholder="Event Name"
327
- value="customEvent"
328
- />
329
- <textarea
330
- id="eventProperties"
331
- placeholder="Event Properties JSON"
332
- rows="4"
333
- style="resize: vertical; font-family: monospace"
334
- >
335
- {
336
- "timestamp": "2024-01-15T10:30:00Z",
337
- "source": "manual_trigger",
338
- "trackEvent": "trackEvent",
339
- "userId": "12345"
340
- }</textarea
341
- >
342
- <button id="trackEventBtn">đŸŽ¯ Track Event</button>
343
- </div>
344
- </div>
345
-
346
- <!-- User Identification Card -->
347
- <div class="card">
348
- <h3>👤 User Identification</h3>
349
- <div class="tabs">
350
- <button class="tab active" onclick="switchTab('simple')">
351
- Simple
352
- </button>
353
- <button class="tab" onclick="switchTab('json')">JSON</button>
354
- </div>
355
-
356
- <!-- Simple Tab -->
357
- <div id="simple-tab" class="tab-content active">
358
- <div class="column">
359
- <input
360
- type="text"
361
- id="userName"
362
- placeholder="User Name"
363
- value="test@test.com"
364
- />
365
- <input type="text" id="email" placeholder="Email" value="" />
366
- <input type="text" id="phone" placeholder="Phone" value="" />
367
- <input type="text" id="name" placeholder="Name" value="" />
368
- <input type="text" id="age" placeholder="Age" value="" />
369
- <input
370
- type="text"
371
- id="setFields"
372
- placeholder="$set fields (comma separated)"
373
- value=""
374
- />
375
- <input
376
- type="text"
377
- id="setOnceFields"
378
- placeholder="$set_once fields (comma separated)"
379
- value=""
380
- />
381
- <input
382
- type="text"
383
- id="counterName"
384
- placeholder="$counter name"
385
- value="feedbackCount"
386
- />
387
- <input
388
- type="text"
389
- id="counterValue"
390
- placeholder="$counter value"
391
- value="1"
392
- />
393
- <input
394
- type="text"
395
- id="unsetFields"
396
- placeholder="$unset fields (comma separated)"
397
- value=""
398
- />
399
- <button id="identifyUserSimple">👤 Set User (Simple)</button>
400
- </div>
401
- </div>
402
-
403
- <!-- JSON Tab -->
404
- <div id="json-tab" class="tab-content">
405
- <div class="column">
406
- <input
407
- type="text"
408
- id="userNameJson"
409
- placeholder="User Name"
410
- value="test@test.com"
411
- />
412
- <textarea
413
- id="identifyPayload"
414
- placeholder="User Payload JSON"
415
- rows="8"
416
- style="resize: vertical; font-family: monospace"
417
- >
418
- {
419
- "email": "user@example.com",
420
- "name": "John Doe",
421
- "age": 30,
422
- "$set": {
423
- "email": "user@example.com",
424
- "name": "John Doe"
425
- },
426
- "$set_once": {
427
- "first_login": "2024-01-01T00:00:00Z",
428
- "signup_date": "2024-01-01"
429
- },
430
- "$counter": {
431
- "loginCount": 1,
432
- "feedbackCount": 1
433
- },
434
- "$unset": ["old_field", "deprecated_prop"]
435
- }</textarea
436
- >
437
- <button id="identifyUserJson">👤 Set User (JSON)</button>
438
- </div>
439
- </div>
440
- </div>
441
- </div>
442
-
443
- <!-- Fetched Feedbacks Section -->
444
- <div class="examples" style="margin-top: 2rem;">
445
- <h3>đŸ“Ļ Available Feedbacks (from Session Storage)</h3>
446
- <div style="background: #f8f9fa; padding: 1rem; border-radius: 6px; margin-bottom: 1rem;">
447
- <p style="margin: 0 0 0.5rem 0; color: #666; font-size: 0.9rem;">
448
- Click on any feedback ID or name to copy and auto-fill the input fields above
449
- </p>
450
- <div style="display: flex; gap: 0.5rem;">
451
- <button
452
- onclick="displayFeedbacks()"
453
- style="padding: 0.5rem 1rem; background: #667eea; color: white; border: none; border-radius: 6px; cursor: pointer; font-size: 0.9rem;"
454
- >
455
- 🔄 Refresh Display
456
- </button>
457
- <button
458
- onclick="clearSessionStorage()"
459
- style="padding: 0.5rem 1rem; background: #dc3545; color: white; border: none; border-radius: 6px; cursor: pointer; font-size: 0.9rem;"
460
- >
461
- đŸ—‘ī¸ Clear Session Storage
462
- </button>
463
- </div>
464
- </div>
465
- <div id="feedbacksList" style="display: grid; grid-template-columns: repeat(auto-fill, minmax(350px, 1fr)); gap: 1rem;">
466
- <div style="background: #f8f9fa; padding: 1rem; border-radius: 6px; text-align: center; color: #666;">
467
- Loading feedbacks from session storage...
468
- </div>
469
- </div>
470
- </div>
471
-
472
- <!-- Examples Section -->
473
- <div class="examples">
474
- <h3>📋 Copy-Paste Examples</h3>
475
- <div class="example-grid">
476
- <div class="example-item">
477
- <h4>đŸŽ¯ Basic Event Properties</h4>
478
- <div class="example-code" onclick="copyToClipboard(this)">
479
- { "timestamp": "2024-01-15T10:30:00Z", "source": "button_click",
480
- "page": "/dashboard", "userId": "user123" }
481
- </div>
482
- <button
483
- class="copy-btn"
484
- onclick="copyToClipboard(this.previousElementSibling)"
485
- >
486
- 📋 Copy
487
- </button>
488
- </div>
489
-
490
- <div class="example-item">
491
- <h4>đŸĒ E-commerce Event</h4>
492
- <div class="example-code" onclick="copyToClipboard(this)">
493
- { "productId": "prod_123", "productName": "Premium Plan", "price":
494
- 99.99, "currency": "USD", "category": "subscription" }
495
- </div>
496
- <button
497
- class="copy-btn"
498
- onclick="copyToClipboard(this.previousElementSibling)"
499
- >
500
- 📋 Copy
501
- </button>
502
- </div>
503
-
504
- <div class="example-item">
505
- <h4>👤 Basic User Properties</h4>
506
- <div class="example-code" onclick="copyToClipboard(this)">
507
- { "email": "user@example.com", "name": "John Doe", "age": 30,
508
- "plan": "premium", "signup_date": "2024-01-01" }
509
- </div>
510
- <button
511
- class="copy-btn"
512
- onclick="copyToClipboard(this.previousElementSibling)"
513
- >
514
- 📋 Copy
515
- </button>
516
- </div>
517
-
518
- <div class="example-item">
519
- <h4>🔧 $set Operation</h4>
520
- <div class="example-code" onclick="copyToClipboard(this)">
521
- { "$set": { "email": "newemail@example.com", "last_login":
522
- "2024-01-15T10:30:00Z", "subscription_status": "active",
523
- "preferences": { "theme": "dark", "notifications": true } } }
524
- </div>
525
- <button
526
- class="copy-btn"
527
- onclick="copyToClipboard(this.previousElementSibling)"
528
- >
529
- 📋 Copy
530
- </button>
531
- </div>
532
-
533
- <div class="example-item">
534
- <h4>đŸŽ¯ $set_once Operation</h4>
535
- <div class="example-code" onclick="copyToClipboard(this)">
536
- { "$set_once": { "first_login": "2024-01-01T00:00:00Z",
537
- "signup_source": "google_ads", "referrer": "https://google.com",
538
- "initial_plan": "free" } }
539
- </div>
540
- <button
541
- class="copy-btn"
542
- onclick="copyToClipboard(this.previousElementSibling)"
543
- >
544
- 📋 Copy
545
- </button>
546
- </div>
547
-
548
- <div class="example-item">
549
- <h4>📈 $counter Operation</h4>
550
- <div class="example-code" onclick="copyToClipboard(this)">
551
- { "$counter": { "loginCount": 1, "pageViews": 5,
552
- "feedbackSubmitted": 1, "totalPurchases": 2, "supportTickets": 1 }
553
- }
554
- </div>
555
- <button
556
- class="copy-btn"
557
- onclick="copyToClipboard(this.previousElementSibling)"
558
- >
559
- 📋 Copy
560
- </button>
561
- </div>
562
-
563
- <div class="example-item">
564
- <h4>đŸ—‘ī¸ $unset Operation</h4>
565
- <div class="example-code" onclick="copyToClipboard(this)">
566
- { "$unset": [ "old_email", "deprecated_field", "temp_token",
567
- "trial_data", "beta_features" ] }
568
- </div>
569
- <button
570
- class="copy-btn"
571
- onclick="copyToClipboard(this.previousElementSibling)"
572
- >
573
- 📋 Copy
574
- </button>
575
- </div>
576
-
577
- <div class="example-item">
578
- <h4>īŋŊ Prepopulated Answers</h4>
579
- <div class="example-code" onclick="copyToClipboard(this)">
580
- [ { "sectionIndex": 0, "questionIndex": 0, "value": { "rating": 5
581
- } }, { "sectionIndex": 0, "questionIndex": 1, "value": {
582
- "short_answer": "Great product!" } }, { "sectionIndex": 1,
583
- "questionIndex": 0, "value": { "single_choice": "Very satisfied" }
584
- }, { "sectionIndex": 1, "questionIndex": 1, "value": { "nps": 9 }
585
- } ]
586
- </div>
587
- <button
588
- class="copy-btn"
589
- onclick="copyToClipboard(this.previousElementSibling)"
590
- >
591
- 📋 Copy
592
- </button>
593
- </div>
594
-
595
- <div class="example-item">
596
- <h4>īŋŊ🚀 Complete Example</h4>
597
- <div class="example-code" onclick="copyToClipboard(this)">
598
- { "email": "premium@example.com", "name": "Premium User", "$set":
599
- { "plan": "premium", "last_active": "2024-01-15T10:30:00Z" },
600
- "$set_once": { "first_purchase": "2024-01-01T00:00:00Z",
601
- "signup_campaign": "winter_sale" }, "$counter": { "loginCount": 1,
602
- "totalSpent": 199 }, "$unset": ["trial_expires", "temp_discount"]
603
- }
604
- </div>
605
- <button
606
- class="copy-btn"
607
- onclick="copyToClipboard(this.previousElementSibling)"
608
- >
609
- 📋 Copy
610
- </button>
611
- </div>
612
- </div>
613
- </div>
614
- </div>
615
- </body>
616
- <script>
617
- (function(){if(!window.encatch){const a={_i:[],apiKey:"",config:{host:void 0,autoStartEnabled:!1,autoStartSessionDisabled:!0,themeMode:"light",language:"en",customCssLink:""},initialized:!1,chunkUrlLoader:t=>window.encatch.config.host+t,init(t,e){if("initialized"in window.encatch&&window.encatch.initialized)return;window.encatch.apiKey=t,e!=null&&e.host&&(window.encatch.config.host=e.host),e!=null&&e.identity&&(window.encatch.config.identity=e.identity),(e==null?void 0:e.autoStartSessionDisabled)!==void 0&&(window.encatch.config.autoStartSessionDisabled=e.autoStartSessionDisabled),(e==null?void 0:e.processAfterIdentitySet)!==void 0?window.encatch.config.processAfterIdentitySet=e.processAfterIdentitySet:window.encatch.config.processAfterIdentitySet=!1,(e==null?void 0:e.autoStartEnabled)!==void 0&&(window.encatch.config.autoStartEnabled=e.autoStartEnabled),e!=null&&e.themeMode?window.encatch.config.themeMode=e.themeMode:window.encatch.config.themeMode="light",e!=null&&e.language?window.encatch.config.language=e.language:window.encatch.config.language="en",e!=null&&e.customCssLink&&(window.encatch.config.customCssLink=e.customCssLink),e!=null&&e.setUser&&(window.encatch.config.setUser=e.setUser),e!=null&&e.onFormEvent&&(window.encatch.config.onFormEvent=e.onFormEvent),window.encatch.initialized=!0;let c="";c&&!c.startsWith("/")&&(c="/"+c),c=c.replace(/\/+$/,"");const d=`${window.encatch.config.host}${c}/encatch-web-sdk.js`,n=document.createElement("script");n.src=d,n.type="module",n.async=!0;const i=document.head.firstChild;i?document.head.insertBefore(n,i):document.head.appendChild(n);const r=document.createElement("div");r.id="enisght-root",document.body.appendChild(r)}};window.encatch=a;const h=["trackEvent","stop","start","setUser","setThemeMode","setLanguage","openFeedbackById","openFeedbackByName","verifyFeedbackIds","forceFetchEligibleFeedbacks","capturePageScrollEvent"];a._eventSubscriptions=[],a.on=((t,e)=>{const c={eventType:t,callback:e};return a._eventSubscriptions.push(c),()=>{const d=a._eventSubscriptions.indexOf(c);d>-1&&a._eventSubscriptions.splice(d,1)}}),h.forEach(t=>{a[t]=((...e)=>{window.encatch._i.push([t,...e])})})}})();
618
-
619
-
620
-
621
- encatch.init("eng_dev_13cj63w5tJ396e30U0pWBAIt1pk1VhdWDQHgAbIdlNnhvbnANXNyQTgCmG4sMr5IroSz9a3Hx5iZ_c4c9d17c", {
622
- autoStartEnabled: true,
623
- processAfterIdentitySet: true,
624
-
625
- ...(window.location.hostname === 'localhost' ? { host: "http://localhost:4173" } : {}),
626
-
627
- // Form event listeners - Config-based approach
628
- onFormEvent: (formEvent) => {
629
- formEvent.onSubmit((data) => {
630
- console.log('🎉 [Config] Form submitted:', data);
631
- alert(`Form submitted!\nFeedback ID: ${data.feedbackIdentifier || 'N/A'}\nConfig ID: ${data.feedbackConfigurationId}`);
632
- });
633
-
634
- formEvent.onView((data) => {
635
- console.log('đŸ‘ī¸ [Config] Form viewed:', data);
636
- });
637
-
638
- formEvent.onClose((data) => {
639
- console.log('❌ [Config] Form closed:', data);
640
- });
641
-
642
- formEvent.onQuestionAnswered((data) => {
643
- console.log('âœī¸ [Config] Question answered:', data.questionId, data.answer);
644
- });
645
-
646
- formEvent.onSectionChange((data) => {
647
- console.log('📄 [Config] Section changed to:', data.sectionIndex);
648
- });
649
-
650
- formEvent.onError((data) => {
651
- console.error('âš ī¸ [Config] Form error:', data.error);
652
- });
653
- }
654
- });
655
-
656
- // Runtime subscription example - Alternative approach using window.encatch.on()
657
- // You can also subscribe to events at runtime like this:
658
- const unsubscribeSubmit = encatch.on('form:submit', (data) => {
659
- console.log('đŸŽ¯ [Runtime] Form submitted:', data);
660
- });
661
-
662
- // To unsubscribe later: unsubscribeSubmit();
663
- // Add this to test in the browser console:
664
- console.log("autoStartEnabled:", window.encatch.config.autoStartEnabled);
665
- // setTimeout(() => {
666
- // encatch.identify("test@test.com",{"email":"test@test.com", "age":38});
667
- // }, 5000);
668
- // Example usage in the HTML preview file
669
- window.encatch.onSessionDisabled = (functionName, message) => {
670
- console.error(`Function ${functionName} is disabled: ${message}`);
671
- // Show user notification
672
- alert(`Session management is disabled. Please contact your administrator to enable session functions.`);
673
- };
674
- // Tab switching functionality
675
- function switchTab(tabName) {
676
- // Update tab buttons
677
- document
678
- .querySelectorAll(".tab")
679
- .forEach((tab) => tab.classList.remove("active"));
680
- document
681
- .querySelector(`.tab:nth-child(${tabName === "simple" ? "1" : "2"})`)
682
- .classList.add("active");
683
-
684
- // Update tab content
685
- document
686
- .querySelectorAll(".tab-content")
687
- .forEach((content) => content.classList.remove("active"));
688
- document.getElementById(`${tabName}-tab`).classList.add("active");
689
- }
690
-
691
- // Copy to clipboard functionality
692
- function copyToClipboard(element) {
693
- const text = element.textContent;
694
- navigator.clipboard
695
- .writeText(text)
696
- .then(() => {
697
- // Visual feedback
698
- const originalText = element.textContent;
699
- element.style.backgroundColor = "#28a745";
700
- element.textContent = "✅ Copied!";
701
- setTimeout(() => {
702
- element.style.backgroundColor = "#2d3748";
703
- element.textContent = originalText;
704
- }, 1000);
705
- })
706
- .catch((err) => {
707
- console.error("Failed to copy: ", err);
708
- });
709
- }
710
-
711
- // Make functions global
712
- window.switchTab = switchTab;
713
- window.copyToClipboard = copyToClipboard;
714
-
715
- // Add popup functionality
716
- document.getElementById("openPopupById").addEventListener("click", () => {
717
- const feedbackId = document.getElementById("feedbackId").value;
718
- const prepopulatedAnswersText = document.getElementById(
719
- "prepopulatedAnswersTextarea"
720
- ).value;
721
-
722
- if (feedbackId) {
723
- let prepopulatedAnswers = null;
724
-
725
- // Parse prepopulated answers if provided
726
- if (prepopulatedAnswersText.trim()) {
727
- try {
728
- prepopulatedAnswers = JSON.parse(prepopulatedAnswersText);
729
- console.log("📝 Prepopulated Answers:", prepopulatedAnswers);
730
- } catch (error) {
731
- console.error("Invalid JSON in prepopulated answers:", error);
732
- alert(
733
- "Invalid JSON format in prepopulated answers. Please check your JSON syntax."
734
- );
735
- return;
736
- }
737
- }
738
-
739
- console.log("đŸŽ¯ Opening feedback by ID:", feedbackId);
740
- // Pass all parameters including prepopulated answers
741
- encatch.openFeedbackById(
742
- feedbackId,
743
- undefined, // theme
744
- undefined, // language
745
- undefined, // event
746
- undefined, // customProperties
747
- prepopulatedAnswers // prepopulatedAnswers
748
- );
749
- }
750
- });
751
-
752
- document.getElementById("openPopupByName").addEventListener("click", () => {
753
- const feedbackName = document.getElementById("feedbackName").value;
754
- const prepopulatedAnswersText = document.getElementById(
755
- "prepopulatedAnswersTextarea"
756
- ).value;
757
-
758
- if (feedbackName) {
759
- let prepopulatedAnswers = null;
760
-
761
- // Parse prepopulated answers if provided
762
- if (prepopulatedAnswersText.trim()) {
763
- try {
764
- prepopulatedAnswers = JSON.parse(prepopulatedAnswersText);
765
- console.log("📝 Prepopulated Answers:", prepopulatedAnswers);
766
- } catch (error) {
767
- console.error("Invalid JSON in prepopulated answers:", error);
768
- alert(
769
- "Invalid JSON format in prepopulated answers. Please check your JSON syntax."
770
- );
771
- return;
772
- }
773
- }
774
-
775
- console.log("đŸŽ¯ Opening feedback by name:", feedbackName);
776
- // Note: openFeedbackByName doesn't currently support prepopulated answers
777
- // So we just log them for now
778
- if (prepopulatedAnswers) {
779
- console.log(
780
- "📝 Prepopulated Answers (will be ignored by openFeedbackByName):",
781
- prepopulatedAnswers
782
- );
783
- }
784
- encatch.openFeedbackByName(feedbackName);
785
- }
786
- });
787
-
788
- // Add track event functionality
789
- document.getElementById("trackEventBtn").addEventListener("click", () => {
790
- const eventName = document.getElementById("eventName").value;
791
- const propertiesText = document.getElementById("eventProperties").value;
792
-
793
- if (eventName) {
794
- try {
795
- const properties = propertiesText.trim()
796
- ? JSON.parse(propertiesText)
797
- : {};
798
- console.log("đŸŽ¯ Tracking event:", { eventName, properties });
799
- encatch.trackEvent(eventName, properties);
800
- } catch (error) {
801
- console.error("Invalid JSON in event properties:", error);
802
- alert(
803
- "Invalid JSON format in event properties. Please check your JSON syntax."
804
- );
805
- }
806
- }
807
- });
808
-
809
- // Add theme change functionality
810
- document.getElementById("themeSelect").addEventListener("change", (e) => {
811
- const theme = e.target.value;
812
- document.body.setAttribute("data-theme", theme);
813
- console.log("🎨 Setting theme:", theme);
814
- encatch.setThemeMode(theme);
815
- });
816
-
817
- document.getElementById("customPropertiesTextarea").addEventListener("change", (e) => {
818
- const customPropertiesText = e.target.value;
819
-
820
- if (customPropertiesText.trim()) {
821
- try {
822
- const customProperties = JSON.parse(customPropertiesText);
823
- console.log("đŸ“Ļ Setting custom Properties:", customProperties);
824
- encatch.setCustomProperties(customProperties);
825
- } catch (error) {
826
- console.error("Invalid JSON in custom properties:", error);
827
- alert("Invalid JSON format in custom properties. Please check your JSON syntax.");
828
- }
829
- } else {
830
- encatch.setCustomProperties({});
831
- }
832
- });
833
-
834
- // Add language change functionality
835
- document
836
- .getElementById("languageSelect")
837
- .addEventListener("change", (e) => {
838
- const language = e.target.value;
839
- console.log("🌐 Setting language:", language);
840
- encatch.setLanguage(language);
841
- });
842
-
843
- // Simple setUser functionality
844
- document
845
- .getElementById("identifyUserSimple")
846
- .addEventListener("click", () => {
847
- const userName = document.getElementById("userName").value;
848
- const email = document.getElementById("email").value;
849
- const phone = document.getElementById("phone").value;
850
- const name = document.getElementById("name").value;
851
- const age = document.getElementById("age").value;
852
-
853
- // Get operation configuration from UI
854
- const setFieldsInput = document.getElementById("setFields").value;
855
- const setOnceFieldsInput =
856
- document.getElementById("setOnceFields").value;
857
- const counterName = document.getElementById("counterName").value;
858
- const counterValue = document.getElementById("counterValue").value;
859
- const unsetFieldsInput = document.getElementById("unsetFields").value;
860
-
861
- if (userName) {
862
- const userPayload = {};
863
-
864
- // Available user data
865
- const userData = {
866
- email,
867
- phone,
868
- name,
869
- age: age ? parseInt(age) : undefined,
870
- };
871
-
872
- // Handle $set operation
873
- if (setFieldsInput.trim()) {
874
- const setFieldNames = setFieldsInput
875
- .split(",")
876
- .map((f) => f.trim())
877
- .filter((f) => f);
878
- const setData = {};
879
- setFieldNames.forEach((fieldName) => {
880
- if (
881
- userData[fieldName] !== undefined &&
882
- userData[fieldName] !== ""
883
- ) {
884
- setData[fieldName] = userData[fieldName];
885
- }
886
- });
887
- if (Object.keys(setData).length > 0) {
888
- userPayload.$set = setData;
889
- }
890
- }
891
-
892
- // Handle $set_once operation
893
- if (setOnceFieldsInput.trim()) {
894
- const setOnceFieldNames = setOnceFieldsInput
895
- .split(",")
896
- .map((f) => f.trim())
897
- .filter((f) => f);
898
- const setOnceData = {};
899
- setOnceFieldNames.forEach((fieldName) => {
900
- if (
901
- userData[fieldName] !== undefined &&
902
- userData[fieldName] !== ""
903
- ) {
904
- setOnceData[fieldName] = userData[fieldName];
905
- }
906
- });
907
- // Always add date to set_once
908
- setOnceData.date = new Date().toISOString();
909
- if (Object.keys(setOnceData).length > 0) {
910
- userPayload.$set_once = setOnceData;
911
- }
912
- }
913
-
914
- // Handle $counter operation
915
- if (counterName.trim() && counterValue.trim()) {
916
- userPayload.$counter = {
917
- [counterName]: parseInt(counterValue) || 1,
918
- };
919
- }
920
-
921
- // Handle $unset operation
922
- if (unsetFieldsInput.trim()) {
923
- const unsetFieldNames = unsetFieldsInput
924
- .split(",")
925
- .map((f) => f.trim())
926
- .filter((f) => f);
927
- if (unsetFieldNames.length > 0) {
928
- userPayload.$unset = unsetFieldNames;
929
- }
930
- }
931
-
932
- console.log("👤 Setting user (Simple):", {
933
- userId: userName,
934
- payload: userPayload,
935
- });
936
- encatch.setUser(userName, userPayload);
937
- } else {
938
- alert("Please provide a User Name");
939
- }
940
- });
941
-
942
- // JSON setUser functionality
943
- document
944
- .getElementById("identifyUserJson")
945
- .addEventListener("click", () => {
946
- const userName = document.getElementById("userNameJson").value;
947
- const payloadText = document.getElementById("identifyPayload").value;
948
-
949
- if (userName && payloadText.trim()) {
950
- try {
951
- const userPayload = JSON.parse(payloadText);
952
-
953
- console.log("👤 Setting user (JSON):", {
954
- userId: userName,
955
- payload: userPayload,
956
- });
957
-
958
- encatch.setUser(userName, userPayload);
959
- } catch (error) {
960
- console.error("Invalid JSON payload:", error);
961
- alert("Invalid JSON format. Please check your JSON syntax.");
962
- }
963
- } else {
964
- alert("Please provide both User Name and User Payload JSON");
965
- }
966
- });
967
- // Function to update session status display
968
- function updateSessionStatus() {
969
- const sessionId = sessionStorage.getItem('app_session');
970
- const sessionStatusElement = document.getElementById('sessionStatus');
971
-
972
- if (sessionId) {
973
- sessionStatusElement.textContent = sessionId;
974
- sessionStatusElement.style.color = '#28a745';
975
- } else {
976
- sessionStatusElement.textContent = 'No session active';
977
- sessionStatusElement.style.color = '#666';
978
- }
979
- }
980
-
981
- // Session Management Event Listeners
982
- document.getElementById("startSessionBtn").addEventListener("click", () => {
983
- console.log("🚀 Starting SDK (enables autoStart)");
984
- encatch.start();
985
- setTimeout(updateSessionStatus, 100); // Small delay to ensure session is set
986
- });
987
-
988
- document.getElementById("stopSessionBtn").addEventListener("click", () => {
989
- console.log("âšī¸ Stopping SDK");
990
- encatch.stop();
991
- setTimeout(updateSessionStatus, 100);
992
- });
993
-
994
- document.getElementById("resetSessionBtn").addEventListener("click", () => {
995
- console.log("🔄 Making user anonymous");
996
- encatch.setUser();
997
- setTimeout(updateSessionStatus, 100);
998
- });
999
-
1000
- document.getElementById("checkSessionBtn").addEventListener("click", () => {
1001
- const sessionId = sessionStorage.getItem('app_session');
1002
- const userData = sessionStorage.getItem('encatch_app_user');
1003
-
1004
- console.log("🔍 Session Status Check:");
1005
- console.log("Session ID:", sessionId);
1006
- console.log("User Data:", userData ? JSON.parse(userData) : "No user data");
1007
-
1008
- updateSessionStatus();
1009
- });
1010
-
1011
- // Initialize session status on page load
1012
- document.addEventListener('DOMContentLoaded', () => {
1013
- updateSessionStatus();
1014
- });
1015
-
1016
- // Add scroll event listener to automatically trigger capturePageScrollEvent
1017
- function calculateScrollPercentage() {
1018
- const scrollY = window.scrollY;
1019
- const windowHeight = window.innerHeight;
1020
- const documentHeight = document.documentElement.scrollHeight;
1021
- const maxScroll = documentHeight - windowHeight;
1022
- const percentage = maxScroll > 0 ? (scrollY / maxScroll) * 100 : 0;
1023
- return Math.round(percentage);
1024
- }
1025
-
1026
- let scrollTimeout;
1027
- window.addEventListener('scroll', () => {
1028
- // Throttle scroll events to avoid excessive calls
1029
- clearTimeout(scrollTimeout);
1030
- scrollTimeout = setTimeout(() => {
1031
- const scrollPercent = calculateScrollPercentage();
1032
- console.log(`📜 Current scroll percentage: ${scrollPercent}%`);
1033
-
1034
- // Call encatch.capturePageScrollEvent with current scroll percentage
1035
- if (window.encatch && window.encatch.capturePageScrollEvent) {
1036
- encatch.capturePageScrollEvent(`${scrollPercent}%`);
1037
- }
1038
- }, 100); // Throttle to every 100ms
1039
- }, { passive: true });
1040
-
1041
-
1042
- // Function to clear session storage
1043
- function clearSessionStorage() {
1044
- if (confirm('Are you sure you want to clear the session storage? This will remove all cached feedbacks.')) {
1045
- sessionStorage.removeItem('encatch-configuration');
1046
- console.log("đŸ—‘ī¸ Session storage cleared");
1047
- displayFeedbacks();
1048
- }
1049
- }
1050
-
1051
- // Function to display feedbacks
1052
- function displayFeedbacks() {
1053
- const feedbacksList = document.getElementById('feedbacksList');
1054
-
1055
- // Get the configuration from sessionStorage
1056
- const configData = sessionStorage.getItem('encatch-configuration');
1057
-
1058
- if (!configData) {
1059
- feedbacksList.innerHTML = `
1060
- <div style="background: #fff3cd; padding: 1rem; border-radius: 6px; color: #856404;">
1061
- âš ī¸ No feedbacks found. Make sure you've initialized the SDK and fetched configurations.
1062
- </div>
1063
- `;
1064
- return;
1065
- }
1066
-
1067
- try {
1068
- const config = JSON.parse(configData);
1069
- const feedbacks = config.data?.feedbackConfigurations || [];
1070
-
1071
- if (feedbacks.length === 0) {
1072
- feedbacksList.innerHTML = `
1073
- <div style="background: #e7f3ff; padding: 1rem; border-radius: 6px; color: #004085;">
1074
- â„šī¸ No feedbacks available for this configuration.
1075
- </div>
1076
- `;
1077
- return;
1078
- }
1079
-
1080
- console.log(`đŸ“Ļ Found ${feedbacks.length} feedbacks`);
1081
-
1082
- // Create feedback cards
1083
- let feedbacksHTML = '';
1084
- feedbacks.forEach((feedback, index) => {
1085
- const feedbackId = feedback.feedbackConfigurationId || 'N/A';
1086
- const feedbackName = feedback.feedbackTitle || 'Untitled Feedback';
1087
- const isActive = feedback.isActive !== undefined ? feedback.isActive : true;
1088
-
1089
- feedbacksHTML += `
1090
- <div style="background: white; border: 1px solid #e1e5e9; border-radius: 8px; padding: 1rem; box-shadow: 0 2px 4px rgba(0,0,0,0.05);">
1091
- <div style="display: flex; justify-content: space-between; align-items: start; margin-bottom: 0.75rem;">
1092
- <h4 style="margin: 0; color: #333; font-size: 1rem; flex: 1;">
1093
- ${feedbackName}
1094
- </h4>
1095
- <span style="padding: 0.25rem 0.5rem; background: ${isActive ? '#d4edda' : '#f8d7da'}; color: ${isActive ? '#155724' : '#721c24'}; border-radius: 4px; font-size: 0.75rem; white-space: nowrap;">
1096
- ${isActive ? '✓ Active' : '✗ Inactive'}
1097
- </span>
1098
- </div>
1099
-
1100
- <div style="margin-bottom: 0.5rem;">
1101
- <div style="font-size: 0.75rem; color: #666; margin-bottom: 0.25rem; font-weight: 600;">FEEDBACK ID:</div>
1102
- <div
1103
- onclick="copyToClipboardAndFill('${feedbackId}', 'feedbackId', this)"
1104
- style="background: #f8f9fa; padding: 0.5rem; border-radius: 4px; font-family: monospace; font-size: 0.85rem; cursor: pointer; transition: all 0.2s; border: 1px solid #e1e5e9; word-break: break-all;"
1105
- onmouseover="this.style.background='#e9ecef'; this.style.borderColor='#667eea'"
1106
- onmouseout="this.style.background='#f8f9fa'; this.style.borderColor='#e1e5e9'"
1107
- >
1108
- ${feedbackId}
1109
- </div>
1110
- </div>
1111
-
1112
- <div>
1113
- <div style="font-size: 0.75rem; color: #666; margin-bottom: 0.25rem; font-weight: 600;">FEEDBACK NAME:</div>
1114
- <div
1115
- onclick="copyToClipboardAndFill('${feedbackName.replace(/'/g, "\\'")}', 'feedbackName', this)"
1116
- style="background: #f8f9fa; padding: 0.5rem; border-radius: 4px; font-family: monospace; font-size: 0.85rem; cursor: pointer; transition: all 0.2s; border: 1px solid #e1e5e9; word-break: break-all;"
1117
- onmouseover="this.style.background='#e9ecef'; this.style.borderColor='#667eea'"
1118
- onmouseout="this.style.background='#f8f9fa'; this.style.borderColor='#e1e5e9'"
1119
- >
1120
- ${feedbackName}
1121
- </div>
1122
- </div>
1123
- </div>
1124
- `;
1125
- });
1126
-
1127
- feedbacksList.innerHTML = feedbacksHTML;
1128
- console.log("✅ Feedbacks displayed successfully");
1129
-
1130
- } catch (error) {
1131
- console.error("Error parsing feedback configuration:", error);
1132
- feedbacksList.innerHTML = `
1133
- <div style="background: #fee; padding: 1rem; border-radius: 6px; color: #c33;">
1134
- ❌ Error parsing feedback data. Please check console for details.
1135
- </div>
1136
- `;
1137
- }
1138
- }
1139
-
1140
- // Function to copy to clipboard and fill input
1141
- function copyToClipboardAndFill(text, inputId, element) {
1142
- // Copy to clipboard
1143
- navigator.clipboard.writeText(text).then(() => {
1144
- // Fill the input field
1145
- const input = document.getElementById(inputId);
1146
- if (input) {
1147
- input.value = text;
1148
- }
1149
-
1150
- // Visual feedback
1151
- const originalBg = element.style.background;
1152
- const originalText = element.textContent;
1153
- element.style.background = '#28a745';
1154
- element.style.color = 'white';
1155
- element.textContent = '✅ Copied & Filled!';
1156
-
1157
- setTimeout(() => {
1158
- element.style.background = originalBg;
1159
- element.style.color = '';
1160
- element.textContent = originalText;
1161
- }, 1000);
1162
- }).catch(err => {
1163
- console.error('Failed to copy:', err);
1164
- alert('Failed to copy to clipboard');
1165
- });
1166
- }
1167
-
1168
- // Auto-display feedbacks on page load and set up periodic refresh
1169
- document.addEventListener('DOMContentLoaded', () => {
1170
- // Initial display
1171
- setTimeout(() => {
1172
- displayFeedbacks();
1173
- }, 500);
1174
-
1175
- // Auto-refresh every 2 seconds to pick up any new feedbacks
1176
- setInterval(() => {
1177
- displayFeedbacks();
1178
- }, 2000);
1179
- });
1180
-
1181
- </script>
1182
- </html>