call-control-sdk 2.1.0 → 2.3.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.
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # React Call Control SDK
1
+ # Call Control SDK
2
2
 
3
3
  Achala provide call control SDK with Material-UI components, providing a draggable control panel for call management.
4
4
 
@@ -32,14 +32,23 @@ npm install react react-dom @mui/material @mui/icons-material @emotion/react @em
32
32
  ### 1. Initialize the SDK
33
33
 
34
34
  ```typescript
35
- import { initCallSDK } from 'call-control-sdk';
35
+ import { initSDK } from 'call-control-sdk';
36
36
 
37
37
  // Initialize at the top level of your app
38
- initSDK(
39
- "API_KEY",
40
- "TENANT_ID",
41
- "AGENT_ID",
42
- "BASE_URL");
38
+ useEffect(() => {
39
+ // Initialize the SDK with a test API key
40
+ try {
41
+ initSDK({
42
+ apiKey: "apiKey",
43
+ tenantId: "tenantId",
44
+ agentId: "agentId",
45
+ baseUrl: "baseUrl",
46
+ });
47
+ console.log("SDK initialized successfully");
48
+ } catch (error) {
49
+ console.error("SDK initialization failed:", error);
50
+ }
51
+ }, []);
43
52
  ```
44
53
 
45
54
  ### 2. Use the CallControlPanel
