ahs-cti 0.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.
Files changed (60) hide show
  1. package/LICENSE +53 -0
  2. package/LICENSE-ACHALA +80 -0
  3. package/README.md +639 -0
  4. package/dist/agentDetailReport-7TDO6MYQ.mjs +11 -0
  5. package/dist/agentDetailReport-7TDO6MYQ.mjs.map +1 -0
  6. package/dist/agentPerformanceReport-R3WY7Q7D.mjs +531 -0
  7. package/dist/agentPerformanceReport-R3WY7Q7D.mjs.map +1 -0
  8. package/dist/auditReport-CJ23LXIZ.mjs +15 -0
  9. package/dist/auditReport-CJ23LXIZ.mjs.map +1 -0
  10. package/dist/callHistory-743J7EKD.mjs +783 -0
  11. package/dist/callHistory-743J7EKD.mjs.map +1 -0
  12. package/dist/campaigns-N2RLUJHH.mjs +3005 -0
  13. package/dist/campaigns-N2RLUJHH.mjs.map +1 -0
  14. package/dist/caroQualityAuditDashboard-NRWY6SEC.mjs +66 -0
  15. package/dist/caroQualityAuditDashboard-NRWY6SEC.mjs.map +1 -0
  16. package/dist/caroVoiceAI-Z5BDDDSY.mjs +21 -0
  17. package/dist/caroVoiceAI-Z5BDDDSY.mjs.map +1 -0
  18. package/dist/cdrReport-577UYGZA.mjs +798 -0
  19. package/dist/cdrReport-577UYGZA.mjs.map +1 -0
  20. package/dist/chunk-6ICPXSN6.mjs +61 -0
  21. package/dist/chunk-6ICPXSN6.mjs.map +1 -0
  22. package/dist/chunk-BU6FMNBY.mjs +82 -0
  23. package/dist/chunk-BU6FMNBY.mjs.map +1 -0
  24. package/dist/chunk-DBSNJ3QH.mjs +1060 -0
  25. package/dist/chunk-DBSNJ3QH.mjs.map +1 -0
  26. package/dist/chunk-EJIWPC3H.mjs +747 -0
  27. package/dist/chunk-EJIWPC3H.mjs.map +1 -0
  28. package/dist/chunk-GTDWTI5S.mjs +17217 -0
  29. package/dist/chunk-GTDWTI5S.mjs.map +1 -0
  30. package/dist/chunk-L4LLUMYA.mjs +57 -0
  31. package/dist/chunk-L4LLUMYA.mjs.map +1 -0
  32. package/dist/chunk-NQL4VODC.mjs +180 -0
  33. package/dist/chunk-NQL4VODC.mjs.map +1 -0
  34. package/dist/chunk-NUYGQI7D.mjs +678 -0
  35. package/dist/chunk-NUYGQI7D.mjs.map +1 -0
  36. package/dist/chunk-RZZQ42MG.mjs +115 -0
  37. package/dist/chunk-RZZQ42MG.mjs.map +1 -0
  38. package/dist/chunk-UB5HSUGK.mjs +65 -0
  39. package/dist/chunk-UB5HSUGK.mjs.map +1 -0
  40. package/dist/chunk-VGVOMFYH.mjs +5781 -0
  41. package/dist/chunk-VGVOMFYH.mjs.map +1 -0
  42. package/dist/chunk-VZCHJLAW.mjs +61 -0
  43. package/dist/chunk-VZCHJLAW.mjs.map +1 -0
  44. package/dist/incoming-4WP3FJI4.mp3 +0 -0
  45. package/dist/incoming.mp3 +0 -0
  46. package/dist/index.d.mts +2476 -0
  47. package/dist/index.d.ts +2477 -0
  48. package/dist/index.js +41208 -0
  49. package/dist/index.js.map +1 -0
  50. package/dist/index.mjs +4641 -0
  51. package/dist/index.mjs.map +1 -0
  52. package/dist/liveStatus-IQIEZZE5.mjs +1077 -0
  53. package/dist/liveStatus-IQIEZZE5.mjs.map +1 -0
  54. package/dist/loginReport-H6XJU2MY.mjs +826 -0
  55. package/dist/loginReport-H6XJU2MY.mjs.map +1 -0
  56. package/dist/managementDashboard-NZMAJPPB.mjs +527 -0
  57. package/dist/managementDashboard-NZMAJPPB.mjs.map +1 -0
  58. package/dist/qualityAuditDashboard-ZJEEAMBS.mjs +66 -0
  59. package/dist/qualityAuditDashboard-ZJEEAMBS.mjs.map +1 -0
  60. package/package.json +114 -0
