Files
server-26/drb-frontend/components/CallRow.tsx
T
Logan 2f0597c81b Initial commit — DRB server stack
Includes c2-core (FastAPI/MQTT/Firestore), discord-bot (slash commands),
frontend (Next.js admin UI), and mosquitto config.
2026-04-05 19:01:39 -04:00

52 lines
1.6 KiB
TypeScript

import type { CallRecord } from "@/lib/types";
interface Props {
call: CallRecord;
systemName?: string;
}
function duration(started: string, ended: string | null): string {
if (!ended) return "active";
const ms = new Date(ended).getTime() - new Date(started).getTime();
const s = Math.floor(ms / 1000);
return s < 60 ? `${s}s` : `${Math.floor(s / 60)}m ${s % 60}s`;
}
export function CallRow({ call, systemName }: Props) {
const isActive = call.status === "active";
return (
<tr className="border-b border-gray-800 hover:bg-gray-900/50 font-mono text-sm">
<td className="px-4 py-2 text-gray-400 text-xs">
{new Date(call.started_at).toLocaleTimeString()}
</td>
<td className="px-4 py-2 text-gray-300">
{call.talkgroup_name || call.talkgroup_id || "—"}
</td>
<td className="px-4 py-2 text-gray-400">{systemName ?? call.system_id ?? "—"}</td>
<td className="px-4 py-2 text-gray-400">{call.node_id}</td>
<td className="px-4 py-2">
{isActive ? (
<span className="text-orange-400 animate-pulse"> live</span>
) : (
<span className="text-gray-500">{duration(call.started_at, call.ended_at)}</span>
)}
</td>
<td className="px-4 py-2">
{call.audio_url ? (
<a
href={call.audio_url}
target="_blank"
rel="noopener noreferrer"
className="text-blue-400 hover:text-blue-300 text-xs"
>
audio
</a>
) : (
<span className="text-gray-700 text-xs"></span>
)}
</td>
</tr>
);
}