@@ -64,12 +73,15 @@ function App() {
64
73
 
65
74
  ## API Reference
66
75
 
67
- ### `initSDK(sdkApiKey: string, tenantId: string, agentId: string, baseUrl: string)`
76
+ ### `initSDK({apiKey: "apiKey",tenantId: "tenantId",agentId: "agentId",baseUrl: "baseUrl",})`
68
77
 
69
78
  Initializes the SDK with an API key, tenantId, agentId, baseUrl. Must be called before using any components.
70
79
 
71
80
  **Parameters:**
72
- - `sdkApiKey` (string): Your API key for SDK authentication
81
+ - `apiKey` (string): Your API key for SDK authentication
82
+ - `tenantId` (string): Your Tenant Id key for Events authentication
83
+ - `agentId` (string): Agent Id for access call controls
84
+ - `baseUrl` (string): Base URL for save events info
73
85
 
74
86
  **Throws:** Error if API key is missing or invalid
75
87
 
@@ -113,26 +125,6 @@ All control states are automatically saved to localStorage:
113
125
 
114
126
  The SDK uses Material-UI components and respects your app's MUI theme. Ensure you wrap your app with a `ThemeProvider`:
115
127
 
116
- ```typescript
117
- import { ThemeProvider, createTheme } from '@mui/material/styles';
118
- import CssBaseline from '@mui/material/CssBaseline';
119
-
120
- const theme = createTheme({
121
- palette: {
122
- mode: 'light',
123
- primary: { main: '#1976d2' }
124
- }
125
- });
126
-
127
- function App() {
128
- return (
129
- <ThemeProvider theme={theme}>
130
- <CssBaseline />
131
- {/* Your app content */}
132
- </ThemeProvider>
133
- );
134
- }
135
- ```
136
128
 
137
129
  ## Browser Support
138
130
 
package/dist/index.d.mts CHANGED
@@ -10,13 +10,19 @@ interface CallControlPanelProps {
10
10
  }
11
11
  type CallStatus = "idle" | "ready" | "break";
12
12
 
13
- declare function CallControlPanel({ onDataChange }: CallControlPanelProps): react_jsx_runtime.JSX.Element;
13
+ declare function CallControlPanel({ onDataChange }: CallControlPanelProps): react_jsx_runtime.JSX.Element | null;
14
14
 
15
15
  /**
16
16
  * Initialize the Call Control SDK with an API key
17
17
  * @param sdkApiKey - The API key for SDK authentication
18
18
  * @throws {Error} When API key is missing or invalid
19
19
  */
20
- declare function initSDK(sdkApiKey: string, tenantId: string, agentId: string, baseUrl: string): void;
20
+ type intiSDKParams = {
21
+ apiKey: string;
22
+ tenantId: string;
23
+ agentId: string;
24
+ baseUrl: string;
25
+ };
26
+ declare function initSDK({ apiKey, tenantId, agentId, baseUrl, }: intiSDKParams): void;
21
27
 
22
28
  export { CallControlPanel, type CallControlPanelProps, type CallData, type CallStatus, initSDK };
package/dist/index.d.ts CHANGED
@@ -10,13 +10,19 @@ interface CallControlPanelProps {
10
10
  }
11
11
  type CallStatus = "idle" | "ready" | "break";
12
12
 
13
- declare function CallControlPanel({ onDataChange }: CallControlPanelProps): react_jsx_runtime.JSX.Element;
13
+ declare function CallControlPanel({ onDataChange }: CallControlPanelProps): react_jsx_runtime.JSX.Element | null;
14
14
 
15
15
  /**
16
16
  * Initialize the Call Control SDK with an API key
17
17
  * @param sdkApiKey - The API key for SDK authentication
18
18
  * @throws {Error} When API key is missing or invalid
19
19
  */
20
- declare function initSDK(sdkApiKey: string, tenantId: string, agentId: string, baseUrl: string): void;
20
+ type intiSDKParams = {
21
+ apiKey: string;
22
+ tenantId: string;
23
+ agentId: string;
24
+ baseUrl: string;
25
+ };
26
+ declare function initSDK({ apiKey, tenantId, agentId, baseUrl, }: intiSDKParams): void;
21
27
 
22
28
  export { CallControlPanel, type CallControlPanelProps, type CallData, type CallStatus, initSDK };
package/dist/index.js CHANGED
@@ -1,9 +1,25 @@
1
1
  "use strict";
2
2
  var __defProp = Object.defineProperty;
3
+ var __defProps = Object.defineProperties;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
6
  var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
8
  var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
6
10
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
11
+ var __spreadValues = (a, b) => {
12
+ for (var prop in b || (b = {}))
13
+ if (__hasOwnProp.call(b, prop))
14
+ __defNormalProp(a, prop, b[prop]);
15
+ if (__getOwnPropSymbols)
16
+ for (var prop of __getOwnPropSymbols(b)) {
17
+ if (__propIsEnum.call(b, prop))
18
+ __defNormalProp(a, prop, b[prop]);
19
+ }
20
+ return a;
21
+ };
22
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
7
23
  var __export = (target, all) => {
8
24
  for (var name in all)
9
25
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -43,13 +59,12 @@ var EventTrackerSDK = class {
43
59
  * @param config Configuration object
44
60
  */
45
61
  async init(config) {
46
- this.config = {
62
+ this.config = __spreadValues({
47
63
  autoTrack: true,
48
64
  retryAttempts: 3,
49
65
  queueSize: 100,
50
- flushInterval: 5e3,
51
- ...config
52
- };
66
+ flushInterval: 5e3
67
+ }, config);
53
68
  this.baseUrl = config.baseUrl || (typeof window !== "undefined" ? window.location.origin : "");
54
69
  this.setupNetworkDetection();
55
70
  const ticket = await this.createTicket();
@@ -226,8 +241,9 @@ var EventTrackerSDK = class {
226
241
  * Make an HTTP request with retry logic
227
242
  */
228
243
  async makeRequest(url, options) {
244
+ var _a;
229
245
  const fullUrl = `${this.baseUrl}${url}`;
230
- const maxRetries = this.config?.retryAttempts || 3;
246
+ const maxRetries = ((_a = this.config) == null ? void 0 : _a.retryAttempts) || 3;
231
247
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
232
248
  try {
233
249
  const response = await fetch(fullUrl, options);
@@ -246,7 +262,8 @@ var EventTrackerSDK = class {
246
262
  * Set up automatic event tracking
247
263
  */
248
264
  setupAutoTracking() {
249
- if (typeof window === "undefined" || !this.config?.autoTrack) return;
265
+ var _a;
266
+ if (typeof window === "undefined" || !((_a = this.config) == null ? void 0 : _a.autoTrack)) return;
250
267
  const autoTrackConfig = this.config.autoTrack === true ? {} : this.config.autoTrack;
251
268
  if (autoTrackConfig.pageVisits !== false) {
252
269
  this.logEvent("pageVisit", {
@@ -263,11 +280,12 @@ var EventTrackerSDK = class {
263
280
  }
264
281
  if (autoTrackConfig.clicks !== false) {
265
282
  document.addEventListener("click", (event) => {
283
+ var _a2;
266
284
  const target = event.target;
267
- if (target.tagName === "BUTTON" || target.tagName === "A" || target.onclick || target.getAttribute("role") === "button") {
285
+ if (target.tagName === "BUTTON" || target.tagName === "A" || target.onclick || target.getAttribute("role") === "button" || target instanceof HTMLButtonElement && target.type === "button") {
268
286
  this.logEvent("click", {
269
287
  element: target.tagName,
270
- text: target.textContent?.trim().substring(0, 100),
288
+ text: (_a2 = target.textContent) == null ? void 0 : _a2.trim().substring(0, 100),
271
289
  // Limit text length
272
290
  href: target.getAttribute("href"),
273
291
  id: target.id,
@@ -309,12 +327,13 @@ var EventTrackerSDK = class {
309
327
  if (target.tagName === "INPUT" || target.tagName === "TEXTAREA" || target.tagName === "SELECT") {
310
328
  clearTimeout(inputTimer);
311
329
  inputTimer = setTimeout(() => {
330
+ var _a2;
312
331
  this.logEvent("fieldChange", {
313
332
  element: target.tagName,
314
333
  type: target.getAttribute("type"),
315
334
  name: target.getAttribute("name"),
316
335
  id: target.id,
317
- valueLength: target.value?.length || 0,
336
+ valueLength: ((_a2 = target.value) == null ? void 0 : _a2.length) || 0,
318
337
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
319
338
  }).catch(
320
339
  (error) => console.warn("Failed to track field change:", error)
@@ -360,8 +379,9 @@ var EventTrackerSDK = class {
360
379
  });
361
380
  });
362
381
  window.addEventListener("unhandledrejection", (event) => {
382
+ var _a2;
363
383
  this.logEvent("unhandledRejection", {
364
- reason: event.reason?.toString(),
384
+ reason: (_a2 = event.reason) == null ? void 0 : _a2.toString(),
365
385
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
366
386
  });
367
387
  });
@@ -404,10 +424,11 @@ var EventTrackerSDK = class {
404
424
  * Start periodic flush timer
405
425
  */
406
426
  startPeriodicFlush() {
427
+ var _a;
407
428
  if (this.flushTimer) {
408
429
  clearInterval(this.flushTimer);
409
430
  }
410
- const interval = this.config?.flushInterval || 5e3;
431
+ const interval = ((_a = this.config) == null ? void 0 : _a.flushInterval) || 5e3;
411
432
  this.flushTimer = setInterval(() => {
412
433
  this.flush();
413
434
  }, interval);
@@ -444,7 +465,8 @@ var SDKStateManager = class {
444
465
  isMuted: false,
445
466
  status: "idle",
446
467
  callStartTime: null,
447
- position: { x: 50, y: 50 },
468
+ controlPanelPosition: { x: 0, y: 0 },
469
+ iframePosition: { x: 0, y: 0 },
448
470
  callData: {
449
471
  mobileNumber: "",
450
472
  callReferenceId: "",
@@ -457,14 +479,14 @@ var SDKStateManager = class {
457
479
  const stored = localStorage.getItem(this.STORAGE_KEY);
458
480
  if (stored) {
459
481
  const parsedState = JSON.parse(stored);
460
- this.state = {
461
- ...this.state,
482
+ this.state = __spreadProps(__spreadValues({}, this.state), {
462
483
  isHolding: parsedState.isHolding || false,
463
484
  isMuted: parsedState.isMuted || false,
464
485
  status: parsedState.status || "idle",
465
- position: parsedState.position || { x: 50, y: 50 },
486
+ controlPanelPosition: parsedState.controlPanelPosition || { x: 50, y: 50 },
487
+ iframePosition: parsedState.iframePosition || { x: 50, y: 50 },
466
488
  callStartTime: parsedState.callStartTime || null
467
- };
489
+ });
468
490
  }
469
491
  } catch (error) {
470
492
  console.warn("Failed to load SDK state from localStorage:", error);
@@ -476,7 +498,8 @@ var SDKStateManager = class {
476
498
  isHolding: this.state.isHolding,
477
499
  isMuted: this.state.isMuted,
478
500
  status: this.state.status,
479
- position: this.state.position,
501
+ controlPanelPosition: this.state.controlPanelPosition,
502
+ iframePosition: this.state.iframePosition,
480
503
  callStartTime: this.state.callStartTime
481
504
  };
482
505
  localStorage.setItem(this.STORAGE_KEY, JSON.stringify(persistentState));
@@ -496,7 +519,7 @@ var SDKStateManager = class {
496
519
  this.notifyListeners();
497
520
  }
498
521
  getState() {
499
- return { ...this.state };
522
+ return __spreadValues({}, this.state);
500
523
  }
501
524
  subscribe(listener) {
502
525
  this.listeners.push(listener);
@@ -522,8 +545,13 @@ var SDKStateManager = class {
522
545
  this.saveToStorage();
523
546
  this.notifyListeners();
524
547
  }
525
- setPosition(position) {
526
- this.state.position = position;
548
+ setControlPanelPosition(position) {
549
+ this.state.controlPanelPosition = position;
550
+ this.saveToStorage();
551
+ this.notifyListeners();
552
+ }
553
+ setIframePosition(position) {
554
+ this.state.iframePosition = position;
527
555
  this.saveToStorage();
528
556
  this.notifyListeners();
529
557
  }
@@ -542,7 +570,7 @@ var SDKStateManager = class {
542
570
  this.notifyListeners();
543
571
  }
544
572
  updateCallData(data) {
545
- this.state.callData = { ...this.state.callData, ...data };
573
+ this.state.callData = __spreadValues(__spreadValues({}, this.state.callData), data);
546
574
  this.notifyListeners();
547
575
  }
548
576
  };
@@ -586,7 +614,7 @@ function useDraggable(initialPosition, onPositionChange) {
586
614
  y: Math.max(0, Math.min(newPosition.y, viewportHeight - rect.height))
587
615
  };
588
616
  setPosition(constrainedPosition);
589
- onPositionChange?.(constrainedPosition);
617
+ onPositionChange == null ? void 0 : onPositionChange(constrainedPosition);
590
618
  },
591
619
  [onPositionChange]
592
620
  );
@@ -669,8 +697,12 @@ function CallControlPanel({ onDataChange }) {
669
697
  const [moreOptionsAnchorEl, setMoreOptionsAnchorEl] = (0, import_react3.useState)(null);
670
698
  const [callDuration, setCallDuration] = (0, import_react3.useState)(0);
671
699
  const { position, isDragging, dragRef, handleMouseDown, handleTouchStart } = useDraggable(
672
- state.position,
673
- (newPosition) => sdkStateManager.setPosition(newPosition)
700
+ state.controlPanelPosition,
701
+ (newPosition) => sdkStateManager.setControlPanelPosition(newPosition)
702
+ );
703
+ const { position: xposition, isDragging: xisDragging, dragRef: xdragRef, handleMouseDown: xhandleMouseDown, handleTouchStart: xhandleTouchStart } = useDraggable(
704
+ state.iframePosition,
705
+ (newPosition) => sdkStateManager.setIframePosition(newPosition)
674
706
  );
675
707
  (0, import_react3.useEffect)(() => {
676
708
  let interval;
@@ -746,6 +778,9 @@ function CallControlPanel({ onDataChange }) {
746
778
  const handleCloseDialer = () => {
747
779
  setDialerAnchorEl(null);
748
780
  };
781
+ if (!state.isInitialized) {
782
+ return null;
783
+ }
749
784
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
750
785
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_material.Fade, { in: true, timeout: 300, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
751
786
  import_material.Paper,
@@ -763,7 +798,6 @@ function CallControlPanel({ onDataChange }) {
763
798
  transition: theme.transitions.create(["box-shadow", "transform"], {
764
799
  duration: theme.transitions.duration.short
765
800
  }),
766
- // transform: isDragging ? "scale(1.01)" : "scale(1)",
767
801
  minWidth: 320,
768
802
  userSelect: "none"
769
803
  },
@@ -964,6 +998,63 @@ function CallControlPanel({ onDataChange }) {
964
998
  )
965
999
  }
966
1000
  ) }),
1001
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_material.Fade, { in: true, timeout: 300, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1002
+ import_material.Paper,
1003
+ {
1004
+ ref: xdragRef,
1005
+ elevation: xisDragging ? 2 : 1,
1006
+ sx: {
1007
+ position: "fixed",
1008
+ left: xposition.x,
1009
+ top: xposition.y,
1010
+ p: 1,
1011
+ height: "auto",
1012
+ // borderRadius: 3,
1013
+ bgcolor: "background.paper",
1014
+ cursor: xisDragging ? "grabbing" : "grab",
1015
+ transition: theme.transitions.create(["box-shadow", "transform"], {
1016
+ duration: theme.transitions.duration.short
1017
+ }),
1018
+ // minWidth: 320,
1019
+ userSelect: "none"
1020
+ },
1021
+ onMouseDown: xhandleMouseDown,
1022
+ onTouchStart: xhandleTouchStart,
1023
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_material.Box, { sx: {
1024
+ display: "flex",
1025
+ alignItems: "center",
1026
+ justifyContent: "center",
1027
+ flexDirection: "column"
1028
+ }, children: [
1029
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
1030
+ import_material.Box,
1031
+ {
1032
+ sx: {
1033
+ width: "100%",
1034
+ height: "auto",
1035
+ display: "flex",
1036
+ alignItems: "center",
1037
+ justifyContent: "space-between"
1038
+ },
1039
+ children: [
1040
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_icons_material.DragIndicator, { sx: {
1041
+ transform: "rotate(90deg)"
1042
+ } }),
1043
+ " ",
1044
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_material.IconButton, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_icons_material.Close, {}) })
1045
+ ]
1046
+ }
1047
+ ),
1048
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1049
+ "iframe",
1050
+ {
1051
+ src: "https://h68.deepijatel.in/ConVoxCCS",
1052
+ height: 300
1053
+ }
1054
+ )
1055
+ ] })
1056
+ }
1057
+ ) }),
967
1058
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
968
1059
  import_material.Menu,
969
1060
  {
@@ -1106,10 +1197,15 @@ function CallControlPanel({ onDataChange }) {
1106
1197
  }
1107
1198
 
1108
1199
  // src/index.ts
1109
- function initSDK(sdkApiKey, tenantId, agentId, baseUrl) {
1110
- sdkStateManager.initialize(sdkApiKey);
1200
+ function initSDK({
1201
+ apiKey,
1202
+ tenantId,
1203
+ agentId,
1204
+ baseUrl
1205
+ }) {
1206
+ sdkStateManager.initialize(apiKey);
1111
1207
  eventTracker.init({
1112
- apiKey: sdkApiKey,
1208
+ apiKey,
1113
1209
  tenantId,
1114
1210
  agentId,
1115
1211
  baseUrl
package/dist/index.mjs CHANGED
@@ -1,5 +1,22 @@
1
1
  var __defProp = Object.defineProperty;
2
+ var __defProps = Object.defineProperties;
3
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
2
7
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
+ var __spreadValues = (a, b) => {
9
+ for (var prop in b || (b = {}))
10
+ if (__hasOwnProp.call(b, prop))
11
+ __defNormalProp(a, prop, b[prop]);
12
+ if (__getOwnPropSymbols)
13
+ for (var prop of __getOwnPropSymbols(b)) {
14
+ if (__propIsEnum.call(b, prop))
15
+ __defNormalProp(a, prop, b[prop]);
16
+ }
17
+ return a;
18
+ };
19
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
3
20
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
21
 
5
22
  // src/lib/hooks/eventsTracker.ts
@@ -18,13 +35,12 @@ var EventTrackerSDK = class {
18
35
  * @param config Configuration object
19
36
  */
20
37
  async init(config) {
21
- this.config = {
38
+ this.config = __spreadValues({
22
39
  autoTrack: true,
23
40
  retryAttempts: 3,
24
41
  queueSize: 100,
25
- flushInterval: 5e3,
26
- ...config
27
- };
42
+ flushInterval: 5e3
43
+ }, config);
28
44
  this.baseUrl = config.baseUrl || (typeof window !== "undefined" ? window.location.origin : "");
29
45
  this.setupNetworkDetection();
30
46
  const ticket = await this.createTicket();
@@ -201,8 +217,9 @@ var EventTrackerSDK = class {
201
217
  * Make an HTTP request with retry logic
202
218
  */
203
219
  async makeRequest(url, options) {
220
+ var _a;
204
221
  const fullUrl = `${this.baseUrl}${url}`;
205
- const maxRetries = this.config?.retryAttempts || 3;
222
+ const maxRetries = ((_a = this.config) == null ? void 0 : _a.retryAttempts) || 3;
206
223
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
207
224
  try {
208
225
  const response = await fetch(fullUrl, options);
@@ -221,7 +238,8 @@ var EventTrackerSDK = class {
221
238
  * Set up automatic event tracking
222
239
  */
223
240
  setupAutoTracking() {
224
- if (typeof window === "undefined" || !this.config?.autoTrack) return;
241
+ var _a;
242
+ if (typeof window === "undefined" || !((_a = this.config) == null ? void 0 : _a.autoTrack)) return;
225
243
  const autoTrackConfig = this.config.autoTrack === true ? {} : this.config.autoTrack;
226
244
  if (autoTrackConfig.pageVisits !== false) {
227
245
  this.logEvent("pageVisit", {
@@ -238,11 +256,12 @@ var EventTrackerSDK = class {
238
256
  }
239
257
  if (autoTrackConfig.clicks !== false) {
240
258
  document.addEventListener("click", (event) => {
259
+ var _a2;
241
260
  const target = event.target;
242
- if (target.tagName === "BUTTON" || target.tagName === "A" || target.onclick || target.getAttribute("role") === "button") {
261
+ if (target.tagName === "BUTTON" || target.tagName === "A" || target.onclick || target.getAttribute("role") === "button" || target instanceof HTMLButtonElement && target.type === "button") {
243
262
  this.logEvent("click", {
244
263
  element: target.tagName,
245
- text: target.textContent?.trim().substring(0, 100),
264
+ text: (_a2 = target.textContent) == null ? void 0 : _a2.trim().substring(0, 100),
246
265
  // Limit text length
247
266
  href: target.getAttribute("href"),
248
267
  id: target.id,
@@ -284,12 +303,13 @@ var EventTrackerSDK = class {
284
303
  if (target.tagName === "INPUT" || target.tagName === "TEXTAREA" || target.tagName === "SELECT") {
285
304
  clearTimeout(inputTimer);
286
305
  inputTimer = setTimeout(() => {
306
+ var _a2;
287
307
  this.logEvent("fieldChange", {
288
308
  element: target.tagName,
289
309
  type: target.getAttribute("type"),
290
310
  name: target.getAttribute("name"),
291
311
  id: target.id,
292
- valueLength: target.value?.length || 0,
312
+ valueLength: ((_a2 = target.value) == null ? void 0 : _a2.length) || 0,
293
313
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
294
314
  }).catch(
295
315
  (error) => console.warn("Failed to track field change:", error)
@@ -335,8 +355,9 @@ var EventTrackerSDK = class {
335
355
  });
336
356
  });
337
357
  window.addEventListener("unhandledrejection", (event) => {
358
+ var _a2;
338
359
  this.logEvent("unhandledRejection", {
339
- reason: event.reason?.toString(),
360
+ reason: (_a2 = event.reason) == null ? void 0 : _a2.toString(),
340
361
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
341
362
  });
342
363
  });
@@ -379,10 +400,11 @@ var EventTrackerSDK = class {
379
400
  * Start periodic flush timer
380
401
  */
381
402
  startPeriodicFlush() {
403
+ var _a;
382
404
  if (this.flushTimer) {
383
405
  clearInterval(this.flushTimer);
384
406
  }
385
- const interval = this.config?.flushInterval || 5e3;
407
+ const interval = ((_a = this.config) == null ? void 0 : _a.flushInterval) || 5e3;
386
408
  this.flushTimer = setInterval(() => {
387
409
  this.flush();
388
410
  }, interval);
@@ -419,7 +441,8 @@ var SDKStateManager = class {
419
441
  isMuted: false,
420
442
  status: "idle",
421
443
  callStartTime: null,
422
- position: { x: 50, y: 50 },
444
+ controlPanelPosition: { x: 0, y: 0 },
445
+ iframePosition: { x: 0, y: 0 },
423
446
  callData: {
424
447
  mobileNumber: "",
425
448
  callReferenceId: "",
@@ -432,14 +455,14 @@ var SDKStateManager = class {
432
455
  const stored = localStorage.getItem(this.STORAGE_KEY);
433
456
  if (stored) {
434
457
  const parsedState = JSON.parse(stored);
435
- this.state = {
436
- ...this.state,
458
+ this.state = __spreadProps(__spreadValues({}, this.state), {
437
459
  isHolding: parsedState.isHolding || false,
438
460
  isMuted: parsedState.isMuted || false,
439
461
  status: parsedState.status || "idle",
440
- position: parsedState.position || { x: 50, y: 50 },
462
+ controlPanelPosition: parsedState.controlPanelPosition || { x: 50, y: 50 },
463
+ iframePosition: parsedState.iframePosition || { x: 50, y: 50 },
441
464
  callStartTime: parsedState.callStartTime || null
442
- };
465
+ });
443
466
  }
444
467
  } catch (error) {
445
468
  console.warn("Failed to load SDK state from localStorage:", error);
@@ -451,7 +474,8 @@ var SDKStateManager = class {
451
474
  isHolding: this.state.isHolding,
452
475
  isMuted: this.state.isMuted,
453
476
  status: this.state.status,
454
- position: this.state.position,
477
+ controlPanelPosition: this.state.controlPanelPosition,
478
+ iframePosition: this.state.iframePosition,
455
479
  callStartTime: this.state.callStartTime
456
480
  };
457
481
  localStorage.setItem(this.STORAGE_KEY, JSON.stringify(persistentState));
@@ -471,7 +495,7 @@ var SDKStateManager = class {
471
495
  this.notifyListeners();
472
496
  }
473
497
  getState() {
474
- return { ...this.state };
498
+ return __spreadValues({}, this.state);
475
499
  }
476
500
  subscribe(listener) {
477
501
  this.listeners.push(listener);
@@ -497,8 +521,13 @@ var SDKStateManager = class {
497
521
  this.saveToStorage();
498
522
  this.notifyListeners();
499
523
  }
500
- setPosition(position) {
501
- this.state.position = position;
524
+ setControlPanelPosition(position) {
525
+ this.state.controlPanelPosition = position;
526
+ this.saveToStorage();
527
+ this.notifyListeners();
528
+ }
529
+ setIframePosition(position) {
530
+ this.state.iframePosition = position;
502
531
  this.saveToStorage();
503
532
  this.notifyListeners();
504
533
  }
@@ -517,7 +546,7 @@ var SDKStateManager = class {
517
546
  this.notifyListeners();
518
547
  }
519
548
  updateCallData(data) {
520
- this.state.callData = { ...this.state.callData, ...data };
549
+ this.state.callData = __spreadValues(__spreadValues({}, this.state.callData), data);
521
550
  this.notifyListeners();
522
551
  }
523
552
  };
@@ -556,7 +585,8 @@ import {
556
585
  DragIndicator,
557
586
  WifiCalling3,
558
587
  Layers,
559
- Phone
588
+ Phone,
589
+ Close
560
590
  } from "@mui/icons-material";
561
591
 
562
592
  // src/lib/hooks/useSDKState.ts
@@ -596,7 +626,7 @@ function useDraggable(initialPosition, onPositionChange) {
596
626
  y: Math.max(0, Math.min(newPosition.y, viewportHeight - rect.height))
597
627
  };
598
628
  setPosition(constrainedPosition);
599
- onPositionChange?.(constrainedPosition);
629
+ onPositionChange == null ? void 0 : onPositionChange(constrainedPosition);
600
630
  },
601
631
  [onPositionChange]
602
632
  );
@@ -679,8 +709,12 @@ function CallControlPanel({ onDataChange }) {
679
709
  const [moreOptionsAnchorEl, setMoreOptionsAnchorEl] = useState3(null);
680
710
  const [callDuration, setCallDuration] = useState3(0);
681
711
  const { position, isDragging, dragRef, handleMouseDown, handleTouchStart } = useDraggable(
682
- state.position,
683
- (newPosition) => sdkStateManager.setPosition(newPosition)
712
+ state.controlPanelPosition,
713
+ (newPosition) => sdkStateManager.setControlPanelPosition(newPosition)
714
+ );
715
+ const { position: xposition, isDragging: xisDragging, dragRef: xdragRef, handleMouseDown: xhandleMouseDown, handleTouchStart: xhandleTouchStart } = useDraggable(
716
+ state.iframePosition,
717
+ (newPosition) => sdkStateManager.setIframePosition(newPosition)
684
718
  );
685
719
  useEffect2(() => {
686
720
  let interval;
@@ -756,6 +790,9 @@ function CallControlPanel({ onDataChange }) {
756
790
  const handleCloseDialer = () => {
757
791
  setDialerAnchorEl(null);
758
792
  };
793
+ if (!state.isInitialized) {
794
+ return null;
795
+ }
759
796
  return /* @__PURE__ */ jsxs(Fragment, { children: [
760
797
  /* @__PURE__ */ jsx(Fade, { in: true, timeout: 300, children: /* @__PURE__ */ jsx(
761
798
  Paper,
@@ -773,7 +810,6 @@ function CallControlPanel({ onDataChange }) {
773
810
  transition: theme.transitions.create(["box-shadow", "transform"], {
774
811
  duration: theme.transitions.duration.short
775
812
  }),
776
- // transform: isDragging ? "scale(1.01)" : "scale(1)",
777
813
  minWidth: 320,
778
814
  userSelect: "none"
779
815
  },
@@ -974,6 +1010,63 @@ function CallControlPanel({ onDataChange }) {
974
1010
  )
975
1011
  }
976
1012
  ) }),
1013
+ /* @__PURE__ */ jsx(Fade, { in: true, timeout: 300, children: /* @__PURE__ */ jsx(
1014
+ Paper,
1015
+ {
1016
+ ref: xdragRef,
1017
+ elevation: xisDragging ? 2 : 1,
1018
+ sx: {
1019
+ position: "fixed",
1020
+ left: xposition.x,
1021
+ top: xposition.y,
1022
+ p: 1,
1023
+ height: "auto",
1024
+ // borderRadius: 3,
1025
+ bgcolor: "background.paper",
1026
+ cursor: xisDragging ? "grabbing" : "grab",
1027
+ transition: theme.transitions.create(["box-shadow", "transform"], {
1028
+ duration: theme.transitions.duration.short
1029
+ }),
1030
+ // minWidth: 320,
1031
+ userSelect: "none"
1032
+ },
1033
+ onMouseDown: xhandleMouseDown,
1034
+ onTouchStart: xhandleTouchStart,
1035
+ children: /* @__PURE__ */ jsxs(Box, { sx: {
1036
+ display: "flex",
1037
+ alignItems: "center",
1038
+ justifyContent: "center",
1039
+ flexDirection: "column"
1040
+ }, children: [
1041
+ /* @__PURE__ */ jsxs(
1042
+ Box,
1043
+ {
1044
+ sx: {
1045
+ width: "100%",
1046
+ height: "auto",
1047
+ display: "flex",
1048
+ alignItems: "center",
1049
+ justifyContent: "space-between"
1050
+ },
1051
+ children: [
1052
+ /* @__PURE__ */ jsx(DragIndicator, { sx: {
1053
+ transform: "rotate(90deg)"
1054
+ } }),
1055
+ " ",
1056
+ /* @__PURE__ */ jsx(IconButton, { children: /* @__PURE__ */ jsx(Close, {}) })
1057
+ ]
1058
+ }
1059
+ ),
1060
+ /* @__PURE__ */ jsx(
1061
+ "iframe",
1062
+ {
1063
+ src: "https://h68.deepijatel.in/ConVoxCCS",
1064
+ height: 300
1065
+ }
1066
+ )
1067
+ ] })
1068
+ }
1069
+ ) }),
977
1070
  /* @__PURE__ */ jsx(
978
1071
  Menu,
979
1072
  {
@@ -1116,10 +1209,15 @@ function CallControlPanel({ onDataChange }) {
1116
1209
  }
1117
1210
 
1118
1211
  // src/index.ts
1119
- function initSDK(sdkApiKey, tenantId, agentId, baseUrl) {
1120
- sdkStateManager.initialize(sdkApiKey);
1212
+ function initSDK({
1213
+ apiKey,
1214
+ tenantId,
1215
+ agentId,
1216
+ baseUrl
1217
+ }) {
1218
+ sdkStateManager.initialize(apiKey);
1121
1219
  eventTracker.init({
1122
- apiKey: sdkApiKey,
1220
+ apiKey,
1123
1221
  tenantId,
1124
1222
  agentId,
1125
1223
  baseUrl
package/package.json CHANGED
@@ -1,29 +1,43 @@
1
1
  {
2
2
  "name": "call-control-sdk",
3
- "description": "Call Control SDK",
4
- "version": "2.1.0",
3
+ "description": "Call Control SDK - draggable call controls",
4
+ "version": "2.3.0",
5
5
  "author": "Achala",
6
6
  "license": "MIT",
7
- "main": "dist/index.cjs",
8
- "module": "dist/index.js",
9
- "types": "dist/index.d.ts",
7
+ "main": "./dist/index.cjs",
8
+ "module": "./dist/index.js",
9
+ "types": "./dist/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "import": "./dist/index.js",
14
+ "require": "./dist/index.cjs"
15
+ }
16
+ },
10
17
  "files": [
11
18
  "dist"
12
19
  ],
13
20
  "scripts": {
14
- "dev": "vite",
15
- "start": "vite",
16
- "build": "tsup src/index.ts --format esm,cjs --dts --clean",
21
+ "build": "tsup src/index.ts --format esm,cjs --dts --clean --tsconfig tsconfig.build.json",
17
22
  "lint": "eslint .",
18
23
  "format": "prettier --write .",
19
24
  "prepublishOnly": "npm run build"
20
25
  },
21
26
  "peerDependencies": {
22
- "@emotion/react": "^11.14.0",
23
- "@emotion/styled": "^11.14.1",
24
- "@mui/icons-material": "^7.3.1",
25
- "@mui/material": "^7.3.1",
26
- "react": "^19.1.1",
27
- "react-dom": "^19.1.1"
27
+ "@emotion/react": ">=11.0.0",
28
+ "@emotion/styled": ">=11.0.0",
29
+ "@mui/icons-material": ">=5.0.0",
30
+ "@mui/material": ">=5.0.0",
31
+ "react": ">=17.0.0",
32
+ "react-dom": ">=17.0.0"
33
+ },
34
+ "devDependencies": {
35
+ "typescript": "^5.0.0",
36
+ "tsup": "^8.5.0",
37
+ "vite": "^5.0.0",
38
+ "@types/react": "^18.0.0",
39
+ "@types/react-dom": "^18.0.0",
40
+ "eslint": "^8.0.0",
41
+ "prettier": "^3.0.0"
28
42
  }
29
43
  }