ahs-cti 0.0.2-beta.9 → 0.0.2

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