@dora-cell/sdk-react 0.1.1-beta.9 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -4,7 +4,7 @@ var react = require('react');
4
4
  var sdk = require('@dora-cell/sdk');
5
5
  var jsxRuntime = require('react/jsx-runtime');
6
6
 
7
- // ../../node_modules/.pnpm/lucide-react@0.555.0_react@19.2.4/node_modules/lucide-react/dist/esm/shared/src/utils.js
7
+ // ../../node_modules/.pnpm/lucide-react@0.555.0_react@19.2.3/node_modules/lucide-react/dist/esm/shared/src/utils.js
8
8
  var toKebabCase = (string) => string.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
9
9
  var toCamelCase = (string) => string.replace(
10
10
  /^([A-Z])|[\s-_]+(\w)/g,
@@ -25,7 +25,7 @@ var hasA11yProp = (props) => {
25
25
  }
26
26
  };
27
27
 
28
- // ../../node_modules/.pnpm/lucide-react@0.555.0_react@19.2.4/node_modules/lucide-react/dist/esm/defaultAttributes.js
28
+ // ../../node_modules/.pnpm/lucide-react@0.555.0_react@19.2.3/node_modules/lucide-react/dist/esm/defaultAttributes.js
29
29
  var defaultAttributes = {
30
30
  xmlns: "http://www.w3.org/2000/svg",
31
31
  width: 24,
@@ -38,7 +38,7 @@ var defaultAttributes = {
38
38
  strokeLinejoin: "round"
39
39
  };
40
40
 
41
- // ../../node_modules/.pnpm/lucide-react@0.555.0_react@19.2.4/node_modules/lucide-react/dist/esm/Icon.js
41
+ // ../../node_modules/.pnpm/lucide-react@0.555.0_react@19.2.3/node_modules/lucide-react/dist/esm/Icon.js
42
42
  var Icon = react.forwardRef(
43
43
  ({
44
44
  color = "currentColor",
@@ -69,7 +69,7 @@ var Icon = react.forwardRef(
69
69
  )
70
70
  );
71
71
 
72
- // ../../node_modules/.pnpm/lucide-react@0.555.0_react@19.2.4/node_modules/lucide-react/dist/esm/createLucideIcon.js
72
+ // ../../node_modules/.pnpm/lucide-react@0.555.0_react@19.2.3/node_modules/lucide-react/dist/esm/createLucideIcon.js
73
73
  var createLucideIcon = (iconName, iconNode) => {
74
74
  const Component = react.forwardRef(
75
75
  ({ className, ...props }, ref) => react.createElement(Icon, {
@@ -87,22 +87,26 @@ var createLucideIcon = (iconName, iconNode) => {
87
87
  return Component;
88
88
  };
89
89
 
90
- // ../../node_modules/.pnpm/lucide-react@0.555.0_react@19.2.4/node_modules/lucide-react/dist/esm/icons/arrow-down-left.js
90
+ // ../../node_modules/.pnpm/lucide-react@0.555.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/arrow-down-left.js
91
91
  var __iconNode = [
92
92
  ["path", { d: "M17 7 7 17", key: "15tmo1" }],
93
93
  ["path", { d: "M17 17H7V7", key: "1org7z" }]
94
94
  ];
95
95
  var ArrowDownLeft = createLucideIcon("arrow-down-left", __iconNode);
96
96
 
97
- // ../../node_modules/.pnpm/lucide-react@0.555.0_react@19.2.4/node_modules/lucide-react/dist/esm/icons/arrow-up-right.js
97
+ // ../../node_modules/.pnpm/lucide-react@0.555.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/arrow-up-right.js
98
98
  var __iconNode2 = [
99
99
  ["path", { d: "M7 7h10v10", key: "1tivn9" }],
100
100
  ["path", { d: "M7 17 17 7", key: "1vkiza" }]
101
101
  ];
102
102
  var ArrowUpRight = createLucideIcon("arrow-up-right", __iconNode2);
103
103
 
104
- // ../../node_modules/.pnpm/lucide-react@0.555.0_react@19.2.4/node_modules/lucide-react/dist/esm/icons/delete.js
105
- var __iconNode3 = [
104
+ // ../../node_modules/.pnpm/lucide-react@0.555.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/chevron-down.js
105
+ var __iconNode3 = [["path", { d: "m6 9 6 6 6-6", key: "qrunsl" }]];
106
+ var ChevronDown = createLucideIcon("chevron-down", __iconNode3);
107
+
108
+ // ../../node_modules/.pnpm/lucide-react@0.555.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/delete.js
109
+ var __iconNode4 = [
106
110
  [
107
111
  "path",
108
112
  {
@@ -113,19 +117,19 @@ var __iconNode3 = [
113
117
  ["path", { d: "m12 9 6 6", key: "anjzzh" }],
114
118
  ["path", { d: "m18 9-6 6", key: "1fp51s" }]
115
119
  ];
116
- var Delete = createLucideIcon("delete", __iconNode3);
120
+ var Delete = createLucideIcon("delete", __iconNode4);
117
121
 
118
- // ../../node_modules/.pnpm/lucide-react@0.555.0_react@19.2.4/node_modules/lucide-react/dist/esm/icons/maximize.js
119
- var __iconNode4 = [
122
+ // ../../node_modules/.pnpm/lucide-react@0.555.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/maximize.js
123
+ var __iconNode5 = [
120
124
  ["path", { d: "M8 3H5a2 2 0 0 0-2 2v3", key: "1dcmit" }],
121
125
  ["path", { d: "M21 8V5a2 2 0 0 0-2-2h-3", key: "1e4gt3" }],
122
126
  ["path", { d: "M3 16v3a2 2 0 0 0 2 2h3", key: "wsl5sc" }],
123
127
  ["path", { d: "M16 21h3a2 2 0 0 0 2-2v-3", key: "18trek" }]
124
128
  ];
125
- var Maximize = createLucideIcon("maximize", __iconNode4);
129
+ var Maximize = createLucideIcon("maximize", __iconNode5);
126
130
 
127
- // ../../node_modules/.pnpm/lucide-react@0.555.0_react@19.2.4/node_modules/lucide-react/dist/esm/icons/mic-off.js
128
- var __iconNode5 = [
131
+ // ../../node_modules/.pnpm/lucide-react@0.555.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/mic-off.js
132
+ var __iconNode6 = [
129
133
  ["path", { d: "M12 19v3", key: "npa21l" }],
130
134
  ["path", { d: "M15 9.34V5a3 3 0 0 0-5.68-1.33", key: "1gzdoj" }],
131
135
  ["path", { d: "M16.95 16.95A7 7 0 0 1 5 12v-2", key: "cqa7eg" }],
@@ -133,27 +137,27 @@ var __iconNode5 = [
133
137
  ["path", { d: "m2 2 20 20", key: "1ooewy" }],
134
138
  ["path", { d: "M9 9v3a3 3 0 0 0 5.12 2.12", key: "r2i35w" }]
135
139
  ];
136
- var MicOff = createLucideIcon("mic-off", __iconNode5);
140
+ var MicOff = createLucideIcon("mic-off", __iconNode6);
137
141
 
138
- // ../../node_modules/.pnpm/lucide-react@0.555.0_react@19.2.4/node_modules/lucide-react/dist/esm/icons/mic.js
139
- var __iconNode6 = [
142
+ // ../../node_modules/.pnpm/lucide-react@0.555.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/mic.js
143
+ var __iconNode7 = [
140
144
  ["path", { d: "M12 19v3", key: "npa21l" }],
141
145
  ["path", { d: "M19 10v2a7 7 0 0 1-14 0v-2", key: "1vc78b" }],
142
146
  ["rect", { x: "9", y: "2", width: "6", height: "13", rx: "3", key: "s6n7sd" }]
143
147
  ];
144
- var Mic = createLucideIcon("mic", __iconNode6);
148
+ var Mic = createLucideIcon("mic", __iconNode7);
145
149
 
146
- // ../../node_modules/.pnpm/lucide-react@0.555.0_react@19.2.4/node_modules/lucide-react/dist/esm/icons/minimize-2.js
147
- var __iconNode7 = [
150
+ // ../../node_modules/.pnpm/lucide-react@0.555.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/minimize-2.js
151
+ var __iconNode8 = [
148
152
  ["path", { d: "m14 10 7-7", key: "oa77jy" }],
149
153
  ["path", { d: "M20 10h-6V4", key: "mjg0md" }],
150
154
  ["path", { d: "m3 21 7-7", key: "tjx5ai" }],
151
155
  ["path", { d: "M4 14h6v6", key: "rmj7iw" }]
152
156
  ];
153
- var Minimize2 = createLucideIcon("minimize-2", __iconNode7);
157
+ var Minimize2 = createLucideIcon("minimize-2", __iconNode8);
154
158
 
155
- // ../../node_modules/.pnpm/lucide-react@0.555.0_react@19.2.4/node_modules/lucide-react/dist/esm/icons/phone.js
156
- var __iconNode8 = [
159
+ // ../../node_modules/.pnpm/lucide-react@0.555.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/phone.js
160
+ var __iconNode9 = [
157
161
  [
158
162
  "path",
159
163
  {
@@ -162,21 +166,21 @@ var __iconNode8 = [
162
166
  }
163
167
  ]
164
168
  ];
165
- var Phone = createLucideIcon("phone", __iconNode8);
169
+ var Phone = createLucideIcon("phone", __iconNode9);
166
170
 
167
- // ../../node_modules/.pnpm/lucide-react@0.555.0_react@19.2.4/node_modules/lucide-react/dist/esm/icons/user.js
168
- var __iconNode9 = [
171
+ // ../../node_modules/.pnpm/lucide-react@0.555.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/user.js
172
+ var __iconNode10 = [
169
173
  ["path", { d: "M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2", key: "975kel" }],
170
174
  ["circle", { cx: "12", cy: "7", r: "4", key: "17ys0d" }]
171
175
  ];
172
- var User = createLucideIcon("user", __iconNode9);
176
+ var User = createLucideIcon("user", __iconNode10);
173
177
 
174
- // ../../node_modules/.pnpm/lucide-react@0.555.0_react@19.2.4/node_modules/lucide-react/dist/esm/icons/x.js
175
- var __iconNode10 = [
178
+ // ../../node_modules/.pnpm/lucide-react@0.555.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/x.js
179
+ var __iconNode11 = [
176
180
  ["path", { d: "M18 6 6 18", key: "1bl5f8" }],
177
181
  ["path", { d: "m6 6 12 12", key: "d8bk6v" }]
178
182
  ];
179
- var X = createLucideIcon("x", __iconNode10);
183
+ var X = createLucideIcon("x", __iconNode11);
180
184
  function CallInterface({
181
185
  isOpen = false,
182
186
  onOpenChange,
@@ -191,10 +195,10 @@ function CallInterface({
191
195
  isMuted,
192
196
  hangup,
193
197
  answerCall,
194
- toggleMute
198
+ toggleMute,
199
+ callError
195
200
  } = useCall();
196
201
  const [isMinimized, setIsMinimized] = react.useState(false);
197
- const [localMuted, setLocalMuted] = react.useState(false);
198
202
  const [wasConnected, setWasConnected] = react.useState(false);
199
203
  const [closeCountdown, setCloseCountdown] = react.useState(null);
200
204
  const [connectingCountdown, setConnectingCountdown] = react.useState(null);
@@ -204,15 +208,18 @@ function CallInterface({
204
208
  const remoteNumber = currentCall?.remoteNumber || "Unknown";
205
209
  const displayName = remoteNumber;
206
210
  react.useEffect(() => {
207
- if (!audioRef.current) return;
208
- }, [currentCall]);
211
+ if (currentCall && audioRef.current) {
212
+ const stream = currentCall.getRemoteStream();
213
+ if (stream && audioRef.current.srcObject !== stream) {
214
+ audioRef.current.srcObject = stream;
215
+ }
216
+ }
217
+ }, [currentCall, callStatus]);
209
218
  react.useEffect(() => {
210
219
  if (callStatus === "ringing" && isIncoming) {
211
220
  onOpenChange?.(true);
212
- if (ringtoneRef.current) {
213
- ringtoneRef.current.play().catch(() => {
214
- });
215
- }
221
+ ringtoneRef.current?.play().catch(() => {
222
+ });
216
223
  } else {
217
224
  if (ringtoneRef.current) {
218
225
  ringtoneRef.current.pause();
@@ -221,6 +228,9 @@ function CallInterface({
221
228
  }
222
229
  }, [callStatus, isIncoming, onOpenChange]);
223
230
  react.useEffect(() => {
231
+ if (callStatus === "connecting" || callStatus === "ringing") {
232
+ setWasConnected(false);
233
+ }
224
234
  if (callStatus === "ongoing") {
225
235
  setWasConnected(true);
226
236
  }
@@ -228,33 +238,31 @@ function CallInterface({
228
238
  react.useEffect(() => {
229
239
  if (isOpen && callStatus === "ended") {
230
240
  onCallEnded?.();
231
- const closeDelay = wasConnected ? 1e3 : 5e3;
232
- const countdownStart = Date.now();
233
- const countdownInterval = setInterval(() => {
234
- const elapsed = Date.now() - countdownStart;
235
- const remaining = Math.max(0, closeDelay - elapsed);
236
- const seconds = Math.ceil(remaining / 1e3);
237
- setCloseCountdown(seconds);
241
+ const closeDelay = wasConnected ? 1500 : 3e3;
242
+ const start = Date.now();
243
+ const iv = setInterval(() => {
244
+ const remaining = Math.max(0, closeDelay - (Date.now() - start));
245
+ setCloseCountdown(Math.ceil(remaining / 1e3));
238
246
  if (remaining <= 0) {
239
- clearInterval(countdownInterval);
247
+ clearInterval(iv);
240
248
  onOpenChange?.(false);
249
+ setIsMinimized(false);
241
250
  }
242
251
  }, 100);
243
- return () => clearInterval(countdownInterval);
252
+ return () => clearInterval(iv);
244
253
  } else {
245
254
  setCloseCountdown(null);
246
255
  }
247
256
  }, [callStatus, isOpen, onOpenChange, wasConnected, onCallEnded]);
248
257
  react.useEffect(() => {
249
- let interval;
250
- const isConnecting = callStatus === "connecting";
251
- if (isOpen && isConnecting && !isIncoming) {
258
+ let iv;
259
+ if (isOpen && callStatus === "connecting" && !isIncoming) {
252
260
  setConnectingCountdown(60);
253
- interval = setInterval(() => {
261
+ iv = setInterval(() => {
254
262
  setConnectingCountdown((prev) => {
255
263
  if (prev === null || prev <= 0) {
256
- clearInterval(interval);
257
- hangup();
264
+ clearInterval(iv);
265
+ if (callStatus === "connecting") hangup();
258
266
  return 0;
259
267
  }
260
268
  return prev - 1;
@@ -263,7 +271,7 @@ function CallInterface({
263
271
  } else {
264
272
  setConnectingCountdown(null);
265
273
  }
266
- return () => clearInterval(interval);
274
+ return () => clearInterval(iv);
267
275
  }, [callStatus, isOpen, isIncoming, hangup]);
268
276
  if (!isOpen && callStatus === "idle") return null;
269
277
  return /* @__PURE__ */ jsxRuntime.jsxs(
@@ -271,9 +279,9 @@ function CallInterface({
271
279
  {
272
280
  role: "dialog",
273
281
  "aria-label": "Call interface",
274
- className: `fixed top-14 md:top-16 right-0 md:right-4 z-50 transform transition-all duration-300 ease-in-out bg-[#1E1E1E] shadow-xl ${isOpen ? "translate-x-0" : "translate-x-[110%]"} ${isMinimized ? "w-48 h-20 rounded-2xl p-4 flex items-center justify-between" : "w-full sm:w-96 md:max-w-sm max-h-[calc(100vh-3.5rem)] md:max-h-[calc(100vh-4rem)] rounded-none md:rounded-2xl"}`,
282
+ className: `dora-fixed dora-top-14 md:dora-top-16 dora-right-0 md:dora-right-4 dora-z-50 dora-transform dora-transition-all dora-duration-300 dora-ease-in-out dora-bg-[#1E1E1E] dora-shadow-xl ${isOpen ? "dora-translate-x-0" : "dora-translate-x-[110%]"} ${isMinimized ? "dora-w-48 dora-h-20 dora-rounded-2xl dora-p-4 dora-flex dora-items-center dora-justify-between" : "dora-w-full sm:dora-w-96 md:dora-max-w-sm max-h-[calc(100vh-3.5rem)] md:dora-max-h-[calc(100vh-4rem)] dora-rounded-none md:dora-rounded-2xl"}`,
275
283
  children: [
276
- /* @__PURE__ */ jsxRuntime.jsx("audio", { ref: audioRef, autoPlay: true, className: "hidden" }),
284
+ /* @__PURE__ */ jsxRuntime.jsx("audio", { ref: audioRef, autoPlay: true, className: "dora-hidden" }),
277
285
  /* @__PURE__ */ jsxRuntime.jsx(
278
286
  "audio",
279
287
  {
@@ -281,75 +289,73 @@ function CallInterface({
281
289
  src: "https://assets.mixkit.co/active_storage/sfx/2358/2358-preview.mp3",
282
290
  loop: true,
283
291
  preload: "auto",
284
- className: "hidden"
292
+ className: "dora-hidden"
285
293
  }
286
294
  ),
287
- isMinimized ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between w-full h-full", children: [
295
+ isMinimized ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "dora-flex dora-items-center dora-justify-between dora-w-full dora-h-full", children: [
288
296
  /* @__PURE__ */ jsxRuntime.jsx(
289
297
  "button",
290
298
  {
291
299
  onClick: () => setIsMinimized(false),
292
- className: "w-10 h-10 rounded-full bg-[#2A2A2A] flex items-center justify-center text-slate-400 hover:text-white transition-colors",
293
- "aria-label": "Maximize call interface",
300
+ className: "dora-w-10 dora-h-10 dora-rounded-full dora-bg-[#2A2A2A] dora-flex dora-items-center dora-justify-center dora-text-slate-400 hover:dora-text-white dora-transition-colors",
301
+ "aria-label": "Maximize",
294
302
  children: maximizeIcon || /* @__PURE__ */ jsxRuntime.jsx(Maximize, { size: 18 })
295
303
  }
296
304
  ),
297
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex items-center", children: [
298
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-11 h-11 rounded-full bg-white flex items-center justify-center -mr-3", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xl text-slate-900 font-bold", children: displayName.charAt(0).toUpperCase() }) }),
305
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "dora-relative dora-flex dora-items-center", children: [
306
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "dora-w-11 dora-h-11 dora-rounded-full dora-bg-white dora-flex dora-items-center dora-justify-center dora--mr-3", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "dora-text-xl dora-text-slate-900 dora-font-bold", children: displayName.charAt(0).toUpperCase() }) }),
299
307
  /* @__PURE__ */ jsxRuntime.jsx(
300
308
  "button",
301
309
  {
302
310
  onClick: hangup,
303
- className: "w-11 h-11 rounded-full bg-red-500 text-white flex items-center justify-center shadow-lg hover:bg-red-600 transition-colors z-10",
311
+ className: "dora-w-11 dora-h-11 dora-rounded-full dora-bg-red-500 dora-text-white dora-flex dora-items-center dora-justify-center dora-shadow-lg hover:dora-bg-red-600 dora-transition-colors dora-z-10",
304
312
  "aria-label": "End call",
305
- children: /* @__PURE__ */ jsxRuntime.jsx(Phone, { size: 18, className: "transform rotate-135" })
313
+ children: /* @__PURE__ */ jsxRuntime.jsx(Phone, { size: 18, className: "dora-transform dora-rotate-[135deg]" })
306
314
  }
307
315
  )
308
316
  ] })
309
- ] }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col py-4 md:py-6 gap-2.5 md:gap-3.5 px-3 md:px-5 relative", children: [
317
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "dora-flex dora-flex-col dora-py-4 md:dora-py-6 dora-gap-2.5 md:dora-gap-3.5 dora-px-3 md:dora-px-5 dora-relative", children: [
310
318
  /* @__PURE__ */ jsxRuntime.jsx(
311
319
  "button",
312
320
  {
313
321
  onClick: () => setIsMinimized(true),
314
- className: "absolute top-2 right-2 text-slate-500 hover:text-white transition-colors",
322
+ className: "dora-absolute dora-top-2 dora-right-2 dora-text-slate-500 hover:dora-text-white dora-transition-colors",
315
323
  "aria-label": "Minimize",
316
324
  children: minimizeIcon || /* @__PURE__ */ jsxRuntime.jsx(Minimize2, { size: 16 })
317
325
  }
318
326
  ),
319
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between gap-2 items-start md:items-center", children: [
320
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2.5 md:gap-4 min-w-0", children: [
321
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-9 md:w-11 h-9 md:h-11 rounded-full bg-white flex items-center justify-center shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-lg md:text-2xl text-slate-900 font-bold", children: displayName.charAt(0).toUpperCase() }) }),
322
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [
323
- /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-base md:text-xl font-normal text-white truncate", children: isIncoming ? displayName : displayName === "Unknown" ? "Outgoing Call" : displayName }),
324
- /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-slate-400 text-xs md:text-sm truncate", children: [
327
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "dora-flex dora-justify-between dora-gap-2 dora-items-start md:dora-items-center", children: [
328
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "dora-flex dora-items-center dora-gap-2.5 md:dora-gap-4 dora-min-w-0", children: [
329
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "dora-w-9 md:dora-w-11 dora-h-9 md:dora-h-11 dora-rounded-full dora-bg-white dora-flex dora-items-center dora-justify-center dora-shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "dora-text-lg md:dora-text-2xl dora-text-slate-900 dora-font-bold", children: displayName.charAt(0).toUpperCase() }) }),
330
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "dora-min-w-0 dora-flex-1", children: [
331
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "dora-text-base md:dora-text-xl dora-font-normal dora-text-white dora-truncate", children: isIncoming ? displayName : displayName === "Unknown" ? "Outgoing Call" : displayName }),
332
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "dora-text-slate-400 dora-text-xs md:dora-text-sm dora-truncate", children: [
325
333
  remoteNumber,
326
334
  " \u2022",
327
335
  " ",
328
- isMuted ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-[#F99578]", children: "Call mute" }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
336
+ isMuted ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "dora-text-[#F99578]", children: "Call muted" }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
329
337
  (callStatus === "connecting" || callStatus === "ringing") && /* @__PURE__ */ jsxRuntime.jsx("span", { children: isIncoming ? "Incoming Call..." : callStatus === "connecting" ? "Connecting..." : "Ringing..." }),
330
- callStatus === "ongoing" && /* @__PURE__ */ jsxRuntime.jsx("span", { children: "On Call" })
338
+ callStatus === "ongoing" && /* @__PURE__ */ jsxRuntime.jsx("span", { children: "On Call" }),
339
+ callStatus === "ended" && /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Call Ended" })
331
340
  ] })
332
341
  ] })
333
342
  ] })
334
343
  ] }),
335
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center gap-1.5 md:gap-3 shrink-0", children: [
344
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "dora-flex dora-items-center dora-justify-center dora-gap-1.5 md:dora-gap-3 dora-shrink-0", children: [
336
345
  isIncoming && callStatus === "ringing" && /* @__PURE__ */ jsxRuntime.jsx(
337
346
  "button",
338
347
  {
339
348
  onClick: answerCall,
340
- className: "rounded-full bg-green-500 text-white hover:bg-green-600 transition-colors w-8 md:w-9 h-8 md:h-9 flex items-center justify-center shrink-0",
341
- "aria-label": "Answer call",
349
+ className: "dora-rounded-full dora-bg-green-500 dora-text-white hover:dora-bg-green-600 dora-transition-colors dora-w-8 md:dora-w-9 dora-h-8 md:dora-h-9 dora-flex dora-items-center dora-justify-center dora-shrink-0",
350
+ "aria-label": "Answer",
342
351
  children: /* @__PURE__ */ jsxRuntime.jsx(Phone, { size: 18 })
343
352
  }
344
353
  ),
345
354
  (callStatus === "ongoing" || isIncoming && callStatus === "ringing") && /* @__PURE__ */ jsxRuntime.jsx(
346
355
  "button",
347
356
  {
348
- onClick: () => {
349
- toggleMute();
350
- setLocalMuted((s) => !s);
351
- },
352
- className: `rounded-full transition-colors w-8 md:w-9 h-8 md:h-9 flex items-center justify-center shrink-0 bg-slate-700 hover:bg-slate-600 ${isMuted ? "text-white " : " text-slate-400 "}`,
357
+ onClick: toggleMute,
358
+ className: `dora-rounded-full dora-transition-colors dora-w-8 md:dora-w-9 dora-h-8 md:dora-h-9 dora-flex dora-items-center dora-justify-center dora-shrink-0 ${isMuted ? "dora-bg-slate-700 hover:dora-bg-slate-600 dora-text-white" : "dora-bg-[#2A2A2A] hover:dora-bg-[#333333] dora-text-slate-400"}`,
353
359
  "aria-label": "Toggle mute",
354
360
  children: isMuted ? /* @__PURE__ */ jsxRuntime.jsx(MicOff, { size: 18 }) : /* @__PURE__ */ jsxRuntime.jsx(Mic, { size: 18 })
355
361
  }
@@ -358,31 +364,53 @@ function CallInterface({
358
364
  "button",
359
365
  {
360
366
  onClick: hangup,
361
- className: "rounded-full bg-red-600 text-white hover:bg-red-700 transition-colors w-8 md:w-9 h-8 md:h-9 flex items-center justify-center shrink-0",
362
- "aria-label": isIncoming && callStatus === "ringing" ? "Decline call" : "End call",
363
- children: /* @__PURE__ */ jsxRuntime.jsx(Phone, { size: 18, className: "transform rotate-135" })
367
+ className: "dora-rounded-full dora-bg-red-600 dora-text-white hover:dora-bg-red-700 dora-transition-colors dora-w-8 md:dora-w-9 dora-h-8 md:dora-h-9 dora-flex dora-items-center dora-justify-center dora-shrink-0",
368
+ "aria-label": isIncoming && callStatus === "ringing" ? "Decline" : "End call",
369
+ children: /* @__PURE__ */ jsxRuntime.jsx(Phone, { size: 18, className: "dora-transform dora-rotate-[135deg]" })
364
370
  }
365
371
  )
366
372
  ] })
367
373
  ] }),
368
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 border border-[#282828]" }),
369
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between items-center", children: [
370
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-slate-400 text-xs md:text-sm font-light tracking-wide flex items-center gap-1", children: [
371
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
372
- (callStatus === "connecting" || callStatus === "ringing") && /* @__PURE__ */ jsxRuntime.jsx("span", { children: isIncoming ? "Incoming call" : "Outgoing call" }),
373
- callStatus === "ongoing" && /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Ongoing" }),
374
- callStatus === "ended" && /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Call ended" })
375
- ] }),
376
- (callStatus === "connecting" || callStatus === "ringing" || callStatus === "ongoing") && (isIncoming ? /* @__PURE__ */ jsxRuntime.jsx(ArrowDownLeft, { className: "inline-block ml-1 text-green-400", size: 16 }) : /* @__PURE__ */ jsxRuntime.jsx(ArrowUpRight, { className: "inline-block ml-1 text-blue-400", size: 16 }))
374
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "dora-flex-1 dora-border-t dora-border-[#282828] dora-mt-2 dora-mb-2" }),
375
+ callError && callStatus === "ended" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "dora-bg-red-900/20 dora-border dora-border-red-500/30 dora-rounded-lg dora-p-2 md:dora-p-3 dora-mb-2 md:dora-mb-3", children: [
376
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "dora-text-red-400 dora-text-xs md:dora-text-sm dora-font-medium", children: "Call Failed" }),
377
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "dora-text-red-300 dora-text-xs dora-mt-0.5 md:dora-mt-1", children: callError }),
378
+ closeCountdown !== null && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "dora-mt-1.5 md:dora-mt-2", children: [
379
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "dora-w-full dora-bg-red-900/30 dora-rounded-full dora-h-1.5 dora-overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
380
+ "div",
381
+ {
382
+ className: "dora-bg-red-500 dora-h-full dora-transition-all dora-duration-100",
383
+ style: {
384
+ width: `${Math.max(
385
+ 0,
386
+ closeCountdown / (wasConnected ? 1 : 5) * 100
387
+ )}%`
388
+ }
389
+ }
390
+ ) }),
391
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "dora-text-xs dora-text-red-300 dora-mt-0.5 md:dora-mt-1 dora-text-center", children: [
392
+ "Closing in ",
393
+ closeCountdown,
394
+ "s"
395
+ ] })
396
+ ] })
397
+ ] }),
398
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "dora-flex dora-justify-between dora-items-center", children: [
399
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "dora-text-slate-400 dora-text-xs md:dora-text-sm dora-font-light dora-tracking-wide dora-flex dora-items-center dora-gap-1", children: [
400
+ (callStatus === "connecting" || callStatus === "ringing") && /* @__PURE__ */ jsxRuntime.jsx("span", { children: isIncoming ? "Incoming call" : "Outgoing call" }),
401
+ callStatus === "ongoing" && /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Ongoing" }),
402
+ callStatus === "ended" && /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Call ended" }),
403
+ (callStatus === "connecting" || callStatus === "ringing" || callStatus === "ongoing") && (isIncoming ? /* @__PURE__ */ jsxRuntime.jsx(ArrowDownLeft, { className: "dora-inline-block dora-ml-1 dora-text-green-400", size: 16 }) : /* @__PURE__ */ jsxRuntime.jsx(ArrowUpRight, { className: "dora-inline-block dora-ml-1 dora-text-blue-400", size: 16 }))
377
404
  ] }),
378
- callStatus === "ongoing" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-[#272727] h-6 md:h-7.5 rounded-full px-3 md:px-4.5 text-white font-normal text-xs md:text-sm flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
379
- " ",
380
- callDuration,
381
- " "
405
+ callStatus === "ongoing" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "dora-bg-[#272727] dora-h-6 md:dora-h-7 dora-rounded-full dora-px-3 md:dora-px-4 dora-text-white dora-font-normal dora-text-xs md:dora-text-sm dora-flex dora-items-center dora-justify-center", children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: callDuration }) }),
406
+ callStatus === "ended" && closeCountdown !== null && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "dora-bg-[#272727] dora-h-6 md:dora-h-7 dora-rounded-full dora-px-3 md:dora-px-4 dora-text-slate-400 dora-font-normal dora-text-xs dora-flex dora-items-center dora-justify-center dora-gap-1", children: /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
407
+ "Closing in ",
408
+ closeCountdown,
409
+ "s"
382
410
  ] }) }),
