{"version":3,"sources":["../call-control-sdk/lib/pages/loginReport/index.tsx","../call-control-sdk/lib/pages/loginReport/useLoginReport.ts"],"sourcesContent":["import React, { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\r\nimport {\r\n  Alert,\r\n  Box,\r\n  Chip,\r\n  CircularProgress,\r\n  Dialog,\r\n  DialogContent,\r\n  DialogTitle,\r\n  IconButton,\r\n  Paper,\r\n  Stack,\r\n  Table,\r\n  TableBody,\r\n  TableCell,\r\n  TableContainer,\r\n  TableHead,\r\n  TableRow,\r\n  TablePagination,\r\n  TableSortLabel,\r\n  Tooltip,\r\n  Typography,\r\n} from \"@mui/material\";\r\nimport AppButton from \"../common/components/AppButton\";\r\n\r\nimport CloseIcon from \"@mui/icons-material/Close\";\r\nimport CheckIcon from \"@mui/icons-material/Check\";\r\nimport EditCalendarIcon from \"@mui/icons-material/EditCalendar\";\r\nimport ReportFilterBar, { type QuickRange } from \"../common/components/ReportFilterBar\";\r\nimport DownloadIcon from \"@mui/icons-material/Download\";\r\nimport RefreshIcon from \"@mui/icons-material/Refresh\";\r\n\r\nimport dayjs, { Dayjs } from \"dayjs\";\r\nimport isoWeek from \"dayjs/plugin/isoWeek\";\r\n\r\nimport { LocalizationProvider } from \"@mui/x-date-pickers/LocalizationProvider\";\r\nimport { AdapterDayjs } from \"@mui/x-date-pickers/AdapterDayjs\";\r\nimport { DateTimePicker } from \"@mui/x-date-pickers/DateTimePicker\";\r\nimport {\r\n  getLoginReport,\r\n  getAgentLoginSessions,\r\n  exportLoginReportToExcel,\r\n  exportAgentLoginSessionsToExcel,\r\n  regularizeLoginSession,\r\n  getQueues,\r\n  type Queue,\r\n} from \"./useLoginReport\";\r\nimport type { LoginReportParams, LoginAgentRowResponse, LoginSessionResponse } from \"./types\";\r\nimport { deepFindArray } from \"../../services/axios\";\r\nimport { type AgentOption } from \"../common/components/AgentMultiSelect\";\r\nimport { headCellSx } from \"../common/utils/tableStyles\";\r\nimport PageHeader from \"../common/components/PageHeader\";\r\nimport SearchBar from \"../common/components/SearchBar\";\r\n\r\nimport { SDKProvider } from \"../../components/SDKProvider\";\r\nimport { SDKPermissionGuard } from \"../../components/SDKPermissionGuard\";\r\nimport { SDK_PERMISSIONS } from \"../../permissions/sdk-constants\";\r\n\r\ndayjs.extend(isoWeek);\r\n\r\ntype SortKey =\r\n  | \"fullName\"\r\n  | \"agentId\"\r\n  | \"processNames\"\r\n  | \"queueNames\"\r\n  | \"numLogins\"\r\n  | \"firstLoginTime\"\r\n  | \"lastLogoutTime\"\r\n  | \"workingDurationFormatted\"\r\n  | \"breakDurationFormatted\"\r\n  | \"loginDurationFormatted\"\r\n  | \"utilisationPct\";\r\n\r\ntype SortDir = \"asc\" | \"desc\";\r\n\r\nconst FONT = \"'Inter', 'Segoe UI', 'Roboto', -apple-system, BlinkMacSystemFont, sans-serif\";\r\n\r\nconst COLORS = {\r\n  navy: \"#0d2a56\",\r\n  blue: \"#1565c8\",\r\n  green: \"#0a9a62\",\r\n  amber: \"#c47c00\",\r\n  red: \"#cc2a2a\",\r\n  purple: \"#6b3fbf\",\r\n  bg: \"transparent\",\r\n  surface: \"transparent\",\r\n} as const;\r\n\r\nconst DEFAULT_ROWS_PER_PAGE = 10;\r\n\r\n// Deterministic avatar palette — a name always maps to the same colour.\r\nconst AVATAR_COLORS = [\"#1A5F6C\", \"#00897B\", \"#5E35B1\", \"#F57C00\", \"#00ACC1\", \"#E53935\", \"#0a9a62\", \"#6b3fbf\"];\r\n// Initials = first letter of first name + first letter of last name.\r\nfunction getInitials(name: string): string {\r\n  const parts = (name || \"\").trim().split(/\\s+/).filter(Boolean);\r\n  if (parts.length === 0) return \"\";\r\n  if (parts.length === 1) return parts[0][0].toUpperCase();\r\n  return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();\r\n}\r\nfunction getAvatarColor(name: string): string {\r\n  let h = 0;\r\n  for (let i = 0; i < (name || \"\").length; i++) h = name.charCodeAt(i) + ((h << 5) - h);\r\n  return AVATAR_COLORS[Math.abs(h) % AVATAR_COLORS.length];\r\n}\r\n\r\nfunction LoginReportContent() {\r\n  const [startDate, setStartDate] = useState<Dayjs | null>(dayjs().startOf(\"day\"));\r\n  const [endDate, setEndDate] = useState<Dayjs | null>(dayjs());\r\n  const [activeQuickDate, setActiveQuickDate] = useState<\"today\" | \"week\" | \"month\" | null>(\"today\");\r\n  const [searchText, setSearchText] = useState(\"\");\r\n\r\n  const [selectedAgents, setSelectedAgents] = useState<AgentOption[]>([]);\r\n  const [isAllUsersSelected, setIsAllUsersSelected] = useState(false);\r\n\r\n  const [queues, setQueues] = useState<Queue[]>([]);\r\n  const [selectedQueues, setSelectedQueues] = useState<Queue[]>([]);\r\n\r\n  const [reportData, setReportData] = useState<LoginAgentRowResponse[]>([]);\r\n  const [loading, setLoading] = useState(false);\r\n  const [exporting, setExporting] = useState(false);\r\n  const [exportingSessions, setExportingSessions] = useState(false);\r\n  const [error, setError] = useState(\"\");\r\n\r\n  const [page, setPage] = useState(0);\r\n  const [rowsPerPage, setRowsPerPage] = useState(DEFAULT_ROWS_PER_PAGE);\r\n  const [totalCount, setTotalCount] = useState(-1);\r\n  const [sortKey, setSortKey] = useState<SortKey>(\"fullName\");\r\n  const [sortDir, setSortDir] = useState<SortDir>(\"asc\");\r\n\r\n  // Debounced search (sent to the server)\r\n  const [debouncedSearch, setDebouncedSearch] = useState(\"\");\r\n  const debounceRef = useRef<ReturnType<typeof setTimeout>>(undefined);\r\n\r\n  useEffect(() => {\r\n    debounceRef.current = setTimeout(() => setDebouncedSearch(searchText.trim()), 400);\r\n    return () => clearTimeout(debounceRef.current);\r\n  }, [searchText]);\r\n\r\n  const [dialogOpen, setDialogOpen] = useState(false);\r\n  const [selectedRow, setSelectedRow] = useState<LoginAgentRowResponse | null>(null);\r\n  const [sessions, setSessions] = useState<LoginSessionResponse[]>([]);\r\n  const [sessionsLoading, setSessionsLoading] = useState(false);\r\n  // Sessions dialog sort (server-side) — login time ascending by default.\r\n  const [sessionsSortKey, setSessionsSortKey] = useState<\"loginTime\" | \"logoutTime\">(\"loginTime\");\r\n  const [sessionsSortDir, setSessionsSortDir] = useState<SortDir>(\"asc\");\r\n\r\n  /* ----- regularize (close stuck session) state ----- */\r\n  const [regularizeSessionId, setRegularizeSessionId] = useState<number | null>(null);\r\n  const [regularizeTime, setRegularizeTime] = useState<Dayjs | null>(null);\r\n  const [regularizing, setRegularizing] = useState(false);\r\n  const [regularizeError, setRegularizeError] = useState(\"\");\r\n\r\n  useEffect(() => {\r\n    getQueues().then((data) => setQueues(data || [])).catch(() => setError(\"Failed to load queues\"));\r\n  }, []);\r\n\r\n  const handleQuickRangeChange = (range: QuickRange) => { setActiveQuickDate(range || null); };\r\n\r\n  const handleRefresh = () => {\r\n    if (activeQuickDate) {\r\n      const now = dayjs();\r\n      let sd = now.startOf(\"day\");\r\n      const ed = now;\r\n      if (activeQuickDate === \"week\") sd = now.startOf(\"week\").startOf(\"day\");\r\n      else if (activeQuickDate === \"month\") sd = now.startOf(\"month\").startOf(\"day\");\r\n      // Setting the dates re-triggers the auto-fetch effect below.\r\n      setStartDate(sd);\r\n      setEndDate(ed);\r\n    } else {\r\n      fetchReport(page);\r\n    }\r\n  };\r\n\r\n  const fetchReport = useCallback(\r\n    async (pageNum: number) => {\r\n      const sd = startDate;\r\n      const ed = endDate;\r\n\r\n      if (!sd || !ed) {\r\n        setError(\"Select a valid date range\");\r\n        return;\r\n      }\r\n\r\n      const params: LoginReportParams = {\r\n        start_date: sd.format(\"YYYY-MM-DDTHH:mm:ss\"),\r\n        end_date: ed.format(\"YYYY-MM-DDTHH:mm:ss\"),\r\n        agent_id: !isAllUsersSelected && selectedAgents.length > 0\r\n          ? selectedAgents.map((a) => a.userId)\r\n          : undefined,\r\n        queue_id: selectedQueues.length > 0 && selectedQueues.length < queues.length\r\n          ? selectedQueues.map((q) => q.id)\r\n          : undefined,\r\n        search: debouncedSearch || undefined,\r\n        page: pageNum + 1,\r\n        pageSize: rowsPerPage,\r\n        sortBy: sortKey,\r\n        sortOrder: sortDir,\r\n      };\r\n\r\n      try {\r\n        setError(\"\");\r\n        setLoading(true);\r\n        const res = await getLoginReport(params);\r\n        const agents = deepFindArray<LoginAgentRowResponse>(res, [\"agents\"]);\r\n        setReportData(agents);\r\n        // Real total from the response (falls back defensively to the summary count).\r\n        const total =\r\n          (res as any)?.total ??\r\n          (res as any)?.pagination?.total ??\r\n          res?.summary?.totalAgentsLoggedIn;\r\n        setTotalCount(typeof total === \"number\" ? total : agents.length);\r\n      } catch (err: any) {\r\n        setError(err?.message || \"Failed to fetch login report\");\r\n        setReportData([]);\r\n      } finally {\r\n        setLoading(false);\r\n      }\r\n    },\r\n    [startDate, endDate, selectedAgents, isAllUsersSelected, selectedQueues, debouncedSearch, rowsPerPage, sortKey, sortDir],\r\n  );\r\n\r\n  useEffect(() => {\r\n    setPage(0);\r\n    fetchReport(0);\r\n  }, [fetchReport]);\r\n\r\n  const handlePageChange = useCallback(\r\n    (_event: React.MouseEvent<HTMLButtonElement> | null, newPage: number) => {\r\n      setPage(newPage);\r\n      fetchReport(newPage);\r\n    },\r\n    [fetchReport],\r\n  );\r\n\r\n  // Sort, search and paging are all server-side: the page arrives sorted\r\n  // (sortBy/sortOrder), and a sort change re-fetches from page 1.\r\n  const paginatedData = reportData;\r\n\r\n  const handleSort = (key: SortKey) => {\r\n    if (sortKey === key) {\r\n      setSortDir((d) => (d === \"asc\" ? \"desc\" : \"asc\"));\r\n    } else {\r\n      setSortKey(key);\r\n      setSortDir(\"asc\");\r\n    }\r\n  };\r\n\r\n  const loadSessions = useCallback(async (agentId: string) => {\r\n    setSessionsLoading(true);\r\n    try {\r\n      const sd = startDate ?? dayjs();\r\n      const ed = endDate ?? dayjs();\r\n      const data = await getAgentLoginSessions(agentId, {\r\n        start_date: sd.format(\"YYYY-MM-DDTHH:mm:ss\"),\r\n        end_date: ed.format(\"YYYY-MM-DDTHH:mm:ss\"),\r\n        sortBy: sessionsSortKey,\r\n        sortOrder: sessionsSortDir,\r\n      });\r\n      setSessions(data);\r\n    } catch {\r\n      setSessions([]);\r\n    } finally {\r\n      setSessionsLoading(false);\r\n    }\r\n  }, [startDate, endDate, sessionsSortKey, sessionsSortDir]);\r\n\r\n  // Re-fetch the open dialog when its sort changes.\r\n  useEffect(() => {\r\n    if (dialogOpen && selectedRow) loadSessions(selectedRow.agentId);\r\n    // eslint-disable-next-line react-hooks/exhaustive-deps\r\n  }, [sessionsSortKey, sessionsSortDir]);\r\n\r\n  const handleSessionsSort = (key: \"loginTime\" | \"logoutTime\") => {\r\n    if (sessionsSortKey === key) {\r\n      setSessionsSortDir((d) => (d === \"asc\" ? \"desc\" : \"asc\"));\r\n    } else {\r\n      setSessionsSortKey(key);\r\n      setSessionsSortDir(\"asc\");\r\n    }\r\n  };\r\n\r\n  const openDialog = async (row: LoginAgentRowResponse) => {\r\n    setSelectedRow(row);\r\n    setSessions([]);\r\n    setRegularizeSessionId(null);\r\n    setRegularizeError(\"\");\r\n    setDialogOpen(true);\r\n    await loadSessions(row.agentId);\r\n  };\r\n\r\n  const closeDialog = () => {\r\n    setDialogOpen(false);\r\n    setTimeout(() => {\r\n      setSelectedRow(null);\r\n      setSessions([]);\r\n      setRegularizeSessionId(null);\r\n      setRegularizeError(\"\");\r\n    }, 300);\r\n  };\r\n\r\n  /* ================= REGULARIZE (close stuck session) ================= */\r\n\r\n  const startRegularize = (session: LoginSessionResponse) => {\r\n    if (session.sessionId == null) return;\r\n    setRegularizeError(\"\");\r\n    setRegularizeSessionId(session.sessionId);\r\n    // Default the logout time to now (supervisor can edit before saving).\r\n    setRegularizeTime(dayjs());\r\n  };\r\n\r\n  const cancelRegularize = () => {\r\n    setRegularizeSessionId(null);\r\n    setRegularizeTime(null);\r\n    setRegularizeError(\"\");\r\n  };\r\n\r\n  const saveRegularize = async () => {\r\n    if (regularizeSessionId == null || !regularizeTime || !regularizeTime.isValid()) {\r\n      setRegularizeError(\"Select a valid logout time\");\r\n      return;\r\n    }\r\n    try {\r\n      setRegularizing(true);\r\n      setRegularizeError(\"\");\r\n      await regularizeLoginSession(regularizeSessionId, regularizeTime.toISOString());\r\n      cancelRegularize();\r\n      // Refresh the session list and the underlying report so the row reflects the change.\r\n      if (selectedRow) await loadSessions(selectedRow.agentId);\r\n      fetchReport(page);\r\n    } catch (err: any) {\r\n      setRegularizeError(err?.message || \"Failed to regularize login session\");\r\n    } finally {\r\n      setRegularizing(false);\r\n    }\r\n  };\r\n\r\n  const handleExportExcel = async () => {\r\n    const sd = startDate ?? dayjs();\r\n    const ed = endDate ?? dayjs();\r\n    const params: LoginReportParams = {\r\n      start_date: sd.format(\"YYYY-MM-DDTHH:mm:ss\"),\r\n      end_date: ed.format(\"YYYY-MM-DDTHH:mm:ss\"),\r\n      agent_id: !isAllUsersSelected && selectedAgents.length > 0\r\n        ? selectedAgents.map((a) => a.userId)\r\n        : undefined,\r\n      queue_id: selectedQueues.length > 0 && selectedQueues.length < queues.length\r\n        ? selectedQueues.map((q) => q.id)\r\n        : undefined,\r\n      search: debouncedSearch || undefined,\r\n      sortBy: sortKey,\r\n      sortOrder: sortDir,\r\n    };\r\n    try {\r\n      setExporting(true);\r\n      await exportLoginReportToExcel(params);\r\n    } catch (err: any) {\r\n      setError(err?.message || \"Failed to export Excel\");\r\n    } finally {\r\n      setExporting(false);\r\n    }\r\n  };\r\n\r\n  return (\r\n    <LocalizationProvider dateAdapter={AdapterDayjs}>\r\n      <Box sx={{ height: \"100%\", display: \"flex\", flexDirection: \"column\", fontFamily: FONT }}>\r\n        <PageHeader\r\n          title=\"Login Report\"\r\n          actions={\r\n            <Stack direction=\"row\" alignItems=\"center\" spacing={1}>\r\n              <SearchBar\r\n                value={searchText}\r\n                onChange={(val) => { setSearchText(val); setPage(0); }}\r\n                placeholder=\"Search name, ID...\"\r\n                width={250}\r\n              />\r\n              <SDKPermissionGuard\r\n                permissions={[SDK_PERMISSIONS.REPORTS_AGENT_LOGIN_MANAGE, SDK_PERMISSIONS.REPORTS_AGENT_LOGIN_EXPORT]}\r\n                showFallback={false}\r\n              >\r\n                <AppButton\r\n                  startIcon={exporting ? <CircularProgress size={14} sx={{ color: \"#fff\" }} /> : <DownloadIcon sx={{ fontSize: \"0.95rem !important\" }} />}\r\n                  disabled={exporting || !reportData.length}\r\n                  onClick={handleExportExcel}\r\n                  sx={{ height: 36 }}\r\n                >\r\n                  Export Excel\r\n                </AppButton>\r\n              </SDKPermissionGuard>\r\n            </Stack>\r\n          }\r\n        />\r\n\r\n        <Box sx={{ flex: 1, overflow: \"auto\", py: 0.8, px: 0 }}>\r\n          <Box sx={{ mb: 0.8 }}>\r\n            <ReportFilterBar\r\n              startDate={startDate}\r\n              endDate={endDate}\r\n              onStartChange={setStartDate}\r\n              onEndChange={setEndDate}\r\n              quickRange={activeQuickDate || \"\"}\r\n              onQuickRangeChange={handleQuickRangeChange}\r\n              showAgentSelect\r\n              selectedAgents={selectedAgents}\r\n              onAgentsChange={setSelectedAgents}\r\n              setIsAllUsersSelected={setIsAllUsersSelected}\r\n              showQueueSelect\r\n              queues={queues}\r\n              selectedQueues={selectedQueues}\r\n              onQueuesChange={setSelectedQueues}\r\n              extra={\r\n                <AppButton\r\n                  startIcon={<RefreshIcon sx={{ fontSize: \"0.9rem !important\" }} />}\r\n                  disabled={loading}\r\n                  onClick={handleRefresh}\r\n                  sx={{ height: 32 }}\r\n                >\r\n                  Refresh\r\n                </AppButton>\r\n              }\r\n            />\r\n\r\n            {error && (\r\n              <Alert severity=\"error\" sx={{ mt: 1, fontFamily: FONT, fontSize: \"0.78rem\" }}>\r\n                {error}\r\n              </Alert>\r\n            )}\r\n          </Box>\r\n\r\n          {loading && (\r\n            <Box sx={{ textAlign: \"center\", py: 2.5 }}>\r\n              <CircularProgress sx={{ color: COLORS.blue }} size={28} />\r\n            </Box>\r\n          )}\r\n\r\n          <Paper\r\n            elevation={0}\r\n            sx={{\r\n              borderRadius: \"8px\",\r\n              border: \"1px solid #e0e7ef\",\r\n              overflow: \"hidden\",\r\n              mb: 2,\r\n            }}\r\n          >\r\n            <TableContainer>\r\n              <Table\r\n                size=\"small\"\r\n                sx={{\r\n                  minWidth: 1100,\r\n                  fontFamily: FONT,\r\n                  \"& .MuiTableCell-root\": {\r\n                    fontFamily: FONT,\r\n                    fontSize: \"0.75rem\",\r\n                    borderBottom: \"1px solid #eef1f6\",\r\n                    py: 0.6,\r\n                    px: 1,\r\n                  },\r\n                }}\r\n              >\r\n                <TableHead>\r\n                  <TableRow>\r\n                    {(\r\n                      [\r\n                        { id: \"fullName\" as SortKey, label: \"User\" },\r\n                        { id: \"queueNames\" as SortKey, label: \"Queues\" },\r\n                        { id: \"numLogins\" as SortKey, label: \"Logins\" },\r\n                        { id: \"firstLoginTime\" as SortKey, label: \"First Login\" },\r\n                        { id: \"lastLogoutTime\" as SortKey, label: \"Last Logout\" },\r\n                        { id: \"workingDurationFormatted\" as SortKey, label: \"Working Duration\" },\r\n                        { id: \"breakDurationFormatted\" as SortKey, label: \"Break Duration\" },\r\n                        { id: \"loginDurationFormatted\" as SortKey, label: \"Login Duration\" },\r\n                        { id: \"utilisationPct\" as SortKey, label: \"Utilisation %\" },\r\n                      ] as { id: SortKey; label: string }[]\r\n                    ).map((col) => (\r\n                      <TableCell key={col.id} sx={headCellSx}>\r\n                        <TableSortLabel\r\n                          active={sortKey === col.id}\r\n                          direction={sortKey === col.id ? sortDir : \"asc\"}\r\n                          onClick={() => handleSort(col.id)}\r\n                          sx={{\r\n                            \"&.MuiTableSortLabel-root\": { color: \"#333\" },\r\n                            \"&.MuiTableSortLabel-root:hover\": { color: \"#555\" },\r\n                            \"&.Mui-active\": { color: \"#333\" },\r\n                            \"& .MuiTableSortLabel-icon\": { color: \"#333 !important\" },\r\n                          }}\r\n                        >\r\n                          {col.label}\r\n                        </TableSortLabel>\r\n                      </TableCell>\r\n                    ))}\r\n                  </TableRow>\r\n                </TableHead>\r\n\r\n                <TableBody>\r\n                  {paginatedData.map((row, idx) => {\r\n                    const isLoggedIn = !row.lastLogoutTime;\r\n                    return (\r\n                      <TableRow\r\n                        key={`${row.agentId}-${idx}`}\r\n                        hover\r\n                        sx={{\r\n                          backgroundColor: \"#fff\",\r\n                          \"&:hover\": { backgroundColor: \"#f0f7f8\" },\r\n                        }}\r\n                      >\r\n                        <TableCell sx={{ minWidth: 200 }}>\r\n                          <Box sx={{ display: \"flex\", alignItems: \"center\", gap: 1, minWidth: 0 }}>\r\n                            <Box\r\n                              sx={{\r\n                                width: 30,\r\n                                height: 30,\r\n                                borderRadius: \"50%\",\r\n                                flexShrink: 0,\r\n                                display: \"flex\",\r\n                                alignItems: \"center\",\r\n                                justifyContent: \"center\",\r\n                                background: getAvatarColor(row.fullName || \"\"),\r\n                                color: \"#fff\",\r\n                                fontSize: 11,\r\n                                fontWeight: 600,\r\n                                letterSpacing: 0.3,\r\n                              }}\r\n                            >\r\n                              {getInitials(row.fullName || \"\")}\r\n                            </Box>\r\n                            <Box sx={{ minWidth: 0 }}>\r\n                              <Typography sx={{ fontFamily: FONT, fontSize: 13, color: COLORS.navy, fontWeight: 600, lineHeight: 1.3 }}>\r\n                                {row.fullName || \"\"}\r\n                              </Typography>\r\n                              <Typography\r\n                                noWrap\r\n                                sx={{ fontFamily: FONT, fontSize: 11.5, color: \"#8494a7\", fontWeight: 500, fontVariantNumeric: \"tabular-nums\", lineHeight: 1.3 }}\r\n                              >\r\n                                {row.agentId || \"\"}\r\n                              </Typography>\r\n                            </Box>\r\n                          </Box>\r\n                        </TableCell>\r\n                        <TableCell>\r\n                          {row.queueNames ? (\r\n                            <Chip\r\n                              label={row.queueNames}\r\n                              size=\"small\"\r\n                              sx={{\r\n                                fontFamily: FONT,\r\n                                backgroundColor: \"#f0ebfa\",\r\n                                color: COLORS.purple,\r\n                                fontWeight: 500,\r\n                                fontSize: \"0.67rem\",\r\n                                height: 22,\r\n                              }}\r\n                            />\r\n                          ) : (\r\n                            \"\"\r\n                          )}\r\n                        </TableCell>\r\n                        <TableCell sx={{ textAlign: \"center\" }}>\r\n                          <Chip\r\n                            label={row.numLogins}\r\n                            size=\"small\"\r\n                            onClick={(e) => { e.stopPropagation(); openDialog(row); }}\r\n                            sx={{\r\n                              fontFamily: FONT,\r\n                              backgroundColor: COLORS.navy,\r\n                              color: \"#fff\",\r\n                              fontWeight: 600,\r\n                              minWidth: 28,\r\n                              height: 20,\r\n                              fontSize: \"0.67rem\",\r\n                              cursor: \"pointer\",\r\n                              \"&:hover\": { backgroundColor: COLORS.blue },\r\n                            }}\r\n                          />\r\n                        </TableCell>\r\n                        <TableCell sx={{ fontSize: \"0.73rem\", color: \"#4a5568\" }}>\r\n                          {row.firstLoginTime\r\n                            ? dayjs(row.firstLoginTime).format(\"DD MMM YYYY hh:mm A\")\r\n                            : \"\"}\r\n                        </TableCell>\r\n                        <TableCell sx={{ fontSize: \"0.73rem\", color: \"#4a5568\" }}>\r\n                          {isLoggedIn ? (\r\n                            <Chip\r\n                              label=\"LOGGED-IN\"\r\n                              size=\"small\"\r\n                              sx={{\r\n                                fontFamily: FONT,\r\n                                backgroundColor: COLORS.green,\r\n                                color: \"#fff\",\r\n                                fontWeight: 600,\r\n                                fontSize: \"0.65rem\",\r\n                                height: 20,\r\n                              }}\r\n                            />\r\n                          ) : (\r\n                            dayjs(row.lastLogoutTime).format(\"DD MMM YYYY hh:mm A\")\r\n                          )}\r\n                        </TableCell>\r\n                        <TableCell\r\n                          sx={{ fontWeight: 600, color: COLORS.blue, fontSize: \"0.75rem\", fontVariantNumeric: \"tabular-nums\" }}\r\n                        >\r\n                          {row.workingDurationFormatted || \"\"}\r\n                        </TableCell>\r\n                        <TableCell\r\n                          sx={{ fontWeight: 500, color: COLORS.amber, fontSize: \"0.75rem\", fontVariantNumeric: \"tabular-nums\" }}\r\n                        >\r\n                          {row.breakDurationFormatted || \"\"}\r\n                        </TableCell>\r\n                        <TableCell sx={{ fontWeight: 500, fontSize: \"0.75rem\", fontVariantNumeric: \"tabular-nums\" }}>\r\n                          {row.loginDurationFormatted || \"\"}\r\n                        </TableCell>\r\n                        <TableCell sx={{ minWidth: 120 }}>\r\n                          {row.utilisationPct != null ? (() => {\r\n                            const pct = Math.min(row.utilisationPct, 100);\r\n                            const barColor =\r\n                              pct >= 80 ? \"#10b981\" : pct >= 60 ? \"#f59e0b\" : \"#ef4444\";\r\n                            const bgTint =\r\n                              pct >= 80 ? \"#d1fae5\" : pct >= 60 ? \"#fef3c7\" : \"#fee2e2\";\r\n                            return (\r\n                              <Box sx={{ display: \"flex\", alignItems: \"center\", gap: 0.8 }}>\r\n                                <Box\r\n                                  sx={{\r\n                                    position: \"relative\",\r\n                                    flex: 1,\r\n                                    height: 7,\r\n                                    borderRadius: 4,\r\n                                    backgroundColor: bgTint,\r\n                                    overflow: \"hidden\",\r\n                                  }}\r\n                                >\r\n                                  <Box\r\n                                    sx={{\r\n                                      width: `${pct}%`,\r\n                                      height: \"100%\",\r\n                                      borderRadius: 4,\r\n                                      background: `linear-gradient(90deg, ${barColor}cc, ${barColor})`,\r\n                                      transition: \"width 0.4s ease\",\r\n                                    }}\r\n                                  />\r\n                                </Box>\r\n                                <Chip\r\n                                  label={`${Math.round(pct)}%`}\r\n                                  size=\"small\"\r\n                                  sx={{\r\n                                    fontFamily: FONT,\r\n                                    height: 18,\r\n                                    minWidth: 38,\r\n                                    fontSize: \"0.63rem\",\r\n                                    fontWeight: 700,\r\n                                    backgroundColor: bgTint,\r\n                                    color: barColor,\r\n                                    \"& .MuiChip-label\": { px: 0.6 },\r\n                                  }}\r\n                                />\r\n                              </Box>\r\n                            );\r\n                          })() : (\r\n                            \"\"\r\n                          )}\r\n                        </TableCell>\r\n                      </TableRow>\r\n                    );\r\n                  })}\r\n                </TableBody>\r\n              </Table>\r\n            </TableContainer>\r\n\r\n            <TablePagination\r\n              component=\"div\"\r\n              count={totalCount}\r\n              page={page}\r\n              onPageChange={handlePageChange}\r\n              rowsPerPage={rowsPerPage}\r\n              rowsPerPageOptions={[10, 15, 25, 50, 100]}\r\n              onRowsPerPageChange={(e) => { setRowsPerPage(parseInt(e.target.value, 10)); setPage(0); }}\r\n              sx={{ borderTop: \"1px solid #eef1f6\", fontFamily: FONT, \"& .MuiTablePagination-displayedRows\": { fontFamily: FONT, fontSize: \"0.73rem\" }, \"& .MuiTablePagination-selectLabel\": { fontFamily: FONT, fontSize: \"0.73rem\" } }}\r\n            />\r\n          </Paper>\r\n\r\n          <Dialog\r\n            open={dialogOpen}\r\n            onClose={(_e, reason) => { if (reason !== 'backdropClick') closeDialog(); }}\r\n            maxWidth=\"md\"\r\n            fullWidth\r\n            PaperProps={{\r\n              sx: {\r\n                borderRadius: \"12px\",\r\n                fontFamily: FONT,\r\n                overflow: \"hidden\",\r\n                boxShadow: \"0 8px 32px rgba(0,0,0,0.18)\",\r\n                maxWidth: 450,\r\n              },\r\n            }}\r\n          >\r\n            <DialogTitle\r\n              sx={{\r\n                fontFamily: FONT,\r\n                background: \"linear-gradient(135deg, var(--primary-color-dark, #14505b), var(--primary-color, #1A5F6C))\",\r\n                color: \"#fff\",\r\n                display: \"flex\",\r\n                justifyContent: \"space-between\",\r\n                alignItems: \"center\",\r\n                py: 1.5,\r\n                px: 2.5,\r\n              }}\r\n            >\r\n              <Box>\r\n                <Typography variant=\"h6\" sx={{ fontFamily: FONT, fontWeight: 700, fontSize: \"0.95rem\", letterSpacing: \"0.3px\" }}>\r\n                  Login Sessions\r\n                </Typography>\r\n                <Typography\r\n                  variant=\"body2\"\r\n                  sx={{ fontFamily: FONT, opacity: 0.9, fontSize: \"0.76rem\", mt: 0.3 }}\r\n                >\r\n                  {selectedRow?.fullName} &bull; {selectedRow?.numLogins} session{selectedRow?.numLogins !== 1 ? \"s\" : \"\"}\r\n                </Typography>\r\n              </Box>\r\n              <Box sx={{ display: \"flex\", alignItems: \"center\", gap: 0.5 }}>\r\n                <AppButton\r\n                  size=\"small\"\r\n                  startIcon={exportingSessions ? <CircularProgress size={14} sx={{ color: \"#fff\" }} /> : <DownloadIcon sx={{ fontSize: \"0.85rem !important\" }} />}\r\n                  disabled={exportingSessions}\r\n                  onClick={async () => {\r\n                    if (!selectedRow) return;\r\n                    try {\r\n                      setExportingSessions(true);\r\n                      await exportAgentLoginSessionsToExcel(selectedRow.agentId, {\r\n                        start_date: (startDate ?? dayjs()).format(\"YYYY-MM-DDTHH:mm:ss\"),\r\n                        end_date: (endDate ?? dayjs()).format(\"YYYY-MM-DDTHH:mm:ss\"),\r\n                        sortBy: sessionsSortKey,\r\n                        sortOrder: sessionsSortDir,\r\n                      });\r\n                    } catch (err: any) {\r\n                      setError(err?.message || \"Failed to export Excel\");\r\n                    } finally {\r\n                      setExportingSessions(false);\r\n                    }\r\n                  }}\r\n                  sx={{ whiteSpace: \"nowrap\" }}\r\n                >\r\n                  Export to Excel\r\n                </AppButton>\r\n                <IconButton\r\n                  onClick={closeDialog}\r\n                  size=\"small\"\r\n                  sx={{\r\n                    color: \"#fff\",\r\n                    backgroundColor: \"rgba(255,255,255,0.1)\",\r\n                    \"&:hover\": { backgroundColor: \"rgba(255,255,255,0.2)\" },\r\n                  }}\r\n                >\r\n                  <CloseIcon fontSize=\"small\" />\r\n                </IconButton>\r\n              </Box>\r\n            </DialogTitle>\r\n\r\n            <DialogContent sx={{ p: 0, backgroundColor: \"#f8fafb\" }}>\r\n              {sessionsLoading ? (\r\n                <Box sx={{ p: 4, textAlign: \"center\" }}>\r\n                  <CircularProgress size={28} sx={{ color: \"var(--primary-color, #1A5F6C)\" }} />\r\n                </Box>\r\n              ) : sessions.length > 0 ? (\r\n                <Box sx={{ p: 1.5, maxHeight: 300, overflowY: \"auto\" }}>\r\n                  {Object.entries(\r\n                    sessions.reduce<Record<string, LoginSessionResponse[]>>((acc, s) => {\r\n                      const dateKey = s.loginTime\r\n                        ? dayjs(s.loginTime).format(\"DD MMM YYYY\")\r\n                        : \"Unknown Date\";\r\n                      if (!acc[dateKey]) acc[dateKey] = [];\r\n                      acc[dateKey].push(s);\r\n                      return acc;\r\n                    }, {})\r\n                  ).map(([date, dateSessions]) => (\r\n                    <Paper\r\n                      key={date}\r\n                      elevation={0}\r\n                      sx={{\r\n                        mb: 1.5,\r\n                        borderRadius: \"10px\",\r\n                        border: \"1px solid #e4eaf0\",\r\n                        overflow: \"hidden\",\r\n                        backgroundColor: \"#fff\",\r\n                      }}\r\n                    >\r\n                      <Box\r\n                        sx={{\r\n                          px: 1.5,\r\n                          py: 0.8,\r\n                          backgroundColor: \"#f0f5f4\",\r\n                          borderBottom: \"1px solid #e4eaf0\",\r\n                        }}\r\n                      >\r\n                        <Typography\r\n                          sx={{\r\n                            fontFamily: FONT,\r\n                            fontWeight: 700,\r\n                            fontSize: \"0.8rem\",\r\n                            color: \"var(--primary-color-dark, #14505b)\",\r\n                            letterSpacing: \"0.3px\",\r\n                          }}\r\n                        >\r\n                          {date}\r\n                        </Typography>\r\n                      </Box>\r\n                      <Box sx={{ px: 1.5, py: 1 }}>\r\n                        <Box\r\n                          sx={{\r\n                            display: \"flex\",\r\n                            alignItems: \"center\",\r\n                            gap: 2,\r\n                            pb: 0.5,\r\n                            mb: 0.5,\r\n                            borderBottom: \"1px solid #e4eaf0\",\r\n                          }}\r\n                        >\r\n                          <Typography\r\n                            sx={{\r\n                              flex: 1,\r\n                              fontFamily: FONT,\r\n                              fontSize: \"0.72rem\",\r\n                              fontWeight: 700,\r\n                              color: \"#555\",\r\n                              textTransform: \"uppercase\",\r\n                              letterSpacing: \"0.5px\",\r\n                            }}\r\n                          >\r\n                            <TableSortLabel\r\n                              active={sessionsSortKey === \"loginTime\"}\r\n                              direction={sessionsSortKey === \"loginTime\" ? sessionsSortDir : \"asc\"}\r\n                              onClick={() => handleSessionsSort(\"loginTime\")}\r\n                              sx={{ color: \"inherit !important\", \"& .MuiTableSortLabel-icon\": { color: \"#555 !important\" } }}\r\n                            >\r\n                              Login\r\n                            </TableSortLabel>\r\n                          </Typography>\r\n                          <Typography\r\n                            sx={{\r\n                              flex: 1,\r\n                              fontFamily: FONT,\r\n                              fontSize: \"0.72rem\",\r\n                              fontWeight: 700,\r\n                              color: \"#555\",\r\n                              textTransform: \"uppercase\",\r\n                              letterSpacing: \"0.5px\",\r\n                            }}\r\n                          >\r\n                            <TableSortLabel\r\n                              active={sessionsSortKey === \"logoutTime\"}\r\n                              direction={sessionsSortKey === \"logoutTime\" ? sessionsSortDir : \"asc\"}\r\n                              onClick={() => handleSessionsSort(\"logoutTime\")}\r\n                              sx={{ color: \"inherit !important\", \"& .MuiTableSortLabel-icon\": { color: \"#555 !important\" } }}\r\n                            >\r\n                              Logout\r\n                            </TableSortLabel>\r\n                          </Typography>\r\n                        </Box>\r\n                        {dateSessions.map((s, i) => {\r\n                          const isOpenSession = !s.logoutTime;\r\n                          const isEditing = s.sessionId != null && regularizeSessionId === s.sessionId;\r\n                          return (\r\n                            <Box\r\n                              key={i}\r\n                              sx={{\r\n                                py: 0.6,\r\n                                borderBottom: i < dateSessions.length - 1 ? \"1px dashed #e8ecf0\" : \"none\",\r\n                              }}\r\n                            >\r\n                              <Box sx={{ display: \"flex\", alignItems: \"center\", gap: 2 }}>\r\n                                <Typography\r\n                                  component=\"span\"\r\n                                  sx={{\r\n                                    flex: 1,\r\n                                    fontFamily: FONT,\r\n                                    fontSize: \"0.78rem\",\r\n                                    fontWeight: 500,\r\n                                    color: s.loginTime ? COLORS.green : \"#9e9e9e\",\r\n                                    display: \"flex\",\r\n                                    alignItems: \"center\",\r\n                                    gap: 0.4,\r\n                                  }}\r\n                                >\r\n                                  <span style={{ fontSize: \"0.9rem\" }}>{\"↙\"}</span>\r\n                                  {s.loginTime ? dayjs(s.loginTime).format(\"DD MMM YYYY h:mm:ss A\") : \"Missing\"}\r\n                                </Typography>\r\n                                <Box sx={{ flex: 1, display: \"flex\", alignItems: \"center\", justifyContent: \"space-between\", gap: 0.4 }}>\r\n                                  <Typography\r\n                                    component=\"span\"\r\n                                    sx={{\r\n                                      fontFamily: FONT,\r\n                                      fontSize: \"0.78rem\",\r\n                                      fontWeight: 500,\r\n                                      color: s.logoutTime ? COLORS.red : \"#9e9e9e\",\r\n                                      display: \"flex\",\r\n                                      alignItems: \"center\",\r\n                                      gap: 0.4,\r\n                                    }}\r\n                                  >\r\n                                    <span style={{ fontSize: \"0.9rem\" }}>{\"↗\"}</span>\r\n                                    {s.logoutTime\r\n                                      ? dayjs(s.logoutTime).format(\"DD MMM YYYY h:mm:ss A\")\r\n                                      : \"Missing\"}\r\n                                  </Typography>\r\n                                  {isOpenSession && s.sessionId != null && !isEditing && (\r\n                                    <SDKPermissionGuard\r\n                                      permissions={[SDK_PERMISSIONS.REPORTS_AGENT_LOGIN_MANAGE]}\r\n                                      showFallback={false}\r\n                                    >\r\n                                      <Tooltip title=\"Regularize — set logout time\">\r\n                                        <IconButton\r\n                                          size=\"small\"\r\n                                          onClick={() => startRegularize(s)}\r\n                                          sx={{\r\n                                            p: 0.4,\r\n                                            color: \"var(--primary-color, #1A5F6C)\",\r\n                                            borderRadius: \"6px\",\r\n                                            \"&:hover\": { backgroundColor: \"rgba(26,95,108,0.08)\" },\r\n                                          }}\r\n                                        >\r\n                                          <EditCalendarIcon sx={{ fontSize: \"1.05rem\" }} />\r\n                                        </IconButton>\r\n                                      </Tooltip>\r\n                                    </SDKPermissionGuard>\r\n                                  )}\r\n                                </Box>\r\n                              </Box>\r\n\r\n                              {isEditing && (\r\n                                <Box\r\n                                  sx={{\r\n                                    mt: 1,\r\n                                    p: 1.25,\r\n                                    borderRadius: \"10px\",\r\n                                    backgroundColor: \"#f0f5f4\",\r\n                                    border: \"1px solid #d7e3e1\",\r\n                                  }}\r\n                                >\r\n                                  <Typography\r\n                                    sx={{\r\n                                      fontFamily: FONT,\r\n                                      fontSize: \"0.68rem\",\r\n                                      fontWeight: 700,\r\n                                      textTransform: \"uppercase\",\r\n                                      letterSpacing: \"0.5px\",\r\n                                      color: \"var(--primary-color-dark, #14505b)\",\r\n                                      mb: 0.75,\r\n                                    }}\r\n                                  >\r\n                                    Set Logout Time\r\n                                  </Typography>\r\n                                  <DateTimePicker\r\n                                    value={regularizeTime}\r\n                                    onChange={(val) => setRegularizeTime(val)}\r\n                                    timeSteps={{ minutes: 1 }}\r\n                                    minDateTime={s.loginTime ? dayjs(s.loginTime) : undefined}\r\n                                    maxDateTime={dayjs()}\r\n                                    ampm\r\n                                    format=\"DD MMM YYYY hh:mm A\"\r\n                                    slotProps={{\r\n                                      textField: {\r\n                                        size: \"small\",\r\n                                        fullWidth: true,\r\n                                        sx: {\r\n                                          backgroundColor: \"#fff\",\r\n                                          \"& .MuiOutlinedInput-root\": {\r\n                                            borderRadius: \"8px\",\r\n                                            fontFamily: FONT,\r\n                                            fontSize: \"0.8rem\",\r\n                                            \"&.Mui-focused fieldset\": { borderColor: \"var(--primary-color, #1A5F6C)\" },\r\n                                          },\r\n                                        },\r\n                                      },\r\n                                      actionBar: { actions: [\"clear\", \"cancel\", \"accept\"] },\r\n                                    }}\r\n                                  />\r\n                                  {regularizeError && (\r\n                                    <Typography sx={{ fontFamily: FONT, color: COLORS.red, fontSize: \"0.7rem\", mt: 0.6 }}>\r\n                                      {regularizeError}\r\n                                    </Typography>\r\n                                  )}\r\n                                  <Stack direction=\"row\" justifyContent=\"flex-end\" spacing={1} sx={{ mt: 1 }}>\r\n                                    <AppButton\r\n                                      variant=\"cancel\"\r\n                                      size=\"small\"\r\n                                      onClick={cancelRegularize}\r\n                                      disabled={regularizing}\r\n                                    >\r\n                                      Cancel\r\n                                    </AppButton>\r\n                                    <AppButton\r\n                                      size=\"small\"\r\n                                      onClick={saveRegularize}\r\n                                      disabled={regularizing}\r\n                                      startIcon={\r\n                                        regularizing\r\n                                          ? <CircularProgress size={14} sx={{ color: \"#fff\" }} />\r\n                                          : <CheckIcon sx={{ fontSize: \"0.95rem !important\" }} />\r\n                                      }\r\n                                    >\r\n                                      {regularizing ? \"Saving…\" : \"Regularize\"}\r\n                                    </AppButton>\r\n                                  </Stack>\r\n                                </Box>\r\n                              )}\r\n                            </Box>\r\n                          );\r\n                        })}\r\n                      </Box>\r\n                    </Paper>\r\n                  ))}\r\n                </Box>\r\n              ) : (\r\n                <Box sx={{ p: 4, textAlign: \"center\" }}>\r\n                  <Typography sx={{ fontFamily: FONT, color: \"#9e9e9e\", fontStyle: \"italic\", fontSize: \"0.82rem\" }}>\r\n                    No sessions found\r\n                  </Typography>\r\n                </Box>\r\n              )}\r\n            </DialogContent>\r\n          </Dialog>\r\n        </Box>\r\n      </Box>\r\n    </LocalizationProvider>\r\n  );\r\n}\r\n\r\nconst LoginReport: React.FC = () => (\r\n  <SDKProvider>\r\n    <LoginReportContent />\r\n  </SDKProvider>\r\n);\r\n\r\nexport default LoginReport;\r\n","import { useCallback, useState } from \"react\";\r\nimport axiosInstance from \"../../services/axios\";\r\nimport { END_POINT } from \"../../services/endPoint\";\r\nimport { appendSort, type SortParams } from \"../common/utils/sort\";\r\nimport type {\r\n\tLoginAgentRowResponse,\r\n\tLoginReportParams,\r\n\tLoginReportResponse,\r\n\tLoginSessionResponse,\r\n} from \"./types\";\r\n\r\nexport interface Queue {\r\n\tid: number;\r\n\tname: string;\r\n\tdescription: string;\r\n\tprocessId?: number;\r\n\tisActive: boolean;\r\n}\r\n\r\nexport async function fetchQueues(): Promise<Queue[]> {\r\n\tconst res = await axiosInstance.get(END_POINT.MASTER_QUEUES);\r\n\tif (Array.isArray(res.data)) return res.data;\r\n\tif (Array.isArray(res.data?.data)) return res.data.data;\r\n\treturn [];\r\n}\r\n\r\nexport async function getQueues(): Promise<Queue[]> {\r\n\treturn fetchQueues();\r\n}\r\n\r\nexport async function getLoginReportAgents(params: LoginReportParams): Promise<LoginAgentRowResponse[]> {\r\n\tconst qs = buildLoginReportQueryString(params);\r\n\tconst res = await axiosInstance.get<LoginAgentRowResponse[]>(`${END_POINT.LOGIN_REPORT_AGENTS}${qs}`);\r\n\treturn Array.isArray(res.data) ? res.data : [];\r\n}\r\n\r\n/**\r\n * Combined login report — returns summary + the current page of agent rows.\r\n * Used for server-side pagination (the combined endpoint honours page/pageSize/search).\r\n */\r\nexport async function getLoginReport(params: LoginReportParams): Promise<LoginReportResponse> {\r\n\tconst qs = buildLoginReportQueryString(params);\r\n\tconst res = await axiosInstance.get<LoginReportResponse>(`${END_POINT.LOGIN_REPORT}${qs}`);\r\n\treturn res.data;\r\n}\r\n\r\nexport async function getAgentLoginSessions(\r\n\tagentId: string,\r\n\tparams?: { start_date?: string; end_date?: string } & SortParams,\r\n): Promise<LoginSessionResponse[]> {\r\n\tconst qs = buildSessionQueryString(params);\r\n\tconst res = await axiosInstance.get<LoginSessionResponse[]>(\r\n\t\t`${END_POINT.LOGIN_REPORT_AGENT_SESSIONS(agentId)}${qs}`,\r\n\t);\r\n\treturn Array.isArray(res.data) ? res.data : [];\r\n}\r\n\r\n/**\r\n * Regularize (close) a stuck open login session by setting its logout time.\r\n * Supervisor action from the login report — clears the agent's active session.\r\n */\r\nexport async function regularizeLoginSession(sessionId: number | string, logoutTime: string): Promise<void> {\r\n\tawait axiosInstance.patch(END_POINT.LOGIN_REPORT_REGULARIZE_SESSION(sessionId), { sessionId, logoutTime });\r\n}\r\n\r\nexport async function exportLoginReportToExcel(params: LoginReportParams): Promise<void> {\r\n\tconst qs = buildLoginReportQueryString(params);\r\n\tconst res = await axiosInstance.get(`${END_POINT.LOGIN_REPORT_EXPORT_EXCEL}${qs}`, { responseType: \"blob\" });\r\n\ttriggerBlobDownload(new Blob([res.data]), `login-report-${params.start_date ?? \"export\"}.xlsx`);\r\n}\r\n\r\nexport async function exportAgentLoginSessionsToExcel(\r\n\tagentId: string,\r\n\tparams?: { start_date?: string; end_date?: string } & SortParams,\r\n): Promise<void> {\r\n\tconst qs = buildSessionQueryString(params);\r\n\tconst res = await axiosInstance.get(\r\n\t\t`${END_POINT.LOGIN_REPORT_AGENT_SESSIONS_EXPORT_EXCEL(agentId)}${qs}`,\r\n\t\t{ responseType: \"blob\" },\r\n\t);\r\n\ttriggerBlobDownload(new Blob([res.data]), `login_sessions_${agentId}.xlsx`);\r\n}\r\n\r\nfunction buildLoginReportQueryString(params: LoginReportParams): string {\r\n\tconst qs = new URLSearchParams();\r\n\tif (params.start_date) qs.append(\"start_date\", params.start_date);\r\n\tif (params.end_date) qs.append(\"end_date\", params.end_date);\r\n\tif (params.agent_id) for (const id of params.agent_id) qs.append(\"agent_id\", id);\r\n\tif (params.queue_id) for (const id of params.queue_id) qs.append(\"queue_id\", String(id));\r\n\tif (params.process_id) for (const id of params.process_id) qs.append(\"process_id\", String(id));\r\n\tif (params.search) qs.append(\"search\", params.search);\r\n\tif (params.page) qs.append(\"page\", String(params.page));\r\n\tif (params.pageSize) qs.append(\"pageSize\", String(params.pageSize));\r\n\tappendSort(qs, params);\r\n\tconst str = qs.toString();\r\n\treturn str ? `?${str}` : \"\";\r\n}\r\n\r\nfunction buildSessionQueryString(params?: { start_date?: string; end_date?: string } & SortParams): string {\r\n\tconst qs = new URLSearchParams();\r\n\tif (params?.start_date) qs.append(\"start_date\", params.start_date);\r\n\tif (params?.end_date) qs.append(\"end_date\", params.end_date);\r\n\tappendSort(qs, params);\r\n\tconst str = qs.toString();\r\n\treturn str ? `?${str}` : \"\";\r\n}\r\n\r\nfunction triggerBlobDownload(blob: Blob, filename: string): void {\r\n\tconst url = URL.createObjectURL(blob);\r\n\tconst a = document.createElement(\"a\");\r\n\ta.href = url;\r\n\ta.download = filename;\r\n\tdocument.body.appendChild(a);\r\n\ta.click();\r\n\ta.remove();\r\n\tURL.revokeObjectURL(url);\r\n}\r\n\r\nexport function useLoginReport() {\r\n\tconst [agents, setAgents] = useState<LoginAgentRowResponse[]>([]);\r\n\tconst [loading, setLoading] = useState(false);\r\n\tconst [error, setError] = useState(\"\");\r\n\r\n\tconst fetchAgents = useCallback(async (params: LoginReportParams): Promise<void> => {\r\n\t\tsetLoading(true);\r\n\t\tsetError(\"\");\r\n\t\ttry {\r\n\t\t\tconst qs = buildLoginReportQueryString(params);\r\n\t\t\tconst res = await axiosInstance.get<LoginAgentRowResponse[]>(\r\n\t\t\t\t`${END_POINT.LOGIN_REPORT_AGENTS}${qs}`,\r\n\t\t\t);\r\n\t\t\tsetAgents(Array.isArray(res.data) ? res.data : []);\r\n\t\t} catch (err: any) {\r\n\t\t\tsetAgents([]);\r\n\t\t\tsetError(\r\n\t\t\t\terr?.response?.data?.message ||\r\n\t\t\t\t\terr?.response?.data?.detail ||\r\n\t\t\t\t\terr?.message ||\r\n\t\t\t\t\t\"Failed to fetch login report\",\r\n\t\t\t);\r\n\t\t} finally {\r\n\t\t\tsetLoading(false);\r\n\t\t}\r\n\t}, []);\r\n\r\n\tconst fetchSummary = useCallback(async (params: LoginReportParams): Promise<LoginReportResponse> => {\r\n\t\tconst qs = buildLoginReportQueryString(params);\r\n\t\tconst res = await axiosInstance.get<LoginReportResponse>(\r\n\t\t\t`${END_POINT.LOGIN_REPORT}${qs}`,\r\n\t\t);\r\n\t\treturn res.data;\r\n\t}, []);\r\n\r\n\tconst fetchAgentSessions = useCallback(\r\n\t\tasync (agentId: string, params?: { start_date?: string; end_date?: string } & SortParams): Promise<LoginSessionResponse[]> => {\r\n\t\t\tconst qs = buildSessionQueryString(params);\r\n\t\t\tconst res = await axiosInstance.get<LoginSessionResponse[]>(\r\n\t\t\t\t`${END_POINT.LOGIN_REPORT_AGENT_SESSIONS(agentId)}${qs}`,\r\n\t\t\t);\r\n\t\t\treturn Array.isArray(res.data) ? res.data : [];\r\n\t\t},\r\n\t\t[],\r\n\t);\r\n\r\n\tconst exportReportExcel = useCallback(async (params: LoginReportParams): Promise<void> => {\r\n\t\tconst qs = buildLoginReportQueryString(params);\r\n\t\tconst res = await axiosInstance.get(\r\n\t\t\t`${END_POINT.LOGIN_REPORT_EXPORT_EXCEL}${qs}`,\r\n\t\t\t{ responseType: \"blob\" },\r\n\t\t);\r\n\t\ttriggerBlobDownload(new Blob([res.data]), `login-report-${params.start_date ?? \"export\"}.xlsx`);\r\n\t}, []);\r\n\r\n\tconst exportAgentSessionsExcel = useCallback(\r\n\t\tasync (agentId: string, params?: { start_date?: string; end_date?: string } & SortParams): Promise<void> => {\r\n\t\t\tconst qs = buildSessionQueryString(params);\r\n\t\t\tconst res = await axiosInstance.get(\r\n\t\t\t\t`${END_POINT.LOGIN_REPORT_AGENT_SESSIONS_EXPORT_EXCEL(agentId)}${qs}`,\r\n\t\t\t\t{ responseType: \"blob\" },\r\n\t\t\t);\r\n\t\t\ttriggerBlobDownload(new Blob([res.data]), `login_sessions_${agentId}.xlsx`);\r\n\t\t},\r\n\t\t[],\r\n\t);\r\n\r\n\treturn {\r\n\t\tagents,\r\n\t\tloading,\r\n\t\terror,\r\n\t\tsetError,\r\n\t\tfetchAgents,\r\n\t\tfetchSummary,\r\n\t\tfetchAgentSessions,\r\n\t\texportReportExcel,\r\n\t\texportAgentSessionsExcel,\r\n\t};\r\n}\r\n"],"mappings":"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","names":["useCallback","useState","useState","useCallback"]}