| import type { AnalystLoadRow } from "@/types/api"; | |
| export function AnalystLoad({ rows }: { rows: AnalystLoadRow[] }) { | |
| const maxCases = Math.max(1, ...rows.map((r) => r.open_cases)); | |
| return ( | |
| <div className="panel"> | |
| <div className="px-4 py-3 border-b border-border flex items-center justify-between"> | |
| <div className="heading">Analyst load</div> | |
| <div className="text-xs text-muted">{rows.length}</div> | |
| </div> | |
| <div className="p-4 space-y-2.5"> | |
| {rows.length === 0 && <div className="text-sm text-muted">No open cases.</div>} | |
| {rows.map((r) => { | |
| const isUnassigned = r.analyst === "Unassigned"; | |
| return ( | |
| <div | |
| key={r.analyst} | |
| className="grid grid-cols-[120px,1fr,90px] items-center gap-3 text-sm" | |
| > | |
| <div className={isUnassigned ? "text-warning" : "text-text"}> | |
| {r.analyst} | |
| </div> | |
| <div className="relative h-5 rounded-sm bg-panel2 overflow-hidden border border-border"> | |
| <div | |
| className={isUnassigned ? "absolute inset-y-0 left-0 bg-warning/50" : "absolute inset-y-0 left-0 bg-accent/70"} | |
| style={{ width: `${(r.open_cases / maxCases) * 100}%` }} | |
| /> | |
| <div className="absolute inset-0 flex items-center px-2 text-[11px] num"> | |
| {r.open_cases} {r.open_cases === 1 ? "case" : "cases"} | |
| </div> | |
| </div> | |
| <div className="num text-xs text-muted text-right"> | |
| {r.avg_materiality_bps != null | |
| ? `${r.avg_materiality_bps.toFixed(1)} bps avg` | |
| : "β"} | |
| </div> | |
| </div> | |
| ); | |
| })} | |
| </div> | |
| </div> | |
| ); | |
| } | |