diff --git a/src/app/(admin)/stats/page.tsx b/src/app/(admin)/stats/page.tsx index 82e3b38..815e00e 100644 --- a/src/app/(admin)/stats/page.tsx +++ b/src/app/(admin)/stats/page.tsx @@ -28,7 +28,9 @@ export default async function StatsPage() { const stats = await getStatsOverview(); const maxChannelCount = Math.max(...Object.values(stats.channelCounts), 1); - const maxAgentWorkload = Math.max(...stats.agentWorkload.map((a) => a.ticketCount), 1); + const statusesWithWorkload = (Object.keys(STATUS_META) as (keyof typeof STATUS_META)[]).filter( + (status) => stats.agentWorkloadByStatus[status].length > 0, + ); return (
@@ -88,24 +90,35 @@ export default async function StatsPage() {
-
-

Заявки по агентам (все статусы)

- {stats.agentWorkload.length === 0 ? ( + {statusesWithWorkload.length === 0 ? ( +
+

Заявки по агентам

Пока нет данных.

- ) : ( -
- {stats.agentWorkload.map((agent) => ( - - ))} -
- )} -
+
+ ) : ( + statusesWithWorkload.map((status) => { + const workload = stats.agentWorkloadByStatus[status]; + const max = Math.max(...workload.map((a) => a.count), 1); + return ( +
+

+ Заявки по агентам — {STATUS_META[status].label} +

+
+ {workload.map((agent) => ( + + ))} +
+
+ ); + }) + )} ); diff --git a/src/lib/tickets/service.ts b/src/lib/tickets/service.ts index 19a0054..3c302e3 100644 --- a/src/lib/tickets/service.ts +++ b/src/lib/tickets/service.ts @@ -705,7 +705,7 @@ export interface StatsOverview { statusCounts: Record; channelCounts: Record; ticketsPerDay: { label: string; count: number }[]; - agentWorkload: { name: string; ticketCount: number }[]; + agentWorkloadByStatus: Record; } /** @@ -771,20 +771,32 @@ export async function getStatsOverview(): Promise { : null; const agents = await listAgents(); - const ticketCountByAgent = new Map(); - let unassignedCount = 0; - for (const t of allTickets) { - if (t.assigneeId) { - ticketCountByAgent.set(t.assigneeId, (ticketCountByAgent.get(t.assigneeId) ?? 0) + 1); - } else { - unassignedCount += 1; + + /** Per-agent ticket count for one status, sorted busiest-first. */ + function workloadForStatus(status: TicketStatus): { name: string; count: number }[] { + const countByAgent = new Map(); + let unassignedCount = 0; + for (const t of allTickets) { + if (t.status !== status) continue; + if (t.assigneeId) { + countByAgent.set(t.assigneeId, (countByAgent.get(t.assigneeId) ?? 0) + 1); + } else { + unassignedCount += 1; + } } + const workload = agents.map((a) => ({ name: a.name, count: countByAgent.get(a.id) ?? 0 })); + if (unassignedCount > 0) { + workload.push({ name: "Не назначено", count: unassignedCount }); + } + return workload.sort((a, b) => b.count - a.count); } - const agentWorkload = agents.map((a) => ({ name: a.name, ticketCount: ticketCountByAgent.get(a.id) ?? 0 })); - if (unassignedCount > 0) { - agentWorkload.push({ name: "Не назначено", ticketCount: unassignedCount }); - } - agentWorkload.sort((a, b) => b.ticketCount - a.ticketCount); + + const agentWorkloadByStatus: Record = { + new: workloadForStatus("new"), + open: workloadForStatus("open"), + pending: workloadForStatus("pending"), + closed: workloadForStatus("closed"), + }; return { totalTickets: allTickets.length, @@ -794,6 +806,6 @@ export async function getStatsOverview(): Promise { statusCounts, channelCounts, ticketsPerDay, - agentWorkload, + agentWorkloadByStatus, }; }