Analytics
QualificationContent
The body of a BANT qualification snapshot: a score, a verdict, a confirmed count, and one tile per criterion with its status, rationale and first piece of transcript evidence.
Guidelines#
Use it for a meeting's qualification panel. In Max, QualificationCard wraps it in a Card whose title has a Target icon and a secondary BANT badge. That wrapper is not exported, so the preview builds the same header from Card.
What you provide:
qualification: ConversationQualificationDto, shaped{ framework: "BANT", score, confirmedCount, criteria }.- Each criterion is
{ key: "budget" | "authority" | "need" | "timing", label, status: "confirmed" | "partial" | "missing" | "negative", rationale, evidence: [{ sequenceNumber, excerpt }] }. compact(defaultfalse) stacks the tiles in one column instead ofsm:grid-cols-2.
The server scores confirmed as 100, partial as 50 and anything else as 0, then averages the four.
Verdict: any negative criterion shows "Blocker to resolve". Otherwise ≥ 75 shows "Well qualified", ≥ 50 "Partially qualified", and anything lower "Needs discovery".
Anatomy:
- The score is
text-2xlsemiboldtabular-nums. Tiles arerounded-lg border p-3. - Status badges are
h-5 px-1.5 text-[10px]: Confirmed is emerald, Discussed (partial) is blue, Missing is muted, and Blocker (negative) is amber. - Icons:
CircleCheckin emerald-500,CircleAlertin amber-500, andCircleDashedin muted for the rest. - Evidence is a blockquote with
border-l-2 border-primary/35 pl-2 text-xs.
Don't write these readings to the CRM. They come from transcript evidence only, as the card's footer says.
Facts#
| Group | Analytics |
|---|---|
| Product | Max |
| Global | window.DigitalCrew.QualificationContent |
| Source | max-agent: src/features/meeting-hub/ui/qualification-card.tsx |
| Import in the app | import { QualificationContent } from "@/features/meeting-hub/ui/qualification-card"; |
API#
TypeScript declarations emitted from src/features/meeting-hub/ui/qualification-card.tsx.
export declare function QualificationContent({ qualification, compact, }: {
qualification: ConversationQualificationDto;
compact?: boolean;
}): JSX.Element;
export declare function QualificationCard({ qualification, }: {
qualification: ConversationQualificationDto | null | undefined;
}): JSX.Element;Example#
The code of the preview above: plain React.createElement against window.DigitalCrew, with realistic data.
<div id="root" class="p-6"></div>
<script>
(function () {
var h = React.createElement, DC = window.DigitalCrew, I = DC.Icons;
// ConversationQualificationDto. Score = confirmed 100, partial 50, else 0,
// averaged over the four criteria (conversation-intelligence.core.ts).
var QUALIFICATION = {
framework: "BANT",
score: 38,
confirmedCount: 1,
criteria: [
{ key: "budget", label: "Budget", status: "partial",
rationale: "Budget was discussed but not confirmed by the buyer.",
evidence: [{ sequenceNumber: 6, excerpt: "What would a pilot cost for the DACH segment?" }] },
{ key: "authority", label: "Authority", status: "missing",
rationale: "No authority evidence was found in this transcript.", evidence: [] },
{ key: "need", label: "Need", status: "confirmed",
rationale: "Need is explicitly confirmed by an external participant.",
evidence: [{ sequenceNumber: 2, excerpt: "We doubled the SDR team last year and reply rates went the other way." }] },
{ key: "timing", label: "Timing", status: "negative",
rationale: "Timing has a stated blocker from an external participant.",
evidence: [{ sequenceNumber: 11, excerpt: "Nothing new gets rolled out before the January budget freeze lifts." }] }
]
};
function App() {
return h(DC.Card, null,
h(DC.CardHeader, { className: "pb-2" },
h(DC.CardTitle, { className: "flex items-center gap-2 text-base" },
h(I.Target, { className: "h-4 w-4 text-primary" }), "Qualification",
h(DC.Badge, { variant: "secondary", className: "h-5 text-[10px]" }, QUALIFICATION.framework))),
h(DC.CardContent, null, h(DC.QualificationContent, { qualification: QUALIFICATION })));
}
ReactDOM.createRoot(document.getElementById("root")).render(h(DC.TooltipProvider, { delayDuration: 80 }, h(App)));
})();
</script>