383
- (connectingCountdown !== null || callStatus === "ringing") && !isIncoming && callStatus !== "ongoing" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-[#272727] h-8 rounded-full px-3 md:px-4 text-white font-normal text-xs md:text-sm flex items-center justify-center gap-2", children: [
384
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[#F99578] whitespace-nowrap", children: callStatus === "ringing" ? "Ringing..." : "Call connecting..." }),
385
- callStatus === "connecting" && connectingCountdown && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-mono ml-1", children: [
411
+ (connectingCountdown !== null || callStatus === "ringing") && !isIncoming && callStatus !== "ongoing" && callStatus !== "ended" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "dora-bg-[#272727] dora-h-8 dora-rounded-full dora-px-3 md:dora-px-4 dora-text-white dora-font-normal dora-text-xs md:dora-text-sm dora-flex dora-items-center dora-justify-center dora-gap-2", children: [
412
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "dora-text-[#F99578] dora-whitespace-nowrap", children: callStatus === "ringing" ? "Ringing..." : "Connecting..." }),
413
+ callStatus === "connecting" && connectingCountdown && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "dora-font-mono dora-ml-1 dora-text-slate-400", children: [
386
414
  Math.floor(connectingCountdown / 60),
387
415
  ":",
388
416
  String(connectingCountdown % 60).padStart(2, "0")
@@ -399,42 +427,94 @@ function Dialpad({
399
427
  initialNumber = "",
400
428
  showKeys = true,
401
429
  className = "",
402
- availableExtensions = [],
403
- selectedExtension,
430
+ availableExtensions: providedExtensions,
431
+ selectedExtension: providedSelectedExtension,
404
432
  onExtensionChange
405
433
  }) {
406
434
  const { call, callStatus } = useCall();
435
+ const { isConnected } = useConnectionStatus();
436
+ const { extensions: fetchedExtensions, setExtension } = useExtensions();
407
437
  const [number, setNumber] = react.useState(initialNumber);
408
438
  const [keysVisible, setKeysVisible] = react.useState(showKeys);
439
+ const [localSelectedExt, setLocalSelectedExt] = react.useState("");
440
+ const extensions = providedExtensions?.length ? providedExtensions : fetchedExtensions.map((ext) => ({
441
+ label: ext.extension,
442
+ value: ext.extension
443
+ }));
444
+ const activeExtension = providedSelectedExtension || localSelectedExt || (extensions.length > 0 ? extensions[0].value : "");
445
+ react.useEffect(() => {
446
+ if (!localSelectedExt && extensions.length > 0 && !providedSelectedExtension) {
447
+ setLocalSelectedExt(extensions[0].value);
448
+ }
449
+ }, [extensions, providedSelectedExtension]);
409
450
  const append = (digit) => setNumber((s) => s + digit);
410
451
  const backspace = () => setNumber((s) => s.slice(0, -1));
452
+ const handleExtensionChange = async (ext) => {
453
+ setLocalSelectedExt(ext);
454
+ onExtensionChange?.(ext);
455
+ await setExtension(ext);
456
+ };
411
457
  const handleCall = async () => {
412
458
  if (!number || number.trim() === "") return;
413
459
  try {
414
- await call(number, selectedExtension);
460
+ await call(number, activeExtension);
415
461
  onCallInitiated?.(number);
416
462
  } catch (e) {
417
463
  console.error("Call failed", e);
418
464
  }
419
465
  };
420
- const isCallDisabled = !number || number.trim() === "" || callStatus === "ringing" || callStatus === "ongoing" || callStatus === "connecting";
421
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `space-y-4 ${className}`, children: [
422
- availableExtensions.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "gap-2 bg-[#F6F7F9] rounded-lg flex items-center justify-between p-2 md:p-2.5 mb-4", children: [
423
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs md:text-sm text-neutral-500 font-normal whitespace-nowrap", children: "Caller ID" }),
424
- /* @__PURE__ */ jsxRuntime.jsx(
425
- "select",
466
+ const isCallDisabled = !number || number.trim() === "" || !isConnected || callStatus === "ringing" || callStatus === "ongoing" || callStatus === "connecting";
467
+ const keypad_icon = /* @__PURE__ */ jsxRuntime.jsx(
468
+ "svg",
469
+ {
470
+ width: "20",
471
+ height: "20",
472
+ viewBox: "0 0 20 20",
473
+ fill: "none",
474
+ xmlns: "http://www.w3.org/2000/svg",
475
+ children: /* @__PURE__ */ jsxRuntime.jsx(
476
+ "path",
426
477
  {
427
- className: "bg-transparent text-sm font-medium outline-none",
428
- value: selectedExtension,
429
- onChange: (e) => onExtensionChange?.(e.target.value),
430
- children: availableExtensions.map((ext) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: ext.value, children: ext.label }, ext.value))
478
+ d: "M11.5333 3.2006C11.5339 3.50413 11.4444 3.801 11.2759 4.05352C11.1075 4.30605 10.8679 4.50284 10.5874 4.61891C10.3069 4.73499 9.99832 4.76512 9.70071 4.70548C9.40309 4.64584 9.12991 4.49911 8.91583 4.28393C8.77351 4.14156 8.66063 3.97254 8.58363 3.78654C8.50662 3.60054 8.46701 3.4012 8.46705 3.19989C8.46709 2.99858 8.50678 2.79925 8.58385 2.61328C8.66093 2.4273 8.77387 2.25834 8.91625 2.11602C9.05862 1.9737 9.22764 1.86081 9.41364 1.78381C9.59964 1.70681 9.79898 1.6672 10.0003 1.66723C10.2016 1.66727 10.4009 1.70696 10.5869 1.78404C10.7729 1.86111 10.9418 1.97406 11.0842 2.11643C11.3717 2.40393 11.5342 2.7931 11.5342 3.19977M14.5333 4.73227C14.7376 4.73703 14.9408 4.7009 15.131 4.62601C15.3211 4.55111 15.4944 4.43896 15.6406 4.29614C15.7868 4.15333 15.9029 3.98273 15.9822 3.79438C16.0616 3.60602 16.1024 3.40372 16.1024 3.19935C16.1024 2.99498 16.0616 2.79267 15.9822 2.60432C15.9029 2.41597 15.7868 2.24537 15.6406 2.10255C15.4944 1.95974 15.3211 1.84759 15.131 1.77269C14.9408 1.6978 14.7376 1.66167 14.5333 1.66643C14.1267 1.66643 13.7367 1.82798 13.4491 2.11554C13.1615 2.40309 13 2.7931 13 3.19977C13 3.60643 13.1615 3.99644 13.4491 4.284C13.7367 4.57155 14.1267 4.73227 14.5333 4.73227ZM7 3.2006C7.00061 3.50413 6.91102 3.801 6.7426 4.05352C6.57419 4.30605 6.33454 4.50284 6.05408 4.61891C5.77362 4.73499 5.46499 4.76512 5.16737 4.70548C4.86976 4.64584 4.59657 4.49911 4.3825 4.28393C4.24018 4.14161 4.12728 3.97265 4.05026 3.7867C3.97324 3.60075 3.93359 3.40145 3.93359 3.20018C3.93359 2.99891 3.97324 2.79961 4.05026 2.61366C4.12728 2.42771 4.24018 2.25875 4.3825 2.11643C4.52482 1.97411 4.69378 1.86122 4.87973 1.78419C5.06568 1.70717 5.26498 1.66753 5.46625 1.66753C5.66752 1.66753 5.86682 1.70717 6.05277 1.78419C6.23872 1.86122 6.40768 1.97411 6.55 2.11643C6.8375 2.40393 6.99917 2.7931 6.99917 3.19977M11.5333 7.7306C11.5352 7.93448 11.4964 8.1367 11.4192 8.32539C11.342 8.51409 11.2279 8.68548 11.0836 8.82952C10.9392 8.97357 10.7677 9.08737 10.5788 9.16426C10.39 9.24114 10.1877 9.27958 9.98381 9.2773C9.77993 9.27503 9.57856 9.2321 9.39148 9.15102C9.2044 9.06994 9.03538 8.95234 8.89433 8.80511C8.75327 8.65789 8.64301 8.484 8.57 8.29362C8.497 8.10325 8.46272 7.90022 8.46917 7.69643C8.48185 7.29562 8.65113 6.91575 8.94068 6.63833C9.23024 6.3609 9.617 6.20802 10.018 6.21249C10.419 6.21697 10.8022 6.37843 11.0855 6.66224C11.3688 6.94606 11.5296 7.32961 11.5333 7.7306ZM14.5333 9.2631C14.7376 9.26786 14.9408 9.23174 15.131 9.15684C15.3211 9.08194 15.4944 8.96979 15.6406 8.82698C15.7868 8.68416 15.9029 8.51356 15.9822 8.32521C16.0616 8.13686 16.1024 7.93455 16.1024 7.73018C16.1024 7.52581 16.0616 7.32351 15.9822 7.13515C15.9029 6.9468 15.7868 6.7762 15.6406 6.63339C15.4944 6.49057 15.3211 6.37842 15.131 6.30352C14.9408 6.22863 14.7376 6.1925 14.5333 6.19727C14.1267 6.19727 13.7367 6.35881 13.4491 6.64637C13.1615 6.93392 13 7.32393 13 7.7306C13 8.13726 13.1615 8.52727 13.4491 8.81483C13.7367 9.10239 14.1267 9.26393 14.5333 9.26393M7 7.7306C7.00021 8.03395 6.91038 8.33054 6.7419 8.58281C6.57341 8.83507 6.33385 9.03165 6.05356 9.14766C5.77326 9.26367 5.46485 9.29389 5.16737 9.23448C4.86989 9.17506 4.59673 9.0287 4.3825 8.81393C4.20461 8.63559 4.07342 8.41615 4.00054 8.17503C3.92766 7.93391 3.91534 7.67854 3.96468 7.43152C4.01401 7.1845 4.12347 6.95345 4.28337 6.75882C4.44328 6.56419 4.64869 6.41197 4.88144 6.31564C5.11419 6.21931 5.36709 6.18184 5.61777 6.20654C5.86845 6.23124 6.10918 6.31735 6.31865 6.45725C6.52812 6.59716 6.69988 6.78654 6.81872 7.00864C6.93756 7.23073 6.99982 7.4787 7 7.7306ZM11.5333 12.2623C11.5348 12.4893 11.4857 12.7138 11.3897 12.9196C11.2937 13.1253 11.1532 13.3071 10.9783 13.4519C10.8034 13.5967 10.5985 13.7007 10.3784 13.7566C10.1583 13.8124 9.9286 13.8186 9.70583 13.7748C9.42088 13.7191 9.1576 13.5836 8.94662 13.3841C8.73564 13.1847 8.58563 12.9294 8.51403 12.648C8.44244 12.3666 8.4522 12.0707 8.5422 11.7947C8.63219 11.5186 8.79871 11.2738 9.02238 11.0887C9.24606 10.9036 9.51769 10.7857 9.8057 10.7489C10.0937 10.7122 10.3862 10.7579 10.6493 10.8808C10.9123 11.0038 11.135 11.1989 11.2915 11.4434C11.448 11.688 11.5319 11.9719 11.5333 12.2623ZM11.5333 16.8006C11.5337 17.0274 11.4836 17.2515 11.3868 17.4567C11.29 17.6618 11.1488 17.8429 10.9735 17.9868C10.7981 18.1308 10.593 18.2339 10.3729 18.2889C10.1528 18.3439 9.92326 18.3493 9.70083 18.3048C9.40375 18.2453 9.13093 18.0992 8.91681 17.8849C8.70269 17.6705 8.55688 17.3975 8.49777 17.1004C8.43866 16.8032 8.46891 16.4952 8.58469 16.2152C8.70048 15.9353 8.89661 15.6959 9.14833 15.5273C9.37915 15.3731 9.64749 15.2845 9.92473 15.2708C10.202 15.2572 10.4777 15.3191 10.7225 15.4499C10.9673 15.5807 11.1721 15.7755 11.3149 16.0135C11.4577 16.2515 11.5332 16.523 11.5333 16.8006ZM16.0667 12.2623C16.0681 12.4893 16.019 12.7138 15.923 12.9196C15.827 13.1253 15.6865 13.3071 15.5116 13.4519C15.3367 13.5967 15.1318 13.7007 14.9117 13.7566C14.6917 13.8124 14.4619 13.8186 14.2392 13.7748C14.0165 13.7312 13.8062 13.6388 13.6236 13.5041C13.4409 13.3695 13.2904 13.1959 13.183 12.9961C13.0755 12.7962 13.0137 12.575 13.0021 12.3484C12.9905 12.1218 13.0294 11.8954 13.1158 11.6856C13.2509 11.3581 13.4952 11.0875 13.8072 10.9197C14.1193 10.7519 14.4797 10.6974 14.8274 10.7653C15.1751 10.8333 15.4886 11.0195 15.7145 11.2924C15.9404 11.5653 16.0648 11.908 16.0667 12.2623ZM7 12.2623C7.00227 12.5661 6.91412 12.8638 6.74675 13.1174C6.57939 13.371 6.34039 13.5691 6.06013 13.6864C5.77987 13.8038 5.47104 13.8352 5.1729 13.7766C4.87476 13.718 4.60079 13.572 4.38583 13.3573C4.20705 13.1796 4.07483 12.9606 4.00086 12.7196C3.9269 12.4787 3.91347 12.2232 3.96176 11.9759C4.01006 11.7285 4.11859 11.4968 4.27776 11.3014C4.43692 11.106 4.64181 10.9528 4.87428 10.8554C5.10676 10.758 5.35966 10.7194 5.61059 10.7431C5.86153 10.7668 6.10276 10.8519 6.31294 10.991C6.52313 11.1301 6.69578 11.3189 6.81561 11.5406C6.93545 11.7624 6.99878 12.0102 7 12.2623Z",
479
+ fill: "#677289"
431
480
  }
432
481
  )
482
+ }
483
+ );
484
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `dora-space-y-4 ${className} dora-font-sans`, children: [
485
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "dora-flex dora-items-center dora-justify-between dora-mb-2", children: [
486
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "dora-flex dora-items-center dora-gap-2", children: [
487
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "dora-w-8 dora-h-8 dora-rounded-lg dora-bg-emerald-500 dora-flex dora-items-center dora-justify-center dora-shadow-sm", children: /* @__PURE__ */ jsxRuntime.jsx(Phone, { size: 16, className: "dora-text-white", fill: "white" }) }),
488
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "dora-text-sm dora-font-bold dora-text-zinc-900", children: "Dora Cell" })
489
+ ] }),
490
+ /* @__PURE__ */ jsxRuntime.jsx(CreditBalance, {})
433
491
  ] }),
