ahs-cti 0.0.8 → 0.0.9

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 (139) hide show
  1. package/dist/agentDetailReport-F44HMQ5O.mjs +27 -0
  2. package/dist/agentDetailReport-F44HMQ5O.mjs.map +1 -0
  3. package/dist/{agentPerformanceReport-JZK5DN5E.mjs → agentPerformanceReport-TTOMNENK.mjs} +25 -15
  4. package/dist/{agentPerformanceReport-JZK5DN5E.mjs.map → agentPerformanceReport-TTOMNENK.mjs.map} +1 -1
  5. package/dist/auditReport-QTMAKVTN.mjs +26 -0
  6. package/dist/auditReport-QTMAKVTN.mjs.map +1 -0
  7. package/dist/{callHistory-T3M76D4B.mjs → callHistory-4J4J2XHA.mjs} +20 -10
  8. package/dist/{callHistory-T3M76D4B.mjs.map → callHistory-4J4J2XHA.mjs.map} +1 -1
  9. package/dist/{campaigns-5PVHXBSD.mjs → campaigns-N3UNUGQP.mjs} +23 -13
  10. package/dist/{campaigns-5PVHXBSD.mjs.map → campaigns-N3UNUGQP.mjs.map} +1 -1
  11. package/dist/{caroQualityAuditDashboard-EUDYZ3QY.mjs → caroQualityAuditDashboard-TNS4L2NR.mjs} +12 -2
  12. package/dist/{caroQualityAuditDashboard-EUDYZ3QY.mjs.map → caroQualityAuditDashboard-TNS4L2NR.mjs.map} +1 -1
  13. package/dist/{caroVoiceAI-GGJCVUIQ.mjs → caroVoiceAI-OUTAAIFE.mjs} +12 -2
  14. package/dist/{caroVoiceAI-GGJCVUIQ.mjs.map → caroVoiceAI-OUTAAIFE.mjs.map} +1 -1
  15. package/dist/{cdrReport-ZMDHSZUW.mjs → cdrReport-Z35OLYUL.mjs} +26 -16
  16. package/dist/{cdrReport-ZMDHSZUW.mjs.map → cdrReport-Z35OLYUL.mjs.map} +1 -1
  17. package/dist/chunk-3PNP6G5P.mjs +92 -0
  18. package/dist/chunk-3PNP6G5P.mjs.map +1 -0
  19. package/dist/{chunk-DF5EFKXC.mjs → chunk-45MLTWV7.mjs} +12 -2
  20. package/dist/{chunk-DF5EFKXC.mjs.map → chunk-45MLTWV7.mjs.map} +1 -1
  21. package/dist/chunk-635IIVZE.mjs +24 -0
  22. package/dist/{chunk-FRKV2U3I.mjs.map → chunk-635IIVZE.mjs.map} +1 -1
  23. package/dist/chunk-677RFPP5.mjs +24 -0
  24. package/dist/{chunk-7LE2VTAI.mjs.map → chunk-677RFPP5.mjs.map} +1 -1
  25. package/dist/{chunk-Q6G3MPS7.mjs → chunk-ERSNXW5X.mjs} +11 -1
  26. package/dist/{chunk-Q6G3MPS7.mjs.map → chunk-ERSNXW5X.mjs.map} +1 -1
  27. package/dist/{chunk-H7GRWLYI.mjs → chunk-G6KRLGGC.mjs} +13 -3
  28. package/dist/{chunk-H7GRWLYI.mjs.map → chunk-G6KRLGGC.mjs.map} +1 -1
  29. package/dist/chunk-GFVR3HLK.mjs +24 -0
  30. package/dist/{chunk-6WLG2PXL.mjs.map → chunk-GFVR3HLK.mjs.map} +1 -1
  31. package/dist/{chunk-E6KYWWAI.mjs → chunk-GTI2ZVQX.mjs} +12 -2
  32. package/dist/{chunk-E6KYWWAI.mjs.map → chunk-GTI2ZVQX.mjs.map} +1 -1
  33. package/dist/chunk-H22TUCN3.mjs +24 -0
  34. package/dist/{chunk-AOJRUZTO.mjs.map → chunk-H22TUCN3.mjs.map} +1 -1
  35. package/dist/{chunk-YAQYTUTX.mjs → chunk-HAOFUADN.mjs} +12 -2
  36. package/dist/{chunk-YAQYTUTX.mjs.map → chunk-HAOFUADN.mjs.map} +1 -1
  37. package/dist/{chunk-33QNSXP7.mjs → chunk-JHC7OUQG.mjs} +21 -11
  38. package/dist/chunk-JHC7OUQG.mjs.map +1 -0
  39. package/dist/chunk-KSVNZKRD.mjs +10930 -0
  40. package/dist/chunk-KSVNZKRD.mjs.map +1 -0
  41. package/dist/{chunk-VVDJLUYT.mjs → chunk-M7FJYZF6.mjs} +12 -2
  42. package/dist/{chunk-VVDJLUYT.mjs.map → chunk-M7FJYZF6.mjs.map} +1 -1
  43. package/dist/{chunk-DNTGBNZD.mjs → chunk-NDZDJWXY.mjs} +13 -3
  44. package/dist/{chunk-DNTGBNZD.mjs.map → chunk-NDZDJWXY.mjs.map} +1 -1
  45. package/dist/chunk-S2SMCH2C.mjs +71 -0
  46. package/dist/chunk-S2SMCH2C.mjs.map +1 -0
  47. package/dist/{chunk-IDZWA6HG.mjs → chunk-S34CQVTF.mjs} +14 -4
  48. package/dist/{chunk-IDZWA6HG.mjs.map → chunk-S34CQVTF.mjs.map} +1 -1
  49. package/dist/{chunk-2M3YEXYA.mjs → chunk-SUS5RUCA.mjs} +17 -7
  50. package/dist/{chunk-2M3YEXYA.mjs.map → chunk-SUS5RUCA.mjs.map} +1 -1
  51. package/dist/{chunk-3J7KQNEU.mjs → chunk-TCYBXDAP.mjs} +13 -3
  52. package/dist/{chunk-3J7KQNEU.mjs.map → chunk-TCYBXDAP.mjs.map} +1 -1
  53. package/dist/chunk-VII5JNA6.mjs +24 -0
  54. package/dist/{chunk-WTBVFN4H.mjs.map → chunk-VII5JNA6.mjs.map} +1 -1
  55. package/dist/chunk-W3ECDLUB.mjs +24 -0
  56. package/dist/{chunk-OHJIW3I3.mjs.map → chunk-W3ECDLUB.mjs.map} +1 -1
  57. package/dist/{chunk-VBIDPX5Z.mjs → chunk-Y4PAUTZ4.mjs} +13 -3
  58. package/dist/{chunk-VBIDPX5Z.mjs.map → chunk-Y4PAUTZ4.mjs.map} +1 -1
  59. package/dist/{chunk-NAZO4HKB.mjs → chunk-ZSRD3ZXF.mjs} +12 -2
  60. package/dist/{chunk-NAZO4HKB.mjs.map → chunk-ZSRD3ZXF.mjs.map} +1 -1
  61. package/dist/index.mjs +33 -23
  62. package/dist/index.mjs.map +1 -1
  63. package/dist/{liveStatus-YSBYSVOO.mjs → liveStatus-PRDEL7CK.mjs} +16 -6
  64. package/dist/{liveStatus-YSBYSVOO.mjs.map → liveStatus-PRDEL7CK.mjs.map} +1 -1
  65. package/dist/{loginReport-YIVBJVJD.mjs → loginReport-47QNACQU.mjs} +22 -12
  66. package/dist/{loginReport-YIVBJVJD.mjs.map → loginReport-47QNACQU.mjs.map} +1 -1
  67. package/dist/{managementDashboard-7EMQC2UA.mjs → managementDashboard-SZFYULKA.mjs} +22 -12
  68. package/dist/{managementDashboard-7EMQC2UA.mjs.map → managementDashboard-SZFYULKA.mjs.map} +1 -1
  69. package/dist/{qualityAuditDashboard-ENGQN2WQ.mjs → qualityAuditDashboard-FHRGB77R.mjs} +12 -2
  70. package/dist/{qualityAuditDashboard-ENGQN2WQ.mjs.map → qualityAuditDashboard-FHRGB77R.mjs.map} +1 -1
  71. package/dist-react/agentDetailReport-PDKQKJNL.mjs +23 -0
  72. package/dist-react/agentPerformanceReport-MU2FASNN.mjs +544 -0
  73. package/dist-react/agentPerformanceReport-MU2FASNN.mjs.map +1 -0
  74. package/dist-react/auditReport-WH2KDNYT.mjs +25 -0
  75. package/{dist/auditReport-6ZUJ4UFO.mjs.map → dist-react/auditReport-WH2KDNYT.mjs.map} +1 -1
  76. package/dist-react/callHistory-HXXRYUIV.mjs +832 -0
  77. package/dist-react/callHistory-HXXRYUIV.mjs.map +1 -0
  78. package/dist-react/campaigns-J7KIAATE.mjs +3139 -0
  79. package/dist-react/campaigns-J7KIAATE.mjs.map +1 -0
  80. package/dist-react/caroQualityAuditDashboard-THYPVOCP.mjs +76 -0
  81. package/dist-react/caroQualityAuditDashboard-THYPVOCP.mjs.map +1 -0
  82. package/dist-react/caroVoiceAI-XGDUETXI.mjs +31 -0
  83. package/dist-react/caroVoiceAI-XGDUETXI.mjs.map +1 -0
  84. package/dist-react/cdrReport-SX2FZAO6.mjs +858 -0
  85. package/dist-react/cdrReport-SX2FZAO6.mjs.map +1 -0
  86. package/dist-react/chunk-4YF4IDV6.mjs +72 -0
  87. package/dist-react/chunk-4YF4IDV6.mjs.map +1 -0
  88. package/dist-react/chunk-ADM2JJCP.mjs +190 -0
  89. package/dist-react/chunk-ADM2JJCP.mjs.map +1 -0
  90. package/dist-react/chunk-EN7HM2MD.mjs +688 -0
  91. package/dist-react/chunk-EN7HM2MD.mjs.map +1 -0
  92. package/{dist/chunk-LHE4QGJJ.mjs → dist-react/chunk-F7G2XFRU.mjs} +12 -2
  93. package/{dist/chunk-LHE4QGJJ.mjs.map → dist-react/chunk-F7G2XFRU.mjs.map} +1 -1
  94. package/{dist/chunk-DJP744FF.mjs → dist-react/chunk-GUMGXVIT.mjs} +12 -2
  95. package/{dist/chunk-DJP744FF.mjs.map → dist-react/chunk-GUMGXVIT.mjs.map} +1 -1
  96. package/dist-react/chunk-KRXHK4AU.mjs +127 -0
  97. package/dist-react/chunk-KRXHK4AU.mjs.map +1 -0
  98. package/{dist/chunk-U2UDKXMB.mjs → dist-react/chunk-LWDAC6QU.mjs} +12 -2
  99. package/{dist/chunk-U2UDKXMB.mjs.map → dist-react/chunk-LWDAC6QU.mjs.map} +1 -1
  100. package/dist-react/chunk-LX6I32Y4.mjs +106 -0
  101. package/dist-react/chunk-LX6I32Y4.mjs.map +1 -0
  102. package/dist-react/chunk-MCD5FQNY.mjs +428 -0
  103. package/dist-react/chunk-MCD5FQNY.mjs.map +1 -0
  104. package/dist-react/chunk-MD472UKG.mjs +757 -0
  105. package/{dist/chunk-33QNSXP7.mjs.map → dist-react/chunk-MD472UKG.mjs.map} +1 -1
  106. package/dist-react/chunk-ORNNWQI6.mjs +67 -0
  107. package/dist-react/chunk-ORNNWQI6.mjs.map +1 -0
  108. package/dist-react/chunk-S4J35V4B.mjs +126 -0
  109. package/dist-react/chunk-S4J35V4B.mjs.map +1 -0
  110. package/dist-react/chunk-T53WMN5A.mjs +126 -0
  111. package/dist-react/chunk-T53WMN5A.mjs.map +1 -0
  112. package/dist-react/chunk-UTSRABCL.mjs +96 -0
  113. package/dist-react/chunk-UTSRABCL.mjs.map +1 -0
  114. package/dist-react/incoming-4WP3FJI4.mp3 +0 -0
  115. package/dist-react/incoming.mp3 +0 -0
  116. package/dist-react/index.d.mts +2476 -0
  117. package/dist-react/index.d.ts +2477 -0
  118. package/dist-react/index.js +26713 -0
  119. package/dist-react/index.js.map +1 -0
  120. package/dist-react/index.mjs +4675 -0
  121. package/dist-react/index.mjs.map +1 -0
  122. package/dist-react/liveStatus-IDZ7CPYK.mjs +1087 -0
  123. package/dist-react/liveStatus-IDZ7CPYK.mjs.map +1 -0
  124. package/dist-react/loginReport-F47GUU53.mjs +990 -0
  125. package/dist-react/loginReport-F47GUU53.mjs.map +1 -0
  126. package/dist-react/managementDashboard-GC5E7NEL.mjs +540 -0
  127. package/dist-react/managementDashboard-GC5E7NEL.mjs.map +1 -0
  128. package/dist-react/qualityAuditDashboard-ZAM7HRNH.mjs +76 -0
  129. package/dist-react/qualityAuditDashboard-ZAM7HRNH.mjs.map +1 -0
  130. package/package.json +17 -2
  131. package/dist/agentDetailReport-ZR7U2LLB.mjs +0 -17
  132. package/dist/auditReport-6ZUJ4UFO.mjs +0 -16
  133. package/dist/chunk-6WLG2PXL.mjs +0 -14
  134. package/dist/chunk-7LE2VTAI.mjs +0 -14
  135. package/dist/chunk-AOJRUZTO.mjs +0 -14
  136. package/dist/chunk-FRKV2U3I.mjs +0 -14
  137. package/dist/chunk-OHJIW3I3.mjs +0 -14
  138. package/dist/chunk-WTBVFN4H.mjs +0 -14
  139. /package/{dist/agentDetailReport-ZR7U2LLB.mjs.map → dist-react/agentDetailReport-PDKQKJNL.mjs.map} +0 -0
