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