@dora-cell/sdk-react 0.1.1-beta.3 → 0.1.1-beta.30

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.mjs CHANGED
@@ -1,7 +1,534 @@
1
- import { createContext, useState, useRef, useEffect, useContext } from 'react';
1
+ import { forwardRef, createElement, createContext, useState, useRef, useEffect, useContext } from 'react';
2
2
  import { DoraCell } from '@dora-cell/sdk';
3
- import { jsx } from 'react/jsx-runtime';
3
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
4
4
 
5
+ // ../../node_modules/.pnpm/lucide-react@0.555.0_react@19.2.3/node_modules/lucide-react/dist/esm/shared/src/utils.js
6
+ var toKebabCase = (string) => string.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
7
+ var toCamelCase = (string) => string.replace(
8
+ /^([A-Z])|[\s-_]+(\w)/g,
9
+ (match, p1, p2) => p2 ? p2.toUpperCase() : p1.toLowerCase()
10
+ );
11
+ var toPascalCase = (string) => {
12
+ const camelCase = toCamelCase(string);
13
+ return camelCase.charAt(0).toUpperCase() + camelCase.slice(1);
14
+ };
15
+ var mergeClasses = (...classes) => classes.filter((className, index, array) => {
16
+ return Boolean(className) && className.trim() !== "" && array.indexOf(className) === index;
17
+ }).join(" ").trim();
18
+ var hasA11yProp = (props) => {
19
+ for (const prop in props) {
20
+ if (prop.startsWith("aria-") || prop === "role" || prop === "title") {
21
+ return true;
22
+ }
23
+ }
24
+ };
25
+
26
+ // ../../node_modules/.pnpm/lucide-react@0.555.0_react@19.2.3/node_modules/lucide-react/dist/esm/defaultAttributes.js
27
+ var defaultAttributes = {
28
+ xmlns: "http://www.w3.org/2000/svg",
29
+ width: 24,
30
+ height: 24,
31
+ viewBox: "0 0 24 24",
32
+ fill: "none",
33
+ stroke: "currentColor",
34
+ strokeWidth: 2,
35
+ strokeLinecap: "round",
36
+ strokeLinejoin: "round"
37
+ };
38
+
39
+ // ../../node_modules/.pnpm/lucide-react@0.555.0_react@19.2.3/node_modules/lucide-react/dist/esm/Icon.js
40
+ var Icon = forwardRef(
41
+ ({
42
+ color = "currentColor",
43
+ size = 24,
44
+ strokeWidth = 2,
45
+ absoluteStrokeWidth,
46
+ className = "",
47
+ children,
48
+ iconNode,
49
+ ...rest
50
+ }, ref) => createElement(
51
+ "svg",
52
+ {
53
+ ref,
54
+ ...defaultAttributes,
55
+ width: size,
56
+ height: size,
57
+ stroke: color,
58
+ strokeWidth: absoluteStrokeWidth ? Number(strokeWidth) * 24 / Number(size) : strokeWidth,
59
+ className: mergeClasses("lucide", className),
60
+ ...!children && !hasA11yProp(rest) && { "aria-hidden": "true" },
61
+ ...rest
62
+ },
63
+ [
64
+ ...iconNode.map(([tag, attrs]) => createElement(tag, attrs)),
65
+ ...Array.isArray(children) ? children : [children]
66
+ ]
67
+ )
68
+ );
69
+
70
+ // ../../node_modules/.pnpm/lucide-react@0.555.0_react@19.2.3/node_modules/lucide-react/dist/esm/createLucideIcon.js
71
+ var createLucideIcon = (iconName, iconNode) => {
72
+ const Component = forwardRef(
73
+ ({ className, ...props }, ref) => createElement(Icon, {
74
+ ref,
75
+ iconNode,
76
+ className: mergeClasses(
77
+ `lucide-${toKebabCase(toPascalCase(iconName))}`,
78
+ `lucide-${iconName}`,
79
+ className
80
+ ),
81
+ ...props
82
+ })
83
+ );
84
+ Component.displayName = toPascalCase(iconName);
85
+ return Component;
86
+ };
87
+
88
+ // ../../node_modules/.pnpm/lucide-react@0.555.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/arrow-down-left.js
89
+ var __iconNode = [
90
+ ["path", { d: "M17 7 7 17", key: "15tmo1" }],
91
+ ["path", { d: "M17 17H7V7", key: "1org7z" }]
92
+ ];
93
+ var ArrowDownLeft = createLucideIcon("arrow-down-left", __iconNode);
94
+
95
+ // ../../node_modules/.pnpm/lucide-react@0.555.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/arrow-up-right.js
96
+ var __iconNode2 = [
97
+ ["path", { d: "M7 7h10v10", key: "1tivn9" }],
98
+ ["path", { d: "M7 17 17 7", key: "1vkiza" }]
99
+ ];
100
+ var ArrowUpRight = createLucideIcon("arrow-up-right", __iconNode2);
101
+
102
+ // ../../node_modules/.pnpm/lucide-react@0.555.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/delete.js
103
+ var __iconNode3 = [
104
+ [
105
+ "path",
106
+ {
107
+ d: "M10 5a2 2 0 0 0-1.344.519l-6.328 5.74a1 1 0 0 0 0 1.481l6.328 5.741A2 2 0 0 0 10 19h10a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2z",
108
+ key: "1yo7s0"
109
+ }
110
+ ],
111
+ ["path", { d: "m12 9 6 6", key: "anjzzh" }],
112
+ ["path", { d: "m18 9-6 6", key: "1fp51s" }]
113
+ ];
114
+ var Delete = createLucideIcon("delete", __iconNode3);
115
+
116
+ // ../../node_modules/.pnpm/lucide-react@0.555.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/maximize.js
117
+ var __iconNode4 = [
118
+ ["path", { d: "M8 3H5a2 2 0 0 0-2 2v3", key: "1dcmit" }],
119
+ ["path", { d: "M21 8V5a2 2 0 0 0-2-2h-3", key: "1e4gt3" }],
120
+ ["path", { d: "M3 16v3a2 2 0 0 0 2 2h3", key: "wsl5sc" }],
121
+ ["path", { d: "M16 21h3a2 2 0 0 0 2-2v-3", key: "18trek" }]
122
+ ];
123
+ var Maximize = createLucideIcon("maximize", __iconNode4);
124
+
125
+ // ../../node_modules/.pnpm/lucide-react@0.555.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/mic-off.js
126
+ var __iconNode5 = [
127
+ ["path", { d: "M12 19v3", key: "npa21l" }],
128
+ ["path", { d: "M15 9.34V5a3 3 0 0 0-5.68-1.33", key: "1gzdoj" }],
129
+ ["path", { d: "M16.95 16.95A7 7 0 0 1 5 12v-2", key: "cqa7eg" }],
130
+ ["path", { d: "M18.89 13.23A7 7 0 0 0 19 12v-2", key: "16hl24" }],
131
+ ["path", { d: "m2 2 20 20", key: "1ooewy" }],
132
+ ["path", { d: "M9 9v3a3 3 0 0 0 5.12 2.12", key: "r2i35w" }]
133
+ ];
134
+ var MicOff = createLucideIcon("mic-off", __iconNode5);
135
+
136
+ // ../../node_modules/.pnpm/lucide-react@0.555.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/mic.js
137
+ var __iconNode6 = [
138
+ ["path", { d: "M12 19v3", key: "npa21l" }],
139
+ ["path", { d: "M19 10v2a7 7 0 0 1-14 0v-2", key: "1vc78b" }],
140
+ ["rect", { x: "9", y: "2", width: "6", height: "13", rx: "3", key: "s6n7sd" }]
141
+ ];
142
+ var Mic = createLucideIcon("mic", __iconNode6);
143
+
144
+ // ../../node_modules/.pnpm/lucide-react@0.555.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/minimize-2.js
145
+ var __iconNode7 = [
146
+ ["path", { d: "m14 10 7-7", key: "oa77jy" }],
147
+ ["path", { d: "M20 10h-6V4", key: "mjg0md" }],
148
+ ["path", { d: "m3 21 7-7", key: "tjx5ai" }],
149
+ ["path", { d: "M4 14h6v6", key: "rmj7iw" }]
150
+ ];
151
+ var Minimize2 = createLucideIcon("minimize-2", __iconNode7);
152
+
153
+ // ../../node_modules/.pnpm/lucide-react@0.555.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/phone.js
154
+ var __iconNode8 = [
155
+ [
156
+ "path",
157
+ {
158
+ d: "M13.832 16.568a1 1 0 0 0 1.213-.303l.355-.465A2 2 0 0 1 17 15h3a2 2 0 0 1 2 2v3a2 2 0 0 1-2 2A18 18 0 0 1 2 4a2 2 0 0 1 2-2h3a2 2 0 0 1 2 2v3a2 2 0 0 1-.8 1.6l-.468.351a1 1 0 0 0-.292 1.233 14 14 0 0 0 6.392 6.384",
159
+ key: "9njp5v"
160
+ }
161
+ ]
162
+ ];
163
+ var Phone = createLucideIcon("phone", __iconNode8);
164
+
165
+ // ../../node_modules/.pnpm/lucide-react@0.555.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/user.js
166
+ var __iconNode9 = [
167
+ ["path", { d: "M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2", key: "975kel" }],
168
+ ["circle", { cx: "12", cy: "7", r: "4", key: "17ys0d" }]
169
+ ];
170
+ var User = createLucideIcon("user", __iconNode9);
171
+
172
+ // ../../node_modules/.pnpm/lucide-react@0.555.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/x.js
173
+ var __iconNode10 = [
174
+ ["path", { d: "M18 6 6 18", key: "1bl5f8" }],
175
+ ["path", { d: "m6 6 12 12", key: "d8bk6v" }]
176
+ ];
177
+ var X = createLucideIcon("x", __iconNode10);
178
+ function CallInterface({
179
+ isOpen = false,
180
+ onOpenChange,
181
+ onCallEnded,
182
+ maximizeIcon,
183
+ minimizeIcon
184
+ }) {
185
+ const {
186
+ callStatus,
187
+ currentCall,
188
+ callDuration,
189
+ isMuted,
190
+ hangup,
191
+ answerCall,
192
+ toggleMute,
193
+ callError
194
+ } = useCall();
195
+ const [isMinimized, setIsMinimized] = useState(false);
196
+ const [wasConnected, setWasConnected] = useState(false);
197
+ const [closeCountdown, setCloseCountdown] = useState(null);
198
+ const [connectingCountdown, setConnectingCountdown] = useState(null);
199
+ const audioRef = useRef(null);
200
+ const ringtoneRef = useRef(null);
201
+ const isIncoming = currentCall?.direction === "inbound";
202
+ const remoteNumber = currentCall?.remoteNumber || "Unknown";
203
+ const displayName = remoteNumber;
204
+ useEffect(() => {
205
+ if (currentCall && audioRef.current) {
206
+ const stream = currentCall.getRemoteStream();
207
+ if (stream && audioRef.current.srcObject !== stream) {
208
+ audioRef.current.srcObject = stream;
209
+ }
210
+ }
211
+ }, [currentCall, callStatus]);
212
+ useEffect(() => {
213
+ if (callStatus === "ringing" && isIncoming) {
214
+ onOpenChange?.(true);
215
+ ringtoneRef.current?.play().catch(() => {
216
+ });
217
+ } else {
218
+ if (ringtoneRef.current) {
219
+ ringtoneRef.current.pause();
220
+ ringtoneRef.current.currentTime = 0;
221
+ }
222
+ }
223
+ }, [callStatus, isIncoming, onOpenChange]);
224
+ useEffect(() => {
225
+ if (callStatus === "connecting" || callStatus === "ringing") {
226
+ setWasConnected(false);
227
+ }
228
+ if (callStatus === "ongoing") {
229
+ setWasConnected(true);
230
+ }
231
+ }, [callStatus]);
232
+ useEffect(() => {
233
+ if (isOpen && callStatus === "ended") {
234
+ onCallEnded?.();
235
+ const closeDelay = wasConnected ? 1500 : 3e3;
236
+ const start = Date.now();
237
+ const iv = setInterval(() => {
238
+ const remaining = Math.max(0, closeDelay - (Date.now() - start));
239
+ setCloseCountdown(Math.ceil(remaining / 1e3));
240
+ if (remaining <= 0) {
241
+ clearInterval(iv);
242
+ onOpenChange?.(false);
243
+ setIsMinimized(false);
244
+ }
245
+ }, 100);
246
+ return () => clearInterval(iv);
247
+ } else {
248
+ setCloseCountdown(null);
249
+ }
250
+ }, [callStatus, isOpen, onOpenChange, wasConnected, onCallEnded]);
251
+ useEffect(() => {
252
+ let iv;
253
+ if (isOpen && callStatus === "connecting" && !isIncoming) {
254
+ setConnectingCountdown(60);
255
+ iv = setInterval(() => {
256
+ setConnectingCountdown((prev) => {
257
+ if (prev === null || prev <= 0) {
258
+ clearInterval(iv);
259
+ if (callStatus === "connecting") hangup();
260
+ return 0;
261
+ }
262
+ return prev - 1;
263
+ });
264
+ }, 1e3);
265
+ } else {
266
+ setConnectingCountdown(null);
267
+ }
268
+ return () => clearInterval(iv);
269
+ }, [callStatus, isOpen, isIncoming, hangup]);
270
+ if (!isOpen && callStatus === "idle") return null;
271
+ return /* @__PURE__ */ jsxs(
272
+ "div",
273
+ {
274
+ role: "dialog",
275
+ "aria-label": "Call interface",
276
+ 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"}`,
277
+ children: [
278
+ /* @__PURE__ */ jsx("audio", { ref: audioRef, autoPlay: true, className: "dora-hidden" }),
279
+ /* @__PURE__ */ jsx(
280
+ "audio",
281
+ {
282
+ ref: ringtoneRef,
283
+ src: "https://assets.mixkit.co/active_storage/sfx/2358/2358-preview.mp3",
284
+ loop: true,
285
+ preload: "auto",
286
+ className: "dora-hidden"
287
+ }
288
+ ),
289
+ isMinimized ? /* @__PURE__ */ jsxs("div", { className: "dora-flex dora-items-center dora-justify-between dora-w-full dora-h-full", children: [
290
+ /* @__PURE__ */ jsx(
291
+ "button",
292
+ {
293
+ onClick: () => setIsMinimized(false),
294
+ 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",
295
+ "aria-label": "Maximize",
296
+ children: maximizeIcon || /* @__PURE__ */ jsx(Maximize, { size: 18 })
297
+ }
298
+ ),
299
+ /* @__PURE__ */ jsxs("div", { className: "dora-relative dora-flex dora-items-center", children: [
300
+ /* @__PURE__ */ 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__ */ jsx("span", { className: "dora-text-xl dora-text-slate-900 dora-font-bold", children: displayName.charAt(0).toUpperCase() }) }),
301
+ /* @__PURE__ */ jsx(
302
+ "button",
303
+ {
304
+ onClick: hangup,
305
+ 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",
306
+ "aria-label": "End call",
307
+ children: /* @__PURE__ */ jsx(Phone, { size: 18, className: "dora-transform dora-rotate-[135deg]" })
308
+ }
309
+ )
310
+ ] })
311
+ ] }) : /* @__PURE__ */ 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: [
312
+ /* @__PURE__ */ jsx(
313
+ "button",
314
+ {
315
+ onClick: () => setIsMinimized(true),
316
+ className: "dora-absolute dora-top-2 dora-right-2 dora-text-slate-500 hover:dora-text-white dora-transition-colors",
317
+ "aria-label": "Minimize",
318
+ children: minimizeIcon || /* @__PURE__ */ jsx(Minimize2, { size: 16 })
319
+ }
320
+ ),
321
+ /* @__PURE__ */ jsxs("div", { className: "dora-flex dora-justify-between dora-gap-2 dora-items-start md:dora-items-center", children: [
322
+ /* @__PURE__ */ jsxs("div", { className: "dora-flex dora-items-center dora-gap-2.5 md:dora-gap-4 dora-min-w-0", children: [
323
+ /* @__PURE__ */ 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__ */ jsx("span", { className: "dora-text-lg md:dora-text-2xl dora-text-slate-900 dora-font-bold", children: displayName.charAt(0).toUpperCase() }) }),
324
+ /* @__PURE__ */ jsxs("div", { className: "dora-min-w-0 dora-flex-1", children: [
325
+ /* @__PURE__ */ 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 }),
326
+ /* @__PURE__ */ jsxs("p", { className: "dora-text-slate-400 dora-text-xs md:dora-text-sm dora-truncate", children: [
327
+ remoteNumber,
328
+ " \u2022",
329
+ " ",
330
+ isMuted ? /* @__PURE__ */ jsx("span", { className: "dora-text-[#F99578]", children: "Call muted" }) : /* @__PURE__ */ jsxs(Fragment, { children: [
331
+ (callStatus === "connecting" || callStatus === "ringing") && /* @__PURE__ */ jsx("span", { children: isIncoming ? "Incoming Call..." : callStatus === "connecting" ? "Connecting..." : "Ringing..." }),
332
+ callStatus === "ongoing" && /* @__PURE__ */ jsx("span", { children: "On Call" }),
333
+ callStatus === "ended" && /* @__PURE__ */ jsx("span", { children: "Call Ended" })
334
+ ] })
335
+ ] })
336
+ ] })
337
+ ] }),
338
+ /* @__PURE__ */ jsxs("div", { className: "dora-flex dora-items-center dora-justify-center dora-gap-1.5 md:dora-gap-3 dora-shrink-0", children: [
339
+ isIncoming && callStatus === "ringing" && /* @__PURE__ */ jsx(
340
+ "button",
341
+ {
342
+ onClick: answerCall,
343
+ 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",
344
+ "aria-label": "Answer",
345
+ children: /* @__PURE__ */ jsx(Phone, { size: 18 })
346
+ }
347
+ ),
348
+ (callStatus === "ongoing" || isIncoming && callStatus === "ringing") && /* @__PURE__ */ jsx(
349
+ "button",
350
+ {
351
+ onClick: toggleMute,
352
+ 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
+ "aria-label": "Toggle mute",
354
+ children: isMuted ? /* @__PURE__ */ jsx(MicOff, { size: 18 }) : /* @__PURE__ */ jsx(Mic, { size: 18 })
355
+ }
356
+ ),
357
+ /* @__PURE__ */ jsx(
358
+ "button",
359
+ {
360
+ onClick: hangup,
361
+ 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",
362
+ "aria-label": isIncoming && callStatus === "ringing" ? "Decline" : "End call",
363
+ children: /* @__PURE__ */ jsx(Phone, { size: 18, className: "dora-transform dora-rotate-[135deg]" })
364
+ }
365
+ )
366
+ ] })
367
+ ] }),
368
+ /* @__PURE__ */ jsx("div", { className: "dora-flex-1 dora-border-t dora-border-[#282828] dora-mt-2 dora-mb-2" }),
369
+ callError && callStatus === "ended" && /* @__PURE__ */ 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: [
370
+ /* @__PURE__ */ jsx("p", { className: "dora-text-red-400 dora-text-xs md:dora-text-sm dora-font-medium", children: "Call Failed" }),
371
+ /* @__PURE__ */ jsx("p", { className: "dora-text-red-300 dora-text-xs dora-mt-0.5 md:dora-mt-1", children: callError }),
372
+ closeCountdown !== null && /* @__PURE__ */ jsxs("div", { className: "dora-mt-1.5 md:dora-mt-2", children: [
373
+ /* @__PURE__ */ jsx("div", { className: "dora-w-full dora-bg-red-900/30 dora-rounded-full dora-h-1.5 dora-overflow-hidden", children: /* @__PURE__ */ jsx(
374
+ "div",
375
+ {
376
+ className: "dora-bg-red-500 dora-h-full dora-transition-all dora-duration-100",
377
+ style: {
378
+ width: `${Math.max(
379
+ 0,
380
+ closeCountdown / (wasConnected ? 1 : 5) * 100
381
+ )}%`
382
+ }
383
+ }
384
+ ) }),
385
+ /* @__PURE__ */ jsxs("p", { className: "dora-text-xs dora-text-red-300 dora-mt-0.5 md:dora-mt-1 dora-text-center", children: [
386
+ "Closing in ",
387
+ closeCountdown,
388
+ "s"
389
+ ] })
390
+ ] })
391
+ ] }),
392
+ /* @__PURE__ */ jsxs("div", { className: "dora-flex dora-justify-between dora-items-center", children: [
393
+ /* @__PURE__ */ 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: [
394
+ (callStatus === "connecting" || callStatus === "ringing") && /* @__PURE__ */ jsx("span", { children: isIncoming ? "Incoming call" : "Outgoing call" }),
395
+ callStatus === "ongoing" && /* @__PURE__ */ jsx("span", { children: "Ongoing" }),
396
+ callStatus === "ended" && /* @__PURE__ */ jsx("span", { children: "Call ended" }),
397
+ (callStatus === "connecting" || callStatus === "ringing" || callStatus === "ongoing") && (isIncoming ? /* @__PURE__ */ jsx(ArrowDownLeft, { className: "dora-inline-block dora-ml-1 dora-text-green-400", size: 16 }) : /* @__PURE__ */ jsx(ArrowUpRight, { className: "dora-inline-block dora-ml-1 dora-text-blue-400", size: 16 }))
398
+ ] }),
399
+ callStatus === "ongoing" && /* @__PURE__ */ 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__ */ jsx("span", { children: callDuration }) }),
400
+ callStatus === "ended" && closeCountdown !== null && /* @__PURE__ */ 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__ */ jsxs("span", { children: [
401
+ "Closing in ",
402
+ closeCountdown,
403
+ "s"
404
+ ] }) }),
405
+ (connectingCountdown !== null || callStatus === "ringing") && !isIncoming && callStatus !== "ongoing" && callStatus !== "ended" && /* @__PURE__ */ 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: [
406
+ /* @__PURE__ */ jsx("span", { className: "dora-text-[#F99578] dora-whitespace-nowrap", children: callStatus === "ringing" ? "Ringing..." : "Connecting..." }),
407
+ callStatus === "connecting" && connectingCountdown && /* @__PURE__ */ jsxs("span", { className: "dora-font-mono dora-ml-1 dora-text-slate-400", children: [
408
+ Math.floor(connectingCountdown / 60),
409
+ ":",
410
+ String(connectingCountdown % 60).padStart(2, "0")
411
+ ] })
412
+ ] })
413
+ ] })
414
+ ] })
415
+ ]
416
+ }
417
+ );
418
+ }
419
+ function Dialpad({
420
+ onCallInitiated,
421
+ initialNumber = "",
422
+ showKeys = true,
423
+ className = "",
424
+ availableExtensions = [],
425
+ selectedExtension,
426
+ onExtensionChange
427
+ }) {
428
+ const { call, callStatus } = useCall();
429
+ const { isConnected } = useConnectionStatus();
430
+ const [number, setNumber] = useState(initialNumber);
431
+ const [keysVisible, setKeysVisible] = useState(showKeys);
432
+ const append = (digit) => setNumber((s) => s + digit);
433
+ const backspace = () => setNumber((s) => s.slice(0, -1));
434
+ const handleCall = async () => {
435
+ if (!number || number.trim() === "") return;
436
+ try {
437
+ await call(number, selectedExtension);
438
+ onCallInitiated?.(number);
439
+ } catch (e) {
440
+ console.error("Call failed", e);
441
+ }
442
+ };
443
+ const isCallDisabled = !number || number.trim() === "" || !isConnected || callStatus === "ringing" || callStatus === "ongoing" || callStatus === "connecting";
444
+ return /* @__PURE__ */ jsxs("div", { className: `dora-space-y-4 ${className}`, children: [
445
+ availableExtensions.length > 0 && /* @__PURE__ */ jsxs("div", { className: "dora-gap-2 dora-bg-[#F6F7F9] dora-rounded-lg dora-flex dora-items-center dora-justify-between dora-p-2 md:dora-p-2.5 dora-mb-4", children: [
446
+ /* @__PURE__ */ jsx("div", { className: "dora-text-xs md:dora-text-sm dora-text-neutral-500 dora-font-normal dora-whitespace-nowrap", children: "Caller ID" }),
447
+ /* @__PURE__ */ jsx(
448
+ "select",
449
+ {
450
+ className: "dora-bg-transparent dora-text-sm dora-font-medium dora-outline-none",
451
+ value: selectedExtension,
452
+ onChange: (e) => onExtensionChange?.(e.target.value),
453
+ children: availableExtensions.map((ext) => /* @__PURE__ */ jsx("option", { value: ext.value, children: ext.label }, ext.value))
454
+ }
455
+ )
456
+ ] }),
457
+ /* @__PURE__ */ jsxs("div", { className: "dora-space-y-2 md:dora-space-y-3 dora-bg-[#F6F7F9] dora-p-2 md:dora-p-2.5 dora-rounded-lg", children: [
458
+ /* @__PURE__ */ jsxs("div", { className: "dora-flex dora-items-center dora-gap-2 md:dora-gap-3", children: [
459
+ /* @__PURE__ */ jsxs("div", { className: "dora-flex-1 dora-min-w-0 dora-flex dora-items-center dora-bg-white dora-rounded-md dora-px-3 dora-h-10 dora-border dora-border-transparent focus-within:dora-border-green-500 dora-transition-colors", children: [
460
+ /* @__PURE__ */ jsx(User, { className: "dora-text-gray-400 dora-mr-2", size: 18 }),
461
+ /* @__PURE__ */ jsx(
462
+ "input",
463
+ {
464
+ type: "tel",
465
+ placeholder: "Enter number",
466
+ value: number,
467
+ onChange: (e) => setNumber(e.target.value),
468
+ className: "dora-bg-transparent dora-border-none dora-outline-none dora-w-full dora-text-base dora-text-black"
469
+ }
470
+ )
471
+ ] }),
472
+ /* @__PURE__ */ jsx(
473
+ "button",
474
+ {
475
+ disabled: isCallDisabled,
476
+ onClick: handleCall,
477
+ title: "Place Call",
478
+ className: "dora-bg-green-500 dora-text-white hover:dora-bg-green-600 dora-rounded-lg dora-h-9 md:dora-h-10 dora-w-9 md:dora-w-11 dora-flex dora-items-center dora-justify-center disabled:dora-opacity-50 disabled:dora-cursor-not-allowed dora-transition-colors",
479
+ children: /* @__PURE__ */ jsx(Phone, { size: 16, fill: "currentColor" })
480
+ }
481
+ )
482
+ ] }),
483
+ /* @__PURE__ */ jsx("div", { children: keysVisible ? /* @__PURE__ */ jsxs("div", { className: "dora-pt-3", children: [
484
+ /* @__PURE__ */ jsx("div", { className: "dora-flex dora-items-center dora-gap-3 dora-mb-3", children: /* @__PURE__ */ jsxs(
485
+ "button",
486
+ {
487
+ onClick: () => setKeysVisible(false),
488
+ 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",
489
+ children: [
490
+ /* @__PURE__ */ jsx(X, { color: "red", size: 16 }),
491
+ " Close keypad"
492
+ ]
493
+ }
494
+ ) }),
495
+ /* @__PURE__ */ jsx("div", { className: "dora-grid dora-grid-cols-3 dora-gap-2 md:dora-gap-3", children: [
496
+ "1",
497
+ "2",
498
+ "3",
499
+ "4",
500
+ "5",
501
+ "6",
502
+ "7",
503
+ "8",
504
+ "9",
505
+ "+",
506
+ "0",
507
+ "del"
508
+ ].map((d) => /* @__PURE__ */ jsx(
509
+ "button",
510
+ {
511
+ onClick: () => d === "del" ? backspace() : append(d),
512
+ 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",
513
+ "aria-label": d === "del" ? "Delete" : `Dial ${d}`,
514
+ children: d === "del" ? /* @__PURE__ */ jsx(Delete, { size: 18 }) : d
515
+ },
516
+ d
517
+ )) })
518
+ ] }) : /* @__PURE__ */ jsx("div", { className: "dora-pt-2 md:dora-pt-3", children: /* @__PURE__ */ jsxs(
519
+ "button",
520
+ {
521
+ onClick: () => setKeysVisible(true),
522
+ className: "dora-rounded-full dora-bg-[#EDEEF1] dora-h-9 md:dora-h-10 dora-flex dora-justify-center dora-items-center dora-px-3 md:dora-px-4 dora-w-full dora-text-xs md:dora-text-sm hover:dora-bg-[#E3E4E8] dora-transition-colors",
523
+ children: [
524
+ /* @__PURE__ */ jsx("span", { className: "dora-mr-2", children: "\u{1F522}" }),
525
+ /* @__PURE__ */ jsx("span", { className: "dora-text-xs md:dora-text-sm dora-text-neutral-500 dora-font-normal dora-ml-1.5", children: "Open dialer" })
526
+ ]
527
+ }
528
+ ) }) })
529
+ ] })
530
+ ] });
531
+ }
5
532
  var DoraCellContext = createContext(void 0);
