import { useMemo } from "react"; import { faUserHeadset } from "@fortawesome/pro-duotone-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { Link } from "react-router"; import { Table, TableCard } from "@/components/application/table/table"; import { Avatar } from "@/components/base/avatar/avatar"; import { Badge } from "@/components/base/badges/badges"; import { getInitials } from "@/lib/format"; import type { Call } from "@/types/entities"; const formatDuration = (seconds: number): string => { if (seconds < 60) return `${seconds}s`; const mins = Math.floor(seconds / 60); const secs = seconds % 60; return secs > 0 ? `${mins}m ${secs}s` : `${mins}m`; }; const formatPercent = (value: number): string => { if (isNaN(value) || !isFinite(value)) return "0%"; return `${Math.round(value)}%`; }; interface AgentTableProps { calls: Call[]; } export const AgentTable = ({ calls }: AgentTableProps) => { const agents = useMemo(() => { const agentMap = new Map(); for (const call of calls) { const agent = call.agentName ?? "Unknown"; if (!agentMap.has(agent)) agentMap.set(agent, []); agentMap.get(agent)!.push(call); } return Array.from(agentMap.entries()) .map(([name, agentCalls]) => { const inbound = agentCalls.filter((c) => c.callDirection === "INBOUND").length; const outbound = agentCalls.filter((c) => c.callDirection === "OUTBOUND").length; const missed = agentCalls.filter((c) => c.callStatus === "MISSED").length; const total = agentCalls.length; const completedCalls = agentCalls.filter((c) => (c.durationSeconds ?? 0) > 0); const totalDuration = completedCalls.reduce((sum, c) => sum + (c.durationSeconds ?? 0), 0); const avgHandle = completedCalls.length > 0 ? Math.round(totalDuration / completedCalls.length) : 0; const booked = agentCalls.filter((c) => c.disposition === "APPOINTMENT_BOOKED").length; const conversion = total > 0 ? (booked / total) * 100 : 0; const nameParts = name.split(" "); return { id: name, name, initials: getInitials(nameParts[0] ?? "", nameParts[1] ?? ""), inbound, outbound, missed, total, avgHandle, conversion, }; }) .sort((a, b) => b.total - a.total); }, [calls]); if (agents.length === 0) { return (

No agent data available

); } return ( {(agent) => (
{agent.name}
{agent.inbound} {agent.outbound} {agent.missed > 0 ? ( {agent.missed} ) : ( 0 )} {formatDuration(agent.avgHandle)} = 30 ? "success" : agent.conversion >= 15 ? "warning" : "gray"}> {formatPercent(agent.conversion)}
)}
); };