Xzero UI
Pro library

Call insightsPro

A sales call insights card where talk time, flagged pricing, competitor and objection moments, an AI summary and owned next steps sit in one view. Selecting a moment plays its quote, and checking off next steps lowers the deal risk.

$ pnpm dlx shadcn@4.23.0 add @xzero-ui-pro/call-insights
Live · keyboard ready

Pass call, speakers (with side and talk share), moments (type, seconds, speakerId, quote, clip length), summary and nextSteps (with ownerId and due) from your transcription or conversation intelligence pipeline. Wire loadClip(moment, signal) to seek your audio player to moment.at; it should resolve when playback can start and abort on the signal. Use onNextStepChange to save step state. Leave risk unset to tie it to the open next steps, or pass your own score. Set autoPlay={false} in a product so the demo tour does not run.

When to use

When not to use

Installation

Register both Xzero UI namespaces in your project's components.json:

{
  "registries": {
    "@xzero-ui": "https://mcp.xzero.co.uk/r/{name}.json",
    "@xzero-ui-pro": "https://mcp.xzero.co.uk/r/pro/{name}.json"
  }
}
npx shadcn@4.23.0 add @xzero-ui-pro/call-insights

Install xzero-foundation once, and import @/components/xzero/foundation.css in your app root. No Xzero token is used by this snapshot. For sample portraits, photos, fonts, or logos, download https://mcp.xzero.co.uk/install-assets.mjs and run node xzero-install-assets.mjs <receiving-project>.

Usage

import { CallInsights } from "@/components/xzero/blocks/call-insights/call-insights";

export function DealCall({ call, transcript }) {
  return (
    <CallInsights
      call={{ title: "Data platform evaluation", company: "Ramp", date: "Oct 22, 2026", duration: 2052 }}
      speakers={transcript.speakers}
      moments={transcript.moments}
      summary={transcript.summary}
      nextSteps={transcript.nextSteps}
      autoPlay={false}
      loadClip={(moment, signal) => audio.load(call.recordingUrl, moment.at, { signal })}
      onNextStepChange={(step, done) => fetch(`/api/steps/${step.id}`, { method: "PATCH", body: JSON.stringify({ done }) })}
    />
  );
}

API reference

CallInsights

A sales call distilled into one card. The header carries the prospect's logo, the call title, the meeting platform mark, date and length, the attendees and a deal risk chip. Talk time is one bar split by speaker and grouped by side, with a legend in tabular percentages. Key moments sit on a rail for the whole call as 24px markers (pricing, competitor mention, objection, each with its own icon); selecting one fills the rail up to it and crossfades the quote, speaker and timestamp into a well with a play button and a seekable waveform. Below are the AI summary, which streams in once with a copy button, and next steps with owners and due dates. Checking off a step lowers the deal risk when the risk is derived. With no props it renders a 34 minute Ramp evaluation on Zoom that tours its moments until someone interacts.

PropTypeDefaultDescription
callCallDetailsRamp evaluation on Zoom{ title, company, logo?: ReactNode (20px, currentColor), platform?, platformMark?: ReactNode (14px), date, duration (seconds) }.
speakersCallSpeaker[]four sample speakers{ id, name, title?, avatar?, side: "internal" | "external", talk }. talk is any scale and is normalised to 100. Talk time groups your team first, then the prospect.
momentsCallMoment[]five sample moments{ id, type: "pricing" | "competitor" | "objection", at (seconds), speakerId, quote, clip (seconds) }. Positioned on the rail by at / call.duration.
summarystringsample summaryAI summary. Streams in once when the card first scrolls into view, over a reserved block so the card never grows. An empty string shows the empty state.
summaryModelstring"Claude Sonnet 5.5"Model credited next to the summary heading.
nextStepsCallNextStep[]three sample steps{ id, label, ownerId, due, done?, risk? }. ownerId is a speaker id. risk (default true) means the open step keeps the deal at risk.
risk"low" | "medium" | "high"–Fixed deal risk. When omitted it follows the open risk steps: all open (two or more) is high, some open is medium, none open is low.
autoPlaybooleantrueTours the moments and plays each clip while the card is on screen, until the first pointer or key press inside it. Always off with reduced motion.
defaultMomentIdstring–Moment selected first. Defaults to the first moment.
loadClip(moment: CallMoment, signal: AbortSignal) => Promise<void>–Resolves when the clip is ready to play; the button shows a spinner meanwhile and a rejection shows Clip unavailable with Retry. The signal aborts when another moment is selected or loading is cancelled. Without it, loading is simulated and the status region says no audio plays.
onMomentChange(moment: CallMoment) => void–Called when a moment is selected, by click, keyboard or the tour.
onNextStepChange(step: CallNextStep, done: boolean) => void–Called when a next step is checked or unchecked. Persist it here.
classNamestring–Class on the root section.

deriveRisk

The rule the card uses when risk is omitted, exported so a list view can show the same chip.

PropTypeDefaultDescription
steps (required)CallNextStep[]–Next steps.
done (required)Record<string, boolean>–Done state by step id.

Keyboard interactions

KeysAction
TabMoves through the selected moment marker, the play button, the waveform, the copy button and each next step checkbox.
Arrow keys, Home, EndOn the markers, select the previous, next, first or last moment. On the waveform, seek one second back or forward, or to the start or end.
Space / EnterPlay, pause, cancel loading or retry the clip; toggle a next step.

Accessibility

Motion

Responsive behavior

Performance

Notes for AI

Guidance for AI tools

Blocks are complete, self-contained screens with sample data. Replace the sample data and connect the callbacks described above. Follow the declared prop types and do not invent props. Keep keyboard access, reduced motion support, and both light and dark themes intact when adapting it.

Full library index: https://ui.xzero.co.uk/llms.txt

Browse all components