6
533
  function DoraCellProvider({
7
534
  config,
@@ -167,15 +694,17 @@ function useDoraCell() {
167
694
  return context;
168
695
  }
169
696
  function useCall() {
170
- const { call, hangup, toggleMute, callStatus, callDuration, isMuted, currentCall } = useDoraCell();
697
+ const { call, hangup, toggleMute, answerCall, callStatus, callDuration, isMuted, currentCall, error } = useDoraCell();
171
698
  return {
172
699
  call,
173
700
  hangup,
174
701
  toggleMute,
702
+ answerCall,
175
703
  callStatus,
176
704
  callDuration,
177
705
  isMuted,
178
- currentCall
706
+ currentCall,
707
+ callError: error?.message
179
708
  };
180
709
  }
181
710
  function useConnectionStatus() {
@@ -187,7 +716,31 @@ function useConnectionStatus() {
187
716
  error
188
717
  };
189
718
  }
719
+ /*! Bundled license information:
720
+
721
+ lucide-react/dist/esm/shared/src/utils.js:
722
+ lucide-react/dist/esm/defaultAttributes.js:
723
+ lucide-react/dist/esm/Icon.js:
724
+ lucide-react/dist/esm/createLucideIcon.js:
725
+ lucide-react/dist/esm/icons/arrow-down-left.js:
726
+ lucide-react/dist/esm/icons/arrow-up-right.js:
727
+ lucide-react/dist/esm/icons/delete.js:
728
+ lucide-react/dist/esm/icons/maximize.js:
729
+ lucide-react/dist/esm/icons/mic-off.js:
730
+ lucide-react/dist/esm/icons/mic.js:
731
+ lucide-react/dist/esm/icons/minimize-2.js:
732
+ lucide-react/dist/esm/icons/phone.js:
733
+ lucide-react/dist/esm/icons/user.js:
734
+ lucide-react/dist/esm/icons/x.js:
735
+ lucide-react/dist/esm/lucide-react.js:
736
+ (**
737
+ * @license lucide-react v0.555.0 - ISC
738
+ *
739
+ * This source code is licensed under the ISC license.
740
+ * See the LICENSE file in the root directory of this source tree.
741
+ *)
742
+ */
190
743
 
191
- export { DoraCellProvider, useCall, useConnectionStatus, useDoraCell };
744
+ export { CallInterface, Dialpad, DoraCellProvider, useCall, useConnectionStatus, useDoraCell };
192
745
  //# sourceMappingURL=index.mjs.map
193
746
  //# sourceMappingURL=index.mjs.map