@@ -0,0 +1,757 @@
1
+ import * as __ext_react from "react";
2
+ import * as __ext_react_dom from "react-dom";
3
+ import * as __ext_react_jsx from "react/jsx-runtime";
4
+ var __cjsExternals = { "react": __ext_react, "react-dom": __ext_react_dom, "react/jsx-runtime": __ext_react_jsx };
5
+ var require = function (id) {
6
+ var mod = __cjsExternals[id];
7
+ if (mod) return mod.default || mod;
8
+ throw new Error('Dynamic require of "' + id + '" is not supported');
9
+ };
10
+
11
+ import {
12
+ PageHeader
13
+ } from "./chunk-KRXHK4AU.mjs";
14
+ import {
15
+ AppButton
16
+ } from "./chunk-LX6I32Y4.mjs";
17
+ import {
18
+ DateRangePicker
19
+ } from "./chunk-UTSRABCL.mjs";
20
+ import {
21
+ SDKProvider
22
+ } from "./chunk-4YF4IDV6.mjs";
23
+ import {
24
+ END_POINT,
25
+ axios_default,
26
+ deepFindArray,
27
+ sdkStateManager
28
+ } from "./chunk-F7G2XFRU.mjs";
29
+ import {
30
+ __spreadProps,
31
+ __spreadValues
32
+ } from "./chunk-S4J35V4B.mjs";
33
+
34
+ // call-control-sdk/lib/pages/agentDetailReport/index.tsx
35
+ import { useState as useState2, useEffect, useMemo, useCallback as useCallback2 } from "react";
36
+ import {
37
+ Box,
38
+ Typography,
39
+ Table,
40
+ TableBody,
41
+ TableCell,
42
+ TableContainer,
43
+ TableHead,
44
+ TableRow,
45
+ TablePagination,
46
+ IconButton,
47
+ Chip,
48
+ CircularProgress,
49
+ Alert
50
+ } from "@mui/material";
51
+ import SearchIcon from "@mui/icons-material/Search";
52
+ import RefreshIcon from "@mui/icons-material/Refresh";
53
+ import PlayArrowIcon from "@mui/icons-material/PlayArrow";
54
+ import FileDownloadIcon from "@mui/icons-material/FileDownload";
55
+ import Tooltip from "@mui/material/Tooltip";
56
+ import {
57
+ BarChart,
58
+ Bar,
59
+ XAxis,
60
+ YAxis,
61
+ CartesianGrid,
62
+ Tooltip as RTooltip,
63
+ PieChart,
64
+ Pie,
65
+ Cell,
66
+ Legend,
67
+ ResponsiveContainer,
68
+ LabelList
69
+ } from "recharts";
70
+ import dayjs from "dayjs";
71
+ import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider";
72
+ import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs";
73
+
74
+ // call-control-sdk/lib/pages/agentDetailReport/useAgentDetailReport.ts
75
+ import { useCallback, useState } from "react";
76
+ function buildCdrQs(params) {
77
+ const qs = new URLSearchParams();
78
+ if (params.start_date) qs.append("start_date", params.start_date);
79
+ if (params.end_date) qs.append("end_date", params.end_date);
80
+ if (params.agent_id) for (const id of params.agent_id) qs.append("agent_id", String(id));
81
+ if (params.queue_id) for (const id of params.queue_id) qs.append("queue_id", String(id));
82
+ if (params.call_type) qs.append("call_type", params.call_type);
83
+ if (params.status) qs.append("status", params.status);
84
+ if (params.search) qs.append("search", params.search);
85
+ if (params.page) qs.append("page", String(params.page));
86
+ if (params.pageSize) qs.append("pageSize", String(params.pageSize));
87
+ const str = qs.toString();
88
+ return str ? `?${str}` : "";
89
+ }
90
+ async function fetchRecordingBlob(callUuid) {
91
+ const res = await axios_default.get(END_POINT.RECORDING_BY_CALL(callUuid), {
92
+ responseType: "blob"
93
+ });
94
+ return res.data;
95
+ }
96
+ async function getAgentDetailReport(agentId, params) {
97
+ const qs = new URLSearchParams();
98
+ if (params == null ? void 0 : params.start_date) qs.append("start_date", params.start_date);
99
+ if (params == null ? void 0 : params.end_date) qs.append("end_date", params.end_date);
100
+ const qsStr = qs.toString();
101
+ const res = await axios_default.get(
102
+ `${END_POINT.AGENT_DETAIL_REPORT(agentId)}${qsStr ? `?${qsStr}` : ""}`
103
+ );
104
+ return res.data;
105
+ }
106
+ async function getCdrReport(params) {
107
+ const qs = buildCdrQs(params);
108
+ const res = await axios_default.get(`${END_POINT.CDR_REPORT}${qs}`);
109
+ return res.data;
110
+ }
111
+ async function getRecordingByCall(callUuid) {
112
+ return fetchRecordingBlob(callUuid);
113
+ }
114
+
115
+ // call-control-sdk/lib/pages/agentDetailReport/index.tsx
116
+ import { jsx, jsxs } from "react/jsx-runtime";
117
+ var C = {
118
+ navy: "#0d2a56",
119
+ blue: "#1565c8",
120
+ green: "#0a9a62",
121
+ amber: "#c47c00",
122
+ red: "#cc2a2a",
123
+ purple: "#6b3fbf",
124
+ teal: "#0b7a8f",
125
+ bg: "#fff",
126
+ surface: "#fff",
127
+ s2: "#f7f9fc",
128
+ s3: "#eef2f7",
129
+ b1: "rgba(20,50,100,.07)",
130
+ b2: "rgba(20,50,100,.13)",
131
+ t1: "#0d1e35",
132
+ t2: "#364f6e",
133
+ t3: "#7a93b5",
134
+ t4: "#bccad9",
135
+ blt: "#e8f0fc",
136
+ glt: "#e4f6ef",
137
+ alt: "#fdf3e0",
138
+ rlt: "#fde8e8",
139
+ plt: "#f0eafa",
140
+ tlt: "#e3f4f7"
141
+ };
142
+ var monoSx = { fontFamily: "'JetBrains Mono', monospace", fontSize: 11, fontWeight: 600 };
143
+ var QUEUE_COLORS = [C.blue, C.green, C.purple, C.amber, C.teal, C.red, C.navy];
144
+ function StatCard({ value, label, color }) {
145
+ return /* @__PURE__ */ jsxs(Box, { sx: {
146
+ px: 1.5,
147
+ py: 1.2,
148
+ borderRadius: "10px",
149
+ backgroundColor: "#fafafa",
150
+ border: "1px solid #e0e0e0",
151
+ borderLeftWidth: "3px",
152
+ borderLeftStyle: "solid",
153
+ borderLeftColor: color
154
+ }, children: [
155
+ /* @__PURE__ */ jsx(Typography, { sx: { fontFamily: "poppins, Arial, sans-serif", fontSize: "0.72rem", fontWeight: 600, color: "#888", mb: 0.3 }, children: label }),
156
+ /* @__PURE__ */ jsx(Typography, { sx: { fontFamily: "poppins, Arial, sans-serif", fontSize: "0.95rem", fontWeight: 700, color: "#1a1a1a" }, children: value })
157
+ ] });
158
+ }
159
+ function StatusChip({ status }) {
160
+ const s = status == null ? void 0 : status.toLowerCase();
161
+ const isAns = s === "answered";
162
+ const isAband = s === "abandoned";
163
+ return /* @__PURE__ */ jsx(Chip, { label: status || "\u2014", size: "small", sx: {
164
+ fontSize: 11,
165
+ fontWeight: 700,
166
+ height: 22,
167
+ background: isAns ? C.glt : isAband ? C.alt : C.rlt,
168
+ color: isAns ? C.green : isAband ? C.amber : C.red,
169
+ border: `1px solid ${isAns ? "rgba(10,154,98,.2)" : isAband ? "rgba(196,124,0,.2)" : "rgba(204,42,42,.2)"}`,
170
+ fontFamily: "'JetBrains Mono', monospace"
171
+ } });
172
+ }
173
+ function CallTypeChip({ type }) {
174
+ const isIn = (type == null ? void 0 : type.toLowerCase()) === "inbound";
175
+ return /* @__PURE__ */ jsx(Chip, { label: type || "\u2014", size: "small", sx: {
176
+ fontSize: 11,
177
+ fontWeight: 700,
178
+ height: 22,
179
+ background: isIn ? C.glt : C.blt,
180
+ color: isIn ? C.green : C.blue,
181
+ border: `1px solid ${isIn ? "rgba(10,154,98,.2)" : "rgba(21,101,200,.2)"}`,
182
+ fontFamily: "'JetBrains Mono', monospace"
183
+ } });
184
+ }
185
+ function RecordingCell({ callUuid, recordingPath }) {
186
+ const [audioUrl, setAudioUrl] = useState2(null);
187
+ const [loading, setLoading] = useState2(false);
188
+ const [error, setError] = useState2(false);
189
+ if (!recordingPath) {
190
+ return /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: "center", gap: 0.3 }, children: [
191
+ /* @__PURE__ */ jsx(Tooltip, { title: "No recording available", children: /* @__PURE__ */ jsx("span", { children: /* @__PURE__ */ jsx(IconButton, { size: "small", disabled: true, sx: { p: 0.4 }, children: /* @__PURE__ */ jsx(PlayArrowIcon, { sx: { fontSize: 16 } }) }) }) }),
192
+ /* @__PURE__ */ jsx(Tooltip, { title: "No recording available", children: /* @__PURE__ */ jsx("span", { children: /* @__PURE__ */ jsx(IconButton, { size: "small", disabled: true, sx: { p: 0.4 }, children: /* @__PURE__ */ jsx(FileDownloadIcon, { sx: { fontSize: 16 } }) }) }) })
193
+ ] });
194
+ }
195
+ const handlePlay = async () => {
196
+ if (audioUrl) return;
197
+ try {
198
+ setLoading(true);
199
+ setError(false);
200
+ const blob = await getRecordingByCall(callUuid);
201
+ const url = URL.createObjectURL(blob);
202
+ setAudioUrl(url);
203
+ } catch (e) {
204
+ setError(true);
205
+ } finally {
206
+ setLoading(false);
207
+ }
208
+ };
209
+ const handleDownload = async () => {
210
+ try {
211
+ const blob = audioUrl ? await fetch(audioUrl).then((r) => r.blob()) : await getRecordingByCall(callUuid);
212
+ const url = URL.createObjectURL(blob);
213
+ const a = document.createElement("a");
214
+ a.href = url;
215
+ a.download = `recording_${callUuid}.wav`;
216
+ a.click();
217
+ URL.revokeObjectURL(url);
218
+ } catch (e) {
219
+ }
220
+ };
221
+ if (audioUrl) {
222
+ return /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: "center", gap: 0.5 }, children: [
223
+ /* @__PURE__ */ jsx(
224
+ "audio",
225
+ {
226
+ controls: true,
227
+ autoPlay: true,
228
+ src: audioUrl,
229
+ onEnded: () => {
230
+ if (audioUrl.startsWith("blob:")) URL.revokeObjectURL(audioUrl);
231
+ setAudioUrl(null);
232
+ },
233
+ style: { width: 140, height: 30 }
234
+ }
235
+ ),
236
+ /* @__PURE__ */ jsx(Tooltip, { title: "Download", children: /* @__PURE__ */ jsx(IconButton, { size: "small", onClick: handleDownload, sx: { color: C.blue, p: 0.4 }, children: /* @__PURE__ */ jsx(FileDownloadIcon, { sx: { fontSize: 16 } }) }) })
237
+ ] });
238
+ }
239
+ return /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: "center", gap: 0.3 }, children: [
240
+ /* @__PURE__ */ jsx(Tooltip, { title: error ? "Recording unavailable" : "Play", children: /* @__PURE__ */ jsx("span", { children: /* @__PURE__ */ jsx(IconButton, { size: "small", onClick: handlePlay, disabled: loading || error, sx: { color: C.green, p: 0.4 }, children: loading ? /* @__PURE__ */ jsx(CircularProgress, { size: 14 }) : /* @__PURE__ */ jsx(PlayArrowIcon, { sx: { fontSize: 16 } }) }) }) }),
241
+ /* @__PURE__ */ jsx(Tooltip, { title: error ? "Recording unavailable" : "Download", children: /* @__PURE__ */ jsx("span", { children: /* @__PURE__ */ jsx(IconButton, { size: "small", onClick: handleDownload, disabled: loading || error, sx: { color: C.blue, p: 0.4 }, children: /* @__PURE__ */ jsx(FileDownloadIcon, { sx: { fontSize: 16 } }) }) }) }),
242
+ error && /* @__PURE__ */ jsx(Chip, { label: "No File", size: "small", sx: { fontSize: "0.6rem", height: 18 } })
243
+ ] });
244
+ }
245
+ var cdrHeadSx = {
246
+ bgcolor: "#f1f1f1",
247
+ color: "#333",
248
+ fontWeight: 600,
249
+ whiteSpace: "nowrap",
250
+ fontSize: "14px",
251
+ py: 0.7,
252
+ px: 1
253
+ };
254
+ function AgentDetailReportContent({ agentRow: propAgentRow, onBack, from, initialStartDate, initialEndDate, initialQuickRange } = {}) {
255
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
256
+ const agentRow = propAgentRow || null;
257
+ const isFromReportsList = from === "REPORTS_LIST";
258
+ const agentIdFromRow = isFromReportsList ? ((_a = agentRow == null ? void 0 : agentRow.agentDetails) == null ? void 0 : _a.agentId) || "" : sdkStateManager.getState().agentId || ((_b = agentRow == null ? void 0 : agentRow.agentDetails) == null ? void 0 : _b.agentId) || "";
259
+ const [quickRange, setQuickRange] = useState2(initialQuickRange || "today");
260
+ const [startDate, setStartDate] = useState2(initialStartDate != null ? initialStartDate : dayjs());
261
+ const [endDate, setEndDate] = useState2(initialEndDate != null ? initialEndDate : dayjs());
262
+ const syncFilterToUrl = (_sd, _ed, _range) => {
263
+ };
264
+ const [activeTab, setActiveTab] = useState2(0);
265
+ const [detail, setDetail] = useState2(null);
266
+ const [detailLoading, setDetailLoading] = useState2(!isFromReportsList);
267
+ const [detailError, setDetailError] = useState2("");
268
+ const [cdrRecords, setCdrRecords] = useState2([]);
269
+ const [cdrTotal, setCdrTotal] = useState2(0);
270
+ const [cdrPage, setCdrPage] = useState2(0);
271
+ const [cdrPageSize, setCdrPageSize] = useState2(10);
272
+ const [cdrLoading, setCdrLoading] = useState2(false);
273
+ const [cdrError, setCdrError] = useState2("");
274
+ const profile = (detail == null ? void 0 : detail.profile) || null;
275
+ const agentName = (profile == null ? void 0 : profile.fullName) || ((_c = agentRow == null ? void 0 : agentRow.agentDetails) == null ? void 0 : _c.fullName) || "Unknown Agent";
276
+ const showInitialSpinner = !isFromReportsList && detailLoading && !profile && !((_d = agentRow == null ? void 0 : agentRow.agentDetails) == null ? void 0 : _d.fullName);
277
+ const setQuick = (range) => {
278
+ setQuickRange(range);
279
+ const today = dayjs();
280
+ let sd = today;
281
+ const ed = today;
282
+ if (range === "week") sd = today.startOf("week");
283
+ else if (range === "month") sd = today.startOf("month");
284
+ setStartDate(sd);
285
+ setEndDate(ed);
286
+ syncFilterToUrl(sd, ed, range);
287
+ };
288
+ const fetchDetailFn = async (sd, ed) => {
289
+ if (!agentIdFromRow) return;
290
+ try {
291
+ setDetailLoading(true);
292
+ setDetailError("");
293
+ const res = await getAgentDetailReport(agentIdFromRow, {
294
+ start_date: sd.startOf("day").format("YYYY-MM-DDTHH:mm:ss"),
295
+ end_date: ed.isSame(dayjs(), "day") ? dayjs().format("YYYY-MM-DDTHH:mm:ss") : ed.endOf("day").format("YYYY-MM-DDTHH:mm:ss")
296
+ });
297
+ setDetail(res);
298
+ } catch (err) {
299
+ setDetailError((err == null ? void 0 : err.message) || "Failed to load agent detail");
300
+ } finally {
301
+ setDetailLoading(false);
302
+ }
303
+ };
304
+ const fetchCdrFn = async (sd, ed, page, pageSize) => {
305
+ var _a2, _b2, _c2, _d2, _e2;
306
+ if (!agentIdFromRow) return;
307
+ try {
308
+ setCdrLoading(true);
309
+ setCdrError("");
310
+ const params = {
311
+ start_date: sd.startOf("day").format("YYYY-MM-DDTHH:mm:ss"),
312
+ end_date: ed.isSame(dayjs(), "day") ? dayjs().format("YYYY-MM-DDTHH:mm:ss") : ed.endOf("day").format("YYYY-MM-DDTHH:mm:ss"),
313
+ search: agentIdFromRow,
314
+ page: page + 1,
315
+ pageSize
316
+ };
317
+ const res = await getCdrReport(params);
318
+ setCdrRecords(deepFindArray(res, ["data", "records"]));
319
+ setCdrTotal((_e2 = (_d2 = (_b2 = (_a2 = res == null ? void 0 : res.records) == null ? void 0 : _a2.total) != null ? _b2 : res == null ? void 0 : res.total) != null ? _d2 : (_c2 = res == null ? void 0 : res.data) == null ? void 0 : _c2.total) != null ? _e2 : 0);
320
+ } catch (err) {
321
+ setCdrError((err == null ? void 0 : err.message) || "Failed to load call history");
322
+ } finally {
323
+ setCdrLoading(false);
324
+ }
325
+ };
326
+ const handleSearch = (sd, ed) => {
327
+ const fromDate = sd != null ? sd : startDate;
328
+ const toDate = ed != null ? ed : endDate;
329
+ if (!fromDate || !toDate) return;
330
+ fetchDetailFn(fromDate, toDate);
331
+ setCdrPage(0);
332
+ if (activeTab === 1) fetchCdrFn(fromDate, toDate, 0, cdrPageSize);
333
+ };
334
+ useEffect(() => {
335
+ if (agentIdFromRow && startDate && endDate) fetchDetailFn(startDate, endDate);
336
+ }, [agentIdFromRow, startDate, endDate]);
337
+ useEffect(() => {
338
+ if (activeTab === 1 && startDate && endDate) {
339
+ fetchCdrFn(startDate, endDate, cdrPage, cdrPageSize);
340
+ }
341
+ }, [activeTab, cdrPage, cdrPageSize, startDate, endDate]);
342
+ const hourlyCallData = useMemo(() => {
343
+ return ((detail == null ? void 0 : detail.hourlyCalls) || []).map((h) => ({
344
+ hour: String(h.hourOfDay).padStart(2, "0"),
345
+ answered: h.answeredCalls,
346
+ abandoned: h.missedCalls
347
+ }));
348
+ }, [detail]);
349
+ const timeUtilData = useMemo(() => {
350
+ const tu = detail == null ? void 0 : detail.timeUtilisation;
351
+ if (!tu) return [];
352
+ const total = tu.totalLoginSeconds || 1;
353
+ return [
354
+ { name: "On Call / Handle", value: tu.onCallSeconds, pct: tu.onCallSeconds / total * 100, formatted: tu.onCallFormatted, color: C.blue },
355
+ { name: "Idle", value: tu.idleSeconds, pct: tu.idleSeconds / total * 100, formatted: tu.idleFormatted, color: "#e8a0a0" },
356
+ { name: "Break", value: tu.breakSeconds, pct: tu.breakSeconds / total * 100, formatted: tu.breakFormatted, color: C.amber }
357
+ ];
358
+ }, [detail]);
359
+ const talkDurationBuckets = useMemo(() => {
360
+ const items = [...(detail == null ? void 0 : detail.talkDistribution) || []].sort((a, b) => a.bucketOrder - b.bucketOrder);
361
+ const total = items.reduce((s, b) => s + (b.callCount || 0), 0);
362
+ return items.map((b) => ({
363
+ bucket: b.bucketLabel,
364
+ count: b.callCount,
365
+ minSeconds: b.minSeconds,
366
+ maxSeconds: b.maxSeconds,
367
+ pct: total > 0 ? b.callCount / total * 100 : 0
368
+ }));
369
+ }, [detail]);
370
+ const talkDurationTotal = useMemo(
371
+ () => talkDurationBuckets.reduce((s, b) => s + (b.count || 0), 0),
372
+ [talkDurationBuckets]
373
+ );
374
+ const queuePieData = useMemo(() => {
375
+ return ((detail == null ? void 0 : detail.callsByQueue) || []).map((q, i) => ({
376
+ name: q.queueName,
377
+ value: q.callCount,
378
+ pctOfTotal: q.pctOfTotal,
379
+ color: QUEUE_COLORS[i % QUEUE_COLORS.length]
380
+ }));
381
+ }, [detail]);
382
+ const queueMetrics = useMemo(() => {
383
+ const items = (detail == null ? void 0 : detail.queueMetrics) || [];
384
+ const grandTotal = items.reduce((sum, q) => sum + q.totalCalls, 0);
385
+ return items.map((q, i) => __spreadProps(__spreadValues({}, q), {
386
+ pctOfTotal: grandTotal > 0 ? q.totalCalls / grandTotal * 100 : 0,
387
+ answerRate: q.totalCalls > 0 ? q.answeredCalls / q.totalCalls * 100 : 0,
388
+ color: QUEUE_COLORS[i % QUEUE_COLORS.length]
389
+ }));
390
+ }, [detail]);
391
+ const hourlyChartTitle = useMemo(() => {
392
+ if (quickRange === "today") return "Hourly Call Volume \u2014 Today";
393
+ if (quickRange === "month") return `Hourly Call Volume \u2014 ${dayjs().format("MMMM YYYY")}`;
394
+ if (quickRange === "week") return "Hourly Call Volume \u2014 This Week";
395
+ if (startDate && endDate) {
396
+ if (startDate.isSame(endDate, "day")) return `Hourly Call Volume \u2014 ${startDate.format("DD MMM YYYY")}`;
397
+ return `Hourly Call Volume \u2014 ${startDate.format("DD MMM YYYY")} to ${endDate.format("DD MMM YYYY")}`;
398
+ }
399
+ return "Hourly Call Volume";
400
+ }, [quickRange, startDate, endDate]);
401
+ const handleBack = useCallback2(() => {
402
+ onBack == null ? void 0 : onBack();
403
+ }, [onBack]);
404
+ if (!agentIdFromRow) {
405
+ return /* @__PURE__ */ jsxs(Box, { sx: { p: 4, textAlign: "center" }, children: [
406
+ /* @__PURE__ */ jsx(Typography, { sx: { color: C.t3, mb: 2 }, children: "No agent selected." }),
407
+ isFromReportsList && /* @__PURE__ */ jsx(AppButton, { onClick: handleBack, children: "Go Back" })
408
+ ] });
409
+ }
410
+ if (showInitialSpinner) {
411
+ return /* @__PURE__ */ jsx(Box, { sx: { display: "flex", alignItems: "center", justifyContent: "center", minHeight: 400 }, children: /* @__PURE__ */ jsx(CircularProgress, { size: 36 }) });
412
+ }
413
+ const tabs = ["Overview", "Call History", "Break Details"];
414
+ return /* @__PURE__ */ jsx(LocalizationProvider, { dateAdapter: AdapterDayjs, children: /* @__PURE__ */ jsxs(Box, { sx: { background: C.bg, minHeight: "100vh" }, children: [
415
+ /* @__PURE__ */ jsx(
416
+ PageHeader,
417
+ {
418
+ title: agentName,
419
+ showBack: isFromReportsList,
420
+ onBack: handleBack
421
+ }
422
+ ),
423
+ /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: "center", gap: 1, flexWrap: "wrap", pb: 1.5, px: 2 }, children: [
424
+ /* @__PURE__ */ jsx(
425
+ DateRangePicker,
426
+ {
427
+ showTime: false,
428
+ startDate,
429
+ endDate,
430
+ onStartChange: (d) => {
431
+ setStartDate(d);
432
+ setQuickRange("custom");
433
+ if (d && endDate) syncFilterToUrl(d, endDate, "custom");
434
+ },
435
+ onEndChange: (d) => {
436
+ setEndDate(d);
437
+ setQuickRange("custom");
438
+ if (startDate && d) syncFilterToUrl(startDate, d, "custom");
439
+ }
440
+ }
441
+ ),
442
+ /* @__PURE__ */ jsx(AppButton, { variant: quickRange === "today" ? "primary" : "outlined", onClick: () => setQuick("today"), sx: { whiteSpace: "nowrap" }, children: "Today" }),
443
+ /* @__PURE__ */ jsx(AppButton, { variant: quickRange === "week" ? "primary" : "outlined", onClick: () => setQuick("week"), sx: { whiteSpace: "nowrap" }, children: "This Week" }),
444
+ /* @__PURE__ */ jsx(AppButton, { variant: quickRange === "month" ? "primary" : "outlined", onClick: () => setQuick("month"), sx: { whiteSpace: "nowrap" }, children: "This Month" })
445
+ ] }),
446
+ /* @__PURE__ */ jsxs(Box, { sx: { py: 2, px: 2, position: "relative" }, children: [
447
+ detailLoading && /* @__PURE__ */ jsx(Box, { sx: { position: "absolute", top: 0, left: 0, right: 0, bottom: 0, background: "rgba(240,244,248,0.7)", display: "flex", alignItems: "center", justifyContent: "center", zIndex: 10 }, children: /* @__PURE__ */ jsx(CircularProgress, {}) }),
448
+ detailError && /* @__PURE__ */ jsx(Alert, { severity: "error", sx: { mb: 2 }, onClose: () => setDetailError(""), children: detailError }),
449
+ /* @__PURE__ */ jsx(Box, { sx: { display: "grid", gridTemplateColumns: { xs: "1fr 1fr", sm: "repeat(3, 1fr)", md: "repeat(5, 1fr)" }, gap: 1.5, mb: 2 }, children: [
450
+ { v: (_e = profile == null ? void 0 : profile.totalCalls) != null ? _e : 0, l: "Total Calls", c: C.navy },
451
+ { v: (_f = profile == null ? void 0 : profile.answeredCalls) != null ? _f : 0, l: "Answered", c: C.green },
452
+ { v: (_g = profile == null ? void 0 : profile.missedCalls) != null ? _g : 0, l: "Missed", c: C.red },
453
+ { v: (profile == null ? void 0 : profile.avgAhtFormatted) || "00:00:00", l: "Avg AHT", c: C.purple },
454
+ { v: `${((_h = profile == null ? void 0 : profile.answerRate) != null ? _h : 0).toFixed(1)}%`, l: "Answer Rate", c: C.green },
455
+ { v: (profile == null ? void 0 : profile.loginDurationFormatted) || "00:00:00", l: "Login Duration", c: C.blue },
456
+ { v: (profile == null ? void 0 : profile.productionFormatted) || "00:00:00", l: "Production", c: C.blue },
457
+ { v: (profile == null ? void 0 : profile.handleTimeFormatted) || "00:00:00", l: "Handle Time", c: C.purple },
458
+ { v: (profile == null ? void 0 : profile.breakTimeFormatted) || "00:00:00", l: "Break Time", c: C.amber },
459
+ { v: `${((_i = profile == null ? void 0 : profile.adherencePct) != null ? _i : 0).toFixed(1)}%`, l: `Adherence${(profile == null ? void 0 : profile.adherenceGrade) ? ` (${profile.adherenceGrade})` : ""}`, c: C.teal }
460
+ ].map((kpi, i) => /* @__PURE__ */ jsxs(Box, { sx: {
461
+ px: 1.5,
462
+ py: 1.2,
463
+ borderRadius: "10px",
464
+ backgroundColor: "#fafafa",
465
+ borderLeft: `3px solid ${kpi.c}`,
466
+ border: "1px solid #e0e0e0",
467
+ borderLeftWidth: "3px",
468
+ borderLeftStyle: "solid",
469
+ borderLeftColor: kpi.c
470
+ }, children: [
471
+ /* @__PURE__ */ jsx(Typography, { sx: {
472
+ fontFamily: "poppins, Arial, sans-serif",
473
+ fontSize: "0.72rem",
474
+ fontWeight: 600,
475
+ color: "#888",
476
+ mb: 0.3
477
+ }, children: kpi.l }),
478
+ /* @__PURE__ */ jsx(Typography, { sx: {
479
+ fontFamily: "poppins, Arial, sans-serif",
480
+ fontSize: "0.95rem",
481
+ fontWeight: 700,
482
+ color: "#1a1a1a"
483
+ }, children: kpi.v })
484
+ ] }, i)) }),
485
+ /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: { xs: "flex-start", sm: "center" }, justifyContent: "space-between", flexDirection: { xs: "column", sm: "row" }, gap: 1, borderBottom: `2px solid ${C.b1}`, mb: 2 }, children: [
486
+ /* @__PURE__ */ jsx(Box, { sx: { display: "flex", gap: 0.5, flexWrap: "wrap" }, children: tabs.map((tab, idx) => /* @__PURE__ */ jsx(
487
+ Box,
488
+ {
489
+ onClick: () => setActiveTab(idx),
490
+ sx: {
491
+ px: 2,
492
+ py: 1,
493
+ fontSize: 13,
494
+ fontWeight: 600,
495
+ cursor: "pointer",
496
+ color: activeTab === idx ? C.blue : C.t3,
497
+ borderBottom: `2px solid ${activeTab === idx ? C.blue : "transparent"}`,
498
+ mb: "-2px",
499
+ transition: "all .15s",
500
+ "&:hover": { color: C.t1 }
501
+ },
502
+ children: tab
503
+ },
504
+ tab
505
+ )) }),
506
+ /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: "center", gap: 0.5, mb: "-2px" }, children: [
507
+ /* @__PURE__ */ jsx(
508
+ AppButton,
509
+ {
510
+ size: "small",
511
+ startIcon: /* @__PURE__ */ jsx(RefreshIcon, {}),
512
+ disabled: detailLoading || cdrLoading,
513
+ onClick: () => handleSearch(),
514
+ children: "Refresh"
515
+ }
516
+ ),
517
+ /* @__PURE__ */ jsx(AppButton, { size: "small", startIcon: /* @__PURE__ */ jsx(SearchIcon, {}), onClick: () => handleSearch(), children: "Search" })
518
+ ] })
519
+ ] }),
520
+ activeTab === 0 && /* @__PURE__ */ jsxs(Box, { children: [
521
+ /* @__PURE__ */ jsxs(Box, { sx: { display: "grid", gridTemplateColumns: { xs: "1fr", md: "1fr 1fr" }, gap: 2, mb: 2 }, children: [
522
+ /* @__PURE__ */ jsxs(Box, { sx: { border: `1px solid ${C.b1}`, borderRadius: "10px", overflow: "hidden", background: "transparent" }, children: [
523
+ /* @__PURE__ */ jsxs(Box, { sx: { px: 2, py: 1.2, background: C.s2, borderBottom: `1px solid ${C.b1}`, display: "flex", alignItems: "center", justifyContent: "space-between" }, children: [
524
+ /* @__PURE__ */ jsx(Typography, { sx: { fontSize: 12, fontWeight: 700, letterSpacing: 0.8, textTransform: "uppercase", color: C.t2 }, children: hourlyChartTitle }),
525
+ /* @__PURE__ */ jsx(Chip, { label: agentName, size: "small", sx: { fontSize: 11, fontWeight: 700, background: C.blt, color: C.blue, border: `1px solid rgba(21,101,200,.2)` } })
526
+ ] }),
527
+ /* @__PURE__ */ jsx(Box, { sx: { p: 2, height: 260 }, children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(BarChart, { data: hourlyCallData, barGap: 1, children: [
528
+ /* @__PURE__ */ jsx(CartesianGrid, { strokeDasharray: "3 3", stroke: C.b1 }),
529
+ /* @__PURE__ */ jsx(XAxis, { dataKey: "hour", tick: { fontSize: 11, fill: C.t3 } }),
530
+ /* @__PURE__ */ jsx(YAxis, { tick: { fontSize: 11, fill: C.t3 }, allowDecimals: false }),
531
+ /* @__PURE__ */ jsx(RTooltip, { labelFormatter: (label) => `${String(label).padStart(2, "0")}:00`, contentStyle: { fontSize: 12, borderRadius: 8, border: `1px solid ${C.b2}` } }),
532
+ /* @__PURE__ */ jsx(Legend, { wrapperStyle: { fontSize: 11 } }),
533
+ /* @__PURE__ */ jsx(Bar, { dataKey: "answered", name: "Answered", fill: C.blue, radius: [3, 3, 0, 0] }),
534
+ /* @__PURE__ */ jsx(Bar, { dataKey: "abandoned", name: "Abandoned", fill: C.red, radius: [3, 3, 0, 0] })
535
+ ] }) }) })
536
+ ] }),
537
+ /* @__PURE__ */ jsxs(Box, { sx: { border: `1px solid ${C.b1}`, borderRadius: "10px", overflow: "hidden", background: "transparent" }, children: [
538
+ /* @__PURE__ */ jsx(Box, { sx: { px: 2, py: 1.2, background: C.s2, borderBottom: `1px solid ${C.b1}` }, children: /* @__PURE__ */ jsx(Typography, { sx: { fontSize: 12, fontWeight: 700, letterSpacing: 0.8, textTransform: "uppercase", color: C.t2 }, children: "Time Utilisation Breakdown" }) }),
539
+ /* @__PURE__ */ jsx(Box, { sx: { p: 2, height: 260 }, children: timeUtilData.length > 0 ? /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(PieChart, { children: [
540
+ /* @__PURE__ */ jsx(Pie, { data: timeUtilData, cx: "50%", cy: "50%", innerRadius: 60, outerRadius: 95, dataKey: "value", nameKey: "name", minAngle: 8, children: timeUtilData.map((entry, idx) => /* @__PURE__ */ jsx(Cell, { fill: entry.color }, idx)) }),
541
+ /* @__PURE__ */ jsx(RTooltip, { formatter: (_val, name, entry) => [`${entry.payload.formatted} (${entry.payload.pct.toFixed(1)}%)`, name], contentStyle: { fontSize: 12, borderRadius: 8, border: `1px solid ${C.b2}` } }),
542
+ /* @__PURE__ */ jsx(Legend, { wrapperStyle: { fontSize: 12 }, formatter: (value) => /* @__PURE__ */ jsx("span", { style: { color: C.t1, fontWeight: 500 }, children: value }) })
543
+ ] }) }) : /* @__PURE__ */ jsx(Box, { sx: { display: "flex", alignItems: "center", justifyContent: "center", height: "100%", color: C.t3, fontSize: 13 }, children: "No data" }) })
544
+ ] })
545
+ ] }),
546
+ /* @__PURE__ */ jsxs(Box, { sx: { border: `1px solid ${C.b1}`, borderRadius: "10px", overflow: "hidden", background: "transparent", mb: 2 }, children: [
547
+ /* @__PURE__ */ jsxs(Box, { sx: { px: 2, py: 1.2, background: C.s2, borderBottom: `1px solid ${C.b1}`, display: "flex", alignItems: "center", justifyContent: "space-between" }, children: [
548
+ /* @__PURE__ */ jsx(Typography, { sx: { fontSize: 12, fontWeight: 700, letterSpacing: 0.8, textTransform: "uppercase", color: C.t2 }, children: "Talk Duration Distribution" }),
549
+ /* @__PURE__ */ jsx(Chip, { label: `${talkDurationTotal} call${talkDurationTotal === 1 ? "" : "s"}`, size: "small", sx: { fontSize: 11, fontWeight: 700, background: C.glt, color: C.green, border: `1px solid rgba(10,154,98,.2)` } })
550
+ ] }),
551
+ /* @__PURE__ */ jsx(Box, { sx: { p: 2, height: 260 }, children: talkDurationBuckets.length > 0 ? /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(BarChart, { data: talkDurationBuckets, margin: { top: 16, right: 16, left: 0, bottom: 20 }, children: [
552
+ /* @__PURE__ */ jsx(CartesianGrid, { strokeDasharray: "3 3", stroke: C.b1 }),
553
+ /* @__PURE__ */ jsx(XAxis, { dataKey: "bucket", tick: { fontSize: 11, fill: C.t3 }, label: { value: "Talking Duration", position: "insideBottom", offset: -5, style: { fontSize: 11, fontWeight: 600, fill: C.t2 } } }),
554
+ /* @__PURE__ */ jsx(YAxis, { tick: { fontSize: 11, fill: C.t3 }, allowDecimals: false, label: { value: "Call Count", angle: -90, position: "insideLeft", offset: 10, style: { fontSize: 11, fontWeight: 600, fill: C.t2 } } }),
555
+ /* @__PURE__ */ jsx(
556
+ RTooltip,
557
+ {
558
+ contentStyle: { fontSize: 12, borderRadius: 8, border: `1px solid ${C.b2}` },
559
+ labelFormatter: (label, payload) => {
560
+ var _a2;
561
+ const p = (_a2 = payload == null ? void 0 : payload[0]) == null ? void 0 : _a2.payload;
562
+ if (!p) return String(label);
563
+ return `${label} (${p.minSeconds}\u2013${p.maxSeconds}s)`;
564
+ },
565
+ formatter: (val, _name, entry) => {
566
+ var _a2;
567
+ const pct = (_a2 = entry == null ? void 0 : entry.payload) == null ? void 0 : _a2.pct;
568
+ return [`${val} call${val === 1 ? "" : "s"}${pct != null ? ` (${pct.toFixed(1)}%)` : ""}`, "Calls"];
569
+ }
570
+ }
571
+ ),
572
+ /* @__PURE__ */ jsx(Bar, { dataKey: "count", name: "Calls", fill: C.teal, radius: [4, 4, 0, 0], children: /* @__PURE__ */ jsx(LabelList, { dataKey: "count", position: "top", style: { fontSize: 11, fontWeight: 700, fill: C.t1 } }) })
573
+ ] }) }) : /* @__PURE__ */ jsx(Box, { sx: { display: "flex", alignItems: "center", justifyContent: "center", height: "100%", color: C.t3, fontSize: 13 }, children: "No data" }) })
574
+ ] }),
575
+ /* @__PURE__ */ jsxs(Box, { sx: { display: "grid", gridTemplateColumns: { xs: "1fr", md: "1fr 1fr" }, gap: 2 }, children: [
576
+ /* @__PURE__ */ jsxs(Box, { sx: { border: `1px solid ${C.b1}`, borderRadius: "10px", overflow: "hidden", background: "transparent" }, children: [
577
+ /* @__PURE__ */ jsx(Box, { sx: { px: 2, py: 1.2, background: C.s2, borderBottom: `1px solid ${C.b1}` }, children: /* @__PURE__ */ jsx(Typography, { sx: { fontSize: 12, fontWeight: 700, letterSpacing: 0.8, textTransform: "uppercase", color: C.t2 }, children: "Calls by Queue" }) }),
578
+ /* @__PURE__ */ jsx(Box, { sx: { p: 2, height: 260 }, children: queuePieData.length > 0 ? /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(PieChart, { children: [
579
+ /* @__PURE__ */ jsx(Pie, { data: queuePieData, cx: "50%", cy: "50%", outerRadius: 90, dataKey: "value", nameKey: "name", children: queuePieData.map((entry, idx) => /* @__PURE__ */ jsx(Cell, { fill: entry.color }, idx)) }),
580
+ /* @__PURE__ */ jsx(
581
+ RTooltip,
582
+ {
583
+ contentStyle: { fontSize: 12, borderRadius: 8, border: `1px solid ${C.b2}` },
584
+ formatter: (val, name, entry) => {
585
+ var _a2;
586
+ const pct = (_a2 = entry == null ? void 0 : entry.payload) == null ? void 0 : _a2.pctOfTotal;
587
+ return [`${val} calls${pct != null ? ` (${pct.toFixed(1)}%)` : ""}`, name];
588
+ }
589
+ }
590
+ ),
591
+ /* @__PURE__ */ jsx(Legend, { wrapperStyle: { fontSize: 12 }, formatter: (value) => /* @__PURE__ */ jsx("span", { style: { color: C.t1, fontWeight: 500 }, children: value }) })
592
+ ] }) }) : /* @__PURE__ */ jsx(Box, { sx: { display: "flex", alignItems: "center", justifyContent: "center", height: "100%", color: C.t3, fontSize: 13 }, children: "No queue data" }) })
593
+ ] }),
594
+ /* @__PURE__ */ jsxs(Box, { sx: { border: `1px solid ${C.b1}`, borderRadius: "10px", overflow: "hidden", background: "transparent" }, children: [
595
+ /* @__PURE__ */ jsx(Box, { sx: { px: 2, py: 1.2, background: C.s2, borderBottom: `1px solid ${C.b1}` }, children: /* @__PURE__ */ jsx(Typography, { sx: { fontSize: 12, fontWeight: 700, letterSpacing: 0.8, textTransform: "uppercase", color: C.t2 }, children: "Queue Performance Metrics" }) }),
596
+ /* @__PURE__ */ jsx(Box, { sx: { p: 2 }, children: queueMetrics.length > 0 ? queueMetrics.map((q) => {
597
+ var _a2, _b2, _c2;
598
+ return /* @__PURE__ */ jsxs(Box, { sx: { mb: 2, "&:last-child": { mb: 0 } }, children: [
599
+ /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: "center", justifyContent: "space-between", mb: 0.3 }, children: [
600
+ /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: "center", gap: 1 }, children: [
601
+ /* @__PURE__ */ jsx(Box, { sx: { width: 10, height: 10, borderRadius: "50%", background: q.color, flexShrink: 0 } }),
602
+ /* @__PURE__ */ jsx(Typography, { sx: { fontSize: 13, fontWeight: 700, color: C.t1 }, children: q.queueName })
603
+ ] }),
604
+ /* @__PURE__ */ jsxs(Typography, { sx: __spreadProps(__spreadValues({}, monoSx), { fontSize: 13, fontWeight: 800, color: q.color }), children: [
605
+ q.totalCalls,
606
+ " calls",
607
+ /* @__PURE__ */ jsxs(Typography, { component: "span", sx: __spreadProps(__spreadValues({}, monoSx), { color: C.t3, ml: 0.5 }), children: [
608
+ "(",
609
+ q.answeredCalls,
610
+ " ans / ",
611
+ q.missedCalls,
612
+ " miss)"
613
+ ] })
614
+ ] })
615
+ ] }),
616
+ /* @__PURE__ */ jsx(Box, { sx: { height: 6, background: C.s3, borderRadius: 3, overflow: "hidden", mb: 0.3 }, children: /* @__PURE__ */ jsx(Box, { sx: { height: "100%", width: `${(_a2 = q.pctOfTotal) != null ? _a2 : 0}%`, background: q.color, borderRadius: 3 } }) }),
617
+ /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", flexWrap: "wrap", columnGap: 1.5, rowGap: 0.2 }, children: [
618
+ /* @__PURE__ */ jsxs(Typography, { sx: { fontSize: 11, color: C.t3 }, children: [
619
+ ((_b2 = q.pctOfTotal) != null ? _b2 : 0).toFixed(0),
620
+ "% of total"
621
+ ] }),
622
+ /* @__PURE__ */ jsxs(Typography, { sx: { fontSize: 11, color: C.t3 }, children: [
623
+ "Ans: ",
624
+ ((_c2 = q.answerRate) != null ? _c2 : 0).toFixed(0),
625
+ "%"
626
+ ] }),
627
+ /* @__PURE__ */ jsxs(Typography, { sx: { fontSize: 11, color: C.t3 }, children: [
628
+ "Talk: ",
629
+ /* @__PURE__ */ jsx("span", { style: __spreadProps(__spreadValues({}, monoSx), { color: C.t2 }), children: q.avgTalkFormatted })
630
+ ] }),
631
+ /* @__PURE__ */ jsxs(Typography, { sx: { fontSize: 11, color: C.t3 }, children: [
632
+ "Hold: ",
633
+ /* @__PURE__ */ jsx("span", { style: __spreadProps(__spreadValues({}, monoSx), { color: C.t2 }), children: q.avgHoldFormatted })
634
+ ] }),
635
+ /* @__PURE__ */ jsxs(Typography, { sx: { fontSize: 11, color: C.t3 }, children: [
636
+ "Wrap: ",
637
+ /* @__PURE__ */ jsx("span", { style: __spreadProps(__spreadValues({}, monoSx), { color: C.t2 }), children: q.avgWrapupFormatted })
638
+ ] }),
639
+ /* @__PURE__ */ jsxs(Typography, { sx: { fontSize: 11, color: C.t3 }, children: [
640
+ "AHT: ",
641
+ /* @__PURE__ */ jsx("span", { style: __spreadProps(__spreadValues({}, monoSx), { color: C.t2 }), children: q.avgAhtFormatted })
642
+ ] })
643
+ ] })
644
+ ] }, q.queueName);
645
+ }) : /* @__PURE__ */ jsx(Box, { sx: { textAlign: "center", py: 4, color: C.t3, fontSize: 13 }, children: "No queue data" }) })
646
+ ] })
647
+ ] })
648
+ ] }),
649
+ activeTab === 1 && /* @__PURE__ */ jsxs(Box, { sx: { borderRadius: "8px", border: "1px solid #e0e7ef", overflow: "hidden", background: "transparent" }, children: [
650
+ /* @__PURE__ */ jsx(Box, { sx: { px: 2, py: 1.2, background: C.s2, borderBottom: `1px solid ${C.b1}`, display: "flex", alignItems: "center", justifyContent: "space-between" }, children: /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: "center", gap: 1 }, children: [
651
+ /* @__PURE__ */ jsx(Typography, { sx: { fontSize: 12, fontWeight: 700, letterSpacing: 0.8, textTransform: "uppercase", color: C.t2 }, children: "Call History" }),
652
+ /* @__PURE__ */ jsx(Chip, { label: `${cdrTotal} records`, size: "small", sx: { fontSize: 11, fontWeight: 700, background: C.s2, color: C.t3, border: `1px solid ${C.b2}` } })
653
+ ] }) }),
654
+ cdrError && /* @__PURE__ */ jsx(Alert, { severity: "error", sx: { mx: 2, mt: 1 }, onClose: () => setCdrError(""), children: cdrError }),
655
+ /* @__PURE__ */ jsxs(TableContainer, { sx: { position: "relative" }, children: [
656
+ cdrLoading && /* @__PURE__ */ jsx(Box, { sx: { position: "absolute", top: 0, left: 0, right: 0, bottom: 0, background: "rgba(255,255,255,0.7)", display: "flex", alignItems: "center", justifyContent: "center", zIndex: 5 }, children: /* @__PURE__ */ jsx(CircularProgress, { size: 28 }) }),
657
+ /* @__PURE__ */ jsxs(Table, { size: "small", sx: {
658
+ minWidth: 1400,
659
+ "& .MuiTableCell-root": { fontSize: "0.75rem", borderBottom: "1px solid #eef1f6", py: 0.6, px: 1 }
660
+ }, children: [
661
+ /* @__PURE__ */ jsx(TableHead, { children: /* @__PURE__ */ jsx(TableRow, { children: [
662
+ "Phone Number",
663
+ "Call Start",
664
+ "Call Type",
665
+ "Status",
666
+ "Queue",
667
+ "Extension",
668
+ "Talk Duration",
669
+ "Hold Duration",
670
+ "Ringing Duration",
671
+ "Wrapup Duration",
672
+ "Disposition",
673
+ "Transferred",
674
+ "Recording"
675
+ ].map((label) => /* @__PURE__ */ jsx(TableCell, { sx: cdrHeadSx, children: label }, label)) }) }),
676
+ /* @__PURE__ */ jsxs(TableBody, { children: [
677
+ cdrRecords.map((row, idx) => {
678
+ var _a2;
679
+ return /* @__PURE__ */ jsxs(TableRow, { hover: true, sx: {
680
+ backgroundColor: "#fff",
681
+ "&:hover": { backgroundColor: "#f0f7f8" }
682
+ }, children: [
683
+ /* @__PURE__ */ jsx(TableCell, { sx: { fontWeight: 600, color: C.navy, fontSize: "0.75rem" }, children: row.phoneNumber || "" }),
684
+ /* @__PURE__ */ jsx(TableCell, { sx: { fontSize: "0.73rem", color: "#4a5568" }, children: row.callStartTime ? dayjs(row.callStartTime).format("DD MMM YYYY hh:mm A") : "" }),
685
+ /* @__PURE__ */ jsx(TableCell, { children: /* @__PURE__ */ jsx(CallTypeChip, { type: row.callType || "" }) }),
686
+ /* @__PURE__ */ jsx(TableCell, { children: /* @__PURE__ */ jsx(StatusChip, { status: row.callStatus || "" }) }),
687
+ /* @__PURE__ */ jsx(TableCell, { children: row.queueName ? /* @__PURE__ */ jsx(Chip, { label: row.queueName, size: "small", sx: { backgroundColor: "#f0ebfa", color: C.purple, fontWeight: 500, fontSize: "0.67rem", height: 22 } }) : "" }),
688
+ /* @__PURE__ */ jsx(TableCell, { sx: { fontSize: "0.73rem", color: "#4a5568" }, children: row.extension || "" }),
689
+ /* @__PURE__ */ jsx(TableCell, { sx: { fontWeight: 600, color: C.blue, fontSize: "0.75rem", fontVariantNumeric: "tabular-nums" }, children: row.talkDurationFmt || "" }),
690
+ /* @__PURE__ */ jsx(TableCell, { sx: { fontWeight: 500, color: C.amber, fontSize: "0.75rem", fontVariantNumeric: "tabular-nums" }, children: row.holdDurationFmt || "" }),
691
+ /* @__PURE__ */ jsx(TableCell, { sx: { fontWeight: 500, fontSize: "0.75rem", fontVariantNumeric: "tabular-nums" }, children: row.ringingDurationFmt || "" }),
692
+ /* @__PURE__ */ jsx(TableCell, { sx: { fontWeight: 500, color: C.purple, fontSize: "0.75rem", fontVariantNumeric: "tabular-nums" }, children: row.wrapupDurationFmt || "" }),
693
+ /* @__PURE__ */ jsx(TableCell, { sx: { fontSize: "0.73rem", color: "#4a5568" }, children: row.disposition || "" }),
694
+ /* @__PURE__ */ jsx(TableCell, { children: row.wasTransferred ? /* @__PURE__ */ jsx(Chip, { label: "Yes", size: "small", sx: { backgroundColor: "#e6f7ef", color: C.green, fontWeight: 600, fontSize: "0.65rem", height: 20, borderRadius: "6px" } }) : /* @__PURE__ */ jsx(Chip, { label: "No", size: "small", sx: { backgroundColor: "transparent", color: "#6b7b8d", fontWeight: 600, fontSize: "0.65rem", height: 20, borderRadius: "6px" } }) }),
695
+ /* @__PURE__ */ jsx(TableCell, { children: row.callUuid ? /* @__PURE__ */ jsx(RecordingCell, { callUuid: row.callUuid, recordingPath: (_a2 = row.recordingPath) != null ? _a2 : null }) : "" })
696
+ ] }, row.callUuid || idx);
697
+ }),
698
+ !cdrLoading && cdrRecords.length === 0 && /* @__PURE__ */ jsx(TableRow, { children: /* @__PURE__ */ jsx(TableCell, { colSpan: 13, sx: { textAlign: "center", py: 4, color: C.t3, fontSize: 13 }, children: "No call records found" }) })
699
+ ] })
700
+ ] })
701
+ ] }),
702
+ /* @__PURE__ */ jsx(
703
+ TablePagination,
704
+ {
705
+ component: "div",
706
+ count: cdrTotal,
707
+ page: cdrPage,
708
+ onPageChange: (_, p) => setCdrPage(p),
709
+ rowsPerPage: cdrPageSize,
710
+ onRowsPerPageChange: (e) => {
711
+ setCdrPageSize(parseInt(e.target.value, 10));
712
+ setCdrPage(0);
713
+ },
714
+ rowsPerPageOptions: [10, 15, 25, 50, 100],
715
+ sx: { borderTop: "1px solid #eef1f6", "& .MuiTablePagination-displayedRows": { fontSize: "0.73rem" }, "& .MuiTablePagination-selectLabel": { fontSize: "0.73rem" } }
716
+ }
717
+ )
718
+ ] }),
719
+ activeTab === 2 && /* @__PURE__ */ jsxs(Box, { children: [
720
+ /* @__PURE__ */ jsxs(Box, { sx: { display: "grid", gridTemplateColumns: { xs: "1fr 1fr", md: "repeat(3, 1fr)", lg: "repeat(4, 1fr)" }, gap: { xs: 1.5, lg: 2 }, mb: 2 }, children: [
721
+ /* @__PURE__ */ jsx(StatCard, { value: (profile == null ? void 0 : profile.breakTimeFormatted) || "00:00:00", label: "Total Break Time", color: C.amber }),
722
+ /* @__PURE__ */ jsx(StatCard, { value: (_j = profile == null ? void 0 : profile.breaksTaken) != null ? _j : 0, label: "Breaks Taken", color: C.purple }),
723
+ /* @__PURE__ */ jsx(StatCard, { value: (profile == null ? void 0 : profile.productionFormatted) || "00:00:00", label: "Production Time", color: C.green }),
724
+ /* @__PURE__ */ jsx(StatCard, { value: (profile == null ? void 0 : profile.loginDurationFormatted) || "00:00:00", label: "Login Duration", color: C.teal })
725
+ ] }),
726
+ /* @__PURE__ */ jsxs(Box, { children: [
727
+ /* @__PURE__ */ jsx(Typography, { sx: { fontSize: "0.72rem", fontWeight: 700, color: "#888", textTransform: "uppercase", letterSpacing: 0.8, mb: 1, fontFamily: "poppins, Arial, sans-serif" }, children: "Attendance Summary" }),
728
+ /* @__PURE__ */ jsx(Box, { sx: { display: "grid", gridTemplateColumns: { xs: "1fr 1fr", md: "repeat(4, 1fr)" }, gap: 1.5 }, children: [
729
+ { label: "First Login", value: (profile == null ? void 0 : profile.firstLoginTime) ? dayjs(profile.firstLoginTime).format("YYYY-MM-DD HH:mm:ss") : "\u2014", color: C.blue },
730
+ { label: "Adherence Score", value: `${(_k = profile == null ? void 0 : profile.adherencePct) != null ? _k : 0}%`, color: C.green },
731
+ { label: "Adherence Grade", value: (profile == null ? void 0 : profile.adherenceGrade) || "\u2014", color: C.purple },
732
+ { label: "Answer Rate", value: `${((_l = profile == null ? void 0 : profile.answerRate) != null ? _l : 0).toFixed(1)}%`, color: C.teal }
733
+ ].map((item) => /* @__PURE__ */ jsxs(Box, { sx: {
734
+ px: 1.5,
735
+ py: 1.2,
736
+ borderRadius: "10px",
737
+ backgroundColor: "#fafafa",
738
+ border: "1px solid #e0e0e0",
739
+ borderLeftWidth: "3px",
740
+ borderLeftStyle: "solid",
741
+ borderLeftColor: item.color
742
+ }, children: [
743
+ /* @__PURE__ */ jsx(Typography, { sx: { fontFamily: "poppins, Arial, sans-serif", fontSize: "0.72rem", fontWeight: 600, color: "#888", mb: 0.3 }, children: item.label }),
744
+ /* @__PURE__ */ jsx(Typography, { sx: { fontFamily: "poppins, Arial, sans-serif", fontSize: "0.95rem", fontWeight: 700, color: "#1a1a1a" }, children: item.value })
745
+ ] }, item.label)) })
746
+ ] })
747
+ ] })
748
+ ] })
749
+ ] }) });
750
+ }
751
+ var AgentDetailReport = (props) => /* @__PURE__ */ jsx(SDKProvider, { children: /* @__PURE__ */ jsx(AgentDetailReportContent, __spreadValues({}, props)) });
752
+ var agentDetailReport_default = AgentDetailReport;
753
+
754
+ export {
755
+ agentDetailReport_default
756
+ };
757
+ //# sourceMappingURL=chunk-MD472UKG.mjs.map