@@ -0,0 +1,3005 @@
1
+ import {
2
+ useGetCallerData
3
+ } from "./chunk-L4LLUMYA.mjs";
4
+ import {
5
+ SDKPageHeader
6
+ } from "./chunk-RZZQ42MG.mjs";
7
+ import {
8
+ getRecordingByCall
9
+ } from "./chunk-VZCHJLAW.mjs";
10
+ import {
11
+ SDKPermissionGuard,
12
+ useSDKPermissions
13
+ } from "./chunk-NQL4VODC.mjs";
14
+ import {
15
+ SDKProvider,
16
+ useToast
17
+ } from "./chunk-6ICPXSN6.mjs";
18
+ import {
19
+ END_POINT,
20
+ SDK_PERMISSIONS,
21
+ axios_default,
22
+ deepFindArray,
23
+ deepFindTotal
24
+ } from "./chunk-DBSNJ3QH.mjs";
25
+ import {
26
+ __spreadProps,
27
+ __spreadValues
28
+ } from "./chunk-UB5HSUGK.mjs";
29
+
30
+ // call-control-sdk/lib/pages/campaigns/index.tsx
31
+ import { memo, useCallback as useCallback2, useEffect, useRef, useState as useState2 } from "react";
32
+ import {
33
+ Box,
34
+ Chip,
35
+ CircularProgress,
36
+ FormControl,
37
+ FormControlLabel,
38
+ Checkbox,
39
+ IconButton,
40
+ InputAdornment,
41
+ MenuItem,
42
+ OutlinedInput,
43
+ Paper,
44
+ Select,
45
+ Tab,
46
+ Table,
47
+ TableBody,
48
+ TableCell,
49
+ TableContainer,
50
+ TableHead,
51
+ TablePagination,
52
+ TableRow,
53
+ Tabs,
54
+ TextField,
55
+ Tooltip,
56
+ Typography,
57
+ useTheme as useTheme2
58
+ } from "@mui/material";
59
+ import AddIcon from "@mui/icons-material/Add";
60
+ import ArchiveIcon from "@mui/icons-material/Archive";
61
+ import ChevronLeftIcon from "@mui/icons-material/ChevronLeft";
62
+ import ChevronRightIcon from "@mui/icons-material/ChevronRight";
63
+ import DeleteIcon from "@mui/icons-material/Delete";
64
+ import DownloadIcon from "@mui/icons-material/Download";
65
+ import EditIcon from "@mui/icons-material/Edit";
66
+ import PauseIcon from "@mui/icons-material/Pause";
67
+ import PhoneIcon from "@mui/icons-material/Phone";
68
+ import PlayArrowIcon from "@mui/icons-material/PlayArrow";
69
+ import RefreshIcon from "@mui/icons-material/Refresh";
70
+ import SearchIcon from "@mui/icons-material/Search";
71
+ import SettingsIcon from "@mui/icons-material/Settings";
72
+ import UploadFileIcon from "@mui/icons-material/UploadFile";
73
+ import VisibilityOutlinedIcon from "@mui/icons-material/VisibilityOutlined";
74
+
75
+ // call-control-sdk/lib/components/SDKButton.tsx
76
+ import { Button, useTheme } from "@mui/material";
77
+ import { alpha } from "@mui/material/styles";
78
+ import { jsx } from "react/jsx-runtime";
79
+ var muiVariant = {
80
+ primary: "contained",
81
+ danger: "contained",
82
+ cancel: "text",
83
+ outlined: "outlined"
84
+ };
85
+ function SDKButton({
86
+ children,
87
+ variant = "primary",
88
+ onClick,
89
+ startIcon,
90
+ endIcon,
91
+ disabled = false,
92
+ type = "button",
93
+ size = "medium",
94
+ fullWidth = false,
95
+ sx
96
+ }) {
97
+ const theme = useTheme();
98
+ const primary = theme.palette.primary.main;
99
+ const primaryDark = theme.palette.primary.dark;
100
+ const styles = {
101
+ primary: {
102
+ textTransform: "none",
103
+ fontWeight: 600,
104
+ backgroundColor: primary,
105
+ borderRadius: "30px",
106
+ fontSize: "0.82rem",
107
+ px: 2,
108
+ boxShadow: `0 2px 8px ${alpha(primary, 0.25)}`,
109
+ "&:hover": {
110
+ backgroundColor: primaryDark,
111
+ boxShadow: `0 4px 12px ${alpha(primary, 0.35)}`
112
+ },
113
+ "&.Mui-disabled": {
114
+ backgroundColor: alpha(primary, 0.4),
115
+ color: "#fff"
116
+ }
117
+ },
118
+ danger: {
119
+ textTransform: "none",
120
+ fontWeight: 600,
121
+ backgroundColor: "#d32f2f",
122
+ borderRadius: "8px",
123
+ fontSize: "0.82rem",
124
+ px: 2,
125
+ "&:hover": { backgroundColor: "#b71c1c" },
126
+ "&.Mui-disabled": { backgroundColor: "#e57373", color: "#fff" }
127
+ },
128
+ cancel: {
129
+ textTransform: "none",
130
+ fontWeight: 600,
131
+ color: "#666",
132
+ borderRadius: "30px",
133
+ fontSize: "0.82rem",
134
+ px: 2,
135
+ border: "1px solid #d0d0d0",
136
+ "&:hover": { backgroundColor: "#f5f5f5", borderColor: "#bbb" }
137
+ },
138
+ outlined: {
139
+ textTransform: "none",
140
+ fontWeight: 600,
141
+ color: primary,
142
+ borderColor: primary,
143
+ borderRadius: "30px",
144
+ fontSize: "0.82rem",
145
+ px: 2,
146
+ "&:hover": { borderColor: primaryDark, backgroundColor: alpha(primary, 0.05) }
147
+ }
148
+ };
149
+ return /* @__PURE__ */ jsx(
150
+ Button,
151
+ {
152
+ variant: muiVariant[variant],
153
+ onClick,
154
+ startIcon,
155
+ endIcon,
156
+ disabled,
157
+ type,
158
+ size,
159
+ fullWidth,
160
+ sx: [styles[variant], ...Array.isArray(sx) ? sx : [sx]],
161
+ children
162
+ }
163
+ );
164
+ }
165
+
166
+ // call-control-sdk/lib/pages/campaigns/useCampaigns.ts
167
+ import { useState, useCallback } from "react";
168
+ function useCampaigns() {
169
+ const [campaigns, setCampaigns] = useState([]);
170
+ const [loading, setLoading] = useState(false);
171
+ const fetchCampaigns = useCallback(async () => {
172
+ setLoading(true);
173
+ try {
174
+ const res = await axios_default.get(END_POINT.CAMPAIGNS_GET_ALL);
175
+ setCampaigns(Array.isArray(res.data) ? res.data : []);
176
+ } catch (e) {
177
+ setCampaigns([]);
178
+ } finally {
179
+ setLoading(false);
180
+ }
181
+ }, []);
182
+ const getCampaignById = useCallback(async (id) => {
183
+ const res = await axios_default.get(END_POINT.CAMPAIGNS_GET_BY_ID(id));
184
+ return res.data;
185
+ }, []);
186
+ const createCampaign = useCallback(async (data) => {
187
+ const res = await axios_default.post(END_POINT.CAMPAIGNS_CREATE, data);
188
+ return res.data;
189
+ }, []);
190
+ const updateCampaign = useCallback(async (id, data) => {
191
+ const res = await axios_default.put(END_POINT.CAMPAIGNS_UPDATE(id), data);
192
+ return res.data;
193
+ }, []);
194
+ const activateCampaign = useCallback(async (id) => {
195
+ const res = await axios_default.post(END_POINT.CAMPAIGNS_ACTIVATE(id));
196
+ return res.data;
197
+ }, []);
198
+ const pauseCampaign = useCallback(async (id) => {
199
+ const res = await axios_default.post(END_POINT.CAMPAIGNS_PAUSE(id));
200
+ return res.data;
201
+ }, []);
202
+ const archiveCampaign = useCallback(async (id) => {
203
+ const res = await axios_default.post(END_POINT.CAMPAIGNS_ARCHIVE(id));
204
+ return res.data;
205
+ }, []);
206
+ return {
207
+ campaigns,
208
+ loading,
209
+ fetchCampaigns,
210
+ getCampaignById,
211
+ createCampaign,
212
+ updateCampaign,
213
+ activateCampaign,
214
+ pauseCampaign,
215
+ archiveCampaign
216
+ };
217
+ }
218
+ function useLeads() {
219
+ const [leads, setLeads] = useState([]);
220
+ const [leadTotal, setLeadTotal] = useState(0);
221
+ const [leadsMeta, setLeadsMeta] = useState(null);
222
+ const [loading, setLoading] = useState(false);
223
+ const fetchLeads = useCallback(async (campaignId, params, opts) => {
224
+ var _a, _b, _c, _d, _e, _f;
225
+ if (!(opts == null ? void 0 : opts.silent)) setLoading(true);
226
+ try {
227
+ const qs = new URLSearchParams();
228
+ if ((params == null ? void 0 : params.page) != null) qs.append("page", String(params.page));
229
+ if ((params == null ? void 0 : params.pageSize) != null) qs.append("pageSize", String(params.pageSize));
230
+ if (params == null ? void 0 : params.lead_status) qs.append("lead_status", params.lead_status);
231
+ if (params == null ? void 0 : params.search) qs.append("search", params.search);
232
+ const qsStr = qs.toString();
233
+ const url = `${END_POINT.CAMPAIGNS_LEADS(campaignId)}${qsStr ? `?${qsStr}` : ""}`;
234
+ const res = await axios_default.get(url);
235
+ const body = res.data;
236
+ const fetchedLeads = deepFindArray(body, ["leads"]);
237
+ setLeads(fetchedLeads);
238
+ const foundTotal = deepFindTotal(body);
239
+ setLeadTotal(foundTotal >= 0 ? foundTotal : fetchedLeads.length);
240
+ setLeadsMeta({
241
+ isDialerEnabled: (_b = body == null ? void 0 : body.isDialerEnabled) != null ? _b : (_a = body == null ? void 0 : body.data) == null ? void 0 : _a.isDialerEnabled,
242
+ dialingMode: (_d = body == null ? void 0 : body.dialingMode) != null ? _d : (_c = body == null ? void 0 : body.data) == null ? void 0 : _c.dialingMode,
243
+ campaignStatus: (_f = body == null ? void 0 : body.campaignStatus) != null ? _f : (_e = body == null ? void 0 : body.data) == null ? void 0 : _e.campaignStatus
244
+ });
245
+ } catch (e) {
246
+ setLeads([]);
247
+ setLeadTotal(0);
248
+ setLeadsMeta(null);
249
+ } finally {
250
+ setLoading(false);
251
+ }
252
+ }, []);
253
+ const createLead = useCallback(async (campaignId, data) => {
254
+ const res = await axios_default.post(END_POINT.CAMPAIGNS_LEADS(campaignId), data);
255
+ return res.data;
256
+ }, []);
257
+ const deleteLead = useCallback(async (campaignId, leadId) => {
258
+ await axios_default.delete(END_POINT.CAMPAIGNS_DELETE_LEAD(campaignId, leadId));
259
+ }, []);
260
+ const dialPreview = useCallback(async (campaignId, leadId) => {
261
+ const res = await axios_default.post(END_POINT.CAMPAIGNS_DIAL_PREVIEW(campaignId, leadId));
262
+ return res.data;
263
+ }, []);
264
+ const getLeadCallData = useCallback(async (callUuid) => {
265
+ var _a, _b;
266
+ const res = await axios_default.get(END_POINT.CALL_DATA_BY_CALL(callUuid));
267
+ return (_b = (_a = res.data) == null ? void 0 : _a.data) != null ? _b : res.data;
268
+ }, []);
269
+ const uploadLeadsExcel = useCallback(async (campaignId, file) => {
270
+ const formData = new FormData();
271
+ formData.append("file", file);
272
+ const res = await axios_default.post(END_POINT.CAMPAIGNS_LEADS_UPLOAD_EXCEL(campaignId), formData, {
273
+ headers: { "Content-Type": "multipart/form-data" }
274
+ });
275
+ return res.data;
276
+ }, []);
277
+ const downloadLeadTemplate = useCallback(async (campaignId) => {
278
+ const res = await axios_default.get(END_POINT.CAMPAIGNS_LEADS_TEMPLATE_EXCEL(campaignId), {
279
+ responseType: "blob"
280
+ });
281
+ const blob = res.data;
282
+ const url = window.URL.createObjectURL(blob);
283
+ const a = document.createElement("a");
284
+ a.href = url;
285
+ a.download = "lead_template.xlsx";
286
+ document.body.appendChild(a);
287
+ a.click();
288
+ a.remove();
289
+ window.URL.revokeObjectURL(url);
290
+ }, []);
291
+ const exportLeads = useCallback(async (campaignId) => {
292
+ const res = await axios_default.get(END_POINT.CAMPAIGNS_LEADS_EXPORT_EXCEL(campaignId), {
293
+ responseType: "blob"
294
+ });
295
+ const blob = res.data;
296
+ const url = window.URL.createObjectURL(blob);
297
+ const a = document.createElement("a");
298
+ a.href = url;
299
+ a.download = "leads_export.xlsx";
300
+ document.body.appendChild(a);
301
+ a.click();
302
+ a.remove();
303
+ window.URL.revokeObjectURL(url);
304
+ }, []);
305
+ return {
306
+ leads,
307
+ leadTotal,
308
+ leadsMeta,
309
+ loading,
310
+ fetchLeads,
311
+ createLead,
312
+ deleteLead,
313
+ dialPreview,
314
+ getLeadCallData,
315
+ uploadLeadsExcel,
316
+ downloadLeadTemplate,
317
+ exportLeads
318
+ };
319
+ }
320
+ function useQueues() {
321
+ const [queues, setQueues] = useState([]);
322
+ const [loading, setLoading] = useState(false);
323
+ const fetchQueues = useCallback(async () => {
324
+ var _a;
325
+ setLoading(true);
326
+ try {
327
+ const res = await axios_default.get(END_POINT.QUEUES_GET_ALL);
328
+ const list = Array.isArray(res.data) ? res.data : Array.isArray((_a = res.data) == null ? void 0 : _a.data) ? res.data.data : [];
329
+ setQueues(list);
330
+ return list;
331
+ } catch (e) {
332
+ setQueues([]);
333
+ return [];
334
+ } finally {
335
+ setLoading(false);
336
+ }
337
+ }, []);
338
+ const createQueue = useCallback(async (payload) => {
339
+ var _a, _b;
340
+ const res = await axios_default.post(END_POINT.QUEUES_CREATE, payload);
341
+ return (_b = (_a = res.data) == null ? void 0 : _a.data) != null ? _b : res.data;
342
+ }, []);
343
+ return { queues, loading, fetchQueues, createQueue };
344
+ }
345
+
346
+ // call-control-sdk/lib/pages/campaigns/types.ts
347
+ var CAMPAIGN_TYPES = ["OUTBOUND_CAMPAIGN", "ABANDONED_CALLBACK"];
348
+ var DIALING_MODES_MAP = {
349
+ OUTBOUND_CAMPAIGN: ["PREVIEW", "AI_CALLBACK"],
350
+ ABANDONED_CALLBACK: ["PROGRESSIVE", "PREDICTIVE"]
351
+ };
352
+ var AGENT_TYPES = ["HUMAN", "AI", "HYBRID"];
353
+ var LEAD_PRIORITY_OPTIONS = [
354
+ { label: "HIGH", value: 10 },
355
+ { label: "MEDIUM", value: 5 },
356
+ { label: "LOW", value: 1 }
357
+ ];
358
+ var DAYS_OF_WEEK = [
359
+ { label: "Sun", value: 0 },
360
+ { label: "Mon", value: 1 },
361
+ { label: "Tue", value: 2 },
362
+ { label: "Wed", value: 3 },
363
+ { label: "Thu", value: 4 },
364
+ { label: "Fri", value: 5 },
365
+ { label: "Sat", value: 6 }
366
+ ];
367
+ var LEAD_STATUSES = [
368
+ "All states",
369
+ "PENDING",
370
+ "SCHEDULED",
371
+ "IN_PROGRESS",
372
+ "COMPLETED",
373
+ "FAILED",
374
+ "DO_NOT_CALL",
375
+ "INVALID",
376
+ "CANCELLED"
377
+ ];
378
+ var defaultFormData = {
379
+ name: "",
380
+ description: "",
381
+ campaignType: "OUTBOUND_CAMPAIGN",
382
+ dialingMode: "PREVIEW",
383
+ maxConcurrentCalls: 5,
384
+ callsPerAgent: 1,
385
+ startTime: "09:00",
386
+ endTime: "17:00",
387
+ daysOfWeek: [1, 2, 3, 4, 5],
388
+ timezone: "Asia/Kolkata",
389
+ scheduledStart: "",
390
+ scheduledEnd: "",
391
+ maxAttempts: 1,
392
+ retryIntervalMinutes: 15,
393
+ callerId: "",
394
+ ringTimeoutSeconds: 30,
395
+ answerTimeoutSeconds: 30,
396
+ agentType: "HUMAN",
397
+ aiBotId: null,
398
+ priority: 5,
399
+ settings: {},
400
+ queueLinks: []
401
+ };
402
+
403
+ // call-control-sdk/lib/pages/campaigns/styles.ts
404
+ var labelSx = {
405
+ fontWeight: 600,
406
+ fontSize: "0.85rem",
407
+ color: "#333",
408
+ mb: 0.5
409
+ };
410
+ var sectionTitleSx = {
411
+ fontWeight: 700,
412
+ fontSize: "1rem",
413
+ color: "#1a1a1a",
414
+ mb: 1.5,
415
+ mt: 0.5,
416
+ fontFamily: "poppins, Arial, sans-serif"
417
+ };
418
+ var headCellSx = {
419
+ fontFamily: "poppins, Arial, sans-serif",
420
+ bgcolor: "#f1f1f1",
421
+ color: "#333",
422
+ fontWeight: 600,
423
+ whiteSpace: "nowrap",
424
+ fontSize: "0.8rem",
425
+ py: "6px",
426
+ px: "12px"
427
+ };
428
+ var bodyCellSx = {
429
+ fontFamily: "poppins, Arial, sans-serif",
430
+ fontSize: "0.82rem",
431
+ py: "4px",
432
+ px: "12px"
433
+ };
434
+ var tableRowSx = {
435
+ "&:hover": { backgroundColor: "#f0f7f8" },
436
+ "&:last-child td, &:last-child th": { border: 0 }
437
+ };
438
+ var campaignCardBaseSx = {
439
+ p: 1.5,
440
+ mb: 0.75,
441
+ borderRadius: "12px",
442
+ cursor: "pointer",
443
+ border: "1px solid #e8e8e8",
444
+ backgroundColor: "#fff",
445
+ boxShadow: "0 1px 2px rgba(0,0,0,0.04)",
446
+ transition: "all 0.2s ease"
447
+ };
448
+ var campaignCardSelectedSx = __spreadProps(__spreadValues({}, campaignCardBaseSx), {
449
+ border: "2px solid #1A5F6C",
450
+ backgroundColor: "#f0f7f8",
451
+ boxShadow: "0 2px 8px rgba(26,95,108,0.12)"
452
+ });
453
+ var inputSx = {
454
+ "& .MuiOutlinedInput-root": {
455
+ borderRadius: "8px",
456
+ backgroundColor: "#fff",
457
+ "&:hover fieldset": { borderColor: "#1A5F6C" },
458
+ "&.Mui-focused fieldset": { borderColor: "#1A5F6C" }
459
+ }
460
+ };
461
+ var dialogHeaderSx = {
462
+ px: 2.5,
463
+ py: 1.5,
464
+ borderBottom: "1px solid #eee",
465
+ display: "flex",
466
+ alignItems: "center",
467
+ justifyContent: "space-between"
468
+ };
469
+ var dialogFooterSx = {
470
+ px: 2.5,
471
+ py: 1.5,
472
+ borderTop: "1px solid #eee",
473
+ display: "flex",
474
+ justifyContent: "flex-end",
475
+ gap: 1
476
+ };
477
+ var STATUS_COLORS = {
478
+ draft: "#9e9e9e",
479
+ active: "#4caf50",
480
+ paused: "#ff9800",
481
+ completed: "#2196f3",
482
+ archived: "#795548"
483
+ };
484
+ function statusChipSx(status) {
485
+ var _a;
486
+ const color = (_a = STATUS_COLORS[status == null ? void 0 : status.toLowerCase()]) != null ? _a : "#9e9e9e";
487
+ return {
488
+ height: 22,
489
+ fontSize: "0.68rem",
490
+ fontWeight: 700,
491
+ textTransform: "capitalize",
492
+ borderRadius: "6px",
493
+ backgroundColor: color + "18",
494
+ color,
495
+ border: `1px solid ${color}40`
496
+ };
497
+ }
498
+ function leadStatusChipSx(status) {
499
+ const s = status == null ? void 0 : status.toUpperCase();
500
+ return {
501
+ height: 22,
502
+ fontSize: "0.72rem",
503
+ fontWeight: 700,
504
+ textTransform: "capitalize",
505
+ borderRadius: "6px",
506
+ backgroundColor: s === "COMPLETED" ? "#e8f5e9" : s === "FAILED" ? "#ffebee" : s === "DIALING" ? "#e3f2fd" : "#f5f5f5",
507
+ color: s === "COMPLETED" ? "#2e7d32" : s === "FAILED" ? "#c62828" : s === "DIALING" ? "#1565c0" : "#666"
508
+ };
509
+ }
510
+ function leadPriorityChipSx(priority) {
511
+ const label = priority == null ? "\u2014" : priority >= 8 ? "HIGH" : priority >= 4 ? "MEDIUM" : "LOW";
512
+ return {
513
+ chip: {
514
+ height: 22,
515
+ fontSize: "0.72rem",
516
+ fontWeight: 700,
517
+ borderRadius: "6px",
518
+ backgroundColor: label === "HIGH" ? "#ffebee" : label === "MEDIUM" ? "#e3f2fd" : label === "LOW" ? "#e8f5e9" : "#f5f5f5",
519
+ color: label === "HIGH" ? "#c62828" : label === "MEDIUM" ? "#1565c0" : label === "LOW" ? "#2e7d32" : "#666"
520
+ },
521
+ label
522
+ };
523
+ }
524
+ function daychipSx(selected) {
525
+ return {
526
+ cursor: "pointer",
527
+ backgroundColor: selected ? "#1A5F6C" : "transparent",
528
+ color: selected ? "#fff" : "#333",
529
+ borderColor: "#1A5F6C",
530
+ fontWeight: 500,
531
+ "&:hover": {
532
+ backgroundColor: selected ? "#164e57" : "#E3F2F5"
533
+ }
534
+ };
535
+ }
536
+
537
+ // call-control-sdk/lib/pages/campaigns/index.tsx
538
+ import { Fragment, jsx as jsx2, jsxs } from "react/jsx-runtime";
539
+ function validatePhone(raw) {
540
+ const trimmed = (raw || "").trim();
541
+ if (!trimmed) return "Phone number is required";
542
+ const digits = trimmed.startsWith("+91") ? trimmed.slice(3) : trimmed.startsWith("91") && trimmed.length === 12 ? trimmed.slice(2) : trimmed;
543
+ if (!/^\d{10}$/.test(digits)) return "Must be 10 digits, 91+10, or +91+10";
544
+ return null;
545
+ }
546
+ function campaignToFormData(c) {
547
+ var _a, _b, _c, _d, _e, _f, _g;
548
+ return {
549
+ name: c.name || "",
550
+ description: c.description || "",
551
+ campaignType: (c.campaignType || "OUTBOUND_CAMPAIGN").toUpperCase(),
552
+ dialingMode: (c.dialingMode || "PREVIEW").toUpperCase(),
553
+ maxConcurrentCalls: (_a = c.maxConcurrentCalls) != null ? _a : 5,
554
+ callsPerAgent: (_b = c.callsPerAgent) != null ? _b : 1,
555
+ startTime: c.startTime ? c.startTime.slice(0, 5) : "09:00",
556
+ endTime: c.endTime ? c.endTime.slice(0, 5) : "17:00",
557
+ daysOfWeek: c.daysOfWeek || [1, 2, 3, 4, 5],
558
+ timezone: c.timezone || "Asia/Kolkata",
559
+ scheduledStart: c.scheduledStart || "",
560
+ scheduledEnd: c.scheduledEnd || "",
561
+ maxAttempts: (_c = c.maxAttempts) != null ? _c : 3,
562
+ retryIntervalMinutes: (_d = c.retryIntervalMinutes) != null ? _d : 15,
563
+ callerId: c.callerId || "",
564
+ ringTimeoutSeconds: (_e = c.ringTimeoutSeconds) != null ? _e : 30,
565
+ answerTimeoutSeconds: (_f = c.answerTimeoutSeconds) != null ? _f : 30,
566
+ agentType: c.agentType || "HUMAN",
567
+ aiBotId: null,
568
+ priority: (_g = c.priority) != null ? _g : 5,
569
+ settings: c.settings || {},
570
+ queueLinks: (c.campaignQueues || []).map((q) => {
571
+ var _a2, _b2;
572
+ return {
573
+ queueId: q.queueId,
574
+ priorityOverride: (_a2 = q.priorityOverride) != null ? _a2 : 1,
575
+ minWaitBeforeCallback: (_b2 = q.minWaitBeforeCallback) != null ? _b2 : 0
576
+ };
577
+ })
578
+ };
579
+ }
580
+ function BasicInfoTab({ formData, setFormData, isEditMode }) {
581
+ var _a;
582
+ const handleChange = (field, value) => {
583
+ setFormData((prev) => {
584
+ var _a2;
585
+ const updated = __spreadProps(__spreadValues({}, prev), { [field]: value });
586
+ if (field === "campaignType") {
587
+ updated.dialingMode = ((_a2 = DIALING_MODES_MAP[value]) == null ? void 0 : _a2[0]) || "";
588
+ }
589
+ return updated;
590
+ });
591
+ };
592
+ const mappedModes = DIALING_MODES_MAP[formData.campaignType] || [];
593
+ const availableModes = formData.dialingMode && !mappedModes.includes(formData.dialingMode) ? [formData.dialingMode, ...mappedModes] : mappedModes;
594
+ return /* @__PURE__ */ jsxs(Box, { sx: { p: 2.5 }, children: [
595
+ /* @__PURE__ */ jsx2(Typography, { sx: sectionTitleSx, children: "Basic Info" }),
596
+ /* @__PURE__ */ jsxs(Box, { sx: { display: "grid", gridTemplateColumns: { xs: "1fr", sm: "1.5fr 1fr", lg: "1.5fr 1fr 1fr" }, gap: 2, mb: 2 }, children: [
597
+ /* @__PURE__ */ jsxs(Box, { children: [
598
+ /* @__PURE__ */ jsxs(Typography, { sx: labelSx, children: [
599
+ "Campaign Name ",
600
+ /* @__PURE__ */ jsx2("span", { style: { color: "red" }, children: "*" })
601
+ ] }),
602
+ /* @__PURE__ */ jsx2(
603
+ TextField,
604
+ {
605
+ fullWidth: true,
606
+ size: "small",
607
+ value: formData.name,
608
+ onChange: (e) => handleChange("name", e.target.value),
609
+ sx: inputSx
610
+ }
611
+ )
612
+ ] }),
613
+ /* @__PURE__ */ jsxs(Box, { children: [
614
+ /* @__PURE__ */ jsxs(Typography, { sx: labelSx, children: [
615
+ "Campaign Type ",
616
+ /* @__PURE__ */ jsx2("span", { style: { color: "red" }, children: "*" })
617
+ ] }),
618
+ /* @__PURE__ */ jsx2(FormControl, { fullWidth: true, size: "small", children: /* @__PURE__ */ jsx2(
619
+ Select,
620
+ {
621
+ value: formData.campaignType,
622
+ onChange: (e) => handleChange("campaignType", e.target.value),
623
+ disabled: isEditMode,
624
+ children: CAMPAIGN_TYPES.map((t) => /* @__PURE__ */ jsx2(MenuItem, { value: t, children: t }, t))
625
+ }
626
+ ) })
627
+ ] })
628
+ ] }),
629
+ /* @__PURE__ */ jsxs(Box, { sx: { mb: 2 }, children: [
630
+ /* @__PURE__ */ jsx2(Typography, { sx: labelSx, children: "Description" }),
631
+ /* @__PURE__ */ jsx2(
632
+ TextField,
633
+ {
634
+ fullWidth: true,
635
+ size: "small",
636
+ multiline: true,
637
+ rows: 3,
638
+ value: formData.description,
639
+ onChange: (e) => handleChange("description", e.target.value),
640
+ sx: inputSx
641
+ }
642
+ )
643
+ ] }),
644
+ /* @__PURE__ */ jsxs(Box, { sx: { display: "grid", gridTemplateColumns: { xs: "1fr", sm: "1fr 1fr", lg: "1fr 1fr 1fr" }, gap: 2 }, children: [
645
+ /* @__PURE__ */ jsxs(Box, { children: [
646
+ /* @__PURE__ */ jsxs(Typography, { sx: labelSx, children: [
647
+ "Dialing Mode ",
648
+ /* @__PURE__ */ jsx2("span", { style: { color: "red" }, children: "*" })
649
+ ] }),
650
+ /* @__PURE__ */ jsx2(FormControl, { fullWidth: true, size: "small", children: /* @__PURE__ */ jsx2(
651
+ Select,
652
+ {
653
+ value: formData.dialingMode,
654
+ onChange: (e) => handleChange("dialingMode", e.target.value),
655
+ children: availableModes.map((m) => /* @__PURE__ */ jsx2(MenuItem, { value: m, children: m }, m))
656
+ }
657
+ ) })
658
+ ] }),
659
+ /* @__PURE__ */ jsxs(Box, { children: [
660
+ /* @__PURE__ */ jsx2(Typography, { sx: labelSx, children: "Priority" }),
661
+ /* @__PURE__ */ jsx2(FormControl, { fullWidth: true, size: "small", children: /* @__PURE__ */ jsx2(
662
+ Select,
663
+ {
664
+ value: (_a = formData.priority) != null ? _a : 5,
665
+ onChange: (e) => handleChange("priority", Number(e.target.value)),
666
+ children: LEAD_PRIORITY_OPTIONS.map((o) => /* @__PURE__ */ jsx2(MenuItem, { value: o.value, children: o.label }, o.label))
667
+ }
668
+ ) })
669
+ ] })
670
+ ] })
671
+ ] });
672
+ }
673
+ function DialingConfigTab({ formData, setFormData }) {
674
+ const handleChange = (field, value) => setFormData((prev) => __spreadProps(__spreadValues({}, prev), { [field]: value }));
675
+ return /* @__PURE__ */ jsxs(Box, { sx: { p: 2.5 }, children: [
676
+ /* @__PURE__ */ jsx2(Typography, { sx: sectionTitleSx, children: "Dialing Configuration" }),
677
+ /* @__PURE__ */ jsxs(Box, { sx: { display: "grid", gridTemplateColumns: { xs: "1fr", sm: "1fr 1fr", lg: "1fr 1fr 1fr" }, gap: 2 }, children: [
678
+ /* @__PURE__ */ jsxs(Box, { children: [
679
+ /* @__PURE__ */ jsxs(Typography, { sx: labelSx, children: [
680
+ "Max Concurrent Calls ",
681
+ /* @__PURE__ */ jsx2("span", { style: { color: "red" }, children: "*" })
682
+ ] }),
683
+ /* @__PURE__ */ jsx2(
684
+ TextField,
685
+ {
686
+ fullWidth: true,
687
+ size: "small",
688
+ type: "number",
689
+ value: formData.maxConcurrentCalls,
690
+ onChange: (e) => handleChange("maxConcurrentCalls", parseInt(e.target.value) || 1),
691
+ slotProps: { htmlInput: { min: 1 } },
692
+ sx: inputSx
693
+ }
694
+ )
695
+ ] }),
696
+ /* @__PURE__ */ jsxs(Box, { children: [
697
+ /* @__PURE__ */ jsx2(Typography, { sx: labelSx, children: "Calls Per Agent" }),
698
+ /* @__PURE__ */ jsx2(
699
+ TextField,
700
+ {
701
+ fullWidth: true,
702
+ size: "small",
703
+ type: "number",
704
+ value: formData.callsPerAgent,
705
+ onChange: (e) => handleChange("callsPerAgent", parseFloat(e.target.value) || 1),
706
+ slotProps: { htmlInput: { min: 0.1, step: 0.1 } },
707
+ sx: inputSx
708
+ }
709
+ )
710
+ ] }),
711
+ /* @__PURE__ */ jsxs(Box, { children: [
712
+ /* @__PURE__ */ jsx2(Typography, { sx: labelSx, children: "Ring Timeout (sec)" }),
713
+ /* @__PURE__ */ jsx2(
714
+ TextField,
715
+ {
716
+ fullWidth: true,
717
+ size: "small",
718
+ type: "number",
719
+ value: formData.ringTimeoutSeconds,
720
+ onChange: (e) => handleChange("ringTimeoutSeconds", parseInt(e.target.value) || 30),
721
+ slotProps: { htmlInput: { min: 5 } },
722
+ sx: inputSx
723
+ }
724
+ )
725
+ ] }),
726
+ /* @__PURE__ */ jsxs(Box, { children: [
727
+ /* @__PURE__ */ jsx2(Typography, { sx: labelSx, children: "Answer Timeout (sec)" }),
728
+ /* @__PURE__ */ jsx2(
729
+ TextField,
730
+ {
731
+ fullWidth: true,
732
+ size: "small",
733
+ type: "number",
734
+ value: formData.answerTimeoutSeconds,
735
+ onChange: (e) => handleChange("answerTimeoutSeconds", parseInt(e.target.value) || 0),
736
+ slotProps: { htmlInput: { min: 0 } },
737
+ sx: inputSx
738
+ }
739
+ )
740
+ ] }),
741
+ /* @__PURE__ */ jsxs(Box, { children: [
742
+ /* @__PURE__ */ jsxs(Typography, { sx: labelSx, children: [
743
+ "Max Attempts ",
744
+ /* @__PURE__ */ jsx2("span", { style: { color: "red" }, children: "*" })
745
+ ] }),
746
+ /* @__PURE__ */ jsx2(
747
+ TextField,
748
+ {
749
+ fullWidth: true,
750
+ size: "small",
751
+ type: "number",
752
+ value: formData.maxAttempts || "",
753
+ onChange: (e) => handleChange("maxAttempts", parseInt(e.target.value) || 0),
754
+ slotProps: { htmlInput: { min: 1 } },
755
+ sx: inputSx
756
+ }
757
+ )
758
+ ] }),
759
+ /* @__PURE__ */ jsxs(Box, { children: [
760
+ /* @__PURE__ */ jsx2(Typography, { sx: labelSx, children: "Retry Interval (min)" }),
761
+ /* @__PURE__ */ jsx2(
762
+ TextField,
763
+ {
764
+ fullWidth: true,
765
+ size: "small",
766
+ type: "number",
767
+ value: formData.retryIntervalMinutes,
768
+ onChange: (e) => handleChange("retryIntervalMinutes", parseInt(e.target.value) || 5),
769
+ slotProps: { htmlInput: { min: 1 } },
770
+ sx: inputSx
771
+ }
772
+ )
773
+ ] }),
774
+ /* @__PURE__ */ jsxs(Box, { children: [
775
+ /* @__PURE__ */ jsx2(Typography, { sx: labelSx, children: "Agent Type" }),
776
+ /* @__PURE__ */ jsx2(FormControl, { fullWidth: true, size: "small", children: /* @__PURE__ */ jsx2(
777
+ Select,
778
+ {
779
+ value: formData.agentType,
780
+ onChange: (e) => handleChange("agentType", e.target.value),
781
+ children: AGENT_TYPES.map((t) => /* @__PURE__ */ jsx2(MenuItem, { value: t, children: t }, t))
782
+ }
783
+ ) })
784
+ ] })
785
+ ] })
786
+ ] });
787
+ }
788
+ function ScheduleTab({ formData, setFormData }) {
789
+ const handleChange = (field, value) => setFormData((prev) => __spreadProps(__spreadValues({}, prev), { [field]: value }));
790
+ const toggleDay = (day) => setFormData((prev) => __spreadProps(__spreadValues({}, prev), {
791
+ daysOfWeek: prev.daysOfWeek.includes(day) ? prev.daysOfWeek.filter((d) => d !== day) : [...prev.daysOfWeek, day].sort()
792
+ }));
793
+ return /* @__PURE__ */ jsxs(Box, { sx: { p: 2.5 }, children: [
794
+ /* @__PURE__ */ jsx2(Typography, { sx: sectionTitleSx, children: "Operating Schedule" }),
795
+ /* @__PURE__ */ jsxs(Box, { sx: { display: "grid", gridTemplateColumns: { xs: "1fr", sm: "1fr 1fr", lg: "1fr 1fr 1fr" }, gap: 2, mb: 2 }, children: [
796
+ /* @__PURE__ */ jsxs(Box, { children: [
797
+ /* @__PURE__ */ jsxs(Typography, { sx: labelSx, children: [
798
+ "Start Time ",
799
+ /* @__PURE__ */ jsx2("span", { style: { color: "red" }, children: "*" })
800
+ ] }),
801
+ /* @__PURE__ */ jsx2(
802
+ TextField,
803
+ {
804
+ fullWidth: true,
805
+ size: "small",
806
+ type: "time",
807
+ value: formData.startTime,
808
+ onChange: (e) => handleChange("startTime", e.target.value),
809
+ sx: inputSx
810
+ }
811
+ )
812
+ ] }),
813
+ /* @__PURE__ */ jsxs(Box, { children: [
814
+ /* @__PURE__ */ jsxs(Typography, { sx: labelSx, children: [
815
+ "End Time ",
816
+ /* @__PURE__ */ jsx2("span", { style: { color: "red" }, children: "*" })
817
+ ] }),
818
+ /* @__PURE__ */ jsx2(
819
+ TextField,
820
+ {
821
+ fullWidth: true,
822
+ size: "small",
823
+ type: "time",
824
+ value: formData.endTime,
825
+ onChange: (e) => handleChange("endTime", e.target.value),
826
+ sx: inputSx
827
+ }
828
+ )
829
+ ] })
830
+ ] }),
831
+ /* @__PURE__ */ jsxs(Box, { sx: { mb: 2 }, children: [
832
+ /* @__PURE__ */ jsx2(Typography, { sx: labelSx, children: "Timezone" }),
833
+ /* @__PURE__ */ jsx2(FormControl, { fullWidth: true, size: "small", children: /* @__PURE__ */ jsx2(Select, { value: formData.timezone, onChange: (e) => handleChange("timezone", e.target.value), children: [
834
+ "Etc/UTC",
835
+ "US/Eastern",
836
+ "US/Central",
837
+ "US/Mountain",
838
+ "US/Pacific",
839
+ "Europe/London",
840
+ "Europe/Berlin",
841
+ "Asia/Kolkata",
842
+ "Asia/Tokyo",
843
+ "Australia/Sydney"
844
+ ].map((tz) => /* @__PURE__ */ jsx2(MenuItem, { value: tz, children: tz }, tz)) }) })
845
+ ] }),
846
+ /* @__PURE__ */ jsxs(Box, { children: [
847
+ /* @__PURE__ */ jsx2(Typography, { sx: labelSx, children: "Days of Week" }),
848
+ /* @__PURE__ */ jsx2(Box, { sx: { display: "flex", gap: 1, flexWrap: "wrap", mt: 0.5 }, children: DAYS_OF_WEEK.map((day) => /* @__PURE__ */ jsx2(
849
+ Chip,
850
+ {
851
+ label: day.label,
852
+ onClick: () => toggleDay(day.value),
853
+ variant: formData.daysOfWeek.includes(day.value) ? "filled" : "outlined",
854
+ size: "small",
855
+ sx: daychipSx(formData.daysOfWeek.includes(day.value))
856
+ },
857
+ day.value
858
+ )) })
859
+ ] })
860
+ ] });
861
+ }
862
+ function QueueLinkingTab({
863
+ formData,
864
+ setFormData,
865
+ editingCampaign,
866
+ parentQueueNameMap,
867
+ onQueuesRefreshed
868
+ }) {
869
+ const { showToast } = useToast();
870
+ const { fetchQueues, createQueue } = useQueues();
871
+ const queueLinks = formData.queueLinks || [];
872
+ const isEditMode = !!editingCampaign;
873
+ const campaignQueues = (editingCampaign == null ? void 0 : editingCampaign.campaignQueues) || [];
874
+ const [allQueues, setAllQueues] = useState2([]);
875
+ const [queueNames, setQueueNames] = useState2({});
876
+ const [selectedQueueIds, setSelectedQueueIds] = useState2([]);
877
+ const [createOpen, setCreateOpen] = useState2(false);
878
+ const [newQueue, setNewQueue] = useState2({ name: "", description: "" });
879
+ const [creatingQueue, setCreatingQueue] = useState2(false);
880
+ const loadQueues = useCallback2(async () => {
881
+ const list = await fetchQueues();
882
+ setAllQueues(list);
883
+ const map = {};
884
+ list.forEach((q) => {
885
+ map[q.id] = q.name;
886
+ });
887
+ setQueueNames(map);
888
+ onQueuesRefreshed == null ? void 0 : onQueuesRefreshed(list);
889
+ }, [fetchQueues, onQueuesRefreshed]);
890
+ useEffect(() => {
891
+ loadQueues();
892
+ }, [loadQueues]);
893
+ const handleCreateQueue = async () => {
894
+ var _a, _b;
895
+ if (!newQueue.name.trim()) {
896
+ showToast("Queue name is required", "warning");
897
+ return;
898
+ }
899
+ setCreatingQueue(true);
900
+ try {
901
+ await createQueue(newQueue);
902
+ showToast("Queue created successfully", "success");
903
+ setCreateOpen(false);
904
+ setNewQueue({ name: "", description: "" });
905
+ loadQueues();
906
+ } catch (err) {
907
+ showToast(((_b = (_a = err == null ? void 0 : err.response) == null ? void 0 : _a.data) == null ? void 0 : _b.message) || (err == null ? void 0 : err.message) || "Failed to create queue", "error");
908
+ } finally {
909
+ setCreatingQueue(false);
910
+ }
911
+ };
912
+ const linkedIds = new Set(
913
+ isEditMode ? campaignQueues.map((q) => q.queueId) : queueLinks.map((q) => q.queueId)
914
+ );
915
+ const availableQueues = allQueues.filter((q) => !linkedIds.has(q.id));
916
+ const handleAddQueues = () => {
917
+ if (selectedQueueIds.length === 0) return;
918
+ const newLinks = selectedQueueIds.map((qId) => ({
919
+ queueId: qId,
920
+ priorityOverride: 5,
921
+ minWaitBeforeCallback: 0
922
+ }));
923
+ setFormData((prev) => __spreadProps(__spreadValues({}, prev), { queueLinks: [...prev.queueLinks || [], ...newLinks] }));
924
+ showToast(`${selectedQueueIds.length} queue(s) added`, "success");
925
+ setSelectedQueueIds([]);
926
+ };
927
+ const handleRemoveQueue = (queueId) => {
928
+ setFormData((prev) => __spreadProps(__spreadValues({}, prev), {
929
+ queueLinks: (prev.queueLinks || []).filter((q) => q.queueId !== queueId)
930
+ }));
931
+ showToast("Queue removed", "success");
932
+ };
933
+ const handleCellUpdate = (queueId, field, value) => {
934
+ const numVal = parseInt(value) || 0;
935
+ setFormData((prev) => __spreadProps(__spreadValues({}, prev), {
936
+ queueLinks: (prev.queueLinks || []).map(
937
+ (q) => q.queueId === queueId ? __spreadProps(__spreadValues({}, q), { [field]: numVal }) : q
938
+ )
939
+ }));
940
+ };
941
+ return /* @__PURE__ */ jsxs(Box, { sx: { p: 2.5 }, children: [
942
+ createOpen && /* @__PURE__ */ jsx2(
943
+ Box,
944
+ {
945
+ sx: {
946
+ position: "fixed",
947
+ inset: 0,
948
+ zIndex: 1600,
949
+ backgroundColor: "rgba(0,0,0,0.45)",
950
+ display: "flex",
951
+ alignItems: "center",
952
+ justifyContent: "center"
953
+ },
954
+ onClick: (e) => e.stopPropagation(),
955
+ children: /* @__PURE__ */ jsxs(Paper, { elevation: 6, sx: { width: { xs: "90vw", sm: 420 }, borderRadius: "16px", overflow: "hidden", boxShadow: "0 8px 32px rgba(26,95,108,0.18)" }, children: [
956
+ /* @__PURE__ */ jsxs(Box, { sx: __spreadProps(__spreadValues({}, dialogHeaderSx), { backgroundColor: "#1A5F6C", color: "#fff" }), children: [
957
+ /* @__PURE__ */ jsx2(Typography, { fontWeight: 700, fontSize: "1rem", fontFamily: "poppins, Arial, sans-serif", children: "Create New Queue" }),
958
+ /* @__PURE__ */ jsx2(IconButton, { size: "small", onClick: () => !creatingQueue && setCreateOpen(false), sx: { color: "#fff" }, children: "\u2715" })
959
+ ] }),
960
+ /* @__PURE__ */ jsxs(Box, { sx: { p: 2.5, display: "flex", flexDirection: "column", gap: 1.5 }, children: [
961
+ /* @__PURE__ */ jsxs(Box, { children: [
962
+ /* @__PURE__ */ jsxs(Typography, { sx: labelSx, children: [
963
+ "Queue Name ",
964
+ /* @__PURE__ */ jsx2("span", { style: { color: "red" }, children: "*" })
965
+ ] }),
966
+ /* @__PURE__ */ jsx2(
967
+ TextField,
968
+ {
969
+ fullWidth: true,
970
+ size: "small",
971
+ value: newQueue.name,
972
+ onChange: (e) => setNewQueue(__spreadProps(__spreadValues({}, newQueue), { name: e.target.value })),
973
+ sx: inputSx
974
+ }
975
+ )
976
+ ] }),
977
+ /* @__PURE__ */ jsxs(Box, { children: [
978
+ /* @__PURE__ */ jsx2(Typography, { sx: labelSx, children: "Description" }),
979
+ /* @__PURE__ */ jsx2(
980
+ TextField,
981
+ {
982
+ fullWidth: true,
983
+ size: "small",
984
+ multiline: true,
985
+ rows: 3,
986
+ value: newQueue.description,
987
+ onChange: (e) => setNewQueue(__spreadProps(__spreadValues({}, newQueue), { description: e.target.value })),
988
+ sx: inputSx
989
+ }
990
+ )
991
+ ] })
992
+ ] }),
993
+ /* @__PURE__ */ jsxs(Box, { sx: dialogFooterSx, children: [
994
+ /* @__PURE__ */ jsx2(SDKButton, { variant: "cancel", onClick: () => setCreateOpen(false), disabled: creatingQueue, children: "Cancel" }),
995
+ /* @__PURE__ */ jsx2(
996
+ SDKButton,
997
+ {
998
+ onClick: handleCreateQueue,
999
+ disabled: creatingQueue,
1000
+ startIcon: creatingQueue ? /* @__PURE__ */ jsx2(CircularProgress, { size: 14, color: "inherit" }) : void 0,
1001
+ children: "Create"
1002
+ }
1003
+ )
1004
+ ] })
1005
+ ] })
1006
+ }
1007
+ ),
1008
+ /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: "center", justifyContent: "space-between", mb: 2 }, children: [
1009
+ /* @__PURE__ */ jsx2(Typography, { sx: sectionTitleSx, children: "Linked Queues" }),
1010
+ /* @__PURE__ */ jsx2(SDKButton, { startIcon: /* @__PURE__ */ jsx2(AddIcon, {}), onClick: () => setCreateOpen(true), children: "Create New Queue" })
1011
+ ] }),
1012
+ /* @__PURE__ */ jsxs(Box, { sx: {
1013
+ display: "flex",
1014
+ alignItems: { xs: "stretch", sm: "center" },
1015
+ flexDirection: { xs: "column", sm: "row" },
1016
+ gap: 1.5,
1017
+ mb: 2
1018
+ }, children: [
1019
+ /* @__PURE__ */ jsx2(FormControl, { size: "small", sx: { flex: 2 }, children: /* @__PURE__ */ jsx2(
1020
+ Select,
1021
+ {
1022
+ multiple: true,
1023
+ value: selectedQueueIds,
1024
+ onChange: (e) => setSelectedQueueIds(e.target.value),
1025
+ displayEmpty: true,
1026
+ renderValue: (selected) => selected.length === 0 ? /* @__PURE__ */ jsx2(Typography, { sx: { color: "#999", fontSize: "0.85rem" }, children: "Select queues to link" }) : /* @__PURE__ */ jsx2(Box, { sx: { display: "flex", flexWrap: "wrap", gap: 0.5 }, children: selected.map((id) => /* @__PURE__ */ jsx2(
1027
+ Chip,
1028
+ {
1029
+ size: "small",
1030
+ label: queueNames[id] || parentQueueNameMap[id] || `Queue #${id}`,
1031
+ sx: { height: 22, fontSize: "0.75rem", fontWeight: 600, backgroundColor: "#e0f2f1", color: "#00695c" }
1032
+ },
1033
+ id
1034
+ )) }),
1035
+ sx: {
1036
+ borderRadius: "8px",
1037
+ fontSize: "0.85rem",
1038
+ "& .MuiSelect-select": { display: "flex", flexWrap: "wrap", gap: 0.5, py: 0.75 }
1039
+ },
1040
+ MenuProps: {
1041
+ PaperProps: { sx: { maxHeight: 250, borderRadius: "8px", mt: 0.5, boxShadow: "0 4px 20px rgba(0,0,0,0.12)" } }
1042
+ },
1043
+ children: availableQueues.length === 0 ? /* @__PURE__ */ jsx2(MenuItem, { value: "", disabled: true, children: "No available queues" }) : availableQueues.map((q) => /* @__PURE__ */ jsxs(MenuItem, { value: q.id, sx: { py: 0.75, px: 1.5, fontSize: "0.85rem" }, children: [
1044
+ /* @__PURE__ */ jsx2(
1045
+ Checkbox,
1046
+ {
1047
+ size: "small",
1048
+ checked: selectedQueueIds.includes(q.id),
1049
+ sx: { p: 0.5, mr: 1, color: "#1A5F6C", "&.Mui-checked": { color: "#1A5F6C" } }
1050
+ }
1051
+ ),
1052
+ q.name,
1053
+ " (ID: ",
1054
+ q.id,
1055
+ ")"
1056
+ ] }, q.id))
1057
+ }
1058
+ ) }),
1059
+ /* @__PURE__ */ jsx2(SDKButton, { onClick: handleAddQueues, disabled: selectedQueueIds.length === 0, sx: { whiteSpace: "nowrap" }, children: "Add To List" })
1060
+ ] }),
1061
+ queueLinks.length === 0 ? /* @__PURE__ */ jsx2(Paper, { variant: "outlined", sx: { p: 3, textAlign: "center", borderRadius: 2, borderStyle: "dashed" }, children: /* @__PURE__ */ jsx2(Typography, { sx: { color: "#999", fontSize: "0.9rem" }, children: "No queues linked yet. Select queues above to add." }) }) : /* @__PURE__ */ jsx2(TableContainer, { component: Paper, variant: "outlined", sx: { borderRadius: 2, overflow: "visible" }, children: /* @__PURE__ */ jsxs(Table, { size: "small", children: [
1062
+ /* @__PURE__ */ jsx2(TableHead, { children: /* @__PURE__ */ jsxs(TableRow, { sx: { backgroundColor: "#f1f1f1" }, children: [
1063
+ /* @__PURE__ */ jsx2(TableCell, { sx: headCellSx, children: "Queue Name" }),
1064
+ /* @__PURE__ */ jsx2(TableCell, { sx: headCellSx, children: "Priority Override" }),
1065
+ /* @__PURE__ */ jsx2(TableCell, { sx: headCellSx, children: "Min Wait Before Callback" }),
1066
+ /* @__PURE__ */ jsx2(TableCell, { sx: __spreadProps(__spreadValues({}, headCellSx), { textAlign: "right" }), children: "Action" })
1067
+ ] }) }),
1068
+ /* @__PURE__ */ jsx2(TableBody, { children: queueLinks.map((q) => {
1069
+ var _a;
1070
+ return /* @__PURE__ */ jsxs(TableRow, { sx: tableRowSx, children: [
1071
+ /* @__PURE__ */ jsx2(TableCell, { sx: bodyCellSx, children: queueNames[q.queueId] || parentQueueNameMap[q.queueId] || `Queue #${q.queueId}` }),
1072
+ /* @__PURE__ */ jsx2(TableCell, { sx: bodyCellSx, children: /* @__PURE__ */ jsx2(FormControl, { size: "small", sx: { width: 120 }, children: /* @__PURE__ */ jsx2(
1073
+ Select,
1074
+ {
1075
+ value: (_a = q.priorityOverride) != null ? _a : 5,
1076
+ onChange: (e) => handleCellUpdate(q.queueId, "priorityOverride", String(e.target.value)),
1077
+ children: LEAD_PRIORITY_OPTIONS.map((opt) => /* @__PURE__ */ jsx2(MenuItem, { value: opt.value, children: opt.label }, opt.label))
1078
+ }
1079
+ ) }) }),
1080
+ /* @__PURE__ */ jsx2(TableCell, { sx: bodyCellSx, children: /* @__PURE__ */ jsx2(
1081
+ TextField,
1082
+ {
1083
+ size: "small",
1084
+ type: "number",
1085
+ value: q.minWaitBeforeCallback,
1086
+ onChange: (e) => handleCellUpdate(q.queueId, "minWaitBeforeCallback", e.target.value),
1087
+ slotProps: {
1088
+ htmlInput: { min: 0, style: { fontSize: "0.85rem", padding: "4px 8px" } },
1089
+ input: {
1090
+ endAdornment: /* @__PURE__ */ jsx2(InputAdornment, { position: "end", children: /* @__PURE__ */ jsx2(Typography, { sx: { fontSize: "0.75rem", color: "#666" }, children: "s" }) })
1091
+ }
1092
+ },
1093
+ sx: { width: 100, "& .MuiOutlinedInput-root": { borderRadius: "4px" } }
1094
+ }
1095
+ ) }),
1096
+ /* @__PURE__ */ jsx2(TableCell, { sx: __spreadProps(__spreadValues({}, bodyCellSx), { textAlign: "right" }), children: /* @__PURE__ */ jsx2(SDKButton, { variant: "danger", size: "small", onClick: () => handleRemoveQueue(q.queueId), children: "Remove" }) })
1097
+ ] }, q.queueId);
1098
+ }) })
1099
+ ] }) })
1100
+ ] });
1101
+ }
1102
+ function LeadsTabInDialog({
1103
+ editingCampaign,
1104
+ onLeadsChange
1105
+ }) {
1106
+ var _a;
1107
+ const { showToast } = useToast();
1108
+ const { leads, fetchLeads, createLead, uploadLeadsExcel, downloadLeadTemplate } = useLeads();
1109
+ const [adding, setAdding] = useState2(false);
1110
+ const [leadForm, setLeadForm] = useState2({ phoneNumber: "", callerName: "", priority: 5 });
1111
+ const [search, setSearch] = useState2("");
1112
+ const [uploadFile, setUploadFile] = useState2(null);
1113
+ const [uploading, setUploading] = useState2(false);
1114
+ const uploadRef = useRef(null);
1115
+ useEffect(() => {
1116
+ if (editingCampaign) fetchLeads(editingCampaign.id, { page: 1, pageSize: 100 });
1117
+ }, [editingCampaign, fetchLeads]);
1118
+ if (!editingCampaign) {
1119
+ return /* @__PURE__ */ jsx2(Box, { sx: { p: 4, textAlign: "center" }, children: /* @__PURE__ */ jsx2(Typography, { sx: { color: "#999", fontSize: "0.9rem", fontFamily: "poppins, Arial, sans-serif" }, children: "Save the campaign first, then you can add leads." }) });
1120
+ }
1121
+ const handleAddLead = async () => {
1122
+ var _a2, _b, _c;
1123
+ const err = validatePhone(leadForm.phoneNumber);
1124
+ if (err) {
1125
+ showToast(err, "warning");
1126
+ return;
1127
+ }
1128
+ setAdding(true);
1129
+ try {
1130
+ await createLead(editingCampaign.id, __spreadProps(__spreadValues({}, leadForm), { priority: (_a2 = leadForm.priority) != null ? _a2 : 5 }));
1131
+ showToast("Lead added successfully", "success");
1132
+ setLeadForm({ phoneNumber: "", callerName: "", priority: 5 });
1133
+ fetchLeads(editingCampaign.id, { page: 1, pageSize: 100 });
1134
+ onLeadsChange == null ? void 0 : onLeadsChange();
1135
+ } catch (err2) {
1136
+ showToast(((_c = (_b = err2 == null ? void 0 : err2.response) == null ? void 0 : _b.data) == null ? void 0 : _c.message) || (err2 == null ? void 0 : err2.message) || "Failed to add lead", "error");
1137
+ } finally {
1138
+ setAdding(false);
1139
+ }
1140
+ };
1141
+ const handleUpload = async () => {
1142
+ var _a2, _b;
1143
+ if (!uploadFile) return;
1144
+ setUploading(true);
1145
+ try {
1146
+ await uploadLeadsExcel(editingCampaign.id, uploadFile);
1147
+ showToast("Leads uploaded successfully", "success");
1148
+ setUploadFile(null);
1149
+ if (uploadRef.current) uploadRef.current.value = "";
1150
+ fetchLeads(editingCampaign.id, { page: 1, pageSize: 100 });
1151
+ onLeadsChange == null ? void 0 : onLeadsChange();
1152
+ } catch (err) {
1153
+ showToast(((_b = (_a2 = err == null ? void 0 : err.response) == null ? void 0 : _a2.data) == null ? void 0 : _b.message) || (err == null ? void 0 : err.message) || "Failed to upload leads", "error");
1154
+ } finally {
1155
+ setUploading(false);
1156
+ }
1157
+ };
1158
+ const handleDownload = async () => {
1159
+ var _a2, _b;
1160
+ try {
1161
+ await downloadLeadTemplate(editingCampaign.id);
1162
+ } catch (err) {
1163
+ showToast(((_b = (_a2 = err == null ? void 0 : err.response) == null ? void 0 : _a2.data) == null ? void 0 : _b.message) || (err == null ? void 0 : err.message) || "Download failed", "error");
1164
+ }
1165
+ };
1166
+ const filtered = leads.filter(
1167
+ (l) => {
1168
+ var _a2, _b;
1169
+ return !search || ((_a2 = l.callerName) == null ? void 0 : _a2.toLowerCase().includes(search.toLowerCase())) || ((_b = l.phoneNumber) == null ? void 0 : _b.includes(search));
1170
+ }
1171
+ );
1172
+ return /* @__PURE__ */ jsxs(Box, { sx: { p: 2.5 }, children: [
1173
+ /* @__PURE__ */ jsx2(Typography, { sx: sectionTitleSx, children: "Add Lead Manually" }),
1174
+ /* @__PURE__ */ jsxs(Paper, { variant: "outlined", sx: { p: 2, mb: 2.5, borderRadius: 2 }, children: [
1175
+ /* @__PURE__ */ jsxs(Box, { sx: { display: "grid", gridTemplateColumns: { xs: "1fr", sm: "1fr 1fr", lg: "1fr 1fr 1fr" }, gap: 2, mb: 2 }, children: [
1176
+ /* @__PURE__ */ jsxs(Box, { children: [
1177
+ /* @__PURE__ */ jsxs(Typography, { sx: labelSx, children: [
1178
+ "Phone Number ",
1179
+ /* @__PURE__ */ jsx2("span", { style: { color: "red" }, children: "*" })
1180
+ ] }),
1181
+ /* @__PURE__ */ jsx2(
1182
+ TextField,
1183
+ {
1184
+ fullWidth: true,
1185
+ size: "small",
1186
+ placeholder: "+1234567890",
1187
+ value: leadForm.phoneNumber,
1188
+ onChange: (e) => setLeadForm((p) => __spreadProps(__spreadValues({}, p), { phoneNumber: e.target.value.replace(/[^0-9+\-() ]/g, "") })),
1189
+ error: !!leadForm.phoneNumber && !!validatePhone(leadForm.phoneNumber),
1190
+ helperText: leadForm.phoneNumber ? validatePhone(leadForm.phoneNumber) || "" : "",
1191
+ sx: inputSx
1192
+ }
1193
+ )
1194
+ ] }),
1195
+ /* @__PURE__ */ jsxs(Box, { children: [
1196
+ /* @__PURE__ */ jsx2(Typography, { sx: labelSx, children: "Caller Name" }),
1197
+ /* @__PURE__ */ jsx2(
1198
+ TextField,
1199
+ {
1200
+ fullWidth: true,
1201
+ size: "small",
1202
+ value: leadForm.callerName || "",
1203
+ onChange: (e) => setLeadForm((p) => __spreadProps(__spreadValues({}, p), { callerName: e.target.value })),
1204
+ sx: inputSx
1205
+ }
1206
+ )
1207
+ ] }),
1208
+ /* @__PURE__ */ jsxs(Box, { children: [
1209
+ /* @__PURE__ */ jsx2(Typography, { sx: labelSx, children: "Source" }),
1210
+ /* @__PURE__ */ jsx2(
1211
+ TextField,
1212
+ {
1213
+ fullWidth: true,
1214
+ size: "small",
1215
+ value: leadForm.source || "",
1216
+ onChange: (e) => setLeadForm((p) => __spreadProps(__spreadValues({}, p), { source: e.target.value })),
1217
+ sx: inputSx
1218
+ }
1219
+ )
1220
+ ] }),
1221
+ /* @__PURE__ */ jsxs(Box, { children: [
1222
+ /* @__PURE__ */ jsx2(Typography, { sx: labelSx, children: "Priority" }),
1223
+ /* @__PURE__ */ jsx2(FormControl, { fullWidth: true, size: "small", children: /* @__PURE__ */ jsx2(
1224
+ Select,
1225
+ {
1226
+ value: (_a = leadForm.priority) != null ? _a : 5,
1227
+ onChange: (e) => setLeadForm((p) => __spreadProps(__spreadValues({}, p), { priority: Number(e.target.value) })),
1228
+ children: LEAD_PRIORITY_OPTIONS.map((opt) => /* @__PURE__ */ jsx2(MenuItem, { value: opt.value, children: opt.label }, opt.label))
1229
+ }
1230
+ ) })
1231
+ ] }),
1232
+ /* @__PURE__ */ jsxs(Box, { sx: { gridColumn: "1 / -1" }, children: [
1233
+ /* @__PURE__ */ jsx2(Typography, { sx: labelSx, children: "Notes" }),
1234
+ /* @__PURE__ */ jsx2(
1235
+ TextField,
1236
+ {
1237
+ fullWidth: true,
1238
+ size: "small",
1239
+ multiline: true,
1240
+ minRows: 2,
1241
+ maxRows: 8,
1242
+ value: leadForm.notes || "",
1243
+ onChange: (e) => setLeadForm((p) => __spreadProps(__spreadValues({}, p), { notes: e.target.value })),
1244
+ sx: inputSx
1245
+ }
1246
+ )
1247
+ ] })
1248
+ ] }),
1249
+ /* @__PURE__ */ jsx2(Box, { sx: { display: "flex", justifyContent: "flex-end" }, children: /* @__PURE__ */ jsx2(
1250
+ SDKButton,
1251
+ {
1252
+ onClick: handleAddLead,
1253
+ disabled: adding,
1254
+ startIcon: adding ? /* @__PURE__ */ jsx2(CircularProgress, { size: 14, color: "inherit" }) : void 0,
1255
+ children: "Add Lead"
1256
+ }
1257
+ ) })
1258
+ ] }),
1259
+ /* @__PURE__ */ jsx2(Typography, { sx: sectionTitleSx, children: "Upload Leads from File" }),
1260
+ /* @__PURE__ */ jsxs(Paper, { variant: "outlined", sx: { p: 2, mb: 2.5, borderRadius: 2 }, children: [
1261
+ /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: "center", gap: 1.5, flexWrap: "wrap" }, children: [
1262
+ /* @__PURE__ */ jsx2(SDKButton, { variant: "outlined", startIcon: /* @__PURE__ */ jsx2(UploadFileIcon, {}), onClick: () => {
1263
+ var _a2;
1264
+ return (_a2 = uploadRef.current) == null ? void 0 : _a2.click();
1265
+ }, children: "Choose File" }),
1266
+ /* @__PURE__ */ jsx2(
1267
+ "input",
1268
+ {
1269
+ ref: uploadRef,
1270
+ type: "file",
1271
+ accept: ".csv,.xlsx,.xls",
1272
+ hidden: true,
1273
+ onChange: (e) => {
1274
+ var _a2;
1275
+ const f = (_a2 = e.target.files) == null ? void 0 : _a2[0];
1276
+ if (!f) return;
1277
+ if (![".csv", ".xlsx", ".xls"].some((ext) => f.name.toLowerCase().endsWith(ext))) {
1278
+ showToast("Please select a CSV or Excel file", "warning");
1279
+ return;
1280
+ }
1281
+ setUploadFile(f);
1282
+ }
1283
+ }
1284
+ ),
1285
+ /* @__PURE__ */ jsx2(Typography, { sx: { fontSize: "0.82rem", color: "#666", flex: 1, fontFamily: "poppins, Arial, sans-serif" }, children: uploadFile ? uploadFile.name : "No file chosen" }),
1286
+ uploadFile && /* @__PURE__ */ jsx2(
1287
+ SDKButton,
1288
+ {
1289
+ variant: "cancel",
1290
+ size: "small",
1291
+ onClick: () => {
1292
+ setUploadFile(null);
1293
+ if (uploadRef.current) uploadRef.current.value = "";
1294
+ },
1295
+ children: "Clear"
1296
+ }
1297
+ ),
1298
+ /* @__PURE__ */ jsx2(SDKButton, { variant: "outlined", startIcon: /* @__PURE__ */ jsx2(DownloadIcon, {}), onClick: handleDownload, children: "Sample Template" })
1299
+ ] }),
1300
+ /* @__PURE__ */ jsx2(Box, { sx: { display: "flex", justifyContent: "flex-end", mt: 1.5 }, children: /* @__PURE__ */ jsx2(
1301
+ SDKButton,
1302
+ {
1303
+ onClick: handleUpload,
1304
+ disabled: uploading || !uploadFile,
1305
+ startIcon: uploading ? /* @__PURE__ */ jsx2(CircularProgress, { size: 14, color: "inherit" }) : void 0,
1306
+ children: "Upload"
1307
+ }
1308
+ ) })
1309
+ ] }),
1310
+ /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: "center", justifyContent: "space-between", mb: 1.5 }, children: [
1311
+ /* @__PURE__ */ jsxs(Typography, { sx: sectionTitleSx, children: [
1312
+ "Leads (",
1313
+ leads.length,
1314
+ ")"
1315
+ ] }),
1316
+ /* @__PURE__ */ jsx2(
1317
+ OutlinedInput,
1318
+ {
1319
+ size: "small",
1320
+ value: search,
1321
+ onChange: (e) => setSearch(e.target.value),
1322
+ placeholder: "Search...",
1323
+ sx: { width: 200, fontSize: "0.85rem", height: 34, borderRadius: "20px" },
1324
+ startAdornment: /* @__PURE__ */ jsx2(InputAdornment, { position: "start", children: /* @__PURE__ */ jsx2(SearchIcon, { sx: { fontSize: 16, color: "#aaa" } }) })
1325
+ }
1326
+ )
1327
+ ] }),
1328
+ filtered.length === 0 ? /* @__PURE__ */ jsx2(Paper, { variant: "outlined", sx: { p: 3, textAlign: "center", borderRadius: 2, borderStyle: "dashed" }, children: /* @__PURE__ */ jsx2(Typography, { sx: { color: "#999", fontSize: "0.9rem" }, children: leads.length === 0 ? "No leads yet." : "No leads match your search." }) }) : /* @__PURE__ */ jsx2(TableContainer, { component: Paper, variant: "outlined", sx: { borderRadius: 2, overflow: "visible" }, children: /* @__PURE__ */ jsxs(Table, { size: "small", children: [
1329
+ /* @__PURE__ */ jsx2(TableHead, { children: /* @__PURE__ */ jsxs(TableRow, { sx: { backgroundColor: "#f1f1f1" }, children: [
1330
+ /* @__PURE__ */ jsx2(TableCell, { sx: headCellSx, children: "Phone Number" }),
1331
+ /* @__PURE__ */ jsx2(TableCell, { sx: headCellSx, children: "Status" }),
1332
+ /* @__PURE__ */ jsx2(TableCell, { sx: headCellSx, children: "Source" }),
1333
+ /* @__PURE__ */ jsx2(TableCell, { sx: headCellSx, children: "Attempts" }),
1334
+ /* @__PURE__ */ jsx2(TableCell, { sx: headCellSx, children: "Last Outcome" }),
1335
+ /* @__PURE__ */ jsx2(TableCell, { sx: headCellSx, children: "Notes" }),
1336
+ /* @__PURE__ */ jsx2(TableCell, { sx: headCellSx, children: "Outcome" })
1337
+ ] }) }),
1338
+ /* @__PURE__ */ jsx2(TableBody, { children: filtered.map((lead) => {
1339
+ var _a2;
1340
+ return /* @__PURE__ */ jsxs(TableRow, { sx: tableRowSx, children: [
1341
+ /* @__PURE__ */ jsx2(TableCell, { sx: bodyCellSx, children: lead.phoneNumber }),
1342
+ /* @__PURE__ */ jsx2(TableCell, { sx: bodyCellSx, children: /* @__PURE__ */ jsx2(Chip, { label: lead.status || "pending", size: "small", sx: leadStatusChipSx(lead.status) }) }),
1343
+ /* @__PURE__ */ jsx2(TableCell, { sx: bodyCellSx, children: lead.source || "" }),
1344
+ /* @__PURE__ */ jsx2(TableCell, { sx: bodyCellSx, children: (_a2 = lead.attemptCount) != null ? _a2 : 0 }),
1345
+ /* @__PURE__ */ jsx2(TableCell, { sx: bodyCellSx, children: lead.lastOutcome || "" }),
1346
+ /* @__PURE__ */ jsx2(TableCell, { sx: __spreadProps(__spreadValues({}, bodyCellSx), { maxWidth: 200, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }), children: lead.notes ? /* @__PURE__ */ jsx2(Tooltip, { title: lead.notes, arrow: true, placement: "top", children: /* @__PURE__ */ jsx2("span", { children: lead.notes }) }) : "" }),
1347
+ /* @__PURE__ */ jsx2(TableCell, { sx: bodyCellSx, children: lead.lastReason || "" })
1348
+ ] }, lead.id);
1349
+ }) })
1350
+ ] }) })
1351
+ ] });
1352
+ }
1353
+ var CampaignDialog = memo(function CampaignDialog2({
1354
+ open,
1355
+ editingCampaign,
1356
+ formData,
1357
+ setFormData,
1358
+ saving,
1359
+ onSave,
1360
+ onClose,
1361
+ parentQueueNameMap,
1362
+ onQueuesRefreshed,
1363
+ onLeadsChange
1364
+ }) {
1365
+ const { showToast } = useToast();
1366
+ const [tab, setTab] = useState2(0);
1367
+ useEffect(() => {
1368
+ if (open) setTab(0);
1369
+ }, [open]);
1370
+ if (!open) return null;
1371
+ const TAB_LABELS = ["Basic Info", "Dialing Configuration", "Schedule & Operating Hours", "Queue Linking", "Leads"];
1372
+ const lastSaveTab = 3;
1373
+ const leadsTabDisabled = !editingCampaign;
1374
+ const isDirty = !editingCampaign || JSON.stringify(formData) !== JSON.stringify(campaignToFormData(editingCampaign));
1375
+ const validateTab = (t) => {
1376
+ if (t === 0) {
1377
+ if (!formData.name.trim()) {
1378
+ showToast("Please fill Campaign Name", "warning");
1379
+ return false;
1380
+ }
1381
+ if (!formData.campaignType) {
1382
+ showToast("Please fill Campaign Type", "warning");
1383
+ return false;
1384
+ }
1385
+ if (!formData.dialingMode) {
1386
+ showToast("Please fill Dialing Mode", "warning");
1387
+ return false;
1388
+ }
1389
+ }
1390
+ if (t === 1) {
1391
+ if (!formData.maxConcurrentCalls) {
1392
+ showToast("Please fill Max Concurrent Calls", "warning");
1393
+ return false;
1394
+ }
1395
+ if (!formData.maxAttempts) {
1396
+ showToast("Please fill Max Attempts", "warning");
1397
+ return false;
1398
+ }
1399
+ }
1400
+ if (t === 2) {
1401
+ if (!formData.startTime) {
1402
+ showToast("Please fill Start Time", "warning");
1403
+ return false;
1404
+ }
1405
+ if (!formData.endTime) {
1406
+ showToast("Please fill End Time", "warning");
1407
+ return false;
1408
+ }
1409
+ }
1410
+ return true;
1411
+ };
1412
+ const handleTabChange = (newTab) => {
1413
+ if (newTab === 4 && leadsTabDisabled) return;
1414
+ if (newTab > tab && !validateTab(tab)) return;
1415
+ setTab(newTab);
1416
+ };
1417
+ return /* @__PURE__ */ jsx2(
1418
+ Box,
1419
+ {
1420
+ sx: {
1421
+ position: "fixed",
1422
+ inset: 0,
1423
+ zIndex: 1300,
1424
+ backgroundColor: "rgba(0,0,0,0.45)",
1425
+ display: "flex",
1426
+ alignItems: "center",
1427
+ justifyContent: "center"
1428
+ },
1429
+ onClick: (e) => e.stopPropagation(),
1430
+ children: /* @__PURE__ */ jsxs(
1431
+ Paper,
1432
+ {
1433
+ elevation: 6,
1434
+ sx: {
1435
+ width: { xs: "95vw", sm: 720, md: 880 },
1436
+ maxHeight: "92vh",
1437
+ display: "flex",
1438
+ flexDirection: "column",
1439
+ borderRadius: "16px",
1440
+ overflow: "hidden",
1441
+ boxShadow: "0 8px 32px rgba(26,95,108,0.18)"
1442
+ },
1443
+ children: [
1444
+ /* @__PURE__ */ jsxs(Box, { sx: __spreadProps(__spreadValues({}, dialogHeaderSx), {
1445
+ backgroundColor: "#1A5F6C",
1446
+ color: "#fff",
1447
+ "& .MuiIconButton-root": { color: "#fff" }
1448
+ }), children: [
1449
+ /* @__PURE__ */ jsx2(Typography, { fontWeight: 700, fontSize: "1rem", fontFamily: "poppins, Arial, sans-serif", children: editingCampaign ? "Edit Campaign" : "Create Campaign" }),
1450
+ /* @__PURE__ */ jsx2(IconButton, { size: "small", onClick: onClose, sx: { color: "#fff" }, children: "\u2715" })
1451
+ ] }),
1452
+ /* @__PURE__ */ jsx2(
1453
+ Tabs,
1454
+ {
1455
+ value: tab,
1456
+ onChange: (_, v) => handleTabChange(v),
1457
+ variant: "scrollable",
1458
+ scrollButtons: "auto",
1459
+ sx: {
1460
+ borderBottom: "1px solid #eee",
1461
+ minHeight: 44,
1462
+ "& .MuiTab-root": {
1463
+ fontSize: "0.85rem",
1464
+ minHeight: 44,
1465
+ textTransform: "none",
1466
+ fontWeight: 600,
1467
+ fontFamily: "poppins, Arial, sans-serif"
1468
+ },
1469
+ "& .Mui-selected": { color: "#1A5F6C" }
1470
+ },
1471
+ TabIndicatorProps: { style: { height: 3, backgroundColor: "#1A5F6C", borderRadius: "3px 3px 0 0" } },
1472
+ children: TAB_LABELS.map((label, i) => /* @__PURE__ */ jsx2(Tab, { label, value: i, disabled: i === 4 && leadsTabDisabled }, label))
1473
+ }
1474
+ ),
1475
+ /* @__PURE__ */ jsxs(Box, { sx: { flex: 1, overflowY: "auto", minHeight: 380 }, children: [
1476
+ tab === 0 && /* @__PURE__ */ jsx2(BasicInfoTab, { formData, setFormData, isEditMode: !!editingCampaign }),
1477
+ tab === 1 && /* @__PURE__ */ jsx2(DialingConfigTab, { formData, setFormData }),
1478
+ tab === 2 && /* @__PURE__ */ jsx2(ScheduleTab, { formData, setFormData }),
1479
+ tab === 3 && /* @__PURE__ */ jsx2(
1480
+ QueueLinkingTab,
1481
+ {
1482
+ formData,
1483
+ setFormData,
1484
+ editingCampaign,
1485
+ parentQueueNameMap,
1486
+ onQueuesRefreshed
1487
+ }
1488
+ ),
1489
+ tab === 4 && /* @__PURE__ */ jsx2(
1490
+ LeadsTabInDialog,
1491
+ {
1492
+ editingCampaign,
1493
+ onLeadsChange
1494
+ }
1495
+ )
1496
+ ] }),
1497
+ /* @__PURE__ */ jsxs(Box, { sx: dialogFooterSx, children: [
1498
+ /* @__PURE__ */ jsx2(SDKButton, { variant: "cancel", onClick: onClose, children: "Cancel" }),
1499
+ tab > 0 && /* @__PURE__ */ jsx2(SDKButton, { variant: "outlined", onClick: () => setTab((t) => t - 1), children: "Back" }),
1500
+ tab < lastSaveTab && /* @__PURE__ */ jsx2(SDKButton, { onClick: () => handleTabChange(tab + 1), children: "Next" }),
1501
+ tab === lastSaveTab && /* @__PURE__ */ jsx2(
1502
+ SDKPermissionGuard,
1503
+ {
1504
+ permissions: [
1505
+ editingCampaign ? SDK_PERMISSIONS.CAMPAIGNS_UPDATE : SDK_PERMISSIONS.CAMPAIGNS_CREATE,
1506
+ SDK_PERMISSIONS.CAMPAIGNS_MANAGE
1507
+ ],
1508
+ showFallback: false,
1509
+ children: /* @__PURE__ */ jsx2(
1510
+ SDKButton,
1511
+ {
1512
+ onClick: onSave,
1513
+ disabled: saving || !isDirty,
1514
+ startIcon: saving ? /* @__PURE__ */ jsx2(CircularProgress, { size: 14, color: "inherit" }) : void 0,
1515
+ children: editingCampaign ? "Update" : "Create"
1516
+ }
1517
+ )
1518
+ }
1519
+ )
1520
+ ] })
1521
+ ]
1522
+ }
1523
+ )
1524
+ }
1525
+ );
1526
+ });
1527
+ var AddLeadDialog = memo(function AddLeadDialog2({
1528
+ open,
1529
+ data,
1530
+ onChange,
1531
+ saving,
1532
+ onSave,
1533
+ onClose
1534
+ }) {
1535
+ var _a;
1536
+ if (!open) return null;
1537
+ const phoneError = data.phoneNumber ? validatePhone(data.phoneNumber) : null;
1538
+ return /* @__PURE__ */ jsx2(
1539
+ Box,
1540
+ {
1541
+ sx: {
1542
+ position: "fixed",
1543
+ inset: 0,
1544
+ zIndex: 1400,
1545
+ backgroundColor: "rgba(0,0,0,0.45)",
1546
+ display: "flex",
1547
+ alignItems: "center",
1548
+ justifyContent: "center"
1549
+ },
1550
+ onClick: (e) => e.stopPropagation(),
1551
+ children: /* @__PURE__ */ jsxs(Paper, { elevation: 6, sx: { width: { xs: "95vw", sm: 560, lg: 720 }, borderRadius: "16px", overflow: "hidden", boxShadow: "0 8px 32px rgba(26,95,108,0.18)" }, children: [
1552
+ /* @__PURE__ */ jsxs(Box, { sx: __spreadProps(__spreadValues({}, dialogHeaderSx), { backgroundColor: "#1A5F6C", color: "#fff" }), children: [
1553
+ /* @__PURE__ */ jsx2(Typography, { fontWeight: 700, fontSize: "1rem", fontFamily: "poppins, Arial, sans-serif", children: "Add Lead" }),
1554
+ /* @__PURE__ */ jsx2(IconButton, { size: "small", onClick: onClose, sx: { color: "#fff" }, children: "\u2715" })
1555
+ ] }),
1556
+ /* @__PURE__ */ jsx2(Box, { sx: { p: 2.5 }, children: /* @__PURE__ */ jsxs(Box, { sx: { display: "grid", gridTemplateColumns: { xs: "1fr", sm: "1fr 1fr", lg: "1fr 1fr 1fr" }, gap: 2 }, children: [
1557
+ /* @__PURE__ */ jsxs(Box, { children: [
1558
+ /* @__PURE__ */ jsxs(Typography, { sx: labelSx, children: [
1559
+ "Phone Number ",
1560
+ /* @__PURE__ */ jsx2("span", { style: { color: "red" }, children: "*" })
1561
+ ] }),
1562
+ /* @__PURE__ */ jsx2(
1563
+ TextField,
1564
+ {
1565
+ fullWidth: true,
1566
+ size: "small",
1567
+ placeholder: "+1234567890",
1568
+ value: data.phoneNumber,
1569
+ onChange: (e) => onChange(__spreadProps(__spreadValues({}, data), { phoneNumber: e.target.value.replace(/[^0-9+\-() ]/g, "") })),
1570
+ error: !!phoneError,
1571
+ helperText: phoneError || "",
1572
+ sx: inputSx
1573
+ }
1574
+ )
1575
+ ] }),
1576
+ /* @__PURE__ */ jsxs(Box, { children: [
1577
+ /* @__PURE__ */ jsx2(Typography, { sx: labelSx, children: "Caller Name" }),
1578
+ /* @__PURE__ */ jsx2(
1579
+ TextField,
1580
+ {
1581
+ fullWidth: true,
1582
+ size: "small",
1583
+ value: data.callerName || "",
1584
+ onChange: (e) => onChange(__spreadProps(__spreadValues({}, data), { callerName: e.target.value })),
1585
+ sx: inputSx
1586
+ }
1587
+ )
1588
+ ] }),
1589
+ /* @__PURE__ */ jsxs(Box, { children: [
1590
+ /* @__PURE__ */ jsx2(Typography, { sx: labelSx, children: "Source" }),
1591
+ /* @__PURE__ */ jsx2(
1592
+ TextField,
1593
+ {
1594
+ fullWidth: true,
1595
+ size: "small",
1596
+ value: data.source || "",
1597
+ onChange: (e) => onChange(__spreadProps(__spreadValues({}, data), { source: e.target.value })),
1598
+ sx: inputSx
1599
+ }
1600
+ )
1601
+ ] }),
1602
+ /* @__PURE__ */ jsxs(Box, { children: [
1603
+ /* @__PURE__ */ jsx2(Typography, { sx: labelSx, children: "Priority" }),
1604
+ /* @__PURE__ */ jsx2(FormControl, { fullWidth: true, size: "small", children: /* @__PURE__ */ jsx2(
1605
+ Select,
1606
+ {
1607
+ value: (_a = data.priority) != null ? _a : 5,
1608
+ onChange: (e) => onChange(__spreadProps(__spreadValues({}, data), { priority: Number(e.target.value) })),
1609
+ children: LEAD_PRIORITY_OPTIONS.map((o) => /* @__PURE__ */ jsx2(MenuItem, { value: o.value, children: o.label }, o.label))
1610
+ }
1611
+ ) })
1612
+ ] }),
1613
+ /* @__PURE__ */ jsxs(Box, { sx: { gridColumn: "1 / -1" }, children: [
1614
+ /* @__PURE__ */ jsx2(Typography, { sx: labelSx, children: "Notes" }),
1615
+ /* @__PURE__ */ jsx2(
1616
+ TextField,
1617
+ {
1618
+ fullWidth: true,
1619
+ size: "small",
1620
+ multiline: true,
1621
+ minRows: 2,
1622
+ maxRows: 8,
1623
+ value: data.notes || "",
1624
+ onChange: (e) => onChange(__spreadProps(__spreadValues({}, data), { notes: e.target.value })),
1625
+ sx: inputSx
1626
+ }
1627
+ )
1628
+ ] })
1629
+ ] }) }),
1630
+ /* @__PURE__ */ jsxs(Box, { sx: dialogFooterSx, children: [
1631
+ /* @__PURE__ */ jsx2(SDKButton, { variant: "cancel", onClick: onClose, children: "Cancel" }),
1632
+ /* @__PURE__ */ jsx2(
1633
+ SDKButton,
1634
+ {
1635
+ onClick: onSave,
1636
+ disabled: saving,
1637
+ startIcon: saving ? /* @__PURE__ */ jsx2(CircularProgress, { size: 14, color: "inherit" }) : void 0,
1638
+ children: "Add Lead"
1639
+ }
1640
+ )
1641
+ ] })
1642
+ ] })
1643
+ }
1644
+ );
1645
+ });
1646
+ function ConfirmDialog({
1647
+ open,
1648
+ title,
1649
+ message,
1650
+ loading,
1651
+ onConfirm,
1652
+ onClose
1653
+ }) {
1654
+ if (!open) return null;
1655
+ return /* @__PURE__ */ jsx2(
1656
+ Box,
1657
+ {
1658
+ sx: { position: "fixed", inset: 0, zIndex: 1500, backgroundColor: "rgba(0,0,0,0.45)", display: "flex", alignItems: "center", justifyContent: "center" },
1659
+ onClick: (e) => e.stopPropagation(),
1660
+ children: /* @__PURE__ */ jsxs(Paper, { elevation: 6, sx: { width: { xs: "90vw", sm: 400 }, borderRadius: "16px", overflow: "hidden", boxShadow: "0 8px 32px rgba(0,0,0,0.18)" }, children: [
1661
+ /* @__PURE__ */ jsxs(Box, { sx: __spreadProps(__spreadValues({}, dialogHeaderSx), { borderBottom: "none", pb: 0 }), children: [
1662
+ /* @__PURE__ */ jsx2(Typography, { fontWeight: 700, fontSize: "1rem", fontFamily: "poppins, Arial, sans-serif", children: title }),
1663
+ /* @__PURE__ */ jsx2(IconButton, { size: "small", onClick: onClose, children: "\u2715" })
1664
+ ] }),
1665
+ /* @__PURE__ */ jsx2(Box, { sx: { px: 2.5, py: 1.5 }, children: /* @__PURE__ */ jsx2(Typography, { fontSize: "0.85rem", color: "#555", fontFamily: "poppins, Arial, sans-serif", children: message }) }),
1666
+ /* @__PURE__ */ jsxs(Box, { sx: dialogFooterSx, children: [
1667
+ /* @__PURE__ */ jsx2(SDKButton, { variant: "cancel", onClick: onClose, children: "Cancel" }),
1668
+ /* @__PURE__ */ jsx2(
1669
+ SDKButton,
1670
+ {
1671
+ variant: "danger",
1672
+ onClick: onConfirm,
1673
+ disabled: loading,
1674
+ startIcon: loading ? /* @__PURE__ */ jsx2(CircularProgress, { size: 14, color: "inherit" }) : void 0,
1675
+ children: "Confirm"
1676
+ }
1677
+ )
1678
+ ] })
1679
+ ] })
1680
+ }
1681
+ );
1682
+ }
1683
+ function CallRecording({ callUuid, recordingPath }) {
1684
+ const [audioUrl, setAudioUrl] = useState2(null);
1685
+ const [loading, setLoading] = useState2(false);
1686
+ const [error, setError] = useState2(false);
1687
+ const unavailable = !recordingPath;
1688
+ const handlePlay = async () => {
1689
+ if (audioUrl) return;
1690
+ try {
1691
+ setLoading(true);
1692
+ setError(false);
1693
+ const blob = await getRecordingByCall(callUuid);
1694
+ setAudioUrl(URL.createObjectURL(blob));
1695
+ } catch (e) {
1696
+ setError(true);
1697
+ } finally {
1698
+ setLoading(false);
1699
+ }
1700
+ };
1701
+ const handleDownload = async () => {
1702
+ try {
1703
+ const blob = audioUrl ? await fetch(audioUrl).then((r) => r.blob()) : await getRecordingByCall(callUuid);
1704
+ const url = URL.createObjectURL(blob);
1705
+ const a = document.createElement("a");
1706
+ a.href = url;
1707
+ a.download = `recording_${callUuid}.wav`;
1708
+ a.click();
1709
+ URL.revokeObjectURL(url);
1710
+ } catch (e) {
1711
+ }
1712
+ };
1713
+ if (unavailable) {
1714
+ return /* @__PURE__ */ jsx2(Typography, { sx: { fontSize: "0.82rem", color: "#999" }, fontFamily: "poppins, Arial, sans-serif", children: "No recording available for this call." });
1715
+ }
1716
+ if (audioUrl) {
1717
+ return /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: "center", gap: 1 }, children: [
1718
+ /* @__PURE__ */ jsx2("audio", { controls: true, autoPlay: true, src: audioUrl, onEnded: () => {
1719
+ URL.revokeObjectURL(audioUrl);
1720
+ setAudioUrl(null);
1721
+ }, style: { height: 38, flex: 1 } }),
1722
+ /* @__PURE__ */ jsx2(Tooltip, { title: "Download", children: /* @__PURE__ */ jsx2(IconButton, { size: "small", onClick: handleDownload, sx: { color: "#1565c0" }, children: /* @__PURE__ */ jsx2(DownloadIcon, { sx: { fontSize: 18 } }) }) })
1723
+ ] });
1724
+ }
1725
+ return /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: "center", gap: 1 }, children: [
1726
+ /* @__PURE__ */ jsx2(SDKButton, { variant: "outlined", onClick: handlePlay, disabled: loading || error, startIcon: loading ? /* @__PURE__ */ jsx2(CircularProgress, { size: 16, color: "inherit" }) : /* @__PURE__ */ jsx2(PlayArrowIcon, { sx: { fontSize: 16 } }), children: error ? "Recording unavailable" : "Play recording" }),
1727
+ /* @__PURE__ */ jsx2(Tooltip, { title: "Download", children: /* @__PURE__ */ jsx2("span", { children: /* @__PURE__ */ jsx2(IconButton, { size: "small", onClick: handleDownload, disabled: loading || error, sx: { color: "#1565c0" }, children: /* @__PURE__ */ jsx2(DownloadIcon, { sx: { fontSize: 18 } }) }) }) })
1728
+ ] });
1729
+ }
1730
+ function CallDataDialog({
1731
+ open,
1732
+ lead,
1733
+ data,
1734
+ loading,
1735
+ error,
1736
+ onClose
1737
+ }) {
1738
+ if (!open) return null;
1739
+ const fmt = (v) => v ? new Date(v).toLocaleString() : "\u2014";
1740
+ const fieldCardSx = {
1741
+ display: "flex",
1742
+ flexDirection: "column",
1743
+ gap: 0.25,
1744
+ p: 1,
1745
+ borderRadius: "8px",
1746
+ backgroundColor: "#fafafa",
1747
+ border: "1px solid #eee"
1748
+ };
1749
+ const fieldLabelSx = {
1750
+ fontSize: "0.66rem",
1751
+ fontWeight: 600,
1752
+ color: "#888",
1753
+ textTransform: "uppercase",
1754
+ letterSpacing: 0.3
1755
+ };
1756
+ const fieldValueSx = {
1757
+ fontSize: "0.82rem",
1758
+ fontWeight: 600,
1759
+ color: "#1a1a1a",
1760
+ wordBreak: "break-word"
1761
+ };
1762
+ const sectionTitle = {
1763
+ fontSize: "0.7rem",
1764
+ fontWeight: 700,
1765
+ color: "#1A5F6C",
1766
+ textTransform: "uppercase",
1767
+ letterSpacing: 0.5,
1768
+ mb: 0.75
1769
+ };
1770
+ const fieldCard = (label, value, full) => /* @__PURE__ */ jsxs(Box, { sx: __spreadValues(__spreadValues({}, fieldCardSx), full ? { gridColumn: "1 / -1" } : {}), children: [
1771
+ /* @__PURE__ */ jsx2(Typography, { sx: fieldLabelSx, fontFamily: "poppins, Arial, sans-serif", children: label }),
1772
+ /* @__PURE__ */ jsx2(Typography, { sx: fieldValueSx, fontFamily: "poppins, Arial, sans-serif", children: value })
1773
+ ] }, label);
1774
+ const overview = data ? [
1775
+ ["Phone Number", data.phoneNumber || "\u2014"],
1776
+ ["Call Type", data.callType || "\u2014"],
1777
+ ["Call Status", data.callStatus || "\u2014"],
1778
+ ["Disposition", data.disposition || "\u2014"],
1779
+ ["Agent Disposition", data.agentSelectedDisposition || "\u2014"],
1780
+ ["Transferred", data.wasTransferred ? "Yes" : "No"],
1781
+ ["Hangup By", data.hangupInitiator || "\u2014"]
1782
+ ] : [];
1783
+ const agentQueue = data ? [
1784
+ ["Agent", data.agentName || "\u2014"],
1785
+ ["Agent ID", data.agentUserId || "\u2014"],
1786
+ ["Extension", data.extension || "\u2014"],
1787
+ ["Queue", data.queueName || "\u2014"]
1788
+ ] : [];
1789
+ const timing = data ? [
1790
+ ["Start Time", fmt(data.callStartTime)],
1791
+ ["Connect Time", fmt(data.connectTime)]
1792
+ ] : [];
1793
+ const durations = data ? [
1794
+ ["Talk", data.talkDurationFmt || "\u2014"],
1795
+ ["Ringing", data.ringingDurationFmt || "\u2014"],
1796
+ ["Hold", data.holdDurationFmt || "\u2014"],
1797
+ ["Mute", data.muteDurationFmt || "\u2014"],
1798
+ ["Wrap-up", data.wrapupDurationFmt || "\u2014"],
1799
+ ["Queue", data.queueDurationFmt || "\u2014"],
1800
+ ["IVR", data.ivrDurationFmt || "\u2014"]
1801
+ ] : [];
1802
+ const twoColGrid = { display: "grid", gridTemplateColumns: { xs: "1fr", sm: "1fr 1fr" }, gap: 1.25 };
1803
+ const compactGrid = { display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(96px, 1fr))", gap: 1.25 };
1804
+ return /* @__PURE__ */ jsx2(Box, { sx: { position: "fixed", inset: 0, zIndex: 1500, backgroundColor: "rgba(0,0,0,0.45)", display: "flex", alignItems: "center", justifyContent: "center" }, onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsxs(Paper, { elevation: 6, sx: { width: { xs: "92vw", sm: 600 }, maxHeight: "85vh", display: "flex", flexDirection: "column", borderRadius: "16px", overflow: "hidden", boxShadow: "0 8px 32px rgba(26,95,108,0.18)" }, children: [
1805
+ /* @__PURE__ */ jsxs(Box, { sx: __spreadProps(__spreadValues({}, dialogHeaderSx), { backgroundColor: "#1A5F6C", color: "#fff" }), children: [
1806
+ /* @__PURE__ */ jsxs(Box, { children: [
1807
+ /* @__PURE__ */ jsx2(Typography, { fontWeight: 700, fontSize: "1rem", fontFamily: "poppins, Arial, sans-serif", children: "Call Details" }),
1808
+ (lead == null ? void 0 : lead.phoneNumber) ? /* @__PURE__ */ jsxs(Typography, { fontSize: "0.72rem", sx: { opacity: 0.85 }, fontFamily: "poppins, Arial, sans-serif", children: [
1809
+ "Latest call for ",
1810
+ lead.phoneNumber
1811
+ ] }) : null
1812
+ ] }),
1813
+ /* @__PURE__ */ jsx2(IconButton, { size: "small", onClick: onClose, sx: { color: "#fff" }, children: "\u2715" })
1814
+ ] }),
1815
+ /* @__PURE__ */ jsx2(Box, { sx: { px: 2.5, py: 2, overflowY: "auto" }, children: loading ? /* @__PURE__ */ jsx2(Box, { sx: { display: "flex", justifyContent: "center", py: 4 }, children: /* @__PURE__ */ jsx2(CircularProgress, { size: 30 }) }) : error ? /* @__PURE__ */ jsx2(Typography, { fontSize: "0.85rem", color: "#d32f2f", textAlign: "center", sx: { py: 3 }, fontFamily: "poppins, Arial, sans-serif", children: error }) : data ? /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", flexDirection: "column", gap: 2 }, children: [
1816
+ /* @__PURE__ */ jsxs(Box, { children: [
1817
+ /* @__PURE__ */ jsx2(Typography, { sx: sectionTitle, fontFamily: "poppins, Arial, sans-serif", children: "Call Overview" }),
1818
+ /* @__PURE__ */ jsx2(Box, { sx: twoColGrid, children: overview.map(([l, v]) => fieldCard(l, v)) })
1819
+ ] }),
1820
+ /* @__PURE__ */ jsxs(Box, { children: [
1821
+ /* @__PURE__ */ jsx2(Typography, { sx: sectionTitle, fontFamily: "poppins, Arial, sans-serif", children: "Agent & Queue" }),
1822
+ /* @__PURE__ */ jsx2(Box, { sx: twoColGrid, children: agentQueue.map(([l, v]) => fieldCard(l, v)) })
1823
+ ] }),
1824
+ /* @__PURE__ */ jsxs(Box, { children: [
1825
+ /* @__PURE__ */ jsx2(Typography, { sx: sectionTitle, fontFamily: "poppins, Arial, sans-serif", children: "Timing" }),
1826
+ /* @__PURE__ */ jsx2(Box, { sx: twoColGrid, children: timing.map(([l, v]) => fieldCard(l, v)) })
1827
+ ] }),
1828
+ /* @__PURE__ */ jsxs(Box, { children: [
1829
+ /* @__PURE__ */ jsx2(Typography, { sx: sectionTitle, fontFamily: "poppins, Arial, sans-serif", children: "Durations" }),
1830
+ /* @__PURE__ */ jsx2(Box, { sx: compactGrid, children: durations.map(([l, v]) => fieldCard(l, v)) })
1831
+ ] }),
1832
+ /* @__PURE__ */ jsxs(Box, { children: [
1833
+ /* @__PURE__ */ jsx2(Typography, { sx: sectionTitle, fontFamily: "poppins, Arial, sans-serif", children: "Remarks" }),
1834
+ /* @__PURE__ */ jsx2(Box, { sx: __spreadProps(__spreadValues({}, fieldCardSx), { minHeight: 44 }), children: /* @__PURE__ */ jsx2(Typography, { sx: fieldValueSx, fontFamily: "poppins, Arial, sans-serif", children: data.remarks || "\u2014" }) })
1835
+ ] }),
1836
+ /* @__PURE__ */ jsxs(Box, { children: [
1837
+ /* @__PURE__ */ jsx2(Typography, { sx: sectionTitle, fontFamily: "poppins, Arial, sans-serif", children: "Recording" }),
1838
+ /* @__PURE__ */ jsx2(Box, { sx: fieldCardSx, children: /* @__PURE__ */ jsx2(CallRecording, { callUuid: data.callUuid, recordingPath: data.recordingPath }) })
1839
+ ] })
1840
+ ] }) : null }),
1841
+ /* @__PURE__ */ jsx2(Box, { sx: dialogFooterSx, children: /* @__PURE__ */ jsx2(SDKButton, { variant: "cancel", onClick: onClose, children: "Close" }) })
1842
+ ] }) });
1843
+ }
1844
+ function ImportLeadsDialog({
1845
+ open,
1846
+ file,
1847
+ onFileChange,
1848
+ uploading,
1849
+ onUpload,
1850
+ onDownloadTemplate,
1851
+ onClose
1852
+ }) {
1853
+ const fileRef = useRef(null);
1854
+ if (!open) return null;
1855
+ return /* @__PURE__ */ jsx2(
1856
+ Box,
1857
+ {
1858
+ sx: { position: "fixed", inset: 0, zIndex: 1400, backgroundColor: "rgba(0,0,0,0.45)", display: "flex", alignItems: "center", justifyContent: "center" },
1859
+ onClick: (e) => e.stopPropagation(),
1860
+ children: /* @__PURE__ */ jsxs(Paper, { elevation: 6, sx: { width: { xs: "90vw", sm: 460 }, borderRadius: "16px", overflow: "hidden", boxShadow: "0 8px 32px rgba(26,95,108,0.18)" }, children: [
1861
+ /* @__PURE__ */ jsxs(Box, { sx: __spreadProps(__spreadValues({}, dialogHeaderSx), { backgroundColor: "#1A5F6C", color: "#fff" }), children: [
1862
+ /* @__PURE__ */ jsx2(Typography, { fontWeight: 700, fontSize: "1rem", fontFamily: "poppins, Arial, sans-serif", children: "Import Leads" }),
1863
+ /* @__PURE__ */ jsx2(IconButton, { size: "small", onClick: onClose, sx: { color: "#fff" }, children: "\u2715" })
1864
+ ] }),
1865
+ /* @__PURE__ */ jsxs(Box, { sx: { p: 2.5 }, children: [
1866
+ /* @__PURE__ */ jsx2(Typography, { fontSize: "0.82rem", color: "#555", fontFamily: "poppins, Arial, sans-serif", mb: 2, children: "Upload a CSV or Excel file. Use the template for the correct format." }),
1867
+ /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: "center", gap: 1.5, flexWrap: "wrap", mb: 1.5 }, children: [
1868
+ /* @__PURE__ */ jsx2(
1869
+ SDKButton,
1870
+ {
1871
+ variant: "outlined",
1872
+ startIcon: /* @__PURE__ */ jsx2(UploadFileIcon, {}),
1873
+ onClick: () => {
1874
+ var _a;
1875
+ return (_a = fileRef.current) == null ? void 0 : _a.click();
1876
+ },
1877
+ children: "Choose File"
1878
+ }
1879
+ ),
1880
+ /* @__PURE__ */ jsx2(
1881
+ "input",
1882
+ {
1883
+ ref: fileRef,
1884
+ type: "file",
1885
+ accept: ".csv,.xlsx,.xls",
1886
+ hidden: true,
1887
+ onChange: (e) => {
1888
+ var _a;
1889
+ const f = (_a = e.target.files) == null ? void 0 : _a[0];
1890
+ if (!f) return;
1891
+ if ([".csv", ".xlsx", ".xls"].some((ext) => f.name.toLowerCase().endsWith(ext))) onFileChange(f);
1892
+ }
1893
+ }
1894
+ ),
1895
+ /* @__PURE__ */ jsx2(Typography, { sx: { fontSize: "0.82rem", color: "#666", flex: 1, fontFamily: "poppins, Arial, sans-serif" }, children: file ? file.name : "No file chosen" }),
1896
+ file && /* @__PURE__ */ jsx2(
1897
+ SDKButton,
1898
+ {
1899
+ variant: "cancel",
1900
+ size: "small",
1901
+ onClick: () => {
1902
+ onFileChange(null);
1903
+ if (fileRef.current) fileRef.current.value = "";
1904
+ },
1905
+ children: "Clear"
1906
+ }
1907
+ )
1908
+ ] }),
1909
+ /* @__PURE__ */ jsx2(SDKButton, { variant: "outlined", startIcon: /* @__PURE__ */ jsx2(DownloadIcon, {}), onClick: onDownloadTemplate, children: "Download Template" })
1910
+ ] }),
1911
+ /* @__PURE__ */ jsxs(Box, { sx: dialogFooterSx, children: [
1912
+ /* @__PURE__ */ jsx2(SDKButton, { variant: "cancel", onClick: onClose, children: "Cancel" }),
1913
+ /* @__PURE__ */ jsx2(
1914
+ SDKButton,
1915
+ {
1916
+ onClick: onUpload,
1917
+ disabled: uploading || !file,
1918
+ startIcon: uploading ? /* @__PURE__ */ jsx2(CircularProgress, { size: 14, color: "inherit" }) : void 0,
1919
+ children: "Upload"
1920
+ }
1921
+ )
1922
+ ] })
1923
+ ] })
1924
+ }
1925
+ );
1926
+ }
1927
+ var CampaignsContent = memo(function CampaignsContent2() {
1928
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
1929
+ const theme = useTheme2();
1930
+ const { showToast } = useToast();
1931
+ const { isBitEnabled } = useSDKPermissions();
1932
+ const callerData = useGetCallerData();
1933
+ const isAgentIdle = callerData.status === "IDLE";
1934
+ const hasOutboundPermission = isBitEnabled("calls", SDK_PERMISSIONS.CALL_OUTBOUND);
1935
+ const {
1936
+ campaigns,
1937
+ loading,
1938
+ fetchCampaigns,
1939
+ getCampaignById,
1940
+ createCampaign,
1941
+ updateCampaign,
1942
+ activateCampaign,
1943
+ pauseCampaign,
1944
+ archiveCampaign
1945
+ } = useCampaigns();
1946
+ const {
1947
+ leads,
1948
+ leadTotal,
1949
+ leadsMeta,
1950
+ loading: leadsLoading,
1951
+ fetchLeads,
1952
+ createLead,
1953
+ deleteLead,
1954
+ dialPreview,
1955
+ getLeadCallData,
1956
+ uploadLeadsExcel,
1957
+ downloadLeadTemplate,
1958
+ exportLeads
1959
+ } = useLeads();
1960
+ const { fetchQueues } = useQueues();
1961
+ const [queueNameMap, setQueueNameMap] = useState2({});
1962
+ useEffect(() => {
1963
+ fetchQueues().then((qs) => {
1964
+ const map = {};
1965
+ qs.forEach((q) => {
1966
+ map[q.id] = q.name;
1967
+ });
1968
+ setQueueNameMap(map);
1969
+ }).catch(() => {
1970
+ });
1971
+ }, [fetchQueues]);
1972
+ const handleQueuesRefreshed = useCallback2((qs) => {
1973
+ const map = {};
1974
+ qs.forEach((q) => {
1975
+ map[q.id] = q.name;
1976
+ });
1977
+ setQueueNameMap(map);
1978
+ }, []);
1979
+ const [selectedId, setSelectedId] = useState2(null);
1980
+ const [showArchived, setShowArchived] = useState2(false);
1981
+ const [campaignListCollapsed, setCampaignListCollapsed] = useState2(false);
1982
+ const [dialogOpen, setDialogOpen] = useState2(false);
1983
+ const [editingCampaign, setEditingCampaign] = useState2(null);
1984
+ const [formData, setFormData] = useState2(defaultFormData);
1985
+ const [saving, setSaving] = useState2(false);
1986
+ const [archiveOpen, setArchiveOpen] = useState2(false);
1987
+ const [archiveTarget, setArchiveTarget] = useState2(null);
1988
+ const [archiving, setArchiving] = useState2(false);
1989
+ const [leadPage, setLeadPage] = useState2(0);
1990
+ const [leadRowsPerPage, setLeadRowsPerPage] = useState2(10);
1991
+ const [leadSearch, setLeadSearch] = useState2("");
1992
+ const [debouncedSearch, setDebouncedSearch] = useState2("");
1993
+ const [leadStatusFilter, setLeadStatusFilter] = useState2("All states");
1994
+ const debounceRef = useRef(null);
1995
+ const [addLeadOpen, setAddLeadOpen] = useState2(false);
1996
+ const [addLeadData, setAddLeadData] = useState2({ phoneNumber: "", callerName: "", priority: 5 });
1997
+ const [addLeadSaving, setAddLeadSaving] = useState2(false);
1998
+ const [importOpen, setImportOpen] = useState2(false);
1999
+ const [importFile, setImportFile] = useState2(null);
2000
+ const [importing, setImporting] = useState2(false);
2001
+ const [deleteLeadOpen, setDeleteLeadOpen] = useState2(false);
2002
+ const [deleteLeadTarget, setDeleteLeadTarget] = useState2(null);
2003
+ const [deletingLead, setDeletingLead] = useState2(false);
2004
+ const [callDataOpen, setCallDataOpen] = useState2(false);
2005
+ const [callDataLead, setCallDataLead] = useState2(null);
2006
+ const [callDataLoading, setCallDataLoading] = useState2(false);
2007
+ const [callData, setCallData] = useState2(null);
2008
+ const [callDataError, setCallDataError] = useState2(null);
2009
+ const handleViewCallData = useCallback2(async (lead) => {
2010
+ var _a2, _b2;
2011
+ const callId = lead.latestCallId || lead.originalCallId;
2012
+ if (!callId) return;
2013
+ setCallDataLead(lead);
2014
+ setCallDataOpen(true);
2015
+ setCallData(null);
2016
+ setCallDataError(null);
2017
+ setCallDataLoading(true);
2018
+ try {
2019
+ const data = await getLeadCallData(callId);
2020
+ setCallData(data);
2021
+ } catch (e) {
2022
+ setCallDataError(((_b2 = (_a2 = e == null ? void 0 : e.response) == null ? void 0 : _a2.data) == null ? void 0 : _b2.message) || "Failed to load call data");
2023
+ } finally {
2024
+ setCallDataLoading(false);
2025
+ }
2026
+ }, [getLeadCallData]);
2027
+ const [dialLoading, setDialLoading] = useState2(null);
2028
+ const selected = (_a = campaigns.find((c) => c.id === selectedId)) != null ? _a : null;
2029
+ const visibleCampaigns = campaigns.filter(
2030
+ (c) => {
2031
+ var _a2;
2032
+ return showArchived ? true : ((_a2 = c.status) == null ? void 0 : _a2.toLowerCase()) !== "archived";
2033
+ }
2034
+ );
2035
+ const handleSelectCampaign = useCallback2((id) => {
2036
+ if (id === selectedId) return;
2037
+ setLeadStatusFilter("All states");
2038
+ setLeadSearch("");
2039
+ setDebouncedSearch("");
2040
+ setLeadPage(0);
2041
+ setSelectedId(id);
2042
+ }, [selectedId]);
2043
+ useEffect(() => {
2044
+ fetchCampaigns();
2045
+ }, [fetchCampaigns]);
2046
+ useEffect(() => {
2047
+ debounceRef.current = setTimeout(() => setDebouncedSearch(leadSearch.trim()), 400);
2048
+ return () => {
2049
+ if (debounceRef.current) clearTimeout(debounceRef.current);
2050
+ };
2051
+ }, [leadSearch]);
2052
+ useEffect(() => {
2053
+ if (!selectedId) return;
2054
+ setLeadPage(0);
2055
+ fetchLeads(selectedId, {
2056
+ page: 1,
2057
+ pageSize: leadRowsPerPage,
2058
+ lead_status: leadStatusFilter !== "All states" ? leadStatusFilter : void 0,
2059
+ search: debouncedSearch || void 0
2060
+ });
2061
+ }, [selectedId, leadRowsPerPage, leadStatusFilter, debouncedSearch, fetchLeads]);
2062
+ const refetchLeads = useCallback2((page = leadPage, silent = false) => {
2063
+ if (!selectedId) return;
2064
+ fetchLeads(selectedId, {
2065
+ page: page + 1,
2066
+ pageSize: leadRowsPerPage,
2067
+ lead_status: leadStatusFilter !== "All states" ? leadStatusFilter : void 0,
2068
+ search: debouncedSearch || void 0
2069
+ }, { silent });
2070
+ }, [selectedId, leadPage, leadRowsPerPage, leadStatusFilter, debouncedSearch, fetchLeads]);
2071
+ useEffect(() => {
2072
+ if (!selectedId) return;
2073
+ const intervalId = setInterval(() => {
2074
+ refetchLeads(leadPage, true);
2075
+ }, 3e3);
2076
+ return () => clearInterval(intervalId);
2077
+ }, [selectedId, leadPage, refetchLeads]);
2078
+ const handleOpenCreate = () => {
2079
+ setEditingCampaign(null);
2080
+ setFormData(defaultFormData);
2081
+ setDialogOpen(true);
2082
+ };
2083
+ const handleOpenEdit = async (c) => {
2084
+ setEditingCampaign(c);
2085
+ setFormData(campaignToFormData(c));
2086
+ setDialogOpen(true);
2087
+ try {
2088
+ const fresh = await getCampaignById(c.id);
2089
+ setEditingCampaign(fresh);
2090
+ setFormData(campaignToFormData(fresh));
2091
+ } catch (e) {
2092
+ }
2093
+ };
2094
+ const handleSave = async () => {
2095
+ var _a2, _b2, _c2, _d2, _e2;
2096
+ if (!formData.name.trim()) {
2097
+ showToast("Campaign name is required", "warning");
2098
+ return;
2099
+ }
2100
+ setSaving(true);
2101
+ const startTime = ((_a2 = formData.startTime) == null ? void 0 : _a2.length) === 5 ? `${formData.startTime}:00` : formData.startTime;
2102
+ const endTime = ((_b2 = formData.endTime) == null ? void 0 : _b2.length) === 5 ? `${formData.endTime}:00` : formData.endTime;
2103
+ const toIso = (d) => d ? new Date(d).toISOString() : void 0;
2104
+ const scheduledStart = toIso(formData.scheduledStart);
2105
+ const scheduledEnd = toIso(formData.scheduledEnd);
2106
+ try {
2107
+ if (editingCampaign) {
2108
+ const updatePayload = __spreadProps(__spreadValues({}, formData), { startTime, endTime });
2109
+ if (scheduledStart) updatePayload.scheduledStart = scheduledStart;
2110
+ else delete updatePayload.scheduledStart;
2111
+ if (scheduledEnd) updatePayload.scheduledEnd = scheduledEnd;
2112
+ else delete updatePayload.scheduledEnd;
2113
+ await updateCampaign(editingCampaign.id, updatePayload);
2114
+ showToast("Campaign updated", "success");
2115
+ } else {
2116
+ const payload = __spreadProps(__spreadValues({}, formData), { startTime, endTime });
2117
+ if (scheduledStart) payload.scheduledStart = scheduledStart;
2118
+ else delete payload.scheduledStart;
2119
+ if (scheduledEnd) payload.scheduledEnd = scheduledEnd;
2120
+ else delete payload.scheduledEnd;
2121
+ if (!payload.callerId) delete payload.callerId;
2122
+ if (!payload.answerTimeoutSeconds) delete payload.answerTimeoutSeconds;
2123
+ if (payload.aiBotId == null) delete payload.aiBotId;
2124
+ if (!((_c2 = payload.queueLinks) == null ? void 0 : _c2.length)) delete payload.queueLinks;
2125
+ if (payload.settings && !Object.keys(payload.settings).length) delete payload.settings;
2126
+ const created = await createCampaign(payload);
2127
+ showToast("Campaign created", "success");
2128
+ setSelectedId(created.id);
2129
+ }
2130
+ setDialogOpen(false);
2131
+ fetchCampaigns();
2132
+ } catch (err) {
2133
+ showToast(((_e2 = (_d2 = err == null ? void 0 : err.response) == null ? void 0 : _d2.data) == null ? void 0 : _e2.message) || (err == null ? void 0 : err.message) || "Failed to save campaign", "error");
2134
+ } finally {
2135
+ setSaving(false);
2136
+ }
2137
+ };
2138
+ const handleStart = async (c) => {
2139
+ var _a2, _b2;
2140
+ try {
2141
+ await activateCampaign(c.id);
2142
+ showToast("Campaign started", "success");
2143
+ fetchCampaigns();
2144
+ } catch (err) {
2145
+ showToast(((_b2 = (_a2 = err == null ? void 0 : err.response) == null ? void 0 : _a2.data) == null ? void 0 : _b2.message) || (err == null ? void 0 : err.message) || "Failed to start", "error");
2146
+ }
2147
+ };
2148
+ const handlePause = async (c) => {
2149
+ var _a2, _b2;
2150
+ try {
2151
+ await pauseCampaign(c.id);
2152
+ showToast("Campaign paused", "success");
2153
+ fetchCampaigns();
2154
+ } catch (err) {
2155
+ showToast(((_b2 = (_a2 = err == null ? void 0 : err.response) == null ? void 0 : _a2.data) == null ? void 0 : _b2.message) || (err == null ? void 0 : err.message) || "Failed to pause", "error");
2156
+ }
2157
+ };
2158
+ const confirmArchive = async () => {
2159
+ var _a2, _b2;
2160
+ if (!archiveTarget) return;
2161
+ setArchiving(true);
2162
+ try {
2163
+ await archiveCampaign(archiveTarget.id);
2164
+ showToast("Campaign archived", "success");
2165
+ setArchiveOpen(false);
2166
+ setArchiveTarget(null);
2167
+ fetchCampaigns();
2168
+ } catch (err) {
2169
+ showToast(((_b2 = (_a2 = err == null ? void 0 : err.response) == null ? void 0 : _a2.data) == null ? void 0 : _b2.message) || (err == null ? void 0 : err.message) || "Failed to archive", "error");
2170
+ } finally {
2171
+ setArchiving(false);
2172
+ }
2173
+ };
2174
+ const handleAddLead = async () => {
2175
+ var _a2, _b2;
2176
+ if (!selectedId) return;
2177
+ const err = validatePhone(addLeadData.phoneNumber);
2178
+ if (err) {
2179
+ showToast(err, "warning");
2180
+ return;
2181
+ }
2182
+ setAddLeadSaving(true);
2183
+ try {
2184
+ await createLead(selectedId, addLeadData);
2185
+ showToast("Lead added", "success");
2186
+ setAddLeadOpen(false);
2187
+ setAddLeadData({ phoneNumber: "", callerName: "", priority: 5 });
2188
+ refetchLeads(0);
2189
+ setLeadPage(0);
2190
+ } catch (err2) {
2191
+ showToast(((_b2 = (_a2 = err2 == null ? void 0 : err2.response) == null ? void 0 : _a2.data) == null ? void 0 : _b2.message) || (err2 == null ? void 0 : err2.message) || "Failed to add lead", "error");
2192
+ } finally {
2193
+ setAddLeadSaving(false);
2194
+ }
2195
+ };
2196
+ const handleImport = async () => {
2197
+ var _a2, _b2;
2198
+ if (!selectedId || !importFile) return;
2199
+ setImporting(true);
2200
+ try {
2201
+ const result = await uploadLeadsExcel(selectedId, importFile);
2202
+ showToast((result == null ? void 0 : result.message) || "Leads uploaded", "success");
2203
+ setImportFile(null);
2204
+ setImportOpen(false);
2205
+ refetchLeads(0);
2206
+ setLeadPage(0);
2207
+ } catch (err) {
2208
+ showToast(((_b2 = (_a2 = err == null ? void 0 : err.response) == null ? void 0 : _a2.data) == null ? void 0 : _b2.message) || (err == null ? void 0 : err.message) || "Upload failed", "error");
2209
+ } finally {
2210
+ setImporting(false);
2211
+ }
2212
+ };
2213
+ const handleExport = async () => {
2214
+ var _a2, _b2;
2215
+ if (!selectedId) return;
2216
+ try {
2217
+ await exportLeads(selectedId);
2218
+ showToast("Leads exported", "success");
2219
+ } catch (err) {
2220
+ showToast(((_b2 = (_a2 = err == null ? void 0 : err.response) == null ? void 0 : _a2.data) == null ? void 0 : _b2.message) || (err == null ? void 0 : err.message) || "Export failed", "error");
2221
+ }
2222
+ };
2223
+ const handleDownloadTemplate = async () => {
2224
+ var _a2, _b2;
2225
+ if (!selectedId) return;
2226
+ try {
2227
+ await downloadLeadTemplate(selectedId);
2228
+ } catch (err) {
2229
+ showToast(((_b2 = (_a2 = err == null ? void 0 : err.response) == null ? void 0 : _a2.data) == null ? void 0 : _b2.message) || (err == null ? void 0 : err.message) || "Download failed", "error");
2230
+ }
2231
+ };
2232
+ const handleDialPreview = async (leadId) => {
2233
+ var _a2, _b2;
2234
+ if (!selectedId) return;
2235
+ setDialLoading(leadId);
2236
+ try {
2237
+ const res = await dialPreview(selectedId, leadId);
2238
+ showToast((res == null ? void 0 : res.message) || "Preview dial initiated", "success");
2239
+ } catch (err) {
2240
+ showToast(((_b2 = (_a2 = err == null ? void 0 : err.response) == null ? void 0 : _a2.data) == null ? void 0 : _b2.message) || (err == null ? void 0 : err.message) || "Dial failed", "error");
2241
+ } finally {
2242
+ setDialLoading(null);
2243
+ }
2244
+ };
2245
+ const confirmDeleteLead = async () => {
2246
+ var _a2, _b2;
2247
+ if (!selectedId || !deleteLeadTarget) return;
2248
+ setDeletingLead(true);
2249
+ try {
2250
+ await deleteLead(selectedId, deleteLeadTarget.id);
2251
+ showToast("Lead deleted", "success");
2252
+ setDeleteLeadOpen(false);
2253
+ setDeleteLeadTarget(null);
2254
+ refetchLeads(leadPage);
2255
+ } catch (err) {
2256
+ showToast(((_b2 = (_a2 = err == null ? void 0 : err.response) == null ? void 0 : _a2.data) == null ? void 0 : _b2.message) || (err == null ? void 0 : err.message) || "Delete failed", "error");
2257
+ } finally {
2258
+ setDeletingLead(false);
2259
+ }
2260
+ };
2261
+ const sc = selected;
2262
+ const scActive = ((_b = sc == null ? void 0 : sc.status) == null ? void 0 : _b.toLowerCase()) === "active";
2263
+ const scDraft = ((_c = sc == null ? void 0 : sc.status) == null ? void 0 : _c.toLowerCase()) === "draft";
2264
+ const scPaused = ((_d = sc == null ? void 0 : sc.status) == null ? void 0 : _d.toLowerCase()) === "paused";
2265
+ const scArchived = ((_e = sc == null ? void 0 : sc.status) == null ? void 0 : _e.toLowerCase()) === "archived";
2266
+ return /* @__PURE__ */ jsxs(Box, { sx: { fontFamily: "poppins, Arial, sans-serif" }, children: [
2267
+ /* @__PURE__ */ jsx2(
2268
+ SDKPageHeader,
2269
+ {
2270
+ title: "Call Scheduling",
2271
+ actions: /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: "center", gap: 1 }, children: [
2272
+ /* @__PURE__ */ jsx2(
2273
+ SDKButton,
2274
+ {
2275
+ startIcon: /* @__PURE__ */ jsx2(RefreshIcon, {}),
2276
+ onClick: () => {
2277
+ fetchCampaigns();
2278
+ if (selectedId) refetchLeads();
2279
+ },
2280
+ children: "Refresh"
2281
+ }
2282
+ ),
2283
+ /* @__PURE__ */ jsx2(
2284
+ SDKPermissionGuard,
2285
+ {
2286
+ permissions: [
2287
+ SDK_PERMISSIONS.CAMPAIGNS_CREATE,
2288
+ SDK_PERMISSIONS.CAMPAIGNS_MANAGE
2289
+ ],
2290
+ showFallback: false,
2291
+ children: /* @__PURE__ */ jsx2(SDKButton, { startIcon: /* @__PURE__ */ jsx2(AddIcon, {}), onClick: handleOpenCreate, children: "New Campaign" })
2292
+ }
2293
+ )
2294
+ ] })
2295
+ }
2296
+ ),
2297
+ /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", flexDirection: { xs: "column", md: "row" }, gap: 1.5, p: 1.5 }, children: [
2298
+ /* @__PURE__ */ jsx2(
2299
+ Paper,
2300
+ {
2301
+ elevation: 0,
2302
+ sx: {
2303
+ width: campaignListCollapsed ? { xs: "100%", md: 48 } : { xs: "100%", md: 280, lg: 320 },
2304
+ minWidth: campaignListCollapsed ? { xs: "auto", md: 48 } : { xs: "auto", md: 240 },
2305
+ flexShrink: 0,
2306
+ borderRadius: "16px",
2307
+ display: "flex",
2308
+ flexDirection: "column",
2309
+ maxHeight: { xs: campaignListCollapsed ? "auto" : 260, md: "calc(100vh - 160px)" },
2310
+ overflow: "hidden",
2311
+ border: "1px solid #e0e0e0",
2312
+ boxShadow: "0 1px 3px rgba(0,0,0,0.08)",
2313
+ transition: "width 0.2s ease, min-width 0.2s ease"
2314
+ },
2315
+ children: campaignListCollapsed ? /* @__PURE__ */ jsxs(Box, { sx: {
2316
+ display: "flex",
2317
+ flexDirection: { xs: "row", md: "column" },
2318
+ alignItems: "center",
2319
+ gap: 0.75,
2320
+ p: 0.75,
2321
+ height: "100%",
2322
+ overflowY: { xs: "visible", md: "auto" },
2323
+ overflowX: { xs: "auto", md: "visible" }
2324
+ }, children: [
2325
+ /* @__PURE__ */ jsx2(Tooltip, { title: "Expand campaigns", arrow: true, placement: "right", children: /* @__PURE__ */ jsx2(
2326
+ IconButton,
2327
+ {
2328
+ size: "small",
2329
+ onClick: () => setCampaignListCollapsed(false),
2330
+ sx: {
2331
+ color: "#1A5F6C",
2332
+ backgroundColor: "#f0f7f8",
2333
+ flexShrink: 0,
2334
+ "&:hover": { backgroundColor: "#e0eff1" }
2335
+ },
2336
+ children: /* @__PURE__ */ jsx2(ChevronRightIcon, { fontSize: "small" })
2337
+ }
2338
+ ) }),
2339
+ visibleCampaigns.map((c, idx) => {
2340
+ var _a2;
2341
+ const isSel = c.id === selectedId;
2342
+ const status = (c.status || "draft").toLowerCase();
2343
+ const statusColor = (_a2 = STATUS_COLORS[status]) != null ? _a2 : "#9e9e9e";
2344
+ return /* @__PURE__ */ jsx2(
2345
+ Tooltip,
2346
+ {
2347
+ arrow: true,
2348
+ placement: "right",
2349
+ title: `${c.name} \u2022 ${c.status || "draft"}`,
2350
+ children: /* @__PURE__ */ jsx2(
2351
+ Box,
2352
+ {
2353
+ onClick: () => handleSelectCampaign(c.id),
2354
+ sx: {
2355
+ width: 32,
2356
+ height: 32,
2357
+ borderRadius: "8px",
2358
+ display: "flex",
2359
+ alignItems: "center",
2360
+ justifyContent: "center",
2361
+ cursor: "pointer",
2362
+ flexShrink: 0,
2363
+ backgroundColor: isSel ? "#fff" : "#fafafa",
2364
+ color: "#333",
2365
+ fontFamily: "poppins, Arial, sans-serif",
2366
+ fontWeight: 700,
2367
+ fontSize: "0.8rem",
2368
+ borderLeft: `3px solid ${statusColor}`,
2369
+ boxShadow: isSel ? `-3px 0 8px ${statusColor}66` : `-2px 0 4px ${statusColor}33`,
2370
+ transition: "box-shadow 0.15s ease",
2371
+ "&:hover": {
2372
+ boxShadow: `-3px 0 8px ${statusColor}80`
2373
+ }
2374
+ },
2375
+ children: idx + 1
2376
+ }
2377
+ )
2378
+ },
2379
+ c.id
2380
+ );
2381
+ })
2382
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
2383
+ /* @__PURE__ */ jsxs(Box, { sx: {
2384
+ display: "flex",
2385
+ alignItems: "center",
2386
+ justifyContent: "space-between",
2387
+ px: 2,
2388
+ py: 1.25,
2389
+ borderBottom: "1px solid #eee",
2390
+ backgroundColor: "#fafafa",
2391
+ gap: 1
2392
+ }, children: [
2393
+ /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: "center", gap: 0.5, minWidth: 0 }, children: [
2394
+ /* @__PURE__ */ jsx2(Tooltip, { title: "Minimize", arrow: true, children: /* @__PURE__ */ jsx2(
2395
+ IconButton,
2396
+ {
2397
+ size: "small",
2398
+ onClick: () => setCampaignListCollapsed(true),
2399
+ sx: { p: 0.5, color: "#666" },
2400
+ children: /* @__PURE__ */ jsx2(ChevronLeftIcon, { fontSize: "small" })
2401
+ }
2402
+ ) }),
2403
+ /* @__PURE__ */ jsx2(Typography, { sx: { fontWeight: 700, fontSize: "0.95rem", color: "#333", fontFamily: "poppins, Arial, sans-serif" }, children: "Campaigns" })
2404
+ ] }),
2405
+ /* @__PURE__ */ jsx2(
2406
+ FormControlLabel,
2407
+ {
2408
+ control: /* @__PURE__ */ jsx2(
2409
+ Checkbox,
2410
+ {
2411
+ size: "small",
2412
+ checked: showArchived,
2413
+ onChange: (e) => setShowArchived(e.target.checked),
2414
+ sx: { p: 0.5 }
2415
+ }
2416
+ ),
2417
+ label: /* @__PURE__ */ jsx2(Typography, { sx: { fontSize: "0.78rem", color: "#666" }, children: "Show archived" }),
2418
+ sx: { mr: 0 }
2419
+ }
2420
+ )
2421
+ ] }),
2422
+ /* @__PURE__ */ jsx2(Box, { sx: { flex: 1, overflow: "auto", p: 1 }, children: loading ? /* @__PURE__ */ jsx2(Box, { sx: { display: "flex", justifyContent: "center", py: 4 }, children: /* @__PURE__ */ jsx2(CircularProgress, { size: 24, sx: { color: "#1A5F6C" } }) }) : visibleCampaigns.length === 0 ? /* @__PURE__ */ jsx2(Typography, { sx: { textAlign: "center", py: 3, color: "#999", fontSize: "0.85rem" }, children: "No campaigns" }) : visibleCampaigns.map((c) => {
2423
+ var _a2, _b2;
2424
+ const isSel = c.id === selectedId;
2425
+ const wStr = `${((_a2 = c.startTime) == null ? void 0 : _a2.slice(0, 5)) || "09:00"}\u2013${((_b2 = c.endTime) == null ? void 0 : _b2.slice(0, 5)) || "17:00"}`;
2426
+ return /* @__PURE__ */ jsxs(
2427
+ Paper,
2428
+ {
2429
+ elevation: 0,
2430
+ onClick: () => handleSelectCampaign(c.id),
2431
+ sx: isSel ? campaignCardSelectedSx : __spreadProps(__spreadValues({}, campaignCardBaseSx), {
2432
+ "&:hover": { borderColor: "#1A5F6C", backgroundColor: "#f5fafb", boxShadow: "0 2px 6px rgba(26,95,108,0.1)" }
2433
+ }),
2434
+ children: [
2435
+ /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", justifyContent: "space-between", alignItems: "center", mb: 0.5 }, children: [
2436
+ /* @__PURE__ */ jsx2(Typography, { sx: { fontWeight: 600, fontSize: "0.88rem", color: "#1a1a1a", fontFamily: "poppins, Arial, sans-serif" }, children: c.name }),
2437
+ /* @__PURE__ */ jsx2(Chip, { label: c.status || "draft", size: "small", sx: statusChipSx(c.status) })
2438
+ ] }),
2439
+ /* @__PURE__ */ jsxs(Typography, { sx: { fontSize: "0.73rem", color: "#999", fontFamily: "poppins, Arial, sans-serif" }, children: [
2440
+ c.dialingMode,
2441
+ " \xB7 TZ: ",
2442
+ c.timezone || "Etc/UTC",
2443
+ " \xB7 ",
2444
+ wStr
2445
+ ] })
2446
+ ]
2447
+ },
2448
+ c.id
2449
+ );
2450
+ }) })
2451
+ ] })
2452
+ }
2453
+ ),
2454
+ /* @__PURE__ */ jsx2(Box, { sx: { flex: 1, display: "flex", flexDirection: "column", gap: 1.5, minWidth: 0, overflow: "hidden" }, children: !sc ? /* @__PURE__ */ jsx2(
2455
+ Paper,
2456
+ {
2457
+ elevation: 0,
2458
+ sx: {
2459
+ borderRadius: "16px",
2460
+ display: "flex",
2461
+ alignItems: "center",
2462
+ justifyContent: "center",
2463
+ minHeight: 200,
2464
+ border: "2px dashed #d0d0d0",
2465
+ backgroundColor: "#fafafa"
2466
+ },
2467
+ children: /* @__PURE__ */ jsxs(Box, { sx: { textAlign: "center" }, children: [
2468
+ /* @__PURE__ */ jsx2(SettingsIcon, { sx: { fontSize: 40, color: "#ccc", mb: 1 } }),
2469
+ /* @__PURE__ */ jsx2(Typography, { sx: { fontSize: "0.95rem", color: "#999", fontFamily: "poppins, Arial, sans-serif" }, children: "Select a campaign to view details" })
2470
+ ] })
2471
+ }
2472
+ ) : /* @__PURE__ */ jsxs(Fragment, { children: [
2473
+ /* @__PURE__ */ jsxs(
2474
+ Paper,
2475
+ {
2476
+ elevation: 0,
2477
+ sx: {
2478
+ borderRadius: "16px",
2479
+ p: { xs: 1.5, sm: 2.5 },
2480
+ border: "1px solid #e0e0e0",
2481
+ boxShadow: "0 1px 3px rgba(0,0,0,0.08)"
2482
+ },
2483
+ children: [
2484
+ /* @__PURE__ */ jsxs(Box, { sx: {
2485
+ display: "flex",
2486
+ alignItems: { xs: "flex-start", sm: "center" },
2487
+ justifyContent: "space-between",
2488
+ flexWrap: "wrap",
2489
+ gap: 1,
2490
+ mb: 2
2491
+ }, children: [
2492
+ /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: "center", gap: 1, flexWrap: "wrap" }, children: [
2493
+ /* @__PURE__ */ jsx2(Typography, { sx: { fontWeight: 700, fontSize: { xs: "1rem", sm: "1.2rem" }, color: "#1a1a1a", fontFamily: "poppins, Arial, sans-serif" }, children: sc.name }),
2494
+ /* @__PURE__ */ jsx2(Chip, { label: sc.status || "draft", size: "small", sx: statusChipSx(sc.status) })
2495
+ ] }),
2496
+ !scArchived && /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", gap: 1, flexWrap: "wrap" }, children: [
2497
+ /* @__PURE__ */ jsx2(
2498
+ SDKPermissionGuard,
2499
+ {
2500
+ permissions: [
2501
+ SDK_PERMISSIONS.CAMPAIGNS_UPDATE,
2502
+ SDK_PERMISSIONS.CAMPAIGNS_MANAGE
2503
+ ],
2504
+ showFallback: false,
2505
+ children: /* @__PURE__ */ jsx2(
2506
+ SDKButton,
2507
+ {
2508
+ variant: "outlined",
2509
+ startIcon: /* @__PURE__ */ jsx2(EditIcon, {}),
2510
+ onClick: () => handleOpenEdit(sc),
2511
+ children: "Edit"
2512
+ }
2513
+ )
2514
+ }
2515
+ ),
2516
+ (scDraft || scPaused) && /* @__PURE__ */ jsx2(
2517
+ SDKPermissionGuard,
2518
+ {
2519
+ permissions: [
2520
+ SDK_PERMISSIONS.CAMPAIGNS_CONTROL,
2521
+ SDK_PERMISSIONS.CAMPAIGNS_MANAGE
2522
+ ],
2523
+ showFallback: false,
2524
+ children: /* @__PURE__ */ jsx2(
2525
+ SDKButton,
2526
+ {
2527
+ startIcon: /* @__PURE__ */ jsx2(PlayArrowIcon, {}),
2528
+ onClick: () => handleStart(sc),
2529
+ sx: { backgroundColor: "#4caf50", "&:hover": { backgroundColor: "#388e3c" } },
2530
+ children: "Start"
2531
+ }
2532
+ )
2533
+ }
2534
+ ),
2535
+ scActive && /* @__PURE__ */ jsx2(
2536
+ SDKPermissionGuard,
2537
+ {
2538
+ permissions: [
2539
+ SDK_PERMISSIONS.CAMPAIGNS_CONTROL,
2540
+ SDK_PERMISSIONS.CAMPAIGNS_MANAGE
2541
+ ],
2542
+ showFallback: false,
2543
+ children: /* @__PURE__ */ jsx2(
2544
+ SDKButton,
2545
+ {
2546
+ startIcon: /* @__PURE__ */ jsx2(PauseIcon, {}),
2547
+ onClick: () => handlePause(sc),
2548
+ sx: { backgroundColor: "#ff9800", boxShadow: "0 2px 8px rgba(255,152,0,0.25)", "&:hover": { backgroundColor: "#f57c00" } },
2549
+ children: "Pause"
2550
+ }
2551
+ )
2552
+ }
2553
+ ),
2554
+ /* @__PURE__ */ jsx2(
2555
+ SDKPermissionGuard,
2556
+ {
2557
+ permissions: [
2558
+ SDK_PERMISSIONS.CAMPAIGNS_DELETE,
2559
+ SDK_PERMISSIONS.CAMPAIGNS_MANAGE
2560
+ ],
2561
+ showFallback: false,
2562
+ children: /* @__PURE__ */ jsx2(
2563
+ SDKButton,
2564
+ {
2565
+ variant: "danger",
2566
+ startIcon: /* @__PURE__ */ jsx2(ArchiveIcon, {}),
2567
+ onClick: () => {
2568
+ setArchiveTarget(sc);
2569
+ setArchiveOpen(true);
2570
+ },
2571
+ children: "Archive"
2572
+ }
2573
+ )
2574
+ }
2575
+ )
2576
+ ] })
2577
+ ] }),
2578
+ sc.description && /* @__PURE__ */ jsx2(Typography, { sx: { fontSize: "0.85rem", color: "#666", mb: 1.5, fontFamily: "poppins, Arial, sans-serif", lineHeight: 1.5 }, children: sc.description }),
2579
+ /* @__PURE__ */ jsx2(
2580
+ Box,
2581
+ {
2582
+ sx: {
2583
+ overflowX: "auto",
2584
+ pb: 0.5,
2585
+ "&::-webkit-scrollbar": { height: 6 },
2586
+ "&::-webkit-scrollbar-track": { backgroundColor: "#f0f0f0", borderRadius: 3 },
2587
+ "&::-webkit-scrollbar-thumb": {
2588
+ backgroundColor: "#c0c0c0",
2589
+ borderRadius: 3,
2590
+ "&:hover": { backgroundColor: "#a0a0a0" }
2591
+ }
2592
+ },
2593
+ children: /* @__PURE__ */ jsx2(
2594
+ Box,
2595
+ {
2596
+ sx: {
2597
+ display: "flex",
2598
+ flexWrap: "nowrap",
2599
+ gap: 1.5
2600
+ },
2601
+ children: [
2602
+ {
2603
+ accent: "#1565c0",
2604
+ fields: [
2605
+ { label: "Type", value: sc.campaignType || "N/A" },
2606
+ { label: "Mode", value: sc.dialingMode || "N/A" }
2607
+ ]
2608
+ },
2609
+ {
2610
+ accent: "#2e7d32",
2611
+ fields: [
2612
+ { label: "Agent", value: sc.agentType || "HUMAN" },
2613
+ { label: "Dialer", value: (leadsMeta == null ? void 0 : leadsMeta.isDialerEnabled) ? "Enabled" : "Disabled" }
2614
+ ]
2615
+ },
2616
+ {
2617
+ accent: "#c62828",
2618
+ fields: [
2619
+ { label: "Priority", value: leadPriorityChipSx(sc.priority).label },
2620
+ { label: "Max Concurrent", value: String((_f = sc.maxConcurrentCalls) != null ? _f : 1) }
2621
+ ]
2622
+ },
2623
+ {
2624
+ accent: "#283593",
2625
+ fields: [
2626
+ { label: "Retry", value: `${(_g = sc.retryIntervalMinutes) != null ? _g : 15}min / ${(_h = sc.maxAttempts) != null ? _h : 3} attempts` },
2627
+ { label: "Leads", value: `${(_i = sc.totalLeads) != null ? _i : 0} total / ${(_j = sc.completedLeads) != null ? _j : 0} completed / ${(_k = sc.successfulCalls) != null ? _k : 0} success` }
2628
+ ]
2629
+ }
2630
+ ].map((card, idx) => /* @__PURE__ */ jsx2(
2631
+ Box,
2632
+ {
2633
+ sx: {
2634
+ display: "flex",
2635
+ flexDirection: "column",
2636
+ gap: 0.5,
2637
+ px: 1.5,
2638
+ py: 1,
2639
+ borderRadius: "10px",
2640
+ backgroundColor: "#fafafa",
2641
+ borderLeft: `3px solid ${card.accent}`,
2642
+ flex: "0 0 auto",
2643
+ minWidth: 180
2644
+ },
2645
+ children: card.fields.map((field) => /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: "center", gap: 0.75 }, children: [
2646
+ /* @__PURE__ */ jsxs(Typography, { sx: { fontFamily: "poppins, Arial, sans-serif", fontSize: "0.72rem", fontWeight: 600, color: "#888", whiteSpace: "nowrap", flexShrink: 0 }, children: [
2647
+ field.label,
2648
+ ":"
2649
+ ] }),
2650
+ /* @__PURE__ */ jsx2(Typography, { sx: { fontFamily: "poppins, Arial, sans-serif", fontSize: "0.75rem", fontWeight: 700, color: "#333", whiteSpace: "nowrap" }, children: field.value })
2651
+ ] }, field.label))
2652
+ },
2653
+ idx
2654
+ ))
2655
+ }
2656
+ )
2657
+ }
2658
+ )
2659
+ ]
2660
+ }
2661
+ ),
2662
+ /* @__PURE__ */ jsx2(SDKPermissionGuard, { permission: SDK_PERMISSIONS.CAMPAIGNS_LEADS_READ, showFallback: false, children: /* @__PURE__ */ jsxs(
2663
+ Paper,
2664
+ {
2665
+ elevation: 0,
2666
+ sx: {
2667
+ borderRadius: "16px",
2668
+ overflow: "hidden",
2669
+ border: "1px solid #e0e0e0",
2670
+ boxShadow: "0 1px 3px rgba(0,0,0,0.08)"
2671
+ },
2672
+ children: [
2673
+ /* @__PURE__ */ jsxs(Box, { sx: {
2674
+ display: "flex",
2675
+ alignItems: { xs: "flex-start", sm: "center" },
2676
+ justifyContent: "space-between",
2677
+ flexDirection: { xs: "column", sm: "row" },
2678
+ gap: 1,
2679
+ px: { xs: 1.5, sm: 2 },
2680
+ py: 1.5,
2681
+ borderBottom: "1px solid #eee",
2682
+ backgroundColor: "#fafafa"
2683
+ }, children: [
2684
+ /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: "center", gap: 1, flexWrap: "wrap" }, children: [
2685
+ /* @__PURE__ */ jsx2(Typography, { sx: { fontWeight: 700, fontSize: "1rem", color: "#1a1a1a", fontFamily: "poppins, Arial, sans-serif" }, children: "Leads" }),
2686
+ /* @__PURE__ */ jsx2(
2687
+ SDKPermissionGuard,
2688
+ {
2689
+ permissions: [
2690
+ SDK_PERMISSIONS.CAMPAIGNS_LEADS_IMPORT
2691
+ ],
2692
+ showFallback: false,
2693
+ children: /* @__PURE__ */ jsx2(SDKButton, { variant: "outlined", onClick: () => setImportOpen(true), disabled: scArchived, startIcon: /* @__PURE__ */ jsx2(UploadFileIcon, { sx: { fontSize: 15 } }), size: "small", children: "Import Leads" })
2694
+ }
2695
+ ),
2696
+ /* @__PURE__ */ jsx2(
2697
+ SDKPermissionGuard,
2698
+ {
2699
+ permissions: [
2700
+ SDK_PERMISSIONS.CAMPAIGNS_READ,
2701
+ SDK_PERMISSIONS.CAMPAIGNS_MANAGE
2702
+ ],
2703
+ showFallback: false,
2704
+ children: /* @__PURE__ */ jsx2(SDKButton, { variant: "primary", onClick: handleExport, disabled: leadsLoading || leadTotal === 0, startIcon: /* @__PURE__ */ jsx2(DownloadIcon, { sx: { fontSize: 15 } }), size: "small", children: "Export Excel" })
2705
+ }
2706
+ ),
2707
+ /* @__PURE__ */ jsx2(
2708
+ SDKPermissionGuard,
2709
+ {
2710
+ permissions: [
2711
+ SDK_PERMISSIONS.CAMPAIGNS_LEADS_CREATE
2712
+ ],
2713
+ showFallback: false,
2714
+ children: /* @__PURE__ */ jsx2(SDKButton, { variant: "primary", onClick: () => setAddLeadOpen(true), disabled: scArchived, startIcon: /* @__PURE__ */ jsx2(AddIcon, { sx: { fontSize: 15 } }), size: "small", children: "Add Lead" })
2715
+ }
2716
+ )
2717
+ ] }),
2718
+ /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: "center", gap: 1, width: { xs: "100%", sm: "auto" } }, children: [
2719
+ /* @__PURE__ */ jsx2(
2720
+ OutlinedInput,
2721
+ {
2722
+ size: "small",
2723
+ value: leadSearch,
2724
+ onChange: (e) => {
2725
+ setLeadSearch(e.target.value);
2726
+ setLeadPage(0);
2727
+ },
2728
+ placeholder: "Search number...",
2729
+ sx: { width: { xs: "100%", sm: 200 }, fontSize: "0.85rem", height: 34, borderRadius: "20px" },
2730
+ startAdornment: /* @__PURE__ */ jsx2(InputAdornment, { position: "start", children: /* @__PURE__ */ jsx2(SearchIcon, { sx: { fontSize: 16, color: "#aaa" } }) })
2731
+ }
2732
+ ),
2733
+ /* @__PURE__ */ jsx2(FormControl, { size: "small", sx: { minWidth: 130 }, children: /* @__PURE__ */ jsx2(
2734
+ Select,
2735
+ {
2736
+ value: leadStatusFilter,
2737
+ onChange: (e) => {
2738
+ setLeadStatusFilter(e.target.value);
2739
+ setLeadPage(0);
2740
+ },
2741
+ sx: { height: 34, borderRadius: "30px", fontSize: "0.85rem" },
2742
+ children: LEAD_STATUSES.map((s) => /* @__PURE__ */ jsx2(MenuItem, { value: s, children: s }, s))
2743
+ }
2744
+ ) })
2745
+ ] })
2746
+ ] }),
2747
+ /* @__PURE__ */ jsx2(Box, { sx: {
2748
+ overflowX: "auto",
2749
+ overflowY: "visible",
2750
+ WebkitOverflowScrolling: "touch",
2751
+ "&::-webkit-scrollbar": { height: 4 },
2752
+ "&::-webkit-scrollbar-thumb": { backgroundColor: "#ccc", borderRadius: 2 }
2753
+ }, children: /* @__PURE__ */ jsxs(Table, { size: "small", sx: { minWidth: 980 }, children: [
2754
+ /* @__PURE__ */ jsx2(TableHead, { children: /* @__PURE__ */ jsx2(TableRow, { sx: { backgroundColor: "#f1f1f1" }, children: [
2755
+ "Number",
2756
+ "Status",
2757
+ "Priority",
2758
+ "Source",
2759
+ "Call ID",
2760
+ "Queue Name",
2761
+ "Attempts",
2762
+ "Created At",
2763
+ "Last Attempt",
2764
+ "Next Attempt",
2765
+ "Last Outcome",
2766
+ "Completed At",
2767
+ "Notes",
2768
+ "Outcome",
2769
+ "Actions"
2770
+ ].map((col) => /* @__PURE__ */ jsx2(TableCell, { sx: __spreadValues(__spreadValues({}, headCellSx), col === "Actions" ? { textAlign: "center" } : {}), children: col }, col)) }) }),
2771
+ /* @__PURE__ */ jsx2(TableBody, { children: leadsLoading ? /* @__PURE__ */ jsx2(TableRow, { children: /* @__PURE__ */ jsx2(TableCell, { colSpan: 14, align: "center", sx: { py: 4 }, children: /* @__PURE__ */ jsx2(CircularProgress, { size: 24, sx: { color: "#1A5F6C" } }) }) }) : leads.length === 0 ? /* @__PURE__ */ jsx2(TableRow, { children: /* @__PURE__ */ jsx2(
2772
+ TableCell,
2773
+ {
2774
+ colSpan: 14,
2775
+ align: "center",
2776
+ sx: { py: 4, color: "#999", fontFamily: "poppins, Arial, sans-serif" },
2777
+ children: 'No leads found. Add leads using "Add Lead" or "Import Leads".'
2778
+ }
2779
+ ) }) : leads.map((lead) => {
2780
+ var _a2;
2781
+ const nonDeletable = ["IN_PROGRESS", "COMPLETED", "FAILED", "DO_NOT_CALL"];
2782
+ const leadStatus = (lead.status || "").toUpperCase();
2783
+ const deleteDisabled = nonDeletable.includes(leadStatus);
2784
+ const isDialerEnabled = !!(leadsMeta == null ? void 0 : leadsMeta.isDialerEnabled);
2785
+ const isCompleted = leadStatus === "COMPLETED";
2786
+ const isInProgress = leadStatus === "IN_PROGRESS";
2787
+ const isDialable = isDialerEnabled && hasOutboundPermission && isAgentIdle && !isCompleted && !isInProgress && dialLoading !== lead.id;
2788
+ const dialTooltip = !isDialerEnabled ? "Dialer is not enabled" : !hasOutboundPermission ? "No outbound call permission" : isCompleted ? "Lead is completed" : isInProgress ? "Lead is in progress" : !isAgentIdle ? "Agent is not idle" : dialLoading === lead.id ? "Dialing\u2026" : `Call ${lead.phoneNumber}`;
2789
+ const { chip: prioChip, label: prioLabel } = leadPriorityChipSx(lead.priority);
2790
+ return /* @__PURE__ */ jsxs(TableRow, { sx: tableRowSx, children: [
2791
+ /* @__PURE__ */ jsx2(TableCell, { sx: bodyCellSx, children: lead.phoneNumber }),
2792
+ /* @__PURE__ */ jsx2(TableCell, { sx: bodyCellSx, children: /* @__PURE__ */ jsx2(Chip, { label: lead.status || "pending", size: "small", sx: leadStatusChipSx(lead.status) }) }),
2793
+ /* @__PURE__ */ jsx2(TableCell, { sx: bodyCellSx, children: /* @__PURE__ */ jsx2(Chip, { label: prioLabel, size: "small", sx: prioChip }) }),
2794
+ /* @__PURE__ */ jsx2(TableCell, { sx: bodyCellSx, children: lead.source || "" }),
2795
+ /* @__PURE__ */ jsx2(TableCell, { sx: __spreadProps(__spreadValues({}, bodyCellSx), { maxWidth: 140, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }), children: /* @__PURE__ */ jsx2(Tooltip, { title: lead.originalCallId || "", children: /* @__PURE__ */ jsx2("span", { children: lead.originalCallId || "" }) }) }),
2796
+ /* @__PURE__ */ jsx2(TableCell, { sx: bodyCellSx, children: lead.queueName || "" }),
2797
+ /* @__PURE__ */ jsx2(TableCell, { sx: bodyCellSx, children: (_a2 = lead.attemptCount) != null ? _a2 : 0 }),
2798
+ /* @__PURE__ */ jsx2(TableCell, { sx: __spreadProps(__spreadValues({}, bodyCellSx), { whiteSpace: "nowrap" }), children: lead.createdAt ? new Date(lead.createdAt).toLocaleString() : "" }),
2799
+ /* @__PURE__ */ jsx2(TableCell, { sx: __spreadProps(__spreadValues({}, bodyCellSx), { whiteSpace: "nowrap" }), children: lead.lastAttemptAt ? new Date(lead.lastAttemptAt).toLocaleString() : "" }),
2800
+ /* @__PURE__ */ jsx2(TableCell, { sx: __spreadProps(__spreadValues({}, bodyCellSx), { whiteSpace: "nowrap" }), children: lead.nextAttemptAt ? new Date(lead.nextAttemptAt).toLocaleString() : "" }),
2801
+ /* @__PURE__ */ jsx2(TableCell, { sx: bodyCellSx, children: lead.lastOutcome || "" }),
2802
+ /* @__PURE__ */ jsx2(TableCell, { sx: __spreadProps(__spreadValues({}, bodyCellSx), { whiteSpace: "nowrap" }), children: lead.completedAt ? new Date(lead.completedAt).toLocaleString() : "" }),
2803
+ /* @__PURE__ */ jsx2(TableCell, { sx: __spreadProps(__spreadValues({}, bodyCellSx), { maxWidth: 150, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }), children: lead.notes ? /* @__PURE__ */ jsx2(Tooltip, { title: lead.notes, arrow: true, placement: "top", children: /* @__PURE__ */ jsx2("span", { children: lead.notes }) }) : "" }),
2804
+ /* @__PURE__ */ jsx2(TableCell, { sx: bodyCellSx, children: lead.lastReason || "" }),
2805
+ /* @__PURE__ */ jsxs(TableCell, { sx: __spreadProps(__spreadValues({}, bodyCellSx), { textAlign: "center", whiteSpace: "nowrap" }), children: [
2806
+ /* @__PURE__ */ jsx2(Tooltip, { title: dialTooltip, children: /* @__PURE__ */ jsx2("span", { children: /* @__PURE__ */ jsx2(
2807
+ IconButton,
2808
+ {
2809
+ size: "small",
2810
+ onClick: () => handleDialPreview(lead.id),
2811
+ disabled: !isDialable,
2812
+ sx: {
2813
+ color: isDialable ? "#2e7d32" : "#bdbdbd",
2814
+ backgroundColor: isDialable ? "#e8f5e9" : "transparent",
2815
+ borderRadius: "50%",
2816
+ transition: "all 0.2s ease-in-out",
2817
+ "&:hover": {
2818
+ backgroundColor: isDialable ? "#43a047" : "transparent",
2819
+ color: isDialable ? "#fff" : "#bdbdbd",
2820
+ transform: isDialable ? "scale(1.2)" : "none",
2821
+ boxShadow: isDialable ? "0 0 8px rgba(67,160,71,0.5)" : "none"
2822
+ }
2823
+ },
2824
+ children: dialLoading === lead.id ? /* @__PURE__ */ jsx2(CircularProgress, { size: 16 }) : /* @__PURE__ */ jsx2(PhoneIcon, { sx: { fontSize: 18 } })
2825
+ }
2826
+ ) }) }),
2827
+ /* @__PURE__ */ jsx2(Tooltip, { title: lead.latestCallId || lead.originalCallId ? "View call details" : "No call data available", children: /* @__PURE__ */ jsx2("span", { children: /* @__PURE__ */ jsx2(
2828
+ IconButton,
2829
+ {
2830
+ size: "small",
2831
+ onClick: () => handleViewCallData(lead),
2832
+ disabled: !(lead.latestCallId || lead.originalCallId),
2833
+ sx: {
2834
+ ml: 0.5,
2835
+ color: lead.latestCallId || lead.originalCallId ? "#1A5F6C" : "#bdbdbd",
2836
+ "&:hover": { backgroundColor: "transparent" }
2837
+ },
2838
+ children: /* @__PURE__ */ jsx2(VisibilityOutlinedIcon, { sx: { fontSize: 18 } })
2839
+ }
2840
+ ) }) }),
2841
+ /* @__PURE__ */ jsx2(
2842
+ SDKPermissionGuard,
2843
+ {
2844
+ permissions: [
2845
+ SDK_PERMISSIONS.CAMPAIGNS_LEADS_DELETE
2846
+ ],
2847
+ showFallback: false,
2848
+ children: /* @__PURE__ */ jsx2(Tooltip, { title: deleteDisabled ? `Cannot delete \u2014 status is ${leadStatus.toLowerCase().replace("_", " ")}` : `Delete lead ${lead.phoneNumber}`, children: /* @__PURE__ */ jsx2("span", { children: /* @__PURE__ */ jsx2(
2849
+ IconButton,
2850
+ {
2851
+ size: "small",
2852
+ onClick: () => {
2853
+ setDeleteLeadTarget(lead);
2854
+ setDeleteLeadOpen(true);
2855
+ },
2856
+ disabled: deleteDisabled,
2857
+ sx: {
2858
+ ml: 0.5,
2859
+ color: deleteDisabled ? "#bdbdbd" : "#c62828",
2860
+ backgroundColor: deleteDisabled ? "transparent" : "#ffebee",
2861
+ borderRadius: "50%",
2862
+ transition: "all 0.2s ease-in-out",
2863
+ "&:hover": {
2864
+ backgroundColor: deleteDisabled ? "transparent" : "#d32f2f",
2865
+ color: deleteDisabled ? "#bdbdbd" : "#fff",
2866
+ transform: deleteDisabled ? "none" : "scale(1.2)",
2867
+ boxShadow: deleteDisabled ? "none" : "0 0 8px rgba(211,47,47,0.5)"
2868
+ }
2869
+ },
2870
+ children: /* @__PURE__ */ jsx2(DeleteIcon, { sx: { fontSize: 18 } })
2871
+ }
2872
+ ) }) })
2873
+ }
2874
+ )
2875
+ ] })
2876
+ ] }, lead.id);
2877
+ }) })
2878
+ ] }) }),
2879
+ leads.length > 0 && /* @__PURE__ */ jsx2(
2880
+ TablePagination,
2881
+ {
2882
+ component: "div",
2883
+ count: leadTotal,
2884
+ page: leadPage,
2885
+ rowsPerPage: leadRowsPerPage,
2886
+ onPageChange: (_, p) => {
2887
+ setLeadPage(p);
2888
+ refetchLeads(p);
2889
+ },
2890
+ onRowsPerPageChange: (e) => {
2891
+ setLeadRowsPerPage(parseInt(e.target.value, 10));
2892
+ setLeadPage(0);
2893
+ },
2894
+ rowsPerPageOptions: [10, 15, 25, 50, 100],
2895
+ sx: {
2896
+ fontSize: "0.82rem",
2897
+ "& .MuiTablePagination-toolbar": { minHeight: 40, px: 1 },
2898
+ "& .MuiTablePagination-selectLabel, & .MuiTablePagination-displayedRows": { fontSize: "0.82rem" }
2899
+ }
2900
+ }
2901
+ )
2902
+ ]
2903
+ }
2904
+ ) })
2905
+ ] }) })
2906
+ ] }),
2907
+ /* @__PURE__ */ jsx2(
2908
+ CampaignDialog,
2909
+ {
2910
+ open: dialogOpen,
2911
+ editingCampaign,
2912
+ formData,
2913
+ setFormData,
2914
+ saving,
2915
+ onSave: handleSave,
2916
+ onClose: () => setDialogOpen(false),
2917
+ parentQueueNameMap: queueNameMap,
2918
+ onQueuesRefreshed: handleQueuesRefreshed,
2919
+ onLeadsChange: () => {
2920
+ fetchCampaigns();
2921
+ if (selectedId) refetchLeads();
2922
+ }
2923
+ }
2924
+ ),
2925
+ /* @__PURE__ */ jsx2(
2926
+ AddLeadDialog,
2927
+ {
2928
+ open: addLeadOpen,
2929
+ data: addLeadData,
2930
+ onChange: setAddLeadData,
2931
+ saving: addLeadSaving,
2932
+ onSave: handleAddLead,
2933
+ onClose: () => {
2934
+ setAddLeadOpen(false);
2935
+ setAddLeadData({ phoneNumber: "", callerName: "", priority: 5 });
2936
+ }
2937
+ }
2938
+ ),
2939
+ /* @__PURE__ */ jsx2(
2940
+ ImportLeadsDialog,
2941
+ {
2942
+ open: importOpen,
2943
+ file: importFile,
2944
+ onFileChange: setImportFile,
2945
+ uploading: importing,
2946
+ onUpload: handleImport,
2947
+ onDownloadTemplate: handleDownloadTemplate,
2948
+ onClose: () => {
2949
+ setImportOpen(false);
2950
+ setImportFile(null);
2951
+ }
2952
+ }
2953
+ ),
2954
+ /* @__PURE__ */ jsx2(
2955
+ ConfirmDialog,
2956
+ {
2957
+ open: archiveOpen,
2958
+ title: "Archive Campaign",
2959
+ message: `Archive "${archiveTarget == null ? void 0 : archiveTarget.name}"? It will no longer run.`,
2960
+ loading: archiving,
2961
+ onConfirm: confirmArchive,
2962
+ onClose: () => {
2963
+ setArchiveOpen(false);
2964
+ setArchiveTarget(null);
2965
+ }
2966
+ }
2967
+ ),
2968
+ /* @__PURE__ */ jsx2(
2969
+ ConfirmDialog,
2970
+ {
2971
+ open: deleteLeadOpen,
2972
+ title: "Delete Lead",
2973
+ message: `Delete lead ${deleteLeadTarget == null ? void 0 : deleteLeadTarget.phoneNumber}? This cannot be undone.`,
2974
+ loading: deletingLead,
2975
+ onConfirm: confirmDeleteLead,
2976
+ onClose: () => {
2977
+ setDeleteLeadOpen(false);
2978
+ setDeleteLeadTarget(null);
2979
+ }
2980
+ }
2981
+ ),
2982
+ /* @__PURE__ */ jsx2(
2983
+ CallDataDialog,
2984
+ {
2985
+ open: callDataOpen,
2986
+ lead: callDataLead,
2987
+ data: callData,
2988
+ loading: callDataLoading,
2989
+ error: callDataError,
2990
+ onClose: () => {
2991
+ setCallDataOpen(false);
2992
+ setCallData(null);
2993
+ setCallDataError(null);
2994
+ setCallDataLead(null);
2995
+ }
2996
+ }
2997
+ )
2998
+ ] });
2999
+ });
3000
+ var Campaigns = () => /* @__PURE__ */ jsx2(SDKProvider, { children: /* @__PURE__ */ jsx2(CampaignsContent, {}) });
3001
+ var campaigns_default = Campaigns;
3002
+ export {
3003
+ campaigns_default as default
3004
+ };
3005
+ //# sourceMappingURL=campaigns-N2RLUJHH.mjs.map