434
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2 md:space-y-3 bg-[#F6F7F9] p-2 md:p-2.5 rounded-lg", children: [
435
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 md:gap-3", children: [
436
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0 flex items-center bg-white rounded-md px-3 h-10 border border-transparent focus-within:border-green-500 transition-colors", children: [
437
- /* @__PURE__ */ jsxRuntime.jsx(User, { className: "text-gray-400 mr-2", size: 18 }),
492
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "dora-h-px dora-bg-zinc-100 dora-w-full dora-mb-4" }),
493
+ extensions.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "dora-gap-2 dora-bg-[#F6F7F9] dora-rounded-xl dora-flex dora-items-center dora-justify-between dora-p-2.5 dora-mb-4 dora-border dora-border-zinc-100", children: [
494
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "dora-text-xs md:dora-text-sm dora-text-zinc-500 dora-font-medium dora-whitespace-nowrap", children: "Caller ID" }),
495
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "dora-relative dora-flex dora-items-center", children: [
496
+ /* @__PURE__ */ jsxRuntime.jsx(
497
+ "select",
498
+ {
499
+ className: "dora-appearance-none dora-bg-white dora-px-3 dora-py-1.5 dora-rounded-lg dora-border dora-border-zinc-200 dora-text-sm dora-font-medium dora-outline-none dora-pr-8 dora-cursor-pointer hover:dora-border-emerald-500 dora-transition-colors dora-shadow-sm",
500
+ value: activeExtension,
501
+ onChange: (e) => handleExtensionChange(e.target.value),
502
+ children: extensions.map((ext) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: ext.value, children: ext.label }, ext.value))
503
+ }
504
+ ),
505
+ /* @__PURE__ */ jsxRuntime.jsx(
506
+ ChevronDown,
507
+ {
508
+ size: 14,
509
+ className: "dora-absolute dora-right-2.5 dora-pointer-events-none dora-text-zinc-400"
510
+ }
511
+ )
512
+ ] })
513
+ ] }),
514
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "dora-space-y-3 dora-bg-[#F6F7F9] dora-p-3 dora-rounded-xl dora-border dora-border-zinc-100", children: [
515
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "dora-flex dora-items-center dora-gap-3", children: [
516
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "dora-flex-1 dora-min-w-0 dora-flex dora-items-center dora-bg-white dora-rounded-xl dora-px-4 dora-h-12 dora-border dora-border-zinc-200 focus-within:dora-border-emerald-500 focus-within:dora-ring-4 focus-within:dora-ring-emerald-500/10 dora-transition-all dora-shadow-sm", children: [
517
+ /* @__PURE__ */ jsxRuntime.jsx(User, { className: "dora-text-zinc-400 dora-mr-2", size: 18 }),
438
518
  /* @__PURE__ */ jsxRuntime.jsx(
439
519
  "input",
440
520
  {
@@ -442,53 +522,64 @@ function Dialpad({
442
522
  placeholder: "Enter number",
443
523
  value: number,
444
524
  onChange: (e) => setNumber(e.target.value),
445
- className: "bg-transparent border-none outline-none w-full text-base"
525
+ className: "dora-bg-transparent dora-border-none dora-outline-none dora-w-full dora-text-base dora-text-zinc-900 dora-placeholder-zinc-400 dora-font-medium"
446
526
  }
447
527
  )
448
528
  ] }),
449
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(
529
+ /* @__PURE__ */ jsxRuntime.jsx(
450
530
  "button",
451
531
  {
452
532
  disabled: isCallDisabled,
453
- className: "bg-green-500 text-white hover:bg-green-600 rounded-lg h-9 md:h-10 w-9 md:w-11 flex items-center justify-center disabled:opacity-50 disabled:cursor-not-allowed transition-colors",
454
533
  onClick: handleCall,
455
534
  title: "Place Call",
456
- children: /* @__PURE__ */ jsxRuntime.jsx(Phone, { size: 16, fill: "currentColor" })
535
+ className: "dora-bg-emerald-500 dora-text-white hover:dora-bg-emerald-600 dora-rounded-xl dora-h-12 dora-w-14 dora-flex dora-items-center dora-justify-center disabled:dora-opacity-50 disabled:dora-cursor-not-allowed dora-transition-all dora-shadow-lg dora-shadow-emerald-500/20 active:dora-scale-95",
536
+ children: /* @__PURE__ */ jsxRuntime.jsx(Phone, { size: 20, fill: "white", className: "dora-text-white" })
457
537
  }
458
- ) })
538
+ )
459
539
  ] }),
