feat: play the recording on the Live monitor too
The operator watches the Live monitor and never sees My calls, so the recording was reachable only by the colleague who took the call. Now both audiences get it, by the route each already uses: operator -> call_recording_url on the lead, via the record view colleague -> GET /api/agent-sessions/:id/call, authorised by owning the session Two paths because they are looking at two different things — a lead record and a conversation — not because the data differs. Placed ABOVE the summary in the drawer: the summary is a claim about the call and this is the call, so on a demo about whether the AI captured things fairly the evidence should not sit below the fold. preload="none" on both. The drawer opens on every row click, and a WAV of a whole phone call is not something to fetch speculatively. tsc -b and vite build clean.
This commit is contained in:
parent
0612626491
commit
e442347b6e
@ -39,6 +39,8 @@ export const FIELDS = {
|
||||
CALL_DURATION: 'call_duration_seconds',
|
||||
CALL_SUMMARY: 'call_summary',
|
||||
CONTACT_NOTES: 'contact_notes',
|
||||
/** Dual-channel WAV of the call, written when it ends. */
|
||||
CALL_RECORDING: 'call_recording_url',
|
||||
} as const
|
||||
|
||||
/**
|
||||
|
||||
@ -169,6 +169,7 @@ function DetailDrawer({ row, onClose }: { row: LeadRow; onClose: () => void }) {
|
||||
const summary = str(row[FIELDS.CALL_SUMMARY])
|
||||
const notes = str(row[FIELDS.CONTACT_NOTES])
|
||||
const transferred = str(row[FIELDS.CALL_END_REASON]) === END_REASON_HANDOVER
|
||||
const recording = str(row[FIELDS.CALL_RECORDING])
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 z-20 flex justify-end bg-slate-900/20" onClick={onClose}>
|
||||
@ -205,6 +206,25 @@ function DetailDrawer({ row, onClose }: { row: LeadRow; onClose: () => void }) {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* The recording sits ABOVE the summary on purpose: the summary is a
|
||||
claim about the conversation, and this is the conversation. On a demo
|
||||
about whether the AI captured things fairly, the evidence should not
|
||||
be below the fold. */}
|
||||
<div className="mt-5">
|
||||
<h3 className="text-xs font-semibold uppercase tracking-wide text-slate-500">Recording</h3>
|
||||
{recording ? (
|
||||
// preload="none": a WAV of a whole call, and the drawer opens on
|
||||
// every row click. Fetch it when someone actually presses play.
|
||||
<audio controls preload="none" src={recording} className="mt-2 h-9 w-full" />
|
||||
) : (
|
||||
<p className="mt-1.5 text-sm text-slate-400">
|
||||
{transferred || str(row[FIELDS.CALL_END_REASON])
|
||||
? 'No recording for this call.'
|
||||
: 'Available once the call ends.'}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<Section title="Call summary" body={summary} empty="No summary yet — it is written when the call ends." />
|
||||
<Section title="Notes" body={notes} />
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user