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,828 @@
1
+ import {
2
+ ReportFilterBar,
3
+ SearchBar,
4
+ headCellSx
5
+ } from "./chunk-CXULBAK6.mjs";
6
+ import {
7
+ SDKPermissionGuard
8
+ } from "./chunk-GGACEO3I.mjs";
9
+ import {
10
+ PageHeader
11
+ } from "./chunk-JOZ4YQMR.mjs";
12
+ import {
13
+ AppButton
14
+ } from "./chunk-HBR2JS4C.mjs";
15
+ import {
16
+ SDKProvider
17
+ } from "./chunk-6ICPXSN6.mjs";
18
+ import {
19
+ END_POINT,
20
+ SDK_PERMISSIONS,
21
+ axios_default,
22
+ deepFindArray
23
+ } from "./chunk-O2XGWZLT.mjs";
24
+ import "./chunk-VQCHBU2Q.mjs";
25
+
26
+ // call-control-sdk/lib/pages/loginReport/index.tsx
27
+ import { useCallback as useCallback2, useEffect, useMemo, useRef, useState as useState2 } from "react";
28
+ import {
29
+ Alert,
30
+ Box,
31
+ Chip,
32
+ CircularProgress,
33
+ Dialog,
34
+ DialogContent,
35
+ DialogTitle,
36
+ IconButton,
37
+ Paper,
38
+ Stack,
39
+ Table,
40
+ TableBody,
41
+ TableCell,
42
+ TableContainer,
43
+ TableHead,
44
+ TableRow,
45
+ TablePagination,
46
+ TableSortLabel,
47
+ Typography
48
+ } from "@mui/material";
49
+ import CloseIcon from "@mui/icons-material/Close";
50
+ import DownloadIcon from "@mui/icons-material/Download";
51
+ import RefreshIcon from "@mui/icons-material/Refresh";
52
+ import dayjs from "dayjs";
53
+ import isoWeek from "dayjs/plugin/isoWeek";
54
+ import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider";
55
+ import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs";
56
+
57
+ // call-control-sdk/lib/pages/loginReport/useLoginReport.ts
58
+ import { useCallback, useState } from "react";
59
+ async function fetchQueues() {
60
+ var _a;
61
+ const res = await axios_default.get(END_POINT.MASTER_QUEUES);
62
+ if (Array.isArray(res.data)) return res.data;
63
+ if (Array.isArray((_a = res.data) == null ? void 0 : _a.data)) return res.data.data;
64
+ return [];
65
+ }
66
+ async function getQueues() {
67
+ return fetchQueues();
68
+ }
69
+ async function getLoginReport(params) {
70
+ const qs = buildLoginReportQueryString(params);
71
+ const res = await axios_default.get(`${END_POINT.LOGIN_REPORT}${qs}`);
72
+ return res.data;
73
+ }
74
+ async function getAgentLoginSessions(agentId, params) {
75
+ const qs = buildSessionQueryString(params);
76
+ const res = await axios_default.get(
77
+ `${END_POINT.LOGIN_REPORT_AGENT_SESSIONS(agentId)}${qs}`
78
+ );
79
+ return Array.isArray(res.data) ? res.data : [];
80
+ }
81
+ async function exportLoginReportToExcel(params) {
82
+ var _a;
83
+ const qs = buildLoginReportQueryString(params);
84
+ const res = await axios_default.get(`${END_POINT.LOGIN_REPORT_EXPORT_EXCEL}${qs}`, { responseType: "blob" });
85
+ triggerBlobDownload(new Blob([res.data]), `login-report-${(_a = params.start_date) != null ? _a : "export"}.xlsx`);
86
+ }
87
+ async function exportAgentLoginSessionsToExcel(agentId, params) {
88
+ const qs = buildSessionQueryString(params);
89
+ const res = await axios_default.get(
90
+ `${END_POINT.LOGIN_REPORT_AGENT_SESSIONS_EXPORT_EXCEL(agentId)}${qs}`,
91
+ { responseType: "blob" }
92
+ );
93
+ triggerBlobDownload(new Blob([res.data]), `login_sessions_${agentId}.xlsx`);
94
+ }
95
+ function buildLoginReportQueryString(params) {
96
+ const qs = new URLSearchParams();
97
+ if (params.start_date) qs.append("start_date", params.start_date);
98
+ if (params.end_date) qs.append("end_date", params.end_date);
99
+ if (params.agent_id) for (const id of params.agent_id) qs.append("agent_id", id);
100
+ if (params.queue_id) for (const id of params.queue_id) qs.append("queue_id", String(id));
101
+ if (params.process_id) for (const id of params.process_id) qs.append("process_id", String(id));
102
+ if (params.search) qs.append("search", params.search);
103
+ if (params.page) qs.append("page", String(params.page));
104
+ if (params.pageSize) qs.append("pageSize", String(params.pageSize));
105
+ const str = qs.toString();
106
+ return str ? `?${str}` : "";
107
+ }
108
+ function buildSessionQueryString(params) {
109
+ const qs = new URLSearchParams();
110
+ if (params == null ? void 0 : params.start_date) qs.append("start_date", params.start_date);
111
+ if (params == null ? void 0 : params.end_date) qs.append("end_date", params.end_date);
112
+ const str = qs.toString();
113
+ return str ? `?${str}` : "";
114
+ }
115
+ function triggerBlobDownload(blob, filename) {
116
+ const url = URL.createObjectURL(blob);
117
+ const a = document.createElement("a");
118
+ a.href = url;
119
+ a.download = filename;
120
+ document.body.appendChild(a);
121
+ a.click();
122
+ a.remove();
123
+ URL.revokeObjectURL(url);
124
+ }
125
+
126
+ // call-control-sdk/lib/pages/loginReport/index.tsx
127
+ import { jsx, jsxs } from "react/jsx-runtime";
128
+ dayjs.extend(isoWeek);
129
+ var FONT = "'Inter', 'Segoe UI', 'Roboto', -apple-system, BlinkMacSystemFont, sans-serif";
130
+ var COLORS = {
131
+ navy: "#0d2a56",
132
+ blue: "#1565c8",
133
+ green: "#0a9a62",
134
+ amber: "#c47c00",
135
+ red: "#cc2a2a",
136
+ purple: "#6b3fbf",
137
+ bg: "transparent",
138
+ surface: "transparent"
139
+ };
140
+ var DEFAULT_ROWS_PER_PAGE = 10;
141
+ var comparator = (a, b, key) => {
142
+ const av = a[key];
143
+ const bv = b[key];
144
+ if (typeof av === "number" && typeof bv === "number") return av - bv;
145
+ return String(av != null ? av : "").localeCompare(String(bv != null ? bv : ""));
146
+ };
147
+ function LoginReportContent() {
148
+ const [startDate, setStartDate] = useState2(dayjs().startOf("day"));
149
+ const [endDate, setEndDate] = useState2(dayjs());
150
+ const [activeQuickDate, setActiveQuickDate] = useState2("today");
151
+ const [searchText, setSearchText] = useState2("");
152
+ const [selectedAgents, setSelectedAgents] = useState2([]);
153
+ const [isAllUsersSelected, setIsAllUsersSelected] = useState2(false);
154
+ const [queues, setQueues] = useState2([]);
155
+ const [selectedQueues, setSelectedQueues] = useState2([]);
156
+ const [reportData, setReportData] = useState2([]);
157
+ const [loading, setLoading] = useState2(false);
158
+ const [error, setError] = useState2("");
159
+ const [page, setPage] = useState2(0);
160
+ const [rowsPerPage, setRowsPerPage] = useState2(DEFAULT_ROWS_PER_PAGE);
161
+ const [totalCount, setTotalCount] = useState2(-1);
162
+ const [sortKey, setSortKey] = useState2("fullName");
163
+ const [sortDir, setSortDir] = useState2("asc");
164
+ const [debouncedSearch, setDebouncedSearch] = useState2("");
165
+ const debounceRef = useRef(void 0);
166
+ useEffect(() => {
167
+ debounceRef.current = setTimeout(() => setDebouncedSearch(searchText.trim()), 400);
168
+ return () => clearTimeout(debounceRef.current);
169
+ }, [searchText]);
170
+ const [dialogOpen, setDialogOpen] = useState2(false);
171
+ const [selectedRow, setSelectedRow] = useState2(null);
172
+ const [sessions, setSessions] = useState2([]);
173
+ const [sessionsLoading, setSessionsLoading] = useState2(false);
174
+ useEffect(() => {
175
+ getQueues().then((data) => setQueues(data || [])).catch(() => setError("Failed to load queues"));
176
+ }, []);
177
+ const handleQuickRangeChange = (range) => {
178
+ setActiveQuickDate(range || null);
179
+ };
180
+ const handleRefresh = () => {
181
+ if (activeQuickDate) {
182
+ const now = dayjs();
183
+ let sd = now.startOf("day");
184
+ const ed = now;
185
+ if (activeQuickDate === "week") sd = now.startOf("week").startOf("day");
186
+ else if (activeQuickDate === "month") sd = now.startOf("month").startOf("day");
187
+ setStartDate(sd);
188
+ setEndDate(ed);
189
+ } else {
190
+ fetchReport(page);
191
+ }
192
+ };
193
+ const fetchReport = useCallback2(
194
+ async (pageNum) => {
195
+ var _a, _b, _c, _d;
196
+ const sd = startDate;
197
+ const ed = endDate;
198
+ if (!sd || !ed) {
199
+ setError("Select a valid date range");
200
+ return;
201
+ }
202
+ const params = {
203
+ start_date: sd.format("YYYY-MM-DDTHH:mm:ss"),
204
+ end_date: ed.format("YYYY-MM-DDTHH:mm:ss"),
205
+ agent_id: !isAllUsersSelected && selectedAgents.length > 0 ? selectedAgents.map((a) => a.userId) : void 0,
206
+ queue_id: selectedQueues.length > 0 && selectedQueues.length < queues.length ? selectedQueues.map((q) => q.id) : void 0,
207
+ search: debouncedSearch || void 0,
208
+ page: pageNum + 1,
209
+ pageSize: rowsPerPage
210
+ };
211
+ try {
212
+ setError("");
213
+ setLoading(true);
214
+ const res = await getLoginReport(params);
215
+ const agents = deepFindArray(res, ["agents"]);
216
+ setReportData(agents);
217
+ const total = (_d = (_b = res == null ? void 0 : res.total) != null ? _b : (_a = res == null ? void 0 : res.pagination) == null ? void 0 : _a.total) != null ? _d : (_c = res == null ? void 0 : res.summary) == null ? void 0 : _c.totalAgentsLoggedIn;
218
+ setTotalCount(typeof total === "number" ? total : agents.length);
219
+ } catch (err) {
220
+ setError((err == null ? void 0 : err.message) || "Failed to fetch login report");
221
+ setReportData([]);
222
+ } finally {
223
+ setLoading(false);
224
+ }
225
+ },
226
+ [startDate, endDate, selectedAgents, isAllUsersSelected, selectedQueues, debouncedSearch, rowsPerPage]
227
+ );
228
+ useEffect(() => {
229
+ setPage(0);
230
+ fetchReport(0);
231
+ }, [fetchReport]);
232
+ const handlePageChange = useCallback2(
233
+ (_event, newPage) => {
234
+ setPage(newPage);
235
+ fetchReport(newPage);
236
+ },
237
+ [fetchReport]
238
+ );
239
+ const filteredData = useMemo(() => {
240
+ const rows = [...reportData];
241
+ rows.sort((a, b) => {
242
+ const cmp = comparator(a, b, sortKey);
243
+ return sortDir === "asc" ? cmp : -cmp;
244
+ });
245
+ return rows;
246
+ }, [reportData, sortKey, sortDir]);
247
+ const paginatedData = filteredData;
248
+ const handleSort = (key) => {
249
+ if (sortKey === key) {
250
+ setSortDir((d) => d === "asc" ? "desc" : "asc");
251
+ } else {
252
+ setSortKey(key);
253
+ setSortDir("asc");
254
+ }
255
+ };
256
+ const openDialog = async (row) => {
257
+ setSelectedRow(row);
258
+ setSessions([]);
259
+ setDialogOpen(true);
260
+ setSessionsLoading(true);
261
+ try {
262
+ const sd = startDate != null ? startDate : dayjs();
263
+ const ed = endDate != null ? endDate : dayjs();
264
+ const data = await getAgentLoginSessions(row.agentId, {
265
+ start_date: sd.format("YYYY-MM-DDTHH:mm:ss"),
266
+ end_date: ed.format("YYYY-MM-DDTHH:mm:ss")
267
+ });
268
+ setSessions(data);
269
+ } catch (e) {
270
+ setSessions([]);
271
+ } finally {
272
+ setSessionsLoading(false);
273
+ }
274
+ };
275
+ const closeDialog = () => {
276
+ setDialogOpen(false);
277
+ setTimeout(() => {
278
+ setSelectedRow(null);
279
+ setSessions([]);
280
+ }, 300);
281
+ };
282
+ const handleExportExcel = async () => {
283
+ const sd = startDate != null ? startDate : dayjs();
284
+ const ed = endDate != null ? endDate : dayjs();
285
+ const params = {
286
+ start_date: sd.format("YYYY-MM-DDTHH:mm:ss"),
287
+ end_date: ed.format("YYYY-MM-DDTHH:mm:ss"),
288
+ agent_id: !isAllUsersSelected && selectedAgents.length > 0 ? selectedAgents.map((a) => a.userId) : void 0,
289
+ queue_id: selectedQueues.length > 0 && selectedQueues.length < queues.length ? selectedQueues.map((q) => q.id) : void 0,
290
+ search: debouncedSearch || void 0
291
+ };
292
+ try {
293
+ await exportLoginReportToExcel(params);
294
+ } catch (err) {
295
+ setError((err == null ? void 0 : err.message) || "Failed to export Excel");
296
+ }
297
+ };
298
+ return /* @__PURE__ */ jsx(LocalizationProvider, { dateAdapter: AdapterDayjs, children: /* @__PURE__ */ jsxs(Box, { sx: { height: "100%", display: "flex", flexDirection: "column", fontFamily: FONT }, children: [
299
+ /* @__PURE__ */ jsx(
300
+ PageHeader,
301
+ {
302
+ title: "Login Report",
303
+ actions: /* @__PURE__ */ jsxs(Stack, { direction: "row", alignItems: "center", spacing: 1, children: [
304
+ /* @__PURE__ */ jsx(
305
+ SearchBar,
306
+ {
307
+ value: searchText,
308
+ onChange: (val) => {
309
+ setSearchText(val);
310
+ setPage(0);
311
+ },
312
+ placeholder: "Search name, ID...",
313
+ width: 250
314
+ }
315
+ ),
316
+ /* @__PURE__ */ jsx(
317
+ SDKPermissionGuard,
318
+ {
319
+ permissions: [SDK_PERMISSIONS.REPORTS_AGENT_LOGIN_MANAGE, SDK_PERMISSIONS.REPORTS_AGENT_LOGIN_EXPORT],
320
+ showFallback: false,
321
+ children: /* @__PURE__ */ jsx(
322
+ AppButton,
323
+ {
324
+ startIcon: /* @__PURE__ */ jsx(DownloadIcon, { sx: { fontSize: "0.95rem !important" } }),
325
+ disabled: !reportData.length,
326
+ onClick: handleExportExcel,
327
+ sx: { height: 36 },
328
+ children: "Export Excel"
329
+ }
330
+ )
331
+ }
332
+ )
333
+ ] })
334
+ }
335
+ ),
336
+ /* @__PURE__ */ jsxs(Box, { sx: { flex: 1, overflow: "auto", py: 0.8, px: 0 }, children: [
337
+ /* @__PURE__ */ jsxs(Box, { sx: { mb: 0.8 }, children: [
338
+ /* @__PURE__ */ jsx(
339
+ ReportFilterBar,
340
+ {
341
+ startDate,
342
+ endDate,
343
+ onStartChange: setStartDate,
344
+ onEndChange: setEndDate,
345
+ quickRange: activeQuickDate || "",
346
+ onQuickRangeChange: handleQuickRangeChange,
347
+ showAgentSelect: true,
348
+ selectedAgents,
349
+ onAgentsChange: setSelectedAgents,
350
+ setIsAllUsersSelected,
351
+ showQueueSelect: true,
352
+ queues,
353
+ selectedQueues,
354
+ onQueuesChange: setSelectedQueues,
355
+ extra: /* @__PURE__ */ jsx(
356
+ AppButton,
357
+ {
358
+ startIcon: /* @__PURE__ */ jsx(RefreshIcon, { sx: { fontSize: "0.9rem !important" } }),
359
+ disabled: loading,
360
+ onClick: handleRefresh,
361
+ sx: { height: 32 },
362
+ children: "Refresh"
363
+ }
364
+ )
365
+ }
366
+ ),
367
+ error && /* @__PURE__ */ jsx(Alert, { severity: "error", sx: { mt: 1, fontFamily: FONT, fontSize: "0.78rem" }, children: error })
368
+ ] }),
369
+ loading && /* @__PURE__ */ jsx(Box, { sx: { textAlign: "center", py: 2.5 }, children: /* @__PURE__ */ jsx(CircularProgress, { sx: { color: COLORS.blue }, size: 28 }) }),
370
+ /* @__PURE__ */ jsxs(
371
+ Paper,
372
+ {
373
+ elevation: 0,
374
+ sx: {
375
+ borderRadius: "8px",
376
+ border: "1px solid #e0e7ef",
377
+ overflow: "hidden",
378
+ mb: 2
379
+ },
380
+ children: [
381
+ /* @__PURE__ */ jsx(TableContainer, { children: /* @__PURE__ */ jsxs(
382
+ Table,
383
+ {
384
+ size: "small",
385
+ sx: {
386
+ minWidth: 1100,
387
+ fontFamily: FONT,
388
+ "& .MuiTableCell-root": {
389
+ fontFamily: FONT,
390
+ fontSize: "0.75rem",
391
+ borderBottom: "1px solid #eef1f6",
392
+ py: 0.6,
393
+ px: 1
394
+ }
395
+ },
396
+ children: [
397
+ /* @__PURE__ */ jsx(TableHead, { children: /* @__PURE__ */ jsx(TableRow, { children: [
398
+ { id: "fullName", label: "User Name" },
399
+ { id: "agentId", label: "User ID" },
400
+ { id: "queueNames", label: "Queues" },
401
+ { id: "numLogins", label: "Logins" },
402
+ { id: "firstLoginTime", label: "First Login" },
403
+ { id: "lastLogoutTime", label: "Last Logout" },
404
+ { id: "workingDurationFormatted", label: "Working Duration" },
405
+ { id: "breakDurationFormatted", label: "Break Duration" },
406
+ { id: "loginDurationFormatted", label: "Login Duration" },
407
+ { id: "utilisationPct", label: "Utilisation %" }
408
+ ].map((col) => /* @__PURE__ */ jsx(TableCell, { sx: headCellSx, children: /* @__PURE__ */ jsx(
409
+ TableSortLabel,
410
+ {
411
+ active: sortKey === col.id,
412
+ direction: sortKey === col.id ? sortDir : "asc",
413
+ onClick: () => handleSort(col.id),
414
+ sx: {
415
+ "&.MuiTableSortLabel-root": { color: "#333" },
416
+ "&.MuiTableSortLabel-root:hover": { color: "#555" },
417
+ "&.Mui-active": { color: "#333" },
418
+ "& .MuiTableSortLabel-icon": { color: "#333 !important" }
419
+ },
420
+ children: col.label
421
+ }
422
+ ) }, col.id)) }) }),
423
+ /* @__PURE__ */ jsx(TableBody, { children: paginatedData.map((row, idx) => {
424
+ const isLoggedIn = !row.lastLogoutTime;
425
+ return /* @__PURE__ */ jsxs(
426
+ TableRow,
427
+ {
428
+ hover: true,
429
+ sx: {
430
+ backgroundColor: "#fff",
431
+ "&:hover": { backgroundColor: "#f0f7f8" }
432
+ },
433
+ children: [
434
+ /* @__PURE__ */ jsx(TableCell, { sx: { fontWeight: 600, color: COLORS.navy, fontSize: "0.75rem" }, children: row.fullName || "\u2014" }),
435
+ /* @__PURE__ */ jsx(TableCell, { sx: { fontSize: "0.73rem", color: "#4a5568" }, children: row.agentId || "\u2014" }),
436
+ /* @__PURE__ */ jsx(TableCell, { children: row.queueNames ? /* @__PURE__ */ jsx(
437
+ Chip,
438
+ {
439
+ label: row.queueNames,
440
+ size: "small",
441
+ sx: {
442
+ fontFamily: FONT,
443
+ backgroundColor: "#f0ebfa",
444
+ color: COLORS.purple,
445
+ fontWeight: 500,
446
+ fontSize: "0.67rem",
447
+ height: 22
448
+ }
449
+ }
450
+ ) : "\u2014" }),
451
+ /* @__PURE__ */ jsx(TableCell, { sx: { textAlign: "center" }, children: /* @__PURE__ */ jsx(
452
+ Chip,
453
+ {
454
+ label: row.numLogins,
455
+ size: "small",
456
+ onClick: (e) => {
457
+ e.stopPropagation();
458
+ openDialog(row);
459
+ },
460
+ sx: {
461
+ fontFamily: FONT,
462
+ backgroundColor: COLORS.navy,
463
+ color: "#fff",
464
+ fontWeight: 600,
465
+ minWidth: 28,
466
+ height: 20,
467
+ fontSize: "0.67rem",
468
+ cursor: "pointer",
469
+ "&:hover": { backgroundColor: COLORS.blue }
470
+ }
471
+ }
472
+ ) }),
473
+ /* @__PURE__ */ jsx(TableCell, { sx: { fontSize: "0.73rem", color: "#4a5568" }, children: row.firstLoginTime ? dayjs(row.firstLoginTime).format("DD MMM YYYY hh:mm A") : "\u2014" }),
474
+ /* @__PURE__ */ jsx(TableCell, { sx: { fontSize: "0.73rem", color: "#4a5568" }, children: isLoggedIn ? /* @__PURE__ */ jsx(
475
+ Chip,
476
+ {
477
+ label: "LOGGED-IN",
478
+ size: "small",
479
+ sx: {
480
+ fontFamily: FONT,
481
+ backgroundColor: COLORS.green,
482
+ color: "#fff",
483
+ fontWeight: 600,
484
+ fontSize: "0.65rem",
485
+ height: 20
486
+ }
487
+ }
488
+ ) : dayjs(row.lastLogoutTime).format("DD MMM YYYY hh:mm A") }),
489
+ /* @__PURE__ */ jsx(
490
+ TableCell,
491
+ {
492
+ sx: { fontWeight: 600, color: COLORS.blue, fontSize: "0.75rem", fontVariantNumeric: "tabular-nums" },
493
+ children: row.workingDurationFormatted || "\u2014"
494
+ }
495
+ ),
496
+ /* @__PURE__ */ jsx(
497
+ TableCell,
498
+ {
499
+ sx: { fontWeight: 500, color: COLORS.amber, fontSize: "0.75rem", fontVariantNumeric: "tabular-nums" },
500
+ children: row.breakDurationFormatted || "\u2014"
501
+ }
502
+ ),
503
+ /* @__PURE__ */ jsx(TableCell, { sx: { fontWeight: 500, fontSize: "0.75rem", fontVariantNumeric: "tabular-nums" }, children: row.loginDurationFormatted || "\u2014" }),
504
+ /* @__PURE__ */ jsx(TableCell, { sx: { minWidth: 120 }, children: row.utilisationPct != null ? (() => {
505
+ const pct = Math.min(row.utilisationPct, 100);
506
+ const barColor = pct >= 80 ? "#10b981" : pct >= 60 ? "#f59e0b" : "#ef4444";
507
+ const bgTint = pct >= 80 ? "#d1fae5" : pct >= 60 ? "#fef3c7" : "#fee2e2";
508
+ return /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: "center", gap: 0.8 }, children: [
509
+ /* @__PURE__ */ jsx(
510
+ Box,
511
+ {
512
+ sx: {
513
+ position: "relative",
514
+ flex: 1,
515
+ height: 7,
516
+ borderRadius: 4,
517
+ backgroundColor: bgTint,
518
+ overflow: "hidden"
519
+ },
520
+ children: /* @__PURE__ */ jsx(
521
+ Box,
522
+ {
523
+ sx: {
524
+ width: `${pct}%`,
525
+ height: "100%",
526
+ borderRadius: 4,
527
+ background: `linear-gradient(90deg, ${barColor}cc, ${barColor})`,
528
+ transition: "width 0.4s ease"
529
+ }
530
+ }
531
+ )
532
+ }
533
+ ),
534
+ /* @__PURE__ */ jsx(
535
+ Chip,
536
+ {
537
+ label: `${Math.round(pct)}%`,
538
+ size: "small",
539
+ sx: {
540
+ fontFamily: FONT,
541
+ height: 18,
542
+ minWidth: 38,
543
+ fontSize: "0.63rem",
544
+ fontWeight: 700,
545
+ backgroundColor: bgTint,
546
+ color: barColor,
547
+ "& .MuiChip-label": { px: 0.6 }
548
+ }
549
+ }
550
+ )
551
+ ] });
552
+ })() : "\u2014" })
553
+ ]
554
+ },
555
+ `${row.agentId}-${idx}`
556
+ );
557
+ }) })
558
+ ]
559
+ }
560
+ ) }),
561
+ /* @__PURE__ */ jsx(
562
+ TablePagination,
563
+ {
564
+ component: "div",
565
+ count: totalCount,
566
+ page,
567
+ onPageChange: handlePageChange,
568
+ rowsPerPage,
569
+ rowsPerPageOptions: [10, 15, 25, 50, 100],
570
+ onRowsPerPageChange: (e) => {
571
+ setRowsPerPage(parseInt(e.target.value, 10));
572
+ setPage(0);
573
+ },
574
+ sx: { borderTop: "1px solid #eef1f6", fontFamily: FONT, "& .MuiTablePagination-displayedRows": { fontFamily: FONT, fontSize: "0.73rem" }, "& .MuiTablePagination-selectLabel": { fontFamily: FONT, fontSize: "0.73rem" } }
575
+ }
576
+ )
577
+ ]
578
+ }
579
+ ),
580
+ /* @__PURE__ */ jsxs(
581
+ Dialog,
582
+ {
583
+ open: dialogOpen,
584
+ onClose: (_e, reason) => {
585
+ if (reason !== "backdropClick") closeDialog();
586
+ },
587
+ maxWidth: "md",
588
+ fullWidth: true,
589
+ PaperProps: {
590
+ sx: {
591
+ borderRadius: "12px",
592
+ fontFamily: FONT,
593
+ overflow: "hidden",
594
+ boxShadow: "0 8px 32px rgba(0,0,0,0.18)",
595
+ maxWidth: 450
596
+ }
597
+ },
598
+ children: [
599
+ /* @__PURE__ */ jsxs(
600
+ DialogTitle,
601
+ {
602
+ sx: {
603
+ fontFamily: FONT,
604
+ background: "linear-gradient(135deg, var(--primary-color-dark, #14505b), var(--primary-color, #1A5F6C))",
605
+ color: "#fff",
606
+ display: "flex",
607
+ justifyContent: "space-between",
608
+ alignItems: "center",
609
+ py: 1.5,
610
+ px: 2.5
611
+ },
612
+ children: [
613
+ /* @__PURE__ */ jsxs(Box, { children: [
614
+ /* @__PURE__ */ jsx(Typography, { variant: "h6", sx: { fontFamily: FONT, fontWeight: 700, fontSize: "0.95rem", letterSpacing: "0.3px" }, children: "Login Sessions" }),
615
+ /* @__PURE__ */ jsxs(
616
+ Typography,
617
+ {
618
+ variant: "body2",
619
+ sx: { fontFamily: FONT, opacity: 0.9, fontSize: "0.76rem", mt: 0.3 },
620
+ children: [
621
+ selectedRow == null ? void 0 : selectedRow.fullName,
622
+ " \u2022 ",
623
+ selectedRow == null ? void 0 : selectedRow.numLogins,
624
+ " session",
625
+ (selectedRow == null ? void 0 : selectedRow.numLogins) !== 1 ? "s" : ""
626
+ ]
627
+ }
628
+ )
629
+ ] }),
630
+ /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: "center", gap: 0.5 }, children: [
631
+ /* @__PURE__ */ jsx(
632
+ AppButton,
633
+ {
634
+ size: "small",
635
+ startIcon: /* @__PURE__ */ jsx(DownloadIcon, { sx: { fontSize: "0.85rem !important" } }),
636
+ onClick: async () => {
637
+ if (!selectedRow) return;
638
+ try {
639
+ await exportAgentLoginSessionsToExcel(selectedRow.agentId, {
640
+ start_date: (startDate != null ? startDate : dayjs()).format("YYYY-MM-DDTHH:mm:ss"),
641
+ end_date: (endDate != null ? endDate : dayjs()).format("YYYY-MM-DDTHH:mm:ss")
642
+ });
643
+ } catch (err) {
644
+ setError((err == null ? void 0 : err.message) || "Failed to export Excel");
645
+ }
646
+ },
647
+ sx: { whiteSpace: "nowrap" },
648
+ children: "Export to Excel"
649
+ }
650
+ ),
651
+ /* @__PURE__ */ jsx(
652
+ IconButton,
653
+ {
654
+ onClick: closeDialog,
655
+ size: "small",
656
+ sx: {
657
+ color: "#fff",
658
+ backgroundColor: "rgba(255,255,255,0.1)",
659
+ "&:hover": { backgroundColor: "rgba(255,255,255,0.2)" }
660
+ },
661
+ children: /* @__PURE__ */ jsx(CloseIcon, { fontSize: "small" })
662
+ }
663
+ )
664
+ ] })
665
+ ]
666
+ }
667
+ ),
668
+ /* @__PURE__ */ jsx(DialogContent, { sx: { p: 0, backgroundColor: "#f8fafb" }, children: sessionsLoading ? /* @__PURE__ */ jsx(Box, { sx: { p: 4, textAlign: "center" }, children: /* @__PURE__ */ jsx(CircularProgress, { size: 28, sx: { color: "var(--primary-color, #1A5F6C)" } }) }) : sessions.length > 0 ? /* @__PURE__ */ jsx(Box, { sx: { p: 1.5, maxHeight: 300, overflowY: "auto" }, children: Object.entries(
669
+ sessions.reduce((acc, s) => {
670
+ const dateKey = s.loginTime ? dayjs(s.loginTime).format("DD MMM YYYY") : "Unknown Date";
671
+ if (!acc[dateKey]) acc[dateKey] = [];
672
+ acc[dateKey].push(s);
673
+ return acc;
674
+ }, {})
675
+ ).map(([date, dateSessions]) => /* @__PURE__ */ jsxs(
676
+ Paper,
677
+ {
678
+ elevation: 0,
679
+ sx: {
680
+ mb: 1.5,
681
+ borderRadius: "10px",
682
+ border: "1px solid #e4eaf0",
683
+ overflow: "hidden",
684
+ backgroundColor: "#fff"
685
+ },
686
+ children: [
687
+ /* @__PURE__ */ jsx(
688
+ Box,
689
+ {
690
+ sx: {
691
+ px: 1.5,
692
+ py: 0.8,
693
+ backgroundColor: "#f0f5f4",
694
+ borderBottom: "1px solid #e4eaf0"
695
+ },
696
+ children: /* @__PURE__ */ jsx(
697
+ Typography,
698
+ {
699
+ sx: {
700
+ fontFamily: FONT,
701
+ fontWeight: 700,
702
+ fontSize: "0.8rem",
703
+ color: "var(--primary-color-dark, #14505b)",
704
+ letterSpacing: "0.3px"
705
+ },
706
+ children: date
707
+ }
708
+ )
709
+ }
710
+ ),
711
+ /* @__PURE__ */ jsxs(Box, { sx: { px: 1.5, py: 1 }, children: [
712
+ /* @__PURE__ */ jsxs(
713
+ Box,
714
+ {
715
+ sx: {
716
+ display: "flex",
717
+ alignItems: "center",
718
+ gap: 2,
719
+ pb: 0.5,
720
+ mb: 0.5,
721
+ borderBottom: "1px solid #e4eaf0"
722
+ },
723
+ children: [
724
+ /* @__PURE__ */ jsx(
725
+ Typography,
726
+ {
727
+ sx: {
728
+ flex: 1,
729
+ fontFamily: FONT,
730
+ fontSize: "0.72rem",
731
+ fontWeight: 700,
732
+ color: "#555",
733
+ textTransform: "uppercase",
734
+ letterSpacing: "0.5px"
735
+ },
736
+ children: "Login"
737
+ }
738
+ ),
739
+ /* @__PURE__ */ jsx(
740
+ Typography,
741
+ {
742
+ sx: {
743
+ flex: 1,
744
+ fontFamily: FONT,
745
+ fontSize: "0.72rem",
746
+ fontWeight: 700,
747
+ color: "#555",
748
+ textTransform: "uppercase",
749
+ letterSpacing: "0.5px"
750
+ },
751
+ children: "Logout"
752
+ }
753
+ )
754
+ ]
755
+ }
756
+ ),
757
+ dateSessions.map((s, i) => /* @__PURE__ */ jsxs(
758
+ Box,
759
+ {
760
+ sx: {
761
+ display: "flex",
762
+ alignItems: "center",
763
+ gap: 2,
764
+ py: 0.6,
765
+ borderBottom: i < dateSessions.length - 1 ? "1px dashed #e8ecf0" : "none"
766
+ },
767
+ children: [
768
+ /* @__PURE__ */ jsxs(
769
+ Typography,
770
+ {
771
+ component: "span",
772
+ sx: {
773
+ flex: 1,
774
+ fontFamily: FONT,
775
+ fontSize: "0.78rem",
776
+ fontWeight: 500,
777
+ color: s.loginTime ? COLORS.green : "#9e9e9e",
778
+ display: "flex",
779
+ alignItems: "center",
780
+ gap: 0.4
781
+ },
782
+ children: [
783
+ /* @__PURE__ */ jsx("span", { style: { fontSize: "0.9rem" }, children: "\u2199" }),
784
+ s.loginTime ? dayjs(s.loginTime).format("DD MMM YYYY h:mm:ss A") : "Missing"
785
+ ]
786
+ }
787
+ ),
788
+ /* @__PURE__ */ jsxs(
789
+ Typography,
790
+ {
791
+ component: "span",
792
+ sx: {
793
+ flex: 1,
794
+ fontFamily: FONT,
795
+ fontSize: "0.78rem",
796
+ fontWeight: 500,
797
+ color: s.logoutTime ? COLORS.red : "#9e9e9e",
798
+ display: "flex",
799
+ alignItems: "center",
800
+ gap: 0.4
801
+ },
802
+ children: [
803
+ /* @__PURE__ */ jsx("span", { style: { fontSize: "0.9rem" }, children: "\u2197" }),
804
+ s.logoutTime ? dayjs(s.logoutTime).format("DD MMM YYYY h:mm:ss A") : "Missing"
805
+ ]
806
+ }
807
+ )
808
+ ]
809
+ },
810
+ i
811
+ ))
812
+ ] })
813
+ ]
814
+ },
815
+ date
816
+ )) }) : /* @__PURE__ */ jsx(Box, { sx: { p: 4, textAlign: "center" }, children: /* @__PURE__ */ jsx(Typography, { sx: { fontFamily: FONT, color: "#9e9e9e", fontStyle: "italic", fontSize: "0.82rem" }, children: "No sessions found" }) }) })
817
+ ]
818
+ }
819
+ )
820
+ ] })
821
+ ] }) });
822
+ }
823
+ var LoginReport = () => /* @__PURE__ */ jsx(SDKProvider, { children: /* @__PURE__ */ jsx(LoginReportContent, {}) });
824
+ var loginReport_default = LoginReport;
825
+ export {
826
+ loginReport_default as default
827
+ };
828
+ //# sourceMappingURL=loginReport-7GBMZP55.mjs.map