460
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: keysVisible ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pt-3", children: [
461
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-3 mb-3", children: /* @__PURE__ */ jsxRuntime.jsxs(
540
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: keysVisible ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "dora-pt-3", children: [
541
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "dora-flex dora-items-center dora-gap-3 dora-mb-3", children: /* @__PURE__ */ jsxRuntime.jsxs(
462
542
  "button",
463
543
  {
464
544
  onClick: () => setKeysVisible(false),
465
- className: "px-2 md:px-2.5 h-8 bg-white rounded-full shadow text-neutral-500 flex items-center gap-1.5 md:gap-2 text-xs md:text-sm font-normal hover:bg-gray-50 transition-colors",
545
+ className: "dora-px-2 md:dora-px-2.5 dora-h-8 dora-bg-white dora-rounded-full dora-shadow dora-text-neutral-500 dora-flex dora-items-center dora-gap-1.5 md:dora-gap-2 dora-text-xs md:dora-text-sm dora-font-normal hover:dora-bg-gray-50 dora-transition-colors",
466
546
  children: [
467
547
  /* @__PURE__ */ jsxRuntime.jsx(X, { color: "red", size: 16 }),
468
548
  " Close keypad"
469
549
  ]
470
550
  }
471
551
  ) }),
472
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-3 gap-2 md:gap-3", children: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "+", "0", "del"].map(
473
- (d) => /* @__PURE__ */ jsxRuntime.jsx(
474
- "button",
475
- {
476
- onClick: () => d === "del" ? backspace() : append(d),
477
- className: "h-10 md:h-12 bg-white rounded-xl shadow flex items-center justify-center text-base md:text-lg font-medium hover:bg-gray-50 active:bg-gray-100 transition-colors",
478
- "aria-label": d === "del" ? "Delete" : `Dial ${d}`,
479
- children: d === "del" ? /* @__PURE__ */ jsxRuntime.jsx(Delete, { size: 18 }) : d
480
- },
481
- d
482
- )
483
- ) })
484
- ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pt-2 md:pt-3", children: /* @__PURE__ */ jsxRuntime.jsxs(
552
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "dora-grid dora-grid-cols-3 dora-gap-2 md:dora-gap-3", children: [
553
+ "1",
554
+ "2",
555
+ "3",
556
+ "4",
557
+ "5",
558
+ "6",
559
+ "7",
560
+ "8",
561
+ "9",
562
+ "+",
563
+ "0",
564
+ "del"
565
+ ].map((d) => /* @__PURE__ */ jsxRuntime.jsx(
566
+ "button",
567
+ {
568
+ onClick: () => d === "del" ? backspace() : append(d),
569
+ className: "dora-h-10 md:dora-h-12 dora-bg-white dora-rounded-xl dora-shadow dora-flex dora-items-center dora-justify-center dora-text-base md:dora-text-lg dora-font-medium dora-text-slate-900 hover:dora-bg-gray-50 active:dora-bg-gray-100 dora-transition-colors",
570
+ "aria-label": d === "del" ? "Delete" : `Dial ${d}`,
571
+ children: d === "del" ? /* @__PURE__ */ jsxRuntime.jsx(Delete, { size: 18 }) : d
572
+ },
573
+ d
574
+ )) })
575
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "dora-pt-3", children: /* @__PURE__ */ jsxRuntime.jsxs(
485
576
  "button",
486
577
  {
487
578
  onClick: () => setKeysVisible(true),
488
- className: "rounded-full bg-[#EDEEF1] h-9 md:h-10 flex justify-center items-center px-3 md:px-4 w-full text-xs md:text-sm hover:bg-[#E3E4E8] transition-colors",
579
+ className: "dora-rounded-full dora-bg-white dora-border dora-border-zinc-200 dora-h-11 dora-flex dora-justify-center dora-items-center dora-px-5 dora-w-full dora-text-sm hover:dora-bg-zinc-50 dora-transition-all dora-shadow-sm active:dora-scale-[0.98]",
489
580
  children: [
490
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "mr-2", children: "\u{1F522}" }),
491
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs md:text-sm text-neutral-500 font-normal ml-1.5", children: "Open dialer" })
581
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "dora-mr-2", children: keypad_icon }),
582
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "dora-text-sm dora-text-zinc-600 dora-font-medium", children: "Open dialer keypad" })
492
583
  ]
493
584
  }
494
585
  ) }) })
@@ -509,6 +600,7 @@ function DoraCellProvider({
509
600
  const [callDuration, setCallDuration] = react.useState("00:00");
510
601
  const [isMuted, setIsMuted] = react.useState(false);
511
602
  const [error, setError] = react.useState(null);
603
+ const [extension, setExtension] = react.useState(null);
512
604
  const durationIntervalRef = react.useRef(null);
513
605
  react.useEffect(() => {
514
606
  if (!autoInitialize) return;
@@ -529,6 +621,9 @@ function DoraCellProvider({
529
621
  if (!sdk$1) return;
530
622
  const handleConnectionStatus = (state) => {
531
623
  setConnectionStatus(state.status);
624
+ if (state.extension) {
625
+ setExtension(state.extension);
626
+ }
532
627
  if (state.error) {
533
628
  setError(new Error(state.error));
534
629
  }
@@ -603,10 +698,10 @@ function DoraCellProvider({
603
698
  }
604
699
  };
605
700
  }, [callStatus, currentCall]);
606
- const call = async (phoneNumber, extension) => {
701
+ const call = async (phoneNumber, extension2) => {
607
702
  try {
608
703
  setError(null);
609
- await sdk$1.call(phoneNumber, { extension });
704
+ await sdk$1.call(phoneNumber, { extension: extension2 });
610
705
  } catch (err) {
611
706
  setError(err instanceof Error ? err : new Error("Failed to make call"));
612
707
  throw err;
@@ -648,7 +743,8 @@ function DoraCellProvider({
648
743
  call,
649
744
  hangup,
650
745
  toggleMute,
651
- answerCall
746
+ answerCall,
747
+ extension
652
748
  };
653
749
  return /* @__PURE__ */ jsxRuntime.jsx(DoraCellContext.Provider, { value: contextValue, children });
654
750
  }
@@ -660,7 +756,7 @@ function useDoraCell() {
660
756
  return context;
661
757
  }
662
758
  function useCall() {
663
- const { call, hangup, toggleMute, answerCall, callStatus, callDuration, isMuted, currentCall } = useDoraCell();
759
+ const { call, hangup, toggleMute, answerCall, callStatus, callDuration, isMuted, currentCall, error } = useDoraCell();
664
760
  return {
665
761
  call,
666
762
  hangup,
@@ -669,18 +765,112 @@ function useCall() {
669
765
  callStatus,
670
766
  callDuration,
671
767
  isMuted,
672
- currentCall
768
+ currentCall,
769
+ callError: error?.message
673
770
  };
674
771
  }
675
772
  function useConnectionStatus() {
676
- const { connectionStatus, isInitialized, error } = useDoraCell();
773
+ const { connectionStatus, isInitialized, error, extension } = useDoraCell();
677
774
  return {
678
775
  connectionStatus,
679
776
  isInitialized,
680
777
  isConnected: connectionStatus === "registered",
681
- error
778
+ error,
779
+ extension
682
780
  };
683
781
  }
782
+ function useWallet() {
783
+ const { sdk, isInitialized } = useDoraCell();
784
+ const [data, setData] = react.useState(null);
785
+ const [isLoading, setIsLoading] = react.useState(false);
786
+ const [error, setError] = react.useState(null);
787
+ const fetchData = async () => {
788
+ if (!sdk || !isInitialized) return;
789
+ setIsLoading(true);
790
+ setError(null);
791
+ try {
792
+ const val = await sdk.getWallet();
793
+ setData(val);
794
+ } catch (err) {
795
+ setError(err instanceof Error ? err : new Error("Failed to fetch wallet"));
796
+ } finally {
797
+ setIsLoading(false);
798
+ }
799
+ };
800
+ react.useEffect(() => {
801
+ if (isInitialized) {
802
+ console.log("SDK: useWallet fetching data...");
803
+ fetchData();
804
+ }
805
+ }, [isInitialized, sdk]);
806
+ react.useEffect(() => {
807
+ if (!sdk || !isInitialized) return;
808
+ const handleCallEnded = () => {
809
+ console.log("SDK: Call ended, refreshing wallet balance in 2 seconds...");
810
+ setTimeout(fetchData, 2e3);
811
+ };
812
+ sdk.on("call:ended", handleCallEnded);
813
+ return () => {
814
+ sdk.off("call:ended", handleCallEnded);
815
+ };
816
+ }, [sdk, isInitialized]);
817
+ return {
818
+ balance: data?.balance ?? 0,
819
+ currency: data?.currency ?? "NGN",
820
+ isLoading,
821
+ error,
822
+ refresh: fetchData
823
+ };
824
+ }
825
+ function useExtensions() {
826
+ const { sdk, isInitialized } = useDoraCell();
827
+ const [extensions, setExtensions] = react.useState([]);
828
+ const [isLoading, setIsLoading] = react.useState(false);
829
+ const [error, setError] = react.useState(null);
830
+ const fetchExtensions = async () => {
831
+ if (!sdk || !isInitialized) return;
832
+ setIsLoading(true);
833
+ setError(null);
834
+ try {
835
+ const data = await sdk.fetchExtensions();
836
+ setExtensions(data);
837
+ } catch (err) {
838
+ setError(err instanceof Error ? err : new Error("Failed to fetch extensions"));
839
+ } finally {
840
+ setIsLoading(false);
841
+ }
842
+ };
843
+ const setExtension = async (extension) => {
844
+ if (!sdk) return;
845
+ await sdk.setExtension(extension);
846
+ };
847
+ react.useEffect(() => {
848
+ if (isInitialized) {
849
+ fetchExtensions();
850
+ }
851
+ }, [isInitialized, sdk]);
852
+ return {
853
+ extensions,
854
+ isLoading,
855
+ error,
856
+ setExtension,
857
+ refresh: fetchExtensions
858
+ };
859
+ }
860
+ function CreditBalance() {
861
+ const { balance, currency, isLoading, error } = useWallet();
862
+ if (error) {
863
+ console.warn("SDK: CreditBalance error:", error);
864
+ }
865
+ const formatted = new Intl.NumberFormat("en-NG", {
866
+ style: "currency",
867
+ currency: currency === "NGN" ? "NGN" : currency || "NGN"
868
+ }).format(balance);
869
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "dora-credit-balance px-3 md:px-5 py-2 md:py-3 bg-[#F6F7F9] border border-[#EDEEF1] rounded-full text-xs md:text-sm text-slate-700 whitespace-nowrap", children: [
870
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs md:text-sm text-slate-500 mr-1 md:mr-2", children: "Credit balance:" }),
871
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-semibold", children: isLoading ? "..." : formatted })
872
+ ] });
873
+ }
684
874
  /*! Bundled license information:
685
875
 
686
876
  lucide-react/dist/esm/shared/src/utils.js:
@@ -689,6 +879,7 @@ lucide-react/dist/esm/Icon.js:
689
879
  lucide-react/dist/esm/createLucideIcon.js:
690
880
  lucide-react/dist/esm/icons/arrow-down-left.js:
691
881
  lucide-react/dist/esm/icons/arrow-up-right.js:
882
+ lucide-react/dist/esm/icons/chevron-down.js:
692
883
  lucide-react/dist/esm/icons/delete.js:
693
884
  lucide-react/dist/esm/icons/maximize.js:
694
885
  lucide-react/dist/esm/icons/mic-off.js:
@@ -707,10 +898,13 @@ lucide-react/dist/esm/lucide-react.js:
707
898
  */
708
899
 
709
900
  exports.CallInterface = CallInterface;
901
+ exports.CreditBalance = CreditBalance;
710
902
  exports.Dialpad = Dialpad;
711
903
  exports.DoraCellProvider = DoraCellProvider;
712
904
  exports.useCall = useCall;
713
905
  exports.useConnectionStatus = useConnectionStatus;
714
906
  exports.useDoraCell = useDoraCell;
907
+ exports.useExtensions = useExtensions;
908
+ exports.useWallet = useWallet;
715
909
  //# sourceMappingURL=index.js.map
716
910
  //# sourceMappingURL=index.js.map