@handled-ai/design-system 0.18.23 → 0.18.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/case-panel-detail.d.ts +3 -1
- package/dist/components/case-panel-detail.js +29 -15
- package/dist/components/case-panel-detail.js.map +1 -1
- package/dist/components/case-panel-email-composer.d.ts +2 -1
- package/dist/components/case-panel-email-composer.js +4 -2
- package/dist/components/case-panel-email-composer.js.map +1 -1
- package/dist/components/data-table.js +1 -0
- package/dist/components/data-table.js.map +1 -1
- package/dist/components/score-analysis-modal.d.ts +8 -2
- package/dist/components/score-analysis-modal.js +19 -6
- package/dist/components/score-analysis-modal.js.map +1 -1
- package/dist/components/score-breakdown.d.ts +3 -1
- package/dist/components/score-breakdown.js +5 -6
- package/dist/components/score-breakdown.js.map +1 -1
- package/dist/components/score-ring.d.ts +6 -3
- package/dist/components/score-ring.js +11 -14
- package/dist/components/score-ring.js.map +1 -1
- package/dist/components/score-semantics.d.ts +27 -0
- package/dist/components/score-semantics.js +173 -0
- package/dist/components/score-semantics.js.map +1 -0
- package/dist/components/score-why-chips.d.ts +3 -2
- package/dist/components/score-why-chips.js +10 -21
- package/dist/components/score-why-chips.js.map +1 -1
- package/dist/components/signal-priority-popover.d.ts +1 -0
- package/dist/components/signal-priority-popover.js +20 -20
- package/dist/components/signal-priority-popover.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/prototype/index.d.ts +1 -0
- package/dist/prototype/prototype-accounts-view.d.ts +1 -0
- package/dist/prototype/prototype-admin-view.d.ts +1 -0
- package/dist/prototype/prototype-config.d.ts +1 -0
- package/dist/prototype/prototype-inbox-view.d.ts +1 -0
- package/dist/prototype/prototype-insights-view.d.ts +1 -0
- package/dist/prototype/prototype-shell.d.ts +1 -0
- package/package.json +1 -1
- package/src/components/__tests__/case-panel-detail.test.tsx +17 -1
- package/src/components/__tests__/case-panel-email-composer.test.tsx +7 -0
- package/src/components/__tests__/contextual-quick-action-launcher.test.tsx +4 -1
- package/src/components/__tests__/score-analysis-modal.test.tsx +55 -0
- package/src/components/__tests__/score-breakdown-intent.test.tsx +47 -0
- package/src/components/__tests__/score-ring.test.tsx +43 -0
- package/src/components/__tests__/score-semantics.test.ts +107 -0
- package/src/components/__tests__/signal-priority-popover.test.tsx +7 -5
- package/src/components/case-panel-detail.tsx +31 -13
- package/src/components/case-panel-email-composer.tsx +25 -21
- package/src/components/data-table.tsx +1 -0
- package/src/components/score-analysis-modal.tsx +22 -5
- package/src/components/score-breakdown.tsx +7 -6
- package/src/components/score-ring.tsx +11 -13
- package/src/components/score-semantics.ts +187 -0
- package/src/components/score-why-chips.tsx +12 -23
- package/src/components/signal-priority-popover.tsx +21 -21
- package/src/index.ts +1 -0
|
@@ -25,9 +25,11 @@ interface CasePanelIdentityLink {
|
|
|
25
25
|
icon?: React.ReactNode;
|
|
26
26
|
kind?: "icon" | "text";
|
|
27
27
|
disabled?: boolean;
|
|
28
|
+
target?: React.HTMLAttributeAnchorTarget;
|
|
29
|
+
rel?: string;
|
|
28
30
|
}
|
|
29
31
|
interface CasePanelIdentitySublineProps {
|
|
30
|
-
callsign
|
|
32
|
+
callsign?: string | null;
|
|
31
33
|
links?: CasePanelIdentityLink[];
|
|
32
34
|
onCopyCallsign?: (callsign: string) => void;
|
|
33
35
|
copyLabel?: string;
|
|
@@ -46,32 +46,36 @@ function CasePanelIdentitySubline({
|
|
|
46
46
|
className
|
|
47
47
|
}) {
|
|
48
48
|
const [copied, setCopied] = React.useState(false);
|
|
49
|
-
const
|
|
49
|
+
const trimmedCallsign = callsign == null ? void 0 : callsign.trim();
|
|
50
|
+
const normalizedCallsign = trimmedCallsign ? trimmedCallsign.startsWith("@") ? trimmedCallsign : `@${trimmedCallsign}` : null;
|
|
50
51
|
const handleCopy = React.useCallback(() => {
|
|
52
|
+
if (!normalizedCallsign) return;
|
|
51
53
|
onCopyCallsign == null ? void 0 : onCopyCallsign(normalizedCallsign);
|
|
52
54
|
setCopied(true);
|
|
53
55
|
window.setTimeout(() => setCopied(false), 1400);
|
|
54
56
|
}, [normalizedCallsign, onCopyCallsign]);
|
|
55
57
|
return /* @__PURE__ */ jsxs("div", { className: cn("mt-[9px] inline-flex flex-wrap items-center gap-[7px] text-[13px] text-muted-foreground", className), children: [
|
|
56
|
-
/* @__PURE__ */
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
58
|
+
normalizedCallsign ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
59
|
+
/* @__PURE__ */ jsx("span", { className: "font-mono font-medium tracking-[0.01em] text-gray-700", children: normalizedCallsign }),
|
|
60
|
+
/* @__PURE__ */ jsx(
|
|
61
|
+
"button",
|
|
62
|
+
{
|
|
63
|
+
type: "button",
|
|
64
|
+
onClick: handleCopy,
|
|
65
|
+
"aria-label": copied ? copiedLabel : copyLabel,
|
|
66
|
+
className: "inline-flex h-[22px] w-[22px] items-center justify-center rounded-md text-gray-400 transition-colors hover:bg-accent hover:text-foreground",
|
|
67
|
+
children: copied ? /* @__PURE__ */ jsx(Check, { className: "h-[13px] w-[13px] text-emerald-700", "aria-hidden": "true" }) : /* @__PURE__ */ jsx(Copy, { className: "h-[13px] w-[13px]", "aria-hidden": "true" })
|
|
68
|
+
}
|
|
69
|
+
)
|
|
70
|
+
] }) : null,
|
|
67
71
|
links.length > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
68
|
-
/* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "mx-[3px] h-3.5 w-px bg-gray-200" }),
|
|
72
|
+
normalizedCallsign ? /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "mx-[3px] h-3.5 w-px bg-gray-200" }) : null,
|
|
69
73
|
/* @__PURE__ */ jsx("span", { className: "inline-flex items-center gap-1.5", children: links.map((link) => /* @__PURE__ */ jsx(CasePanelIdentityLinkButton, { link }, link.id)) })
|
|
70
74
|
] }) : null
|
|
71
75
|
] });
|
|
72
76
|
}
|
|
73
77
|
function CasePanelIdentityLinkButton({ link }) {
|
|
74
|
-
var _a;
|
|
78
|
+
var _a, _b, _c;
|
|
75
79
|
const disabled = link.disabled || !link.href;
|
|
76
80
|
const iconOnly = link.kind === "icon";
|
|
77
81
|
const content = iconOnly ? /* @__PURE__ */ jsx(Fragment, { children: (_a = link.icon) != null ? _a : /* @__PURE__ */ jsx(ExternalLink, { className: "h-[13px] w-[13px]", "aria-hidden": "true" }) }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
@@ -83,7 +87,17 @@ function CasePanelIdentityLinkButton({ link }) {
|
|
|
83
87
|
if (disabled) {
|
|
84
88
|
return /* @__PURE__ */ jsx("button", { type: "button", disabled: true, "aria-label": link.label, className, children: content });
|
|
85
89
|
}
|
|
86
|
-
return /* @__PURE__ */ jsx(
|
|
90
|
+
return /* @__PURE__ */ jsx(
|
|
91
|
+
"a",
|
|
92
|
+
{
|
|
93
|
+
href: link.href,
|
|
94
|
+
"aria-label": link.label,
|
|
95
|
+
target: (_b = link.target) != null ? _b : "_blank",
|
|
96
|
+
rel: (_c = link.rel) != null ? _c : "noopener noreferrer",
|
|
97
|
+
className,
|
|
98
|
+
children: content
|
|
99
|
+
}
|
|
100
|
+
);
|
|
87
101
|
}
|
|
88
102
|
function CasePanelSignalBrief({
|
|
89
103
|
children,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/case-panel-detail.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport {\n ArrowUpRight,\n Check,\n Copy,\n ExternalLink,\n} from \"lucide-react\"\nimport { cn } from \"../lib/utils\"\n\nexport type CasePanelDetailWidth = \"comfortable\" | \"modest\" | \"full\"\n\nexport interface CasePanelDetailProps {\n children: React.ReactNode\n /** Reading measure for the detail content column. Defaults to the handoff's comfortable 880px measure. */\n width?: CasePanelDetailWidth\n /** Accessible label for the detail region. */\n \"aria-label\"?: string\n className?: string\n}\n\nconst detailWidthClasses: Record<CasePanelDetailWidth, string> = {\n comfortable: \"mx-auto w-full max-w-[880px] px-10 pb-[120px] pt-8\",\n modest: \"mx-auto w-full max-w-[720px] px-8 pb-[112px] pt-7\",\n full: \"w-full px-8 pb-[120px] pt-8\",\n}\n\nexport function CasePanelDetail({\n children,\n width = \"comfortable\",\n \"aria-label\": ariaLabel = \"Case detail\",\n className,\n}: CasePanelDetailProps) {\n return (\n <section aria-label={ariaLabel} className={cn(\"min-w-0 bg-background\", className)}>\n <div className={detailWidthClasses[width]}>{children}</div>\n </section>\n )\n}\n\nexport interface CasePanelHeaderProps {\n title: React.ReactNode\n /** Optional action, usually a Quick action trigger. */\n action?: React.ReactNode\n children?: React.ReactNode\n className?: string\n}\n\nexport function CasePanelHeader({\n title,\n action,\n children,\n className,\n}: CasePanelHeaderProps) {\n return (\n <header className={cn(\"mb-7\", className)}>\n <div className=\"flex items-start justify-between gap-5\">\n <div className=\"min-w-0 flex-1\">\n <h1 className=\"m-0 text-[27px] font-bold leading-[1.18] tracking-[-0.02em] text-foreground [text-wrap:balance]\">\n {title}\n </h1>\n {children}\n </div>\n {action ? <div className=\"flex shrink-0 items-center gap-2\">{action}</div> : null}\n </div>\n </header>\n )\n}\n\nexport interface CasePanelIdentityLink {\n id: string\n label: string\n href?: string\n icon?: React.ReactNode\n kind?: \"icon\" | \"text\"\n disabled?: boolean\n}\n\nexport interface CasePanelIdentitySublineProps {\n callsign: string\n links?: CasePanelIdentityLink[]\n onCopyCallsign?: (callsign: string) => void\n copyLabel?: string\n copiedLabel?: string\n className?: string\n}\n\nexport function CasePanelIdentitySubline({\n callsign,\n links = [],\n onCopyCallsign,\n copyLabel = \"Copy call sign\",\n copiedLabel = \"Call sign copied\",\n className,\n}: CasePanelIdentitySublineProps) {\n const [copied, setCopied] = React.useState(false)\n const normalizedCallsign = callsign.startsWith(\"@\") ? callsign : `@${callsign}`\n\n const handleCopy = React.useCallback(() => {\n onCopyCallsign?.(normalizedCallsign)\n setCopied(true)\n window.setTimeout(() => setCopied(false), 1400)\n }, [normalizedCallsign, onCopyCallsign])\n\n return (\n <div className={cn(\"mt-[9px] inline-flex flex-wrap items-center gap-[7px] text-[13px] text-muted-foreground\", className)}>\n <span className=\"font-mono font-medium tracking-[0.01em] text-gray-700\">{normalizedCallsign}</span>\n <button\n type=\"button\"\n onClick={handleCopy}\n aria-label={copied ? copiedLabel : copyLabel}\n className=\"inline-flex h-[22px] w-[22px] items-center justify-center rounded-md text-gray-400 transition-colors hover:bg-accent hover:text-foreground\"\n >\n {copied ? <Check className=\"h-[13px] w-[13px] text-emerald-700\" aria-hidden=\"true\" /> : <Copy className=\"h-[13px] w-[13px]\" aria-hidden=\"true\" />}\n </button>\n {links.length > 0 ? (\n <>\n <span aria-hidden=\"true\" className=\"mx-[3px] h-3.5 w-px bg-gray-200\" />\n <span className=\"inline-flex items-center gap-1.5\">\n {links.map((link) => (\n <CasePanelIdentityLinkButton key={link.id} link={link} />\n ))}\n </span>\n </>\n ) : null}\n </div>\n )\n}\n\nfunction CasePanelIdentityLinkButton({ link }: { link: CasePanelIdentityLink }) {\n const disabled = link.disabled || !link.href\n const iconOnly = link.kind === \"icon\"\n const content = iconOnly ? (\n <>{link.icon ?? <ExternalLink className=\"h-[13px] w-[13px]\" aria-hidden=\"true\" />}</>\n ) : (\n <>\n {link.icon ? <span className=\"inline-flex h-3.5 w-3.5 items-center justify-center\">{link.icon}</span> : null}\n <span>{link.label}</span>\n <ArrowUpRight className=\"h-[11px] w-[11px] text-gray-400\" aria-hidden=\"true\" />\n </>\n )\n\n const className = iconOnly\n ? \"inline-flex h-[26px] w-[26px] items-center justify-center rounded-[7px] border border-border bg-background text-foreground shadow-[0_1px_1.5px_rgba(0,0,0,0.03)] transition-colors hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-45\"\n : \"inline-flex h-[26px] items-center gap-1.5 rounded-[7px] border border-border bg-background px-2 text-xs font-medium text-foreground shadow-[0_1px_1.5px_rgba(0,0,0,0.03)] transition-colors hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-45\"\n\n if (disabled) {\n return (\n <button type=\"button\" disabled aria-label={link.label} className={className}>\n {content}\n </button>\n )\n }\n\n return (\n <a href={link.href} aria-label={link.label} className={className}>\n {content}\n </a>\n )\n}\n\nexport interface CasePanelSignalBriefProps {\n children: React.ReactNode\n label?: string\n className?: string\n}\n\nexport function CasePanelSignalBrief({\n children,\n label = \"Signal brief\",\n className,\n}: CasePanelSignalBriefProps) {\n return (\n <section className={cn(\"mt-7\", className)} aria-labelledby=\"case-panel-signal-brief-heading\">\n <div id=\"case-panel-signal-brief-heading\" className=\"mb-2.5 text-[11px] font-semibold uppercase tracking-[0.07em] text-muted-foreground\">\n {label}\n </div>\n <div className=\"text-base leading-[1.6] text-foreground [text-wrap:pretty]\">{children}</div>\n </section>\n )\n}\n\nexport interface CasePanelMetadataRowProps {\n children: React.ReactNode\n label?: string\n className?: string\n}\n\nexport function CasePanelMetadataRow({\n children,\n label = \"Case metadata\",\n className,\n}: CasePanelMetadataRowProps) {\n return (\n <div aria-label={label} className={cn(\"mt-[18px] flex flex-wrap items-center gap-2\", className)}>\n {children}\n </div>\n )\n}\n\nexport interface CasePanelDetailSlotsProps {\n why?: React.ReactNode\n actions?: React.ReactNode\n opportunity?: React.ReactNode\n timeline?: React.ReactNode\n playPanel?: React.ReactNode\n className?: string\n}\n\nexport function CasePanelDetailSlots({\n why,\n actions,\n opportunity,\n timeline,\n playPanel,\n className,\n}: CasePanelDetailSlotsProps) {\n return (\n <div className={cn(\"mt-7 space-y-6\", className)}>\n {why ? <div data-slot=\"why\">{why}</div> : null}\n {actions ? <div data-slot=\"actions\">{actions}</div> : null}\n {opportunity ? <div data-slot=\"opportunity\">{opportunity}</div> : null}\n {timeline ? <div data-slot=\"timeline\">{timeline}</div> : null}\n {playPanel ? <div data-slot=\"play-panel\">{playPanel}</div> : null}\n </div>\n )\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/components/case-panel-detail.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport {\n ArrowUpRight,\n Check,\n Copy,\n ExternalLink,\n} from \"lucide-react\"\nimport { cn } from \"../lib/utils\"\n\nexport type CasePanelDetailWidth = \"comfortable\" | \"modest\" | \"full\"\n\nexport interface CasePanelDetailProps {\n children: React.ReactNode\n /** Reading measure for the detail content column. Defaults to the handoff's comfortable 880px measure. */\n width?: CasePanelDetailWidth\n /** Accessible label for the detail region. */\n \"aria-label\"?: string\n className?: string\n}\n\nconst detailWidthClasses: Record<CasePanelDetailWidth, string> = {\n comfortable: \"mx-auto w-full max-w-[880px] px-10 pb-[120px] pt-8\",\n modest: \"mx-auto w-full max-w-[720px] px-8 pb-[112px] pt-7\",\n full: \"w-full px-8 pb-[120px] pt-8\",\n}\n\nexport function CasePanelDetail({\n children,\n width = \"comfortable\",\n \"aria-label\": ariaLabel = \"Case detail\",\n className,\n}: CasePanelDetailProps) {\n return (\n <section aria-label={ariaLabel} className={cn(\"min-w-0 bg-background\", className)}>\n <div className={detailWidthClasses[width]}>{children}</div>\n </section>\n )\n}\n\nexport interface CasePanelHeaderProps {\n title: React.ReactNode\n /** Optional action, usually a Quick action trigger. */\n action?: React.ReactNode\n children?: React.ReactNode\n className?: string\n}\n\nexport function CasePanelHeader({\n title,\n action,\n children,\n className,\n}: CasePanelHeaderProps) {\n return (\n <header className={cn(\"mb-7\", className)}>\n <div className=\"flex items-start justify-between gap-5\">\n <div className=\"min-w-0 flex-1\">\n <h1 className=\"m-0 text-[27px] font-bold leading-[1.18] tracking-[-0.02em] text-foreground [text-wrap:balance]\">\n {title}\n </h1>\n {children}\n </div>\n {action ? <div className=\"flex shrink-0 items-center gap-2\">{action}</div> : null}\n </div>\n </header>\n )\n}\n\nexport interface CasePanelIdentityLink {\n id: string\n label: string\n href?: string\n icon?: React.ReactNode\n kind?: \"icon\" | \"text\"\n disabled?: boolean\n target?: React.HTMLAttributeAnchorTarget\n rel?: string\n}\n\nexport interface CasePanelIdentitySublineProps {\n callsign?: string | null\n links?: CasePanelIdentityLink[]\n onCopyCallsign?: (callsign: string) => void\n copyLabel?: string\n copiedLabel?: string\n className?: string\n}\n\nexport function CasePanelIdentitySubline({\n callsign,\n links = [],\n onCopyCallsign,\n copyLabel = \"Copy call sign\",\n copiedLabel = \"Call sign copied\",\n className,\n}: CasePanelIdentitySublineProps) {\n const [copied, setCopied] = React.useState(false)\n const trimmedCallsign = callsign?.trim()\n const normalizedCallsign = trimmedCallsign\n ? trimmedCallsign.startsWith(\"@\")\n ? trimmedCallsign\n : `@${trimmedCallsign}`\n : null\n\n const handleCopy = React.useCallback(() => {\n if (!normalizedCallsign) return\n onCopyCallsign?.(normalizedCallsign)\n setCopied(true)\n window.setTimeout(() => setCopied(false), 1400)\n }, [normalizedCallsign, onCopyCallsign])\n\n return (\n <div className={cn(\"mt-[9px] inline-flex flex-wrap items-center gap-[7px] text-[13px] text-muted-foreground\", className)}>\n {normalizedCallsign ? (\n <>\n <span className=\"font-mono font-medium tracking-[0.01em] text-gray-700\">{normalizedCallsign}</span>\n <button\n type=\"button\"\n onClick={handleCopy}\n aria-label={copied ? copiedLabel : copyLabel}\n className=\"inline-flex h-[22px] w-[22px] items-center justify-center rounded-md text-gray-400 transition-colors hover:bg-accent hover:text-foreground\"\n >\n {copied ? <Check className=\"h-[13px] w-[13px] text-emerald-700\" aria-hidden=\"true\" /> : <Copy className=\"h-[13px] w-[13px]\" aria-hidden=\"true\" />}\n </button>\n </>\n ) : null}\n {links.length > 0 ? (\n <>\n {normalizedCallsign ? <span aria-hidden=\"true\" className=\"mx-[3px] h-3.5 w-px bg-gray-200\" /> : null}\n <span className=\"inline-flex items-center gap-1.5\">\n {links.map((link) => (\n <CasePanelIdentityLinkButton key={link.id} link={link} />\n ))}\n </span>\n </>\n ) : null}\n </div>\n )\n}\n\nfunction CasePanelIdentityLinkButton({ link }: { link: CasePanelIdentityLink }) {\n const disabled = link.disabled || !link.href\n const iconOnly = link.kind === \"icon\"\n const content = iconOnly ? (\n <>{link.icon ?? <ExternalLink className=\"h-[13px] w-[13px]\" aria-hidden=\"true\" />}</>\n ) : (\n <>\n {link.icon ? <span className=\"inline-flex h-3.5 w-3.5 items-center justify-center\">{link.icon}</span> : null}\n <span>{link.label}</span>\n <ArrowUpRight className=\"h-[11px] w-[11px] text-gray-400\" aria-hidden=\"true\" />\n </>\n )\n\n const className = iconOnly\n ? \"inline-flex h-[26px] w-[26px] items-center justify-center rounded-[7px] border border-border bg-background text-foreground shadow-[0_1px_1.5px_rgba(0,0,0,0.03)] transition-colors hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-45\"\n : \"inline-flex h-[26px] items-center gap-1.5 rounded-[7px] border border-border bg-background px-2 text-xs font-medium text-foreground shadow-[0_1px_1.5px_rgba(0,0,0,0.03)] transition-colors hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-45\"\n\n if (disabled) {\n return (\n <button type=\"button\" disabled aria-label={link.label} className={className}>\n {content}\n </button>\n )\n }\n\n return (\n <a\n href={link.href}\n aria-label={link.label}\n target={link.target ?? \"_blank\"}\n rel={link.rel ?? \"noopener noreferrer\"}\n className={className}\n >\n {content}\n </a>\n )\n}\n\nexport interface CasePanelSignalBriefProps {\n children: React.ReactNode\n label?: string\n className?: string\n}\n\nexport function CasePanelSignalBrief({\n children,\n label = \"Signal brief\",\n className,\n}: CasePanelSignalBriefProps) {\n return (\n <section className={cn(\"mt-7\", className)} aria-labelledby=\"case-panel-signal-brief-heading\">\n <div id=\"case-panel-signal-brief-heading\" className=\"mb-2.5 text-[11px] font-semibold uppercase tracking-[0.07em] text-muted-foreground\">\n {label}\n </div>\n <div className=\"text-base leading-[1.6] text-foreground [text-wrap:pretty]\">{children}</div>\n </section>\n )\n}\n\nexport interface CasePanelMetadataRowProps {\n children: React.ReactNode\n label?: string\n className?: string\n}\n\nexport function CasePanelMetadataRow({\n children,\n label = \"Case metadata\",\n className,\n}: CasePanelMetadataRowProps) {\n return (\n <div aria-label={label} className={cn(\"mt-[18px] flex flex-wrap items-center gap-2\", className)}>\n {children}\n </div>\n )\n}\n\nexport interface CasePanelDetailSlotsProps {\n why?: React.ReactNode\n actions?: React.ReactNode\n opportunity?: React.ReactNode\n timeline?: React.ReactNode\n playPanel?: React.ReactNode\n className?: string\n}\n\nexport function CasePanelDetailSlots({\n why,\n actions,\n opportunity,\n timeline,\n playPanel,\n className,\n}: CasePanelDetailSlotsProps) {\n return (\n <div className={cn(\"mt-7 space-y-6\", className)}>\n {why ? <div data-slot=\"why\">{why}</div> : null}\n {actions ? <div data-slot=\"actions\">{actions}</div> : null}\n {opportunity ? <div data-slot=\"opportunity\">{opportunity}</div> : null}\n {timeline ? <div data-slot=\"timeline\">{timeline}</div> : null}\n {playPanel ? <div data-slot=\"play-panel\">{playPanel}</div> : null}\n </div>\n )\n}\n"],"mappings":"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","names":[]}
|
|
@@ -41,6 +41,7 @@ interface CasePanelEmailComposerProps extends Omit<React.HTMLAttributes<HTMLDivE
|
|
|
41
41
|
sendBarActions?: React.ReactNode;
|
|
42
42
|
signatureControl?: React.ReactNode;
|
|
43
43
|
disabledReason?: React.ReactNode;
|
|
44
|
+
showSendBar?: boolean;
|
|
44
45
|
disabled?: boolean;
|
|
45
46
|
sendDisabled?: boolean;
|
|
46
47
|
sendLabel?: React.ReactNode;
|
|
@@ -56,6 +57,6 @@ interface CasePanelEmailComposerProps extends Omit<React.HTMLAttributes<HTMLDivE
|
|
|
56
57
|
showRecipientActionChips?: boolean;
|
|
57
58
|
onComposerKeyDown?: React.KeyboardEventHandler<HTMLDivElement>;
|
|
58
59
|
}
|
|
59
|
-
declare function CasePanelEmailComposer({ title, providerLabel, recipientRows, from, to, cc, bcc, subject, toState, draftEditor, toolbar, sendBarActions, signatureControl, disabledReason, disabled, sendDisabled, sendLabel, onSendIntent, onContactsIntent, onAccountDetailsIntent, onAddCcIntent, onAddBccIntent, contactsLabel, accountDetailsLabel, addCcLabel, addBccLabel, showRecipientActionChips, onComposerKeyDown, className, ...props }: CasePanelEmailComposerProps): React.JSX.Element;
|
|
60
|
+
declare function CasePanelEmailComposer({ title, providerLabel, recipientRows, from, to, cc, bcc, subject, toState, draftEditor, toolbar, sendBarActions, signatureControl, disabledReason, showSendBar, disabled, sendDisabled, sendLabel, onSendIntent, onContactsIntent, onAccountDetailsIntent, onAddCcIntent, onAddBccIntent, contactsLabel, accountDetailsLabel, addCcLabel, addBccLabel, showRecipientActionChips, onComposerKeyDown, className, ...props }: CasePanelEmailComposerProps): React.JSX.Element;
|
|
60
61
|
|
|
61
62
|
export { CasePanelEmailComposer, CasePanelEmailComposerChip, type CasePanelEmailComposerChipProps, type CasePanelEmailComposerProps, CasePanelEmailComposerRow, type CasePanelEmailComposerRowProps, type CasePanelEmailComposerRowState, CasePanelEmailComposerSignatureRow, type CasePanelEmailComposerSignatureRowProps, type CasePanelEmailComposerSlotHelpers };
|
|
@@ -163,6 +163,7 @@ function CasePanelEmailComposer(_g) {
|
|
|
163
163
|
sendBarActions,
|
|
164
164
|
signatureControl,
|
|
165
165
|
disabledReason,
|
|
166
|
+
showSendBar = true,
|
|
166
167
|
disabled = false,
|
|
167
168
|
sendDisabled = false,
|
|
168
169
|
sendLabel = "Send",
|
|
@@ -193,6 +194,7 @@ function CasePanelEmailComposer(_g) {
|
|
|
193
194
|
"sendBarActions",
|
|
194
195
|
"signatureControl",
|
|
195
196
|
"disabledReason",
|
|
197
|
+
"showSendBar",
|
|
196
198
|
"disabled",
|
|
197
199
|
"sendDisabled",
|
|
198
200
|
"sendLabel",
|
|
@@ -272,7 +274,7 @@ function CasePanelEmailComposer(_g) {
|
|
|
272
274
|
/* @__PURE__ */ jsx("div", { "data-slot": "case-panel-email-composer-editor", className: "min-h-40 px-4 py-4 text-sm text-foreground", children: draftEditor != null ? draftEditor : /* @__PURE__ */ jsx("div", { className: "text-muted-foreground", children: "Draft editor slot" }) }),
|
|
273
275
|
signatureControl ? /* @__PURE__ */ jsx("div", { "data-slot": "case-panel-email-composer-signature-control", children: signatureControl }) : /* @__PURE__ */ jsx(CasePanelEmailComposerSignatureRow, { disabled }),
|
|
274
276
|
/* @__PURE__ */ jsx("div", { "data-slot": "case-panel-email-composer-toolbar", className: "flex min-h-11 items-center gap-2 border-t border-border/70 bg-muted/10 px-3 py-2", children: toolbar != null ? toolbar : /* @__PURE__ */ jsx("div", { className: "text-xs font-medium text-muted-foreground", children: "Toolbar" }) }),
|
|
275
|
-
/* @__PURE__ */ jsxs("div", { "data-slot": "case-panel-email-composer-send-bar", className: "flex items-center justify-between gap-3 border-t border-border/70 bg-background px-3 py-3", children: [
|
|
277
|
+
showSendBar ? /* @__PURE__ */ jsxs("div", { "data-slot": "case-panel-email-composer-send-bar", className: "flex items-center justify-between gap-3 border-t border-border/70 bg-background px-3 py-3", children: [
|
|
276
278
|
/* @__PURE__ */ jsx("div", { className: "min-w-0 flex-1", children: disabledReason ? /* @__PURE__ */ jsx("div", { id: disabledReasonId, "data-slot": "case-panel-email-composer-disabled-reason", className: "truncate text-xs text-muted-foreground", children: disabledReason }) : null }),
|
|
277
279
|
/* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center gap-2", children: [
|
|
278
280
|
sendBarActions,
|
|
@@ -289,7 +291,7 @@ function CasePanelEmailComposer(_g) {
|
|
|
289
291
|
}
|
|
290
292
|
)
|
|
291
293
|
] })
|
|
292
|
-
] })
|
|
294
|
+
] }) : null
|
|
293
295
|
] })
|
|
294
296
|
]
|
|
295
297
|
})
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/case-panel-email-composer.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\n\nimport { cn } from \"../lib/utils\"\nimport { BRAND_ICONS } from \"../lib/icons\"\n\nexport type CasePanelEmailComposerRowState = \"default\" | \"confirmed\" | \"unconfirmed\"\n\nexport interface CasePanelEmailComposerRowProps extends React.HTMLAttributes<HTMLDivElement> {\n label: React.ReactNode\n children?: React.ReactNode\n value?: React.ReactNode\n placeholder?: React.ReactNode\n actions?: React.ReactNode\n state?: CasePanelEmailComposerRowState\n}\n\nexport function CasePanelEmailComposerRow({\n label,\n children,\n value,\n placeholder,\n actions,\n state = \"default\",\n className,\n ...props\n}: CasePanelEmailComposerRowProps) {\n const content = children ?? value ?? placeholder\n const rowClassName =\n state === \"unconfirmed\"\n ? \"flex min-h-11 items-stretch border-b border-amber-200/80 bg-amber-50/75 text-sm dark:border-amber-900/50 dark:bg-amber-950/20\"\n : \"flex min-h-11 items-stretch border-b border-border/70 bg-background text-sm\"\n const labelClassName =\n state === \"unconfirmed\"\n ? \"flex w-[60px] shrink-0 items-center border-r border-amber-200/80 px-3 text-[11px] font-semibold uppercase tracking-wide text-amber-700 dark:border-amber-900/50 dark:text-amber-300\"\n : \"flex w-[60px] shrink-0 items-center border-r border-border/70 px-3 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground\"\n const contentClassName =\n state === \"unconfirmed\"\n ? \"flex min-w-0 flex-1 items-center gap-2 px-3 py-2 text-amber-950 dark:text-amber-100\"\n : \"flex min-w-0 flex-1 items-center gap-2 px-3 py-2 text-foreground\"\n const placeholderClassName =\n state === \"unconfirmed\"\n ? \"min-w-0 truncate text-amber-700/80 dark:text-amber-200/80\"\n : \"min-w-0 truncate text-muted-foreground\"\n\n return (\n <div\n data-slot=\"case-panel-email-composer-row\"\n data-state={state}\n className={cn(rowClassName, className)}\n {...props}\n >\n <div data-slot=\"case-panel-email-composer-row-label\" className={labelClassName}>\n {label}\n </div>\n <div data-slot=\"case-panel-email-composer-row-content\" className={contentClassName}>\n {content ? (\n <div className=\"min-w-0 flex-1 truncate\">{content}</div>\n ) : (\n <div className={placeholderClassName}>Add {label}</div>\n )}\n {actions ? <div className=\"flex shrink-0 items-center gap-1.5\">{actions}</div> : null}\n </div>\n </div>\n )\n}\n\nexport interface CasePanelEmailComposerChipProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n children: React.ReactNode\n}\n\nexport function CasePanelEmailComposerChip({\n children,\n className,\n type = \"button\",\n ...props\n}: CasePanelEmailComposerChipProps) {\n return (\n <button\n data-slot=\"case-panel-email-composer-chip\"\n type={type}\n className={cn(\n \"inline-flex h-6 items-center justify-center rounded-full border border-border bg-background px-2.5 text-[11px] font-medium text-muted-foreground shadow-xs transition-colors hover:bg-muted/60 hover:text-foreground disabled:pointer-events-none disabled:opacity-50\",\n className,\n )}\n {...props}\n >\n {children}\n </button>\n )\n}\n\nexport interface CasePanelEmailComposerSignatureRowProps extends React.HTMLAttributes<HTMLDivElement> {\n children?: React.ReactNode\n label?: React.ReactNode\n checked?: boolean\n disabled?: boolean\n}\n\nexport function CasePanelEmailComposerSignatureRow({\n children,\n label = \"Include signature\",\n checked = true,\n disabled,\n className,\n ...props\n}: CasePanelEmailComposerSignatureRowProps) {\n return (\n <div\n data-slot=\"case-panel-email-composer-signature-row\"\n className={cn(\n \"flex items-center justify-between border-t border-border/70 bg-muted/20 px-4 py-2.5 text-xs text-muted-foreground\",\n className,\n )}\n {...props}\n >\n {children ?? (\n <div className=\"flex items-center gap-2\">\n <span\n aria-hidden=\"true\"\n data-checked={checked ? \"true\" : \"false\"}\n className={\n checked\n ? \"flex size-4 items-center justify-center rounded border border-foreground bg-foreground text-[10px] leading-none text-background\"\n : \"flex size-4 items-center justify-center rounded border border-border bg-background text-[10px] leading-none text-background\"\n }\n >\n {checked ? \"✓\" : \"\"}\n </span>\n <span className={disabled ? \"text-muted-foreground/60\" : \"text-muted-foreground\"}>{label}</span>\n </div>\n )}\n </div>\n )\n}\n\nexport interface CasePanelEmailComposerSlotHelpers {\n Row: typeof CasePanelEmailComposerRow\n Chip: typeof CasePanelEmailComposerChip\n SignatureRow: typeof CasePanelEmailComposerSignatureRow\n}\n\nexport interface CasePanelEmailComposerProps extends Omit<React.HTMLAttributes<HTMLDivElement>, \"onKeyDown\" | \"title\"> {\n title?: React.ReactNode\n providerLabel?: React.ReactNode\n recipientRows?: React.ReactNode | ((helpers: CasePanelEmailComposerSlotHelpers) => React.ReactNode)\n from?: React.ReactNode\n to?: React.ReactNode\n cc?: React.ReactNode\n bcc?: React.ReactNode\n subject?: React.ReactNode\n toState?: CasePanelEmailComposerRowState\n draftEditor?: React.ReactNode\n toolbar?: React.ReactNode\n sendBarActions?: React.ReactNode\n signatureControl?: React.ReactNode\n disabledReason?: React.ReactNode\n disabled?: boolean\n sendDisabled?: boolean\n sendLabel?: React.ReactNode\n onSendIntent?: () => void\n onContactsIntent?: () => void\n onAccountDetailsIntent?: () => void\n onAddCcIntent?: () => void\n onAddBccIntent?: () => void\n contactsLabel?: React.ReactNode\n accountDetailsLabel?: React.ReactNode\n addCcLabel?: React.ReactNode\n addBccLabel?: React.ReactNode\n showRecipientActionChips?: boolean\n onComposerKeyDown?: React.KeyboardEventHandler<HTMLDivElement>\n}\n\nconst slotHelpers: CasePanelEmailComposerSlotHelpers = {\n Row: CasePanelEmailComposerRow,\n Chip: CasePanelEmailComposerChip,\n SignatureRow: CasePanelEmailComposerSignatureRow,\n}\n\nexport function CasePanelEmailComposer({\n title = \"Draft\",\n providerLabel = \"Gmail\",\n recipientRows,\n from,\n to,\n cc,\n bcc,\n subject,\n toState = \"default\",\n draftEditor,\n toolbar,\n sendBarActions,\n signatureControl,\n disabledReason,\n disabled = false,\n sendDisabled = false,\n sendLabel = \"Send\",\n onSendIntent,\n onContactsIntent,\n onAccountDetailsIntent,\n onAddCcIntent,\n onAddBccIntent,\n contactsLabel = \"Contacts\",\n accountDetailsLabel = \"Account details\",\n addCcLabel = \"Add Cc\",\n addBccLabel = \"Add Bcc\",\n showRecipientActionChips = true,\n onComposerKeyDown,\n className,\n ...props\n}: CasePanelEmailComposerProps) {\n const disabledReasonId = React.useId()\n const sendIsDisabled = disabled || sendDisabled || Boolean(disabledReason)\n\n const handleSendIntent = React.useCallback(() => {\n if (sendIsDisabled) return\n onSendIntent?.()\n }, [onSendIntent, sendIsDisabled])\n\n const handleKeyDown = React.useCallback(\n (event: React.KeyboardEvent<HTMLDivElement>) => {\n onComposerKeyDown?.(event)\n if (event.defaultPrevented) return\n if (event.key === \"Enter\" && (event.metaKey || event.ctrlKey)) {\n event.preventDefault()\n handleSendIntent()\n }\n },\n [handleSendIntent, onComposerKeyDown],\n )\n\n const renderedRecipientRows =\n typeof recipientRows === \"function\"\n ? recipientRows(slotHelpers)\n : recipientRows ?? (\n <>\n <CasePanelEmailComposerRow label=\"From\" value={from} placeholder=\"Sender\" />\n <CasePanelEmailComposerRow label=\"To\" value={to} placeholder=\"Recipient\" state={toState} />\n {cc ? <CasePanelEmailComposerRow label=\"Cc\" value={cc} /> : null}\n {bcc ? <CasePanelEmailComposerRow label=\"Bcc\" value={bcc} /> : null}\n <CasePanelEmailComposerRow label=\"Subject\" value={subject} placeholder=\"Subject\" />\n </>\n )\n\n const showActionChips =\n showRecipientActionChips &&\n (onContactsIntent || onAccountDetailsIntent || onAddCcIntent || onAddBccIntent)\n\n return (\n <div\n data-slot=\"case-panel-email-composer\"\n aria-disabled={disabled ? \"true\" : undefined}\n className={cn(\n \"overflow-hidden rounded-xl border border-border bg-background shadow-sm\",\n className,\n )}\n onKeyDown={handleKeyDown}\n {...props}\n >\n <div data-slot=\"case-panel-email-composer-header\" className=\"flex items-center justify-between border-b border-border/70 bg-muted/20 px-4 py-3\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <img\n src={BRAND_ICONS.gmail.icon}\n alt=\"Gmail\"\n className=\"size-4 shrink-0 object-contain\"\n draggable={false}\n />\n <div className=\"min-w-0 truncate text-sm font-semibold text-foreground\">{title}</div>\n </div>\n <div className=\"shrink-0 text-[11px] font-medium text-muted-foreground\">{providerLabel}</div>\n </div>\n\n <div data-slot=\"case-panel-email-composer-card\" className=\"bg-background\">\n <div data-slot=\"case-panel-email-composer-recipient-rows\">{renderedRecipientRows}</div>\n\n {showActionChips ? (\n <div data-slot=\"case-panel-email-composer-chip-row\" className=\"flex flex-wrap items-center gap-1.5 border-b border-border/70 bg-muted/10 px-3 py-2\">\n {onContactsIntent ? (\n <CasePanelEmailComposerChip onClick={onContactsIntent} disabled={disabled}>\n {contactsLabel}\n </CasePanelEmailComposerChip>\n ) : null}\n {onAccountDetailsIntent ? (\n <CasePanelEmailComposerChip onClick={onAccountDetailsIntent} disabled={disabled}>\n {accountDetailsLabel}\n </CasePanelEmailComposerChip>\n ) : null}\n {onAddCcIntent ? (\n <CasePanelEmailComposerChip onClick={onAddCcIntent} disabled={disabled}>\n {addCcLabel}\n </CasePanelEmailComposerChip>\n ) : null}\n {onAddBccIntent ? (\n <CasePanelEmailComposerChip onClick={onAddBccIntent} disabled={disabled}>\n {addBccLabel}\n </CasePanelEmailComposerChip>\n ) : null}\n </div>\n ) : null}\n\n <div data-slot=\"case-panel-email-composer-editor\" className=\"min-h-40 px-4 py-4 text-sm text-foreground\">\n {draftEditor ?? <div className=\"text-muted-foreground\">Draft editor slot</div>}\n </div>\n\n {signatureControl ? (\n <div data-slot=\"case-panel-email-composer-signature-control\">{signatureControl}</div>\n ) : (\n <CasePanelEmailComposerSignatureRow disabled={disabled} />\n )}\n\n <div data-slot=\"case-panel-email-composer-toolbar\" className=\"flex min-h-11 items-center gap-2 border-t border-border/70 bg-muted/10 px-3 py-2\">\n {toolbar ?? <div className=\"text-xs font-medium text-muted-foreground\">Toolbar</div>}\n </div>\n\n <div data-slot=\"case-panel-email-composer-send-bar\" className=\"flex items-center justify-between gap-3 border-t border-border/70 bg-background px-3 py-3\">\n <div className=\"min-w-0 flex-1\">\n {disabledReason ? (\n <div id={disabledReasonId} data-slot=\"case-panel-email-composer-disabled-reason\" className=\"truncate text-xs text-muted-foreground\">\n {disabledReason}\n </div>\n ) : null}\n </div>\n <div className=\"flex shrink-0 items-center gap-2\">\n {sendBarActions}\n <button\n type=\"button\"\n data-slot=\"case-panel-email-composer-send-button\"\n aria-describedby={disabledReason ? disabledReasonId : undefined}\n disabled={sendIsDisabled}\n onClick={handleSendIntent}\n className=\"inline-flex h-8 items-center justify-center rounded-md bg-foreground px-3 text-xs font-semibold text-background shadow-xs transition-colors hover:bg-foreground/90 disabled:pointer-events-none disabled:bg-muted disabled:text-muted-foreground\"\n >\n {sendLabel}\n </button>\n </div>\n </div>\n </div>\n </div>\n )\n}\n"],"mappings":"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","names":["_a"]}
|
|
1
|
+
{"version":3,"sources":["../../src/components/case-panel-email-composer.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\n\nimport { cn } from \"../lib/utils\"\nimport { BRAND_ICONS } from \"../lib/icons\"\n\nexport type CasePanelEmailComposerRowState = \"default\" | \"confirmed\" | \"unconfirmed\"\n\nexport interface CasePanelEmailComposerRowProps extends React.HTMLAttributes<HTMLDivElement> {\n label: React.ReactNode\n children?: React.ReactNode\n value?: React.ReactNode\n placeholder?: React.ReactNode\n actions?: React.ReactNode\n state?: CasePanelEmailComposerRowState\n}\n\nexport function CasePanelEmailComposerRow({\n label,\n children,\n value,\n placeholder,\n actions,\n state = \"default\",\n className,\n ...props\n}: CasePanelEmailComposerRowProps) {\n const content = children ?? value ?? placeholder\n const rowClassName =\n state === \"unconfirmed\"\n ? \"flex min-h-11 items-stretch border-b border-amber-200/80 bg-amber-50/75 text-sm dark:border-amber-900/50 dark:bg-amber-950/20\"\n : \"flex min-h-11 items-stretch border-b border-border/70 bg-background text-sm\"\n const labelClassName =\n state === \"unconfirmed\"\n ? \"flex w-[60px] shrink-0 items-center border-r border-amber-200/80 px-3 text-[11px] font-semibold uppercase tracking-wide text-amber-700 dark:border-amber-900/50 dark:text-amber-300\"\n : \"flex w-[60px] shrink-0 items-center border-r border-border/70 px-3 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground\"\n const contentClassName =\n state === \"unconfirmed\"\n ? \"flex min-w-0 flex-1 items-center gap-2 px-3 py-2 text-amber-950 dark:text-amber-100\"\n : \"flex min-w-0 flex-1 items-center gap-2 px-3 py-2 text-foreground\"\n const placeholderClassName =\n state === \"unconfirmed\"\n ? \"min-w-0 truncate text-amber-700/80 dark:text-amber-200/80\"\n : \"min-w-0 truncate text-muted-foreground\"\n\n return (\n <div\n data-slot=\"case-panel-email-composer-row\"\n data-state={state}\n className={cn(rowClassName, className)}\n {...props}\n >\n <div data-slot=\"case-panel-email-composer-row-label\" className={labelClassName}>\n {label}\n </div>\n <div data-slot=\"case-panel-email-composer-row-content\" className={contentClassName}>\n {content ? (\n <div className=\"min-w-0 flex-1 truncate\">{content}</div>\n ) : (\n <div className={placeholderClassName}>Add {label}</div>\n )}\n {actions ? <div className=\"flex shrink-0 items-center gap-1.5\">{actions}</div> : null}\n </div>\n </div>\n )\n}\n\nexport interface CasePanelEmailComposerChipProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n children: React.ReactNode\n}\n\nexport function CasePanelEmailComposerChip({\n children,\n className,\n type = \"button\",\n ...props\n}: CasePanelEmailComposerChipProps) {\n return (\n <button\n data-slot=\"case-panel-email-composer-chip\"\n type={type}\n className={cn(\n \"inline-flex h-6 items-center justify-center rounded-full border border-border bg-background px-2.5 text-[11px] font-medium text-muted-foreground shadow-xs transition-colors hover:bg-muted/60 hover:text-foreground disabled:pointer-events-none disabled:opacity-50\",\n className,\n )}\n {...props}\n >\n {children}\n </button>\n )\n}\n\nexport interface CasePanelEmailComposerSignatureRowProps extends React.HTMLAttributes<HTMLDivElement> {\n children?: React.ReactNode\n label?: React.ReactNode\n checked?: boolean\n disabled?: boolean\n}\n\nexport function CasePanelEmailComposerSignatureRow({\n children,\n label = \"Include signature\",\n checked = true,\n disabled,\n className,\n ...props\n}: CasePanelEmailComposerSignatureRowProps) {\n return (\n <div\n data-slot=\"case-panel-email-composer-signature-row\"\n className={cn(\n \"flex items-center justify-between border-t border-border/70 bg-muted/20 px-4 py-2.5 text-xs text-muted-foreground\",\n className,\n )}\n {...props}\n >\n {children ?? (\n <div className=\"flex items-center gap-2\">\n <span\n aria-hidden=\"true\"\n data-checked={checked ? \"true\" : \"false\"}\n className={\n checked\n ? \"flex size-4 items-center justify-center rounded border border-foreground bg-foreground text-[10px] leading-none text-background\"\n : \"flex size-4 items-center justify-center rounded border border-border bg-background text-[10px] leading-none text-background\"\n }\n >\n {checked ? \"✓\" : \"\"}\n </span>\n <span className={disabled ? \"text-muted-foreground/60\" : \"text-muted-foreground\"}>{label}</span>\n </div>\n )}\n </div>\n )\n}\n\nexport interface CasePanelEmailComposerSlotHelpers {\n Row: typeof CasePanelEmailComposerRow\n Chip: typeof CasePanelEmailComposerChip\n SignatureRow: typeof CasePanelEmailComposerSignatureRow\n}\n\nexport interface CasePanelEmailComposerProps extends Omit<React.HTMLAttributes<HTMLDivElement>, \"onKeyDown\" | \"title\"> {\n title?: React.ReactNode\n providerLabel?: React.ReactNode\n recipientRows?: React.ReactNode | ((helpers: CasePanelEmailComposerSlotHelpers) => React.ReactNode)\n from?: React.ReactNode\n to?: React.ReactNode\n cc?: React.ReactNode\n bcc?: React.ReactNode\n subject?: React.ReactNode\n toState?: CasePanelEmailComposerRowState\n draftEditor?: React.ReactNode\n toolbar?: React.ReactNode\n sendBarActions?: React.ReactNode\n signatureControl?: React.ReactNode\n disabledReason?: React.ReactNode\n showSendBar?: boolean\n disabled?: boolean\n sendDisabled?: boolean\n sendLabel?: React.ReactNode\n onSendIntent?: () => void\n onContactsIntent?: () => void\n onAccountDetailsIntent?: () => void\n onAddCcIntent?: () => void\n onAddBccIntent?: () => void\n contactsLabel?: React.ReactNode\n accountDetailsLabel?: React.ReactNode\n addCcLabel?: React.ReactNode\n addBccLabel?: React.ReactNode\n showRecipientActionChips?: boolean\n onComposerKeyDown?: React.KeyboardEventHandler<HTMLDivElement>\n}\n\nconst slotHelpers: CasePanelEmailComposerSlotHelpers = {\n Row: CasePanelEmailComposerRow,\n Chip: CasePanelEmailComposerChip,\n SignatureRow: CasePanelEmailComposerSignatureRow,\n}\n\nexport function CasePanelEmailComposer({\n title = \"Draft\",\n providerLabel = \"Gmail\",\n recipientRows,\n from,\n to,\n cc,\n bcc,\n subject,\n toState = \"default\",\n draftEditor,\n toolbar,\n sendBarActions,\n signatureControl,\n disabledReason,\n showSendBar = true,\n disabled = false,\n sendDisabled = false,\n sendLabel = \"Send\",\n onSendIntent,\n onContactsIntent,\n onAccountDetailsIntent,\n onAddCcIntent,\n onAddBccIntent,\n contactsLabel = \"Contacts\",\n accountDetailsLabel = \"Account details\",\n addCcLabel = \"Add Cc\",\n addBccLabel = \"Add Bcc\",\n showRecipientActionChips = true,\n onComposerKeyDown,\n className,\n ...props\n}: CasePanelEmailComposerProps) {\n const disabledReasonId = React.useId()\n const sendIsDisabled = disabled || sendDisabled || Boolean(disabledReason)\n\n const handleSendIntent = React.useCallback(() => {\n if (sendIsDisabled) return\n onSendIntent?.()\n }, [onSendIntent, sendIsDisabled])\n\n const handleKeyDown = React.useCallback(\n (event: React.KeyboardEvent<HTMLDivElement>) => {\n onComposerKeyDown?.(event)\n if (event.defaultPrevented) return\n if (event.key === \"Enter\" && (event.metaKey || event.ctrlKey)) {\n event.preventDefault()\n handleSendIntent()\n }\n },\n [handleSendIntent, onComposerKeyDown],\n )\n\n const renderedRecipientRows =\n typeof recipientRows === \"function\"\n ? recipientRows(slotHelpers)\n : recipientRows ?? (\n <>\n <CasePanelEmailComposerRow label=\"From\" value={from} placeholder=\"Sender\" />\n <CasePanelEmailComposerRow label=\"To\" value={to} placeholder=\"Recipient\" state={toState} />\n {cc ? <CasePanelEmailComposerRow label=\"Cc\" value={cc} /> : null}\n {bcc ? <CasePanelEmailComposerRow label=\"Bcc\" value={bcc} /> : null}\n <CasePanelEmailComposerRow label=\"Subject\" value={subject} placeholder=\"Subject\" />\n </>\n )\n\n const showActionChips =\n showRecipientActionChips &&\n (onContactsIntent || onAccountDetailsIntent || onAddCcIntent || onAddBccIntent)\n\n return (\n <div\n data-slot=\"case-panel-email-composer\"\n aria-disabled={disabled ? \"true\" : undefined}\n className={cn(\n \"overflow-hidden rounded-xl border border-border bg-background shadow-sm\",\n className,\n )}\n onKeyDown={handleKeyDown}\n {...props}\n >\n <div data-slot=\"case-panel-email-composer-header\" className=\"flex items-center justify-between border-b border-border/70 bg-muted/20 px-4 py-3\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <img\n src={BRAND_ICONS.gmail.icon}\n alt=\"Gmail\"\n className=\"size-4 shrink-0 object-contain\"\n draggable={false}\n />\n <div className=\"min-w-0 truncate text-sm font-semibold text-foreground\">{title}</div>\n </div>\n <div className=\"shrink-0 text-[11px] font-medium text-muted-foreground\">{providerLabel}</div>\n </div>\n\n <div data-slot=\"case-panel-email-composer-card\" className=\"bg-background\">\n <div data-slot=\"case-panel-email-composer-recipient-rows\">{renderedRecipientRows}</div>\n\n {showActionChips ? (\n <div data-slot=\"case-panel-email-composer-chip-row\" className=\"flex flex-wrap items-center gap-1.5 border-b border-border/70 bg-muted/10 px-3 py-2\">\n {onContactsIntent ? (\n <CasePanelEmailComposerChip onClick={onContactsIntent} disabled={disabled}>\n {contactsLabel}\n </CasePanelEmailComposerChip>\n ) : null}\n {onAccountDetailsIntent ? (\n <CasePanelEmailComposerChip onClick={onAccountDetailsIntent} disabled={disabled}>\n {accountDetailsLabel}\n </CasePanelEmailComposerChip>\n ) : null}\n {onAddCcIntent ? (\n <CasePanelEmailComposerChip onClick={onAddCcIntent} disabled={disabled}>\n {addCcLabel}\n </CasePanelEmailComposerChip>\n ) : null}\n {onAddBccIntent ? (\n <CasePanelEmailComposerChip onClick={onAddBccIntent} disabled={disabled}>\n {addBccLabel}\n </CasePanelEmailComposerChip>\n ) : null}\n </div>\n ) : null}\n\n <div data-slot=\"case-panel-email-composer-editor\" className=\"min-h-40 px-4 py-4 text-sm text-foreground\">\n {draftEditor ?? <div className=\"text-muted-foreground\">Draft editor slot</div>}\n </div>\n\n {signatureControl ? (\n <div data-slot=\"case-panel-email-composer-signature-control\">{signatureControl}</div>\n ) : (\n <CasePanelEmailComposerSignatureRow disabled={disabled} />\n )}\n\n <div data-slot=\"case-panel-email-composer-toolbar\" className=\"flex min-h-11 items-center gap-2 border-t border-border/70 bg-muted/10 px-3 py-2\">\n {toolbar ?? <div className=\"text-xs font-medium text-muted-foreground\">Toolbar</div>}\n </div>\n\n {showSendBar ? (\n <div data-slot=\"case-panel-email-composer-send-bar\" className=\"flex items-center justify-between gap-3 border-t border-border/70 bg-background px-3 py-3\">\n <div className=\"min-w-0 flex-1\">\n {disabledReason ? (\n <div id={disabledReasonId} data-slot=\"case-panel-email-composer-disabled-reason\" className=\"truncate text-xs text-muted-foreground\">\n {disabledReason}\n </div>\n ) : null}\n </div>\n <div className=\"flex shrink-0 items-center gap-2\">\n {sendBarActions}\n <button\n type=\"button\"\n data-slot=\"case-panel-email-composer-send-button\"\n aria-describedby={disabledReason ? disabledReasonId : undefined}\n disabled={sendIsDisabled}\n onClick={handleSendIntent}\n className=\"inline-flex h-8 items-center justify-center rounded-md bg-foreground px-3 text-xs font-semibold text-background shadow-xs transition-colors hover:bg-foreground/90 disabled:pointer-events-none disabled:bg-muted disabled:text-muted-foreground\"\n >\n {sendLabel}\n </button>\n </div>\n </div>\n ) : null}\n </div>\n </div>\n )\n}\n"],"mappings":"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","names":["_a"]}
|
|
@@ -802,6 +802,7 @@ function DataTable({
|
|
|
802
802
|
title: data.title,
|
|
803
803
|
description: data.description,
|
|
804
804
|
score: scoreModal.type === "Risk" ? scoreModal.row.riskScore : scoreModal.row.expansionScore,
|
|
805
|
+
scoreIntent: scoreModal.type === "Risk" ? "risk" : "positive",
|
|
805
806
|
whyNow: data.whyNow,
|
|
806
807
|
evidence: data.evidence,
|
|
807
808
|
factors: data.factors,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/data-table.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport {\n Briefcase,\n Calendar,\n DollarSign,\n History,\n Link as LinkIcon,\n SearchX,\n TrendingUp,\n User,\n Users,\n} from \"lucide-react\"\nimport {\n createColumnHelper,\n flexRender,\n getCoreRowModel,\n getSortedRowModel,\n useReactTable,\n type SortingState,\n type VisibilityState,\n} from \"@tanstack/react-table\"\n\nimport { cn } from \"../lib/utils\"\nimport { Badge } from \"./badge\"\nimport {\n DataTableQuickViews,\n type DataTableQuickViewValue,\n} from \"./data-table-quick-views\"\nimport { DataTableToolbar } from \"./data-table-toolbar\"\nimport { type DataTableFilterCategory } from \"./data-table-filter\"\nimport { ScoreAnalysisModal } from \"./score-analysis-modal\"\nimport type { ScoreFactor } from \"./score-breakdown\"\nimport { Citation, type SourceDef } from \"./detail-view\"\n\nexport type DataRow = {\n id: string\n name: string\n industry: string[]\n accountRisks: string[]\n riskScore: number\n expansionScore: number\n growthIndicators: string[]\n lastInteraction: string\n lastInteractionDays: number\n createdAt: string\n revenue: string\n headcount: string\n lastFunding: string\n owner: string\n ownerEmail?: string\n opportunityCount: number\n productAdoptionScore: number\n sourceSystem?: string\n sourceRef?: string\n}\n\nconst QUICK_VIEWS = [\n \"Balance Flight Detected\",\n \"Not Touched in 30+ Days\",\n \"Open Opportunity, Stalled\",\n \"Growth Signal Detected\",\n \"Low Product Adoption\",\n]\n\nconst MORE_QUICK_VIEWS = [\n \"Missed meeting this week\",\n \"High churn risk score\",\n \"Key contact departed\",\n \"Recent large inflow\",\n \"Dormant (no payments)\",\n \"Support tickets elevated\",\n]\n\nconst FILTER_CATEGORIES: DataTableFilterCategory[] = [\n {\n id: \"industry\",\n label: \"Industry\",\n icon: Briefcase,\n options: [\n \"Software\",\n \"E-commerce\",\n \"Financial Technology\",\n \"Workforce Management\",\n \"Artificial Intelligence\",\n \"Health Technology\",\n \"Design\",\n ],\n },\n {\n id: \"lastInteraction\",\n label: \"Last interaction\",\n icon: History,\n options: [\"1 day ago\", \"3 days ago\", \"1 week ago\", \"1 month ago\", \"2 months ago\"],\n },\n {\n id: \"createdAt\",\n label: \"Created at\",\n icon: Calendar,\n options: [\"Last 30 days\", \"Last 90 days\", \"This year\", \"Last year\"],\n },\n {\n id: \"revenue\",\n label: \"Revenue\",\n icon: DollarSign,\n options: [\"$0 - $1M\", \"$1M - $10M\", \"$10M - $50M\", \"$50M+\"],\n },\n {\n id: \"headcount\",\n label: \"Headcount\",\n icon: Users,\n options: [\"11-50\", \"51-200\", \"201-500\", \"500-1000\", \"1000+\"],\n },\n {\n id: \"lastFunding\",\n label: \"Last funding\",\n icon: TrendingUp,\n options: [\"Seed\", \"Series A\", \"Series B\", \"Series C+\", \"Undisclosed\"],\n },\n {\n id: \"owner\",\n label: \"Owner\",\n icon: User,\n options: [\"Sam Lee\", \"Alex Morgan\", \"Jordan Case\", \"Taylor Reed\"],\n },\n {\n id: \"opportunityCount\",\n label: \"Opportunity count\",\n icon: LinkIcon,\n options: [\"0\", \"1\", \"2\", \"3+\"],\n },\n]\n\nconst ROWS: DataRow[] = [\n {\n id: \"rappi\",\n name: \"Rappi\",\n industry: [\"E-commerce\", \"Food Delivery\", \"Financial Technology\"],\n accountRisks: [\"Flight Risk\", \"Low Engagement\"],\n riskScore: 65,\n expansionScore: 45,\n growthIndicators: [\"Job Openings\", \"Recent Funding\"],\n lastInteraction: \"1 week ago\",\n lastInteractionDays: 7,\n createdAt: \"This year\",\n revenue: \"$10M - $50M\",\n headcount: \"1000+\",\n lastFunding: \"Series C+\",\n owner: \"Sam Lee\",\n opportunityCount: 2,\n productAdoptionScore: 62,\n },\n {\n id: \"codeshot\",\n name: \"Codeshot\",\n industry: [\"Software\"],\n accountRisks: [\"Flight Risk\", \"Low Engagement\"],\n riskScore: 85,\n expansionScore: 20,\n growthIndicators: [],\n lastInteraction: \"2 months ago\",\n lastInteractionDays: 64,\n createdAt: \"Last year\",\n revenue: \"$1M - $10M\",\n headcount: \"201-500\",\n lastFunding: \"Series A\",\n owner: \"Alex Morgan\",\n opportunityCount: 1,\n productAdoptionScore: 31,\n },\n {\n id: \"lovi\",\n name: \"Lovi\",\n industry: [\"Artificial Intelligence\", \"Health Technology\"],\n accountRisks: [\"Low Engagement\", \"Key Contact Departure\"],\n riskScore: 55,\n expansionScore: 75,\n growthIndicators: [\"Recent Funding\", \"Headcount Expansion\"],\n lastInteraction: \"1 month ago\",\n lastInteractionDays: 36,\n createdAt: \"This year\",\n revenue: \"$10M - $50M\",\n headcount: \"500-1000\",\n lastFunding: \"Series B\",\n owner: \"Jordan Case\",\n opportunityCount: 3,\n productAdoptionScore: 38,\n },\n {\n id: \"anthropic\",\n name: \"Anthropic\",\n industry: [\"Software\"],\n accountRisks: [],\n riskScore: 25,\n expansionScore: 68,\n growthIndicators: [\"Recent Funding\", \"Headcount Expansion\"],\n lastInteraction: \"3 days ago\",\n lastInteractionDays: 3,\n createdAt: \"Last 90 days\",\n revenue: \"$50M+\",\n headcount: \"1000+\",\n lastFunding: \"Series C+\",\n owner: \"Sam Lee\",\n opportunityCount: 2,\n productAdoptionScore: 86,\n },\n {\n id: \"buildbear\",\n name: \"BuildBear\",\n industry: [\"Software\"],\n accountRisks: [],\n riskScore: 35,\n expansionScore: 92,\n growthIndicators: [\"Recent Funding\", \"Revenue Growth\"],\n lastInteraction: \"1 day ago\",\n lastInteractionDays: 1,\n createdAt: \"Last 30 days\",\n revenue: \"$1M - $10M\",\n headcount: \"51-200\",\n lastFunding: \"Seed\",\n owner: \"Taylor Reed\",\n opportunityCount: 2,\n productAdoptionScore: 91,\n },\n {\n id: \"content-mobbin\",\n name: \"Content-mobbin\",\n industry: [\"Workforce Management\"],\n accountRisks: [],\n riskScore: 28,\n expansionScore: 85,\n growthIndicators: [\"Recent Funding\", \"Headcount Expansion\"],\n lastInteraction: \"1 week ago\",\n lastInteractionDays: 9,\n createdAt: \"Last 30 days\",\n revenue: \"$0 - $1M\",\n headcount: \"11-50\",\n lastFunding: \"Seed\",\n owner: \"Taylor Reed\",\n opportunityCount: 2,\n productAdoptionScore: 77,\n },\n {\n id: \"figma\",\n name: \"Figma\",\n industry: [\"Design\", \"Software\"],\n accountRisks: [],\n riskScore: 15,\n expansionScore: 88,\n growthIndicators: [\"Headcount Expansion\", \"Job Openings\"],\n lastInteraction: \"3 days ago\",\n lastInteractionDays: 3,\n createdAt: \"This year\",\n revenue: \"$50M+\",\n headcount: \"1000+\",\n lastFunding: \"Series C+\",\n owner: \"Alex Morgan\",\n opportunityCount: 1,\n productAdoptionScore: 94,\n },\n {\n id: \"loom\",\n name: \"Loom\",\n industry: [\"Software\"],\n accountRisks: [\"Key Contact Departure\"],\n riskScore: 35,\n expansionScore: 68,\n growthIndicators: [\"Headcount Expansion\", \"Job Openings\"],\n lastInteraction: \"1 month ago\",\n lastInteractionDays: 33,\n createdAt: \"Last year\",\n revenue: \"$10M - $50M\",\n headcount: \"500-1000\",\n lastFunding: \"Series B\",\n owner: \"Jordan Case\",\n opportunityCount: 1,\n productAdoptionScore: 58,\n },\n {\n id: \"miro\",\n name: \"Miro\",\n industry: [\"Software\"],\n accountRisks: [],\n riskScore: 32,\n expansionScore: 55,\n growthIndicators: [],\n lastInteraction: \"1 week ago\",\n lastInteractionDays: 8,\n createdAt: \"This year\",\n revenue: \"$50M+\",\n headcount: \"1000+\",\n lastFunding: \"Series C+\",\n owner: \"Sam Lee\",\n opportunityCount: 0,\n productAdoptionScore: 64,\n },\n {\n id: \"webflow\",\n name: \"Webflow\",\n industry: [\"Software\"],\n accountRisks: [],\n riskScore: 25,\n expansionScore: 72,\n growthIndicators: [\"Recent Funding\", \"Headcount Expansion\"],\n lastInteraction: \"1 week ago\",\n lastInteractionDays: 10,\n createdAt: \"Last 90 days\",\n revenue: \"$10M - $50M\",\n headcount: \"500-1000\",\n lastFunding: \"Series B\",\n owner: \"Alex Morgan\",\n opportunityCount: 2,\n productAdoptionScore: 71,\n },\n]\n\ntype ScoreAnalysisData = {\n title: string\n description: string\n whyNow: string\n evidence: React.ReactNode[]\n factors: ScoreFactor[]\n}\n\nconst RISK_SOURCES: SourceDef[] = [\n { id: 1, summary: \"Weekly active users declined 12% over the past 30 days with no recovery trend.\", meta: \"Product telemetry \\u00b7 2h ago\" },\n { id: 2, summary: \"Critical support ticket #4821 has been unresolved for over 48 hours.\", meta: \"Zendesk \\u00b7 6h ago\" },\n { id: 3, summary: \"Competitor mentions detected in recent Slack conversations from the finance team.\", meta: \"Slack signal \\u00b7 1d ago\" },\n]\n\nconst EXPANSION_SOURCES: SourceDef[] = [\n { id: 1, summary: \"Treasury feature utilization is above the 85th percentile compared to peer accounts.\", meta: \"Product telemetry \\u00b7 3h ago\" },\n { id: 2, summary: \"Multiple feature requests submitted for advanced reporting and API access.\", meta: \"Zendesk \\u00b7 1d ago\" },\n { id: 3, summary: \"Finance department headcount grew from 8 to 14 in the last quarter.\", meta: \"LinkedIn signal \\u00b7 2d ago\" },\n]\n\nconst SCORE_ANALYSIS: Record<string, (row: DataRow) => ScoreAnalysisData> = {\n Risk: (row) => ({\n title: \"Risk Score Analysis\",\n description:\n \"Estimated probability of churn within the next 90 days based on activity and support signals\",\n whyNow:\n row.riskScore >= 60\n ? \"Critical risk factors detected requiring immediate intervention to prevent churn.\"\n : \"Account health is stable, but monitoring recent support interactions is recommended.\",\n evidence: [\n <>Recent decline in <span className=\"font-medium text-foreground\">weekly active users (-12%)</span> with no recovery trend<Citation number={1} source={RISK_SOURCES[0]} /></>,\n <>Unresolved <span className=\"font-medium text-foreground\">critical support ticket</span> open for over 48 hours<Citation number={2} source={RISK_SOURCES[1]} /></>,\n <>Competitor presence detected in recent conversations from finance team<Citation number={3} source={RISK_SOURCES[2]} /></>,\n ],\n factors: [\n { key: \"engagement\", label: \"Engagement drop\", score: Math.min(row.riskScore + 10, 100), why: \"Weekly active users declined 12% over past 30 days\" },\n { key: \"support\", label: \"Support load\", score: Math.min(row.riskScore + 5, 100), why: \"Unresolved critical ticket open for >48h\" },\n { key: \"competitive\", label: \"Competitive risk\", score: null, risk: row.riskScore >= 60 ? \"High\" as const : \"Low\" as const, why: \"Competitor mentions detected in recent conversations\" },\n { key: \"usage\", label: \"Product usage\", score: Math.max(100 - row.riskScore, 10), why: \"Core feature adoption remains consistent\" },\n ],\n }),\n Expansion: (row) => ({\n title: \"Expansion Score Analysis\",\n description:\n \"Likelihood of successful upsell and cross-sell opportunities based on usage and engagement\",\n whyNow:\n row.expansionScore >= 70\n ? \"Usage patterns and growth signals indicate readiness for additional product adoption.\"\n : \"Moderate expansion potential; consider targeted engagement to increase adoption.\",\n evidence: [\n <>Treasury utilization above <span className=\"font-medium text-foreground\">85th percentile</span> vs peer accounts<Citation number={1} source={EXPANSION_SOURCES[0]} /></>,\n <>Frequent <span className=\"font-medium text-foreground\">feature requests</span> for advanced reporting and API access<Citation number={2} source={EXPANSION_SOURCES[1]} /></>,\n <>Recent <span className=\"font-medium text-foreground\">team expansion</span> in finance department (8 → 14)<Citation number={3} source={EXPANSION_SOURCES[2]} /></>,\n ],\n factors: [\n { key: \"usage-depth\", label: \"Usage depth\", score: Math.min(row.expansionScore + 8, 100), why: \"Active usage across 4+ core product features\" },\n { key: \"growth\", label: \"Growth signals\", score: row.expansionScore, why: row.growthIndicators.length > 0 ? row.growthIndicators.join(\", \") + \" detected\" : \"No active growth signals\" },\n { key: \"fit\", label: \"Product fit\", score: Math.min(row.expansionScore + 12, 100), why: \"Company profile matches high-expansion ICP\" },\n { key: \"timing\", label: \"Timing\", score: null, risk: row.expansionScore >= 70 ? \"Low\" as const : \"Medium\" as const, why: \"Within typical evaluation window for upsell\" },\n ],\n }),\n}\n\nconst QUICK_VIEW_FILTERS: Record<string, (row: DataRow) => boolean> = {\n \"Balance Flight Detected\": (row) => row.riskScore >= 60,\n \"Not Touched in 30+ Days\": (row) => row.lastInteractionDays >= 30,\n \"Open Opportunity, Stalled\": (row) =>\n row.opportunityCount > 0 && row.lastInteractionDays >= 21,\n \"Growth Signal Detected\": (row) => row.expansionScore >= 70,\n \"Low Product Adoption\": (row) => row.productAdoptionScore <= 40,\n \"Missed meeting this week\": (row) => row.lastInteractionDays >= 6,\n \"High churn risk score\": (row) => row.riskScore >= 75,\n \"Key contact departed\": (row) =>\n row.accountRisks.some((risk) => risk.toLowerCase().includes(\"contact\")),\n \"Recent large inflow\": (row) => row.expansionScore >= 85,\n \"Dormant (no payments)\": (row) => row.opportunityCount === 0,\n \"Support tickets elevated\": (row) =>\n row.accountRisks.some((risk) => risk.toLowerCase().includes(\"engagement\")),\n}\n\nconst columnHelper = createColumnHelper<DataRow>()\n\nconst DEFAULT_COLUMN_VISIBILITY: VisibilityState = {\n industry: false,\n lastInteraction: false,\n revenue: false,\n headcount: false,\n lastFunding: false,\n owner: false,\n opportunityCount: false,\n}\n\nfunction getEntityColor(name: string) {\n const colors = [\n \"bg-muted text-muted-foreground\",\n \"bg-gray-100 text-gray-600\",\n \"bg-zinc-100 text-zinc-600\",\n \"bg-blue-50 text-blue-600\",\n \"bg-indigo-50 text-indigo-600\",\n \"bg-violet-50 text-violet-600\",\n ]\n\n let hash = 0\n for (let i = 0; i < name.length; i += 1) {\n hash = name.charCodeAt(i) + ((hash << 5) - hash)\n }\n return colors[Math.abs(hash) % colors.length]\n}\n\nfunction getIndustryColor(industry: string) {\n const colors: Record<string, string> = {\n \"E-commerce\": \"bg-emerald-50 text-emerald-700 border-emerald-100\",\n \"Food Delivery\": \"bg-blue-50 text-blue-700 border-blue-100\",\n \"Financial Technology\": \"bg-amber-50 text-amber-700 border-amber-100\",\n \"Workforce Management\": \"bg-violet-50 text-violet-700 border-violet-100\",\n \"Artificial Intelligence\": \"bg-rose-50 text-rose-700 border-rose-100\",\n \"Health Technology\": \"bg-orange-50 text-orange-700 border-orange-100\",\n Software: \"bg-muted text-muted-foreground border-border\",\n }\n\n return colors[industry] ?? \"bg-muted text-muted-foreground border-border\"\n}\n\nfunction toggleFilterValue(\n current: Record<string, string[]>,\n categoryId: string,\n option: string\n) {\n const currentValues = current[categoryId] ?? []\n const isActive = currentValues.includes(option)\n const nextValues = isActive\n ? currentValues.filter((value) => value !== option)\n : [...currentValues, option]\n\n return {\n ...current,\n [categoryId]: nextValues,\n }\n}\n\nfunction isRowMatchingCategoryFilter(\n row: DataRow,\n categoryId: string,\n options: string[]\n) {\n if (options.length === 0) {\n return true\n }\n\n switch (categoryId) {\n case \"industry\":\n return options.some((option) => row.industry.includes(option))\n case \"lastInteraction\":\n return options.includes(row.lastInteraction)\n case \"createdAt\":\n return options.includes(row.createdAt)\n case \"revenue\":\n return options.includes(row.revenue)\n case \"headcount\":\n return options.includes(row.headcount)\n case \"lastFunding\":\n return options.includes(row.lastFunding)\n case \"owner\":\n return options.includes(row.ownerEmail ?? row.owner)\n case \"opportunityCount\":\n return options.some((option) => {\n if (option === \"3+\") {\n return row.opportunityCount >= 3\n }\n return row.opportunityCount === Number(option)\n })\n default:\n return true\n }\n}\n\nexport interface DataTableProps {\n onRowClick?: (row: DataRow) => void\n rows?: DataRow[]\n filterCategories?: DataTableFilterCategory[]\n quickViews?: string[]\n moreQuickViews?: string[]\n quickViewFilters?: Record<string, (row: DataRow) => boolean>\n iconMap?: { salesforce?: string }\n entityUrlBuilder?: (row: DataRow) => string\n onScoreFactorFeedback?: (account: string, scoreType: string, factorKey: string, type: \"up\" | \"down\" | null, detail?: string) => void\n onScoreApproveFeedback?: (account: string, scoreType: string, reasons: string[], detail: string) => void\n onScoreDismissFeedback?: (account: string, scoreType: string, reasons: string[], detail: string) => void\n}\n\nexport function DataTable({\n onRowClick,\n rows: rowsProp,\n filterCategories: filterCategoriesProp,\n quickViews: quickViewsProp,\n moreQuickViews: moreQuickViewsProp,\n quickViewFilters: quickViewFiltersProp,\n iconMap,\n entityUrlBuilder,\n onScoreFactorFeedback,\n onScoreApproveFeedback,\n onScoreDismissFeedback,\n}: DataTableProps = {}) {\n const resolvedRows = rowsProp ?? ROWS\n const resolvedFilterCategories = filterCategoriesProp ?? FILTER_CATEGORIES\n const resolvedQuickViews = quickViewsProp ?? QUICK_VIEWS\n const resolvedMoreQuickViews = moreQuickViewsProp ?? MORE_QUICK_VIEWS\n const resolvedQuickViewFilters = quickViewFiltersProp ?? QUICK_VIEW_FILTERS\n\n const [sorting, setSorting] = React.useState<SortingState>([])\n const [columnVisibility, setColumnVisibility] = React.useState<VisibilityState>(\n DEFAULT_COLUMN_VISIBILITY\n )\n const [selectedFilters, setSelectedFilters] = React.useState<Record<string, string[]>>(\n {}\n )\n const [activeQuickView, setActiveQuickView] =\n React.useState<DataTableQuickViewValue>(null)\n const [scoreModal, setScoreModal] = React.useState<{\n row: DataRow\n type: \"Risk\" | \"Expansion\"\n } | null>(null)\n\n React.useEffect(() => {\n if (!activeQuickView) {\n return\n }\n\n setColumnVisibility((previous) => {\n const next = { ...previous }\n if (activeQuickView.includes(\"Touched\")) {\n next.lastInteraction = true\n }\n if (activeQuickView.includes(\"Growth\")) {\n next.expansionScore = true\n }\n if (activeQuickView.includes(\"risk\") || activeQuickView.includes(\"Risk\")) {\n next.riskScore = true\n }\n return next\n })\n }, [activeQuickView])\n\n const filteredRows = React.useMemo(() => {\n return resolvedRows.filter((row) => {\n const quickViewMatches = activeQuickView\n ? (resolvedQuickViewFilters[activeQuickView]?.(row) ?? true)\n : true\n\n if (!quickViewMatches) {\n return false\n }\n\n return Object.entries(selectedFilters).every(([categoryId, options]) =>\n isRowMatchingCategoryFilter(row, categoryId, options)\n )\n })\n }, [activeQuickView, selectedFilters, resolvedRows, resolvedQuickViewFilters])\n\n const columns = React.useMemo(\n () => [\n columnHelper.accessor(\"name\", {\n header: \"Entity\",\n cell: (info) => {\n const row = info.row.original\n const sfUrl = entityUrlBuilder?.(row)\n return (\n <div className=\"flex items-center gap-3\">\n <div\n className={cn(\n \"flex h-6 w-6 shrink-0 items-center justify-center rounded text-[10px] font-bold\",\n getEntityColor(row.name)\n )}\n >\n {row.name.slice(0, 1)}\n </div>\n <span className=\"text-sm font-medium text-foreground\">\n {row.name}\n </span>\n {iconMap?.salesforce && (\n <a\n href={sfUrl ?? \"#\"}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n onClick={(e) => e.stopPropagation()}\n className=\"shrink-0 text-muted-foreground hover:text-foreground transition-colors\"\n >\n <img src={iconMap.salesforce} alt=\"Salesforce\" className=\"w-4 h-4 object-contain\" />\n </a>\n )}\n </div>\n )\n },\n }),\n columnHelper.accessor(\"accountRisks\", {\n header: \"Risk Signals\",\n cell: (info) => {\n const risks = info.getValue()\n if (!risks.length) {\n return <span className=\"text-xs text-muted-foreground\">None</span>\n }\n\n return (\n <div className=\"flex items-center gap-1.5\">\n {risks.slice(0, 2).map((risk) => (\n <Badge\n key={risk}\n variant=\"outline\"\n className=\"rounded-md border-red-200 bg-red-50 px-2 py-0.5 text-xs font-normal text-red-700\"\n >\n {risk}\n </Badge>\n ))}\n </div>\n )\n },\n }),\n columnHelper.accessor(\"riskScore\", {\n id: \"riskScore\",\n header: \"Risk Score\",\n cell: (info) => (\n <div\n className=\"inline-flex cursor-pointer\"\n onClick={(e) => {\n e.stopPropagation()\n setScoreModal({ row: info.row.original, type: \"Risk\" })\n }}\n >\n <Badge\n variant=\"outline\"\n className={cn(\n \"px-2 py-0.5 text-xs font-medium hover:underline decoration-dotted underline-offset-2\",\n info.getValue() >= 60\n ? \"border-red-200 bg-red-50 text-red-700\"\n : \"border-border bg-muted/50 text-foreground\"\n )}\n >\n {info.getValue()}%\n </Badge>\n </div>\n ),\n }),\n columnHelper.accessor(\"expansionScore\", {\n id: \"expansionScore\",\n header: \"Expansion Score\",\n cell: (info) => (\n <div\n className=\"inline-flex cursor-pointer\"\n onClick={(e) => {\n e.stopPropagation()\n setScoreModal({ row: info.row.original, type: \"Expansion\" })\n }}\n >\n <Badge\n variant=\"outline\"\n className={cn(\n \"px-2 py-0.5 text-xs font-medium hover:underline decoration-dotted underline-offset-2\",\n info.getValue() >= 70\n ? \"border-blue-200 bg-blue-50 text-blue-700\"\n : \"border-border bg-muted/50 text-foreground\"\n )}\n >\n {info.getValue()}%\n </Badge>\n </div>\n ),\n }),\n columnHelper.accessor(\"growthIndicators\", {\n header: \"Growth Signals\",\n cell: (info) => {\n const indicators = info.getValue()\n if (!indicators.length) {\n return <span className=\"text-xs text-muted-foreground\">None</span>\n }\n return (\n <div className=\"flex items-center gap-1.5\">\n {indicators.slice(0, 2).map((indicator) => (\n <Badge\n key={indicator}\n variant=\"outline\"\n className=\"rounded-md border-blue-200 bg-blue-50 px-2 py-0.5 text-xs font-normal text-blue-700\"\n >\n {indicator}\n </Badge>\n ))}\n </div>\n )\n },\n }),\n columnHelper.accessor(\"industry\", {\n header: \"Industry\",\n cell: (info) => (\n <div className=\"flex items-center gap-1.5\">\n {info.getValue().slice(0, 2).map((industry) => (\n <Badge\n key={industry}\n variant=\"outline\"\n className={cn(\n \"rounded-md px-2 py-0.5 text-xs font-normal\",\n getIndustryColor(industry)\n )}\n >\n {industry}\n </Badge>\n ))}\n </div>\n ),\n }),\n columnHelper.accessor(\"lastInteraction\", {\n header: \"Last interaction\",\n cell: (info) => <span className=\"text-sm\">{info.getValue()}</span>,\n }),\n columnHelper.accessor(\"revenue\", {\n header: \"Revenue\",\n cell: (info) => (\n <span className=\"rounded-md bg-muted/50 px-2 py-0.5 text-xs font-medium\">\n {info.getValue()}\n </span>\n ),\n }),\n columnHelper.accessor(\"headcount\", {\n header: \"Headcount\",\n cell: (info) => (\n <span className=\"rounded-md bg-muted/50 px-2 py-0.5 text-xs font-medium\">\n {info.getValue()}\n </span>\n ),\n }),\n columnHelper.accessor(\"lastFunding\", {\n header: \"Last funding\",\n cell: (info) => (\n <span className=\"rounded-md bg-muted/50 px-2 py-0.5 text-xs font-medium\">\n {info.getValue()}\n </span>\n ),\n }),\n columnHelper.accessor(\"owner\", {\n header: \"Owner\",\n cell: (info) => <span className=\"text-sm\">{info.getValue()}</span>,\n }),\n columnHelper.accessor(\"opportunityCount\", {\n header: \"Opportunity count\",\n cell: (info) => (\n <span className=\"rounded-md bg-muted/50 px-2 py-0.5 text-xs font-medium\">\n {info.getValue()}\n </span>\n ),\n }),\n ],\n [iconMap, entityUrlBuilder]\n )\n\n const table = useReactTable({\n data: filteredRows,\n columns,\n state: {\n sorting,\n columnVisibility,\n },\n onSortingChange: setSorting,\n onColumnVisibilityChange: setColumnVisibility,\n getCoreRowModel: getCoreRowModel(),\n getSortedRowModel: getSortedRowModel(),\n })\n\n const displayColumns = table.getAllLeafColumns().map((column) => {\n const header = column.columnDef.header\n const label = typeof header === \"string\" ? header : column.id\n\n return {\n id: column.id,\n label,\n visible: column.getIsVisible(),\n canHide: column.getCanHide(),\n }\n })\n\n const toggleCategoryFilter = (categoryId: string, option: string) => {\n setSelectedFilters((previous) => toggleFilterValue(previous, categoryId, option))\n }\n\n return (\n <div className=\"relative flex h-full min-h-[560px] flex-col bg-background\">\n <DataTableToolbar\n categories={resolvedFilterCategories}\n selectedFilters={selectedFilters}\n onToggleFilter={toggleCategoryFilter}\n sorting={sorting}\n onSortingChange={setSorting}\n displayColumns={displayColumns}\n onToggleColumn={(columnId) => table.getColumn(columnId)?.toggleVisibility()}\n onResetDisplay={() => setColumnVisibility(DEFAULT_COLUMN_VISIBILITY)}\n />\n\n <DataTableQuickViews\n quickViews={resolvedQuickViews}\n moreViews={resolvedMoreQuickViews}\n activeView={activeQuickView}\n onViewChange={setActiveQuickView}\n />\n\n <div className=\"relative min-h-0 flex-1 overflow-auto border-t border-border\">\n <table className=\"w-max min-w-full border-collapse text-sm\">\n <thead className=\"sticky top-0 z-10 bg-background\">\n {table.getHeaderGroups().map((headerGroup) => (\n <tr key={headerGroup.id} className=\"border-b border-border\">\n {headerGroup.headers.map((header) => (\n <th\n key={header.id}\n className=\"h-10 border-r border-border px-4 text-left text-xs font-medium text-muted-foreground/80 last:border-r-0\"\n >\n {header.isPlaceholder\n ? null\n : flexRender(\n header.column.columnDef.header,\n header.getContext()\n )}\n </th>\n ))}\n </tr>\n ))}\n </thead>\n <tbody>\n {table.getRowModel().rows.length > 0 ? (\n <>\n {table.getRowModel().rows.map((row) => (\n <tr\n key={row.id}\n onClick={() => onRowClick?.(row.original)}\n className={cn(\n \"group border-b border-border/50 transition-colors hover:bg-muted/30\",\n onRowClick && \"cursor-pointer\",\n )}\n >\n {row.getVisibleCells().map((cell) => (\n <td\n key={cell.id}\n className=\"border-r border-border/40 px-4 py-2.5 align-middle last:border-r-0\"\n >\n {flexRender(cell.column.columnDef.cell, cell.getContext())}\n </td>\n ))}\n </tr>\n ))}\n <tr>\n <td\n className=\"px-4 py-2 text-xs text-muted-foreground\"\n colSpan={columns.length}\n >\n {table.getRowModel().rows.length} rows\n </td>\n </tr>\n </>\n ) : (\n <tr>\n <td colSpan={columns.length} className=\"h-52 px-4 text-center\">\n <div className=\"flex flex-col items-center gap-1 text-muted-foreground\">\n <SearchX className=\"h-7 w-7 opacity-40\" />\n <p className=\"text-sm font-medium\">No rows found</p>\n <p className=\"text-xs\">Try adjusting your filters or quick views</p>\n </div>\n </td>\n </tr>\n )}\n </tbody>\n </table>\n </div>\n\n {scoreModal && (() => {\n const data = SCORE_ANALYSIS[scoreModal.type](scoreModal.row)\n return (\n <ScoreAnalysisModal\n open\n onOpenChange={(open) => { if (!open) setScoreModal(null) }}\n title={data.title}\n description={data.description}\n score={scoreModal.type === \"Risk\" ? scoreModal.row.riskScore : scoreModal.row.expansionScore}\n whyNow={data.whyNow}\n evidence={data.evidence}\n factors={data.factors}\n onFactorFeedback={onScoreFactorFeedback\n ? (key, type, detail) => onScoreFactorFeedback(scoreModal.row.name, scoreModal.type, key, type, detail)\n : (key, type, detail) => console.log(\"Factor feedback:\", { account: scoreModal.row.name, factor: key, type, detail })\n }\n companyName={scoreModal.row.name}\n opportunityUrl={`https://acme.lightning.force.com/lightning/r/Opportunity/006${scoreModal.row.id}/view`}\n onApprove={() => console.log(\"Approved signal — creating opportunity:\", { account: scoreModal.row.name, type: scoreModal.type })}\n onApproveFeedback={onScoreApproveFeedback\n ? (reasons, detail) => onScoreApproveFeedback(scoreModal.row.name, scoreModal.type, reasons, detail)\n : (reasons, detail) => console.log(\"Approval feedback:\", { account: scoreModal.row.name, reasons, detail })\n }\n onDismiss={onScoreDismissFeedback\n ? (reasons, detail) => onScoreDismissFeedback(scoreModal.row.name, scoreModal.type, reasons, detail)\n : (reasons, detail) => console.log(\"Dismissed signal:\", { account: scoreModal.row.name, reasons, detail })\n }\n />\n )\n })()}\n </div>\n )\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/components/data-table.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport {\n Briefcase,\n Calendar,\n DollarSign,\n History,\n Link as LinkIcon,\n SearchX,\n TrendingUp,\n User,\n Users,\n} from \"lucide-react\"\nimport {\n createColumnHelper,\n flexRender,\n getCoreRowModel,\n getSortedRowModel,\n useReactTable,\n type SortingState,\n type VisibilityState,\n} from \"@tanstack/react-table\"\n\nimport { cn } from \"../lib/utils\"\nimport { Badge } from \"./badge\"\nimport {\n DataTableQuickViews,\n type DataTableQuickViewValue,\n} from \"./data-table-quick-views\"\nimport { DataTableToolbar } from \"./data-table-toolbar\"\nimport { type DataTableFilterCategory } from \"./data-table-filter\"\nimport { ScoreAnalysisModal } from \"./score-analysis-modal\"\nimport type { ScoreFactor } from \"./score-breakdown\"\nimport { Citation, type SourceDef } from \"./detail-view\"\n\nexport type DataRow = {\n id: string\n name: string\n industry: string[]\n accountRisks: string[]\n riskScore: number\n expansionScore: number\n growthIndicators: string[]\n lastInteraction: string\n lastInteractionDays: number\n createdAt: string\n revenue: string\n headcount: string\n lastFunding: string\n owner: string\n ownerEmail?: string\n opportunityCount: number\n productAdoptionScore: number\n sourceSystem?: string\n sourceRef?: string\n}\n\nconst QUICK_VIEWS = [\n \"Balance Flight Detected\",\n \"Not Touched in 30+ Days\",\n \"Open Opportunity, Stalled\",\n \"Growth Signal Detected\",\n \"Low Product Adoption\",\n]\n\nconst MORE_QUICK_VIEWS = [\n \"Missed meeting this week\",\n \"High churn risk score\",\n \"Key contact departed\",\n \"Recent large inflow\",\n \"Dormant (no payments)\",\n \"Support tickets elevated\",\n]\n\nconst FILTER_CATEGORIES: DataTableFilterCategory[] = [\n {\n id: \"industry\",\n label: \"Industry\",\n icon: Briefcase,\n options: [\n \"Software\",\n \"E-commerce\",\n \"Financial Technology\",\n \"Workforce Management\",\n \"Artificial Intelligence\",\n \"Health Technology\",\n \"Design\",\n ],\n },\n {\n id: \"lastInteraction\",\n label: \"Last interaction\",\n icon: History,\n options: [\"1 day ago\", \"3 days ago\", \"1 week ago\", \"1 month ago\", \"2 months ago\"],\n },\n {\n id: \"createdAt\",\n label: \"Created at\",\n icon: Calendar,\n options: [\"Last 30 days\", \"Last 90 days\", \"This year\", \"Last year\"],\n },\n {\n id: \"revenue\",\n label: \"Revenue\",\n icon: DollarSign,\n options: [\"$0 - $1M\", \"$1M - $10M\", \"$10M - $50M\", \"$50M+\"],\n },\n {\n id: \"headcount\",\n label: \"Headcount\",\n icon: Users,\n options: [\"11-50\", \"51-200\", \"201-500\", \"500-1000\", \"1000+\"],\n },\n {\n id: \"lastFunding\",\n label: \"Last funding\",\n icon: TrendingUp,\n options: [\"Seed\", \"Series A\", \"Series B\", \"Series C+\", \"Undisclosed\"],\n },\n {\n id: \"owner\",\n label: \"Owner\",\n icon: User,\n options: [\"Sam Lee\", \"Alex Morgan\", \"Jordan Case\", \"Taylor Reed\"],\n },\n {\n id: \"opportunityCount\",\n label: \"Opportunity count\",\n icon: LinkIcon,\n options: [\"0\", \"1\", \"2\", \"3+\"],\n },\n]\n\nconst ROWS: DataRow[] = [\n {\n id: \"rappi\",\n name: \"Rappi\",\n industry: [\"E-commerce\", \"Food Delivery\", \"Financial Technology\"],\n accountRisks: [\"Flight Risk\", \"Low Engagement\"],\n riskScore: 65,\n expansionScore: 45,\n growthIndicators: [\"Job Openings\", \"Recent Funding\"],\n lastInteraction: \"1 week ago\",\n lastInteractionDays: 7,\n createdAt: \"This year\",\n revenue: \"$10M - $50M\",\n headcount: \"1000+\",\n lastFunding: \"Series C+\",\n owner: \"Sam Lee\",\n opportunityCount: 2,\n productAdoptionScore: 62,\n },\n {\n id: \"codeshot\",\n name: \"Codeshot\",\n industry: [\"Software\"],\n accountRisks: [\"Flight Risk\", \"Low Engagement\"],\n riskScore: 85,\n expansionScore: 20,\n growthIndicators: [],\n lastInteraction: \"2 months ago\",\n lastInteractionDays: 64,\n createdAt: \"Last year\",\n revenue: \"$1M - $10M\",\n headcount: \"201-500\",\n lastFunding: \"Series A\",\n owner: \"Alex Morgan\",\n opportunityCount: 1,\n productAdoptionScore: 31,\n },\n {\n id: \"lovi\",\n name: \"Lovi\",\n industry: [\"Artificial Intelligence\", \"Health Technology\"],\n accountRisks: [\"Low Engagement\", \"Key Contact Departure\"],\n riskScore: 55,\n expansionScore: 75,\n growthIndicators: [\"Recent Funding\", \"Headcount Expansion\"],\n lastInteraction: \"1 month ago\",\n lastInteractionDays: 36,\n createdAt: \"This year\",\n revenue: \"$10M - $50M\",\n headcount: \"500-1000\",\n lastFunding: \"Series B\",\n owner: \"Jordan Case\",\n opportunityCount: 3,\n productAdoptionScore: 38,\n },\n {\n id: \"anthropic\",\n name: \"Anthropic\",\n industry: [\"Software\"],\n accountRisks: [],\n riskScore: 25,\n expansionScore: 68,\n growthIndicators: [\"Recent Funding\", \"Headcount Expansion\"],\n lastInteraction: \"3 days ago\",\n lastInteractionDays: 3,\n createdAt: \"Last 90 days\",\n revenue: \"$50M+\",\n headcount: \"1000+\",\n lastFunding: \"Series C+\",\n owner: \"Sam Lee\",\n opportunityCount: 2,\n productAdoptionScore: 86,\n },\n {\n id: \"buildbear\",\n name: \"BuildBear\",\n industry: [\"Software\"],\n accountRisks: [],\n riskScore: 35,\n expansionScore: 92,\n growthIndicators: [\"Recent Funding\", \"Revenue Growth\"],\n lastInteraction: \"1 day ago\",\n lastInteractionDays: 1,\n createdAt: \"Last 30 days\",\n revenue: \"$1M - $10M\",\n headcount: \"51-200\",\n lastFunding: \"Seed\",\n owner: \"Taylor Reed\",\n opportunityCount: 2,\n productAdoptionScore: 91,\n },\n {\n id: \"content-mobbin\",\n name: \"Content-mobbin\",\n industry: [\"Workforce Management\"],\n accountRisks: [],\n riskScore: 28,\n expansionScore: 85,\n growthIndicators: [\"Recent Funding\", \"Headcount Expansion\"],\n lastInteraction: \"1 week ago\",\n lastInteractionDays: 9,\n createdAt: \"Last 30 days\",\n revenue: \"$0 - $1M\",\n headcount: \"11-50\",\n lastFunding: \"Seed\",\n owner: \"Taylor Reed\",\n opportunityCount: 2,\n productAdoptionScore: 77,\n },\n {\n id: \"figma\",\n name: \"Figma\",\n industry: [\"Design\", \"Software\"],\n accountRisks: [],\n riskScore: 15,\n expansionScore: 88,\n growthIndicators: [\"Headcount Expansion\", \"Job Openings\"],\n lastInteraction: \"3 days ago\",\n lastInteractionDays: 3,\n createdAt: \"This year\",\n revenue: \"$50M+\",\n headcount: \"1000+\",\n lastFunding: \"Series C+\",\n owner: \"Alex Morgan\",\n opportunityCount: 1,\n productAdoptionScore: 94,\n },\n {\n id: \"loom\",\n name: \"Loom\",\n industry: [\"Software\"],\n accountRisks: [\"Key Contact Departure\"],\n riskScore: 35,\n expansionScore: 68,\n growthIndicators: [\"Headcount Expansion\", \"Job Openings\"],\n lastInteraction: \"1 month ago\",\n lastInteractionDays: 33,\n createdAt: \"Last year\",\n revenue: \"$10M - $50M\",\n headcount: \"500-1000\",\n lastFunding: \"Series B\",\n owner: \"Jordan Case\",\n opportunityCount: 1,\n productAdoptionScore: 58,\n },\n {\n id: \"miro\",\n name: \"Miro\",\n industry: [\"Software\"],\n accountRisks: [],\n riskScore: 32,\n expansionScore: 55,\n growthIndicators: [],\n lastInteraction: \"1 week ago\",\n lastInteractionDays: 8,\n createdAt: \"This year\",\n revenue: \"$50M+\",\n headcount: \"1000+\",\n lastFunding: \"Series C+\",\n owner: \"Sam Lee\",\n opportunityCount: 0,\n productAdoptionScore: 64,\n },\n {\n id: \"webflow\",\n name: \"Webflow\",\n industry: [\"Software\"],\n accountRisks: [],\n riskScore: 25,\n expansionScore: 72,\n growthIndicators: [\"Recent Funding\", \"Headcount Expansion\"],\n lastInteraction: \"1 week ago\",\n lastInteractionDays: 10,\n createdAt: \"Last 90 days\",\n revenue: \"$10M - $50M\",\n headcount: \"500-1000\",\n lastFunding: \"Series B\",\n owner: \"Alex Morgan\",\n opportunityCount: 2,\n productAdoptionScore: 71,\n },\n]\n\ntype ScoreAnalysisData = {\n title: string\n description: string\n whyNow: string\n evidence: React.ReactNode[]\n factors: ScoreFactor[]\n}\n\nconst RISK_SOURCES: SourceDef[] = [\n { id: 1, summary: \"Weekly active users declined 12% over the past 30 days with no recovery trend.\", meta: \"Product telemetry \\u00b7 2h ago\" },\n { id: 2, summary: \"Critical support ticket #4821 has been unresolved for over 48 hours.\", meta: \"Zendesk \\u00b7 6h ago\" },\n { id: 3, summary: \"Competitor mentions detected in recent Slack conversations from the finance team.\", meta: \"Slack signal \\u00b7 1d ago\" },\n]\n\nconst EXPANSION_SOURCES: SourceDef[] = [\n { id: 1, summary: \"Treasury feature utilization is above the 85th percentile compared to peer accounts.\", meta: \"Product telemetry \\u00b7 3h ago\" },\n { id: 2, summary: \"Multiple feature requests submitted for advanced reporting and API access.\", meta: \"Zendesk \\u00b7 1d ago\" },\n { id: 3, summary: \"Finance department headcount grew from 8 to 14 in the last quarter.\", meta: \"LinkedIn signal \\u00b7 2d ago\" },\n]\n\nconst SCORE_ANALYSIS: Record<string, (row: DataRow) => ScoreAnalysisData> = {\n Risk: (row) => ({\n title: \"Risk Score Analysis\",\n description:\n \"Estimated probability of churn within the next 90 days based on activity and support signals\",\n whyNow:\n row.riskScore >= 60\n ? \"Critical risk factors detected requiring immediate intervention to prevent churn.\"\n : \"Account health is stable, but monitoring recent support interactions is recommended.\",\n evidence: [\n <>Recent decline in <span className=\"font-medium text-foreground\">weekly active users (-12%)</span> with no recovery trend<Citation number={1} source={RISK_SOURCES[0]} /></>,\n <>Unresolved <span className=\"font-medium text-foreground\">critical support ticket</span> open for over 48 hours<Citation number={2} source={RISK_SOURCES[1]} /></>,\n <>Competitor presence detected in recent conversations from finance team<Citation number={3} source={RISK_SOURCES[2]} /></>,\n ],\n factors: [\n { key: \"engagement\", label: \"Engagement drop\", score: Math.min(row.riskScore + 10, 100), why: \"Weekly active users declined 12% over past 30 days\" },\n { key: \"support\", label: \"Support load\", score: Math.min(row.riskScore + 5, 100), why: \"Unresolved critical ticket open for >48h\" },\n { key: \"competitive\", label: \"Competitive risk\", score: null, risk: row.riskScore >= 60 ? \"High\" as const : \"Low\" as const, why: \"Competitor mentions detected in recent conversations\" },\n { key: \"usage\", label: \"Product usage\", score: Math.max(100 - row.riskScore, 10), why: \"Core feature adoption remains consistent\" },\n ],\n }),\n Expansion: (row) => ({\n title: \"Expansion Score Analysis\",\n description:\n \"Likelihood of successful upsell and cross-sell opportunities based on usage and engagement\",\n whyNow:\n row.expansionScore >= 70\n ? \"Usage patterns and growth signals indicate readiness for additional product adoption.\"\n : \"Moderate expansion potential; consider targeted engagement to increase adoption.\",\n evidence: [\n <>Treasury utilization above <span className=\"font-medium text-foreground\">85th percentile</span> vs peer accounts<Citation number={1} source={EXPANSION_SOURCES[0]} /></>,\n <>Frequent <span className=\"font-medium text-foreground\">feature requests</span> for advanced reporting and API access<Citation number={2} source={EXPANSION_SOURCES[1]} /></>,\n <>Recent <span className=\"font-medium text-foreground\">team expansion</span> in finance department (8 → 14)<Citation number={3} source={EXPANSION_SOURCES[2]} /></>,\n ],\n factors: [\n { key: \"usage-depth\", label: \"Usage depth\", score: Math.min(row.expansionScore + 8, 100), why: \"Active usage across 4+ core product features\" },\n { key: \"growth\", label: \"Growth signals\", score: row.expansionScore, why: row.growthIndicators.length > 0 ? row.growthIndicators.join(\", \") + \" detected\" : \"No active growth signals\" },\n { key: \"fit\", label: \"Product fit\", score: Math.min(row.expansionScore + 12, 100), why: \"Company profile matches high-expansion ICP\" },\n { key: \"timing\", label: \"Timing\", score: null, risk: row.expansionScore >= 70 ? \"Low\" as const : \"Medium\" as const, why: \"Within typical evaluation window for upsell\" },\n ],\n }),\n}\n\nconst QUICK_VIEW_FILTERS: Record<string, (row: DataRow) => boolean> = {\n \"Balance Flight Detected\": (row) => row.riskScore >= 60,\n \"Not Touched in 30+ Days\": (row) => row.lastInteractionDays >= 30,\n \"Open Opportunity, Stalled\": (row) =>\n row.opportunityCount > 0 && row.lastInteractionDays >= 21,\n \"Growth Signal Detected\": (row) => row.expansionScore >= 70,\n \"Low Product Adoption\": (row) => row.productAdoptionScore <= 40,\n \"Missed meeting this week\": (row) => row.lastInteractionDays >= 6,\n \"High churn risk score\": (row) => row.riskScore >= 75,\n \"Key contact departed\": (row) =>\n row.accountRisks.some((risk) => risk.toLowerCase().includes(\"contact\")),\n \"Recent large inflow\": (row) => row.expansionScore >= 85,\n \"Dormant (no payments)\": (row) => row.opportunityCount === 0,\n \"Support tickets elevated\": (row) =>\n row.accountRisks.some((risk) => risk.toLowerCase().includes(\"engagement\")),\n}\n\nconst columnHelper = createColumnHelper<DataRow>()\n\nconst DEFAULT_COLUMN_VISIBILITY: VisibilityState = {\n industry: false,\n lastInteraction: false,\n revenue: false,\n headcount: false,\n lastFunding: false,\n owner: false,\n opportunityCount: false,\n}\n\nfunction getEntityColor(name: string) {\n const colors = [\n \"bg-muted text-muted-foreground\",\n \"bg-gray-100 text-gray-600\",\n \"bg-zinc-100 text-zinc-600\",\n \"bg-blue-50 text-blue-600\",\n \"bg-indigo-50 text-indigo-600\",\n \"bg-violet-50 text-violet-600\",\n ]\n\n let hash = 0\n for (let i = 0; i < name.length; i += 1) {\n hash = name.charCodeAt(i) + ((hash << 5) - hash)\n }\n return colors[Math.abs(hash) % colors.length]\n}\n\nfunction getIndustryColor(industry: string) {\n const colors: Record<string, string> = {\n \"E-commerce\": \"bg-emerald-50 text-emerald-700 border-emerald-100\",\n \"Food Delivery\": \"bg-blue-50 text-blue-700 border-blue-100\",\n \"Financial Technology\": \"bg-amber-50 text-amber-700 border-amber-100\",\n \"Workforce Management\": \"bg-violet-50 text-violet-700 border-violet-100\",\n \"Artificial Intelligence\": \"bg-rose-50 text-rose-700 border-rose-100\",\n \"Health Technology\": \"bg-orange-50 text-orange-700 border-orange-100\",\n Software: \"bg-muted text-muted-foreground border-border\",\n }\n\n return colors[industry] ?? \"bg-muted text-muted-foreground border-border\"\n}\n\nfunction toggleFilterValue(\n current: Record<string, string[]>,\n categoryId: string,\n option: string\n) {\n const currentValues = current[categoryId] ?? []\n const isActive = currentValues.includes(option)\n const nextValues = isActive\n ? currentValues.filter((value) => value !== option)\n : [...currentValues, option]\n\n return {\n ...current,\n [categoryId]: nextValues,\n }\n}\n\nfunction isRowMatchingCategoryFilter(\n row: DataRow,\n categoryId: string,\n options: string[]\n) {\n if (options.length === 0) {\n return true\n }\n\n switch (categoryId) {\n case \"industry\":\n return options.some((option) => row.industry.includes(option))\n case \"lastInteraction\":\n return options.includes(row.lastInteraction)\n case \"createdAt\":\n return options.includes(row.createdAt)\n case \"revenue\":\n return options.includes(row.revenue)\n case \"headcount\":\n return options.includes(row.headcount)\n case \"lastFunding\":\n return options.includes(row.lastFunding)\n case \"owner\":\n return options.includes(row.ownerEmail ?? row.owner)\n case \"opportunityCount\":\n return options.some((option) => {\n if (option === \"3+\") {\n return row.opportunityCount >= 3\n }\n return row.opportunityCount === Number(option)\n })\n default:\n return true\n }\n}\n\nexport interface DataTableProps {\n onRowClick?: (row: DataRow) => void\n rows?: DataRow[]\n filterCategories?: DataTableFilterCategory[]\n quickViews?: string[]\n moreQuickViews?: string[]\n quickViewFilters?: Record<string, (row: DataRow) => boolean>\n iconMap?: { salesforce?: string }\n entityUrlBuilder?: (row: DataRow) => string\n onScoreFactorFeedback?: (account: string, scoreType: string, factorKey: string, type: \"up\" | \"down\" | null, detail?: string) => void\n onScoreApproveFeedback?: (account: string, scoreType: string, reasons: string[], detail: string) => void\n onScoreDismissFeedback?: (account: string, scoreType: string, reasons: string[], detail: string) => void\n}\n\nexport function DataTable({\n onRowClick,\n rows: rowsProp,\n filterCategories: filterCategoriesProp,\n quickViews: quickViewsProp,\n moreQuickViews: moreQuickViewsProp,\n quickViewFilters: quickViewFiltersProp,\n iconMap,\n entityUrlBuilder,\n onScoreFactorFeedback,\n onScoreApproveFeedback,\n onScoreDismissFeedback,\n}: DataTableProps = {}) {\n const resolvedRows = rowsProp ?? ROWS\n const resolvedFilterCategories = filterCategoriesProp ?? FILTER_CATEGORIES\n const resolvedQuickViews = quickViewsProp ?? QUICK_VIEWS\n const resolvedMoreQuickViews = moreQuickViewsProp ?? MORE_QUICK_VIEWS\n const resolvedQuickViewFilters = quickViewFiltersProp ?? QUICK_VIEW_FILTERS\n\n const [sorting, setSorting] = React.useState<SortingState>([])\n const [columnVisibility, setColumnVisibility] = React.useState<VisibilityState>(\n DEFAULT_COLUMN_VISIBILITY\n )\n const [selectedFilters, setSelectedFilters] = React.useState<Record<string, string[]>>(\n {}\n )\n const [activeQuickView, setActiveQuickView] =\n React.useState<DataTableQuickViewValue>(null)\n const [scoreModal, setScoreModal] = React.useState<{\n row: DataRow\n type: \"Risk\" | \"Expansion\"\n } | null>(null)\n\n React.useEffect(() => {\n if (!activeQuickView) {\n return\n }\n\n setColumnVisibility((previous) => {\n const next = { ...previous }\n if (activeQuickView.includes(\"Touched\")) {\n next.lastInteraction = true\n }\n if (activeQuickView.includes(\"Growth\")) {\n next.expansionScore = true\n }\n if (activeQuickView.includes(\"risk\") || activeQuickView.includes(\"Risk\")) {\n next.riskScore = true\n }\n return next\n })\n }, [activeQuickView])\n\n const filteredRows = React.useMemo(() => {\n return resolvedRows.filter((row) => {\n const quickViewMatches = activeQuickView\n ? (resolvedQuickViewFilters[activeQuickView]?.(row) ?? true)\n : true\n\n if (!quickViewMatches) {\n return false\n }\n\n return Object.entries(selectedFilters).every(([categoryId, options]) =>\n isRowMatchingCategoryFilter(row, categoryId, options)\n )\n })\n }, [activeQuickView, selectedFilters, resolvedRows, resolvedQuickViewFilters])\n\n const columns = React.useMemo(\n () => [\n columnHelper.accessor(\"name\", {\n header: \"Entity\",\n cell: (info) => {\n const row = info.row.original\n const sfUrl = entityUrlBuilder?.(row)\n return (\n <div className=\"flex items-center gap-3\">\n <div\n className={cn(\n \"flex h-6 w-6 shrink-0 items-center justify-center rounded text-[10px] font-bold\",\n getEntityColor(row.name)\n )}\n >\n {row.name.slice(0, 1)}\n </div>\n <span className=\"text-sm font-medium text-foreground\">\n {row.name}\n </span>\n {iconMap?.salesforce && (\n <a\n href={sfUrl ?? \"#\"}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n onClick={(e) => e.stopPropagation()}\n className=\"shrink-0 text-muted-foreground hover:text-foreground transition-colors\"\n >\n <img src={iconMap.salesforce} alt=\"Salesforce\" className=\"w-4 h-4 object-contain\" />\n </a>\n )}\n </div>\n )\n },\n }),\n columnHelper.accessor(\"accountRisks\", {\n header: \"Risk Signals\",\n cell: (info) => {\n const risks = info.getValue()\n if (!risks.length) {\n return <span className=\"text-xs text-muted-foreground\">None</span>\n }\n\n return (\n <div className=\"flex items-center gap-1.5\">\n {risks.slice(0, 2).map((risk) => (\n <Badge\n key={risk}\n variant=\"outline\"\n className=\"rounded-md border-red-200 bg-red-50 px-2 py-0.5 text-xs font-normal text-red-700\"\n >\n {risk}\n </Badge>\n ))}\n </div>\n )\n },\n }),\n columnHelper.accessor(\"riskScore\", {\n id: \"riskScore\",\n header: \"Risk Score\",\n cell: (info) => (\n <div\n className=\"inline-flex cursor-pointer\"\n onClick={(e) => {\n e.stopPropagation()\n setScoreModal({ row: info.row.original, type: \"Risk\" })\n }}\n >\n <Badge\n variant=\"outline\"\n className={cn(\n \"px-2 py-0.5 text-xs font-medium hover:underline decoration-dotted underline-offset-2\",\n info.getValue() >= 60\n ? \"border-red-200 bg-red-50 text-red-700\"\n : \"border-border bg-muted/50 text-foreground\"\n )}\n >\n {info.getValue()}%\n </Badge>\n </div>\n ),\n }),\n columnHelper.accessor(\"expansionScore\", {\n id: \"expansionScore\",\n header: \"Expansion Score\",\n cell: (info) => (\n <div\n className=\"inline-flex cursor-pointer\"\n onClick={(e) => {\n e.stopPropagation()\n setScoreModal({ row: info.row.original, type: \"Expansion\" })\n }}\n >\n <Badge\n variant=\"outline\"\n className={cn(\n \"px-2 py-0.5 text-xs font-medium hover:underline decoration-dotted underline-offset-2\",\n info.getValue() >= 70\n ? \"border-blue-200 bg-blue-50 text-blue-700\"\n : \"border-border bg-muted/50 text-foreground\"\n )}\n >\n {info.getValue()}%\n </Badge>\n </div>\n ),\n }),\n columnHelper.accessor(\"growthIndicators\", {\n header: \"Growth Signals\",\n cell: (info) => {\n const indicators = info.getValue()\n if (!indicators.length) {\n return <span className=\"text-xs text-muted-foreground\">None</span>\n }\n return (\n <div className=\"flex items-center gap-1.5\">\n {indicators.slice(0, 2).map((indicator) => (\n <Badge\n key={indicator}\n variant=\"outline\"\n className=\"rounded-md border-blue-200 bg-blue-50 px-2 py-0.5 text-xs font-normal text-blue-700\"\n >\n {indicator}\n </Badge>\n ))}\n </div>\n )\n },\n }),\n columnHelper.accessor(\"industry\", {\n header: \"Industry\",\n cell: (info) => (\n <div className=\"flex items-center gap-1.5\">\n {info.getValue().slice(0, 2).map((industry) => (\n <Badge\n key={industry}\n variant=\"outline\"\n className={cn(\n \"rounded-md px-2 py-0.5 text-xs font-normal\",\n getIndustryColor(industry)\n )}\n >\n {industry}\n </Badge>\n ))}\n </div>\n ),\n }),\n columnHelper.accessor(\"lastInteraction\", {\n header: \"Last interaction\",\n cell: (info) => <span className=\"text-sm\">{info.getValue()}</span>,\n }),\n columnHelper.accessor(\"revenue\", {\n header: \"Revenue\",\n cell: (info) => (\n <span className=\"rounded-md bg-muted/50 px-2 py-0.5 text-xs font-medium\">\n {info.getValue()}\n </span>\n ),\n }),\n columnHelper.accessor(\"headcount\", {\n header: \"Headcount\",\n cell: (info) => (\n <span className=\"rounded-md bg-muted/50 px-2 py-0.5 text-xs font-medium\">\n {info.getValue()}\n </span>\n ),\n }),\n columnHelper.accessor(\"lastFunding\", {\n header: \"Last funding\",\n cell: (info) => (\n <span className=\"rounded-md bg-muted/50 px-2 py-0.5 text-xs font-medium\">\n {info.getValue()}\n </span>\n ),\n }),\n columnHelper.accessor(\"owner\", {\n header: \"Owner\",\n cell: (info) => <span className=\"text-sm\">{info.getValue()}</span>,\n }),\n columnHelper.accessor(\"opportunityCount\", {\n header: \"Opportunity count\",\n cell: (info) => (\n <span className=\"rounded-md bg-muted/50 px-2 py-0.5 text-xs font-medium\">\n {info.getValue()}\n </span>\n ),\n }),\n ],\n [iconMap, entityUrlBuilder]\n )\n\n const table = useReactTable({\n data: filteredRows,\n columns,\n state: {\n sorting,\n columnVisibility,\n },\n onSortingChange: setSorting,\n onColumnVisibilityChange: setColumnVisibility,\n getCoreRowModel: getCoreRowModel(),\n getSortedRowModel: getSortedRowModel(),\n })\n\n const displayColumns = table.getAllLeafColumns().map((column) => {\n const header = column.columnDef.header\n const label = typeof header === \"string\" ? header : column.id\n\n return {\n id: column.id,\n label,\n visible: column.getIsVisible(),\n canHide: column.getCanHide(),\n }\n })\n\n const toggleCategoryFilter = (categoryId: string, option: string) => {\n setSelectedFilters((previous) => toggleFilterValue(previous, categoryId, option))\n }\n\n return (\n <div className=\"relative flex h-full min-h-[560px] flex-col bg-background\">\n <DataTableToolbar\n categories={resolvedFilterCategories}\n selectedFilters={selectedFilters}\n onToggleFilter={toggleCategoryFilter}\n sorting={sorting}\n onSortingChange={setSorting}\n displayColumns={displayColumns}\n onToggleColumn={(columnId) => table.getColumn(columnId)?.toggleVisibility()}\n onResetDisplay={() => setColumnVisibility(DEFAULT_COLUMN_VISIBILITY)}\n />\n\n <DataTableQuickViews\n quickViews={resolvedQuickViews}\n moreViews={resolvedMoreQuickViews}\n activeView={activeQuickView}\n onViewChange={setActiveQuickView}\n />\n\n <div className=\"relative min-h-0 flex-1 overflow-auto border-t border-border\">\n <table className=\"w-max min-w-full border-collapse text-sm\">\n <thead className=\"sticky top-0 z-10 bg-background\">\n {table.getHeaderGroups().map((headerGroup) => (\n <tr key={headerGroup.id} className=\"border-b border-border\">\n {headerGroup.headers.map((header) => (\n <th\n key={header.id}\n className=\"h-10 border-r border-border px-4 text-left text-xs font-medium text-muted-foreground/80 last:border-r-0\"\n >\n {header.isPlaceholder\n ? null\n : flexRender(\n header.column.columnDef.header,\n header.getContext()\n )}\n </th>\n ))}\n </tr>\n ))}\n </thead>\n <tbody>\n {table.getRowModel().rows.length > 0 ? (\n <>\n {table.getRowModel().rows.map((row) => (\n <tr\n key={row.id}\n onClick={() => onRowClick?.(row.original)}\n className={cn(\n \"group border-b border-border/50 transition-colors hover:bg-muted/30\",\n onRowClick && \"cursor-pointer\",\n )}\n >\n {row.getVisibleCells().map((cell) => (\n <td\n key={cell.id}\n className=\"border-r border-border/40 px-4 py-2.5 align-middle last:border-r-0\"\n >\n {flexRender(cell.column.columnDef.cell, cell.getContext())}\n </td>\n ))}\n </tr>\n ))}\n <tr>\n <td\n className=\"px-4 py-2 text-xs text-muted-foreground\"\n colSpan={columns.length}\n >\n {table.getRowModel().rows.length} rows\n </td>\n </tr>\n </>\n ) : (\n <tr>\n <td colSpan={columns.length} className=\"h-52 px-4 text-center\">\n <div className=\"flex flex-col items-center gap-1 text-muted-foreground\">\n <SearchX className=\"h-7 w-7 opacity-40\" />\n <p className=\"text-sm font-medium\">No rows found</p>\n <p className=\"text-xs\">Try adjusting your filters or quick views</p>\n </div>\n </td>\n </tr>\n )}\n </tbody>\n </table>\n </div>\n\n {scoreModal && (() => {\n const data = SCORE_ANALYSIS[scoreModal.type](scoreModal.row)\n return (\n <ScoreAnalysisModal\n open\n onOpenChange={(open) => { if (!open) setScoreModal(null) }}\n title={data.title}\n description={data.description}\n score={scoreModal.type === \"Risk\" ? scoreModal.row.riskScore : scoreModal.row.expansionScore}\n scoreIntent={scoreModal.type === \"Risk\" ? \"risk\" : \"positive\"}\n whyNow={data.whyNow}\n evidence={data.evidence}\n factors={data.factors}\n onFactorFeedback={onScoreFactorFeedback\n ? (key, type, detail) => onScoreFactorFeedback(scoreModal.row.name, scoreModal.type, key, type, detail)\n : (key, type, detail) => console.log(\"Factor feedback:\", { account: scoreModal.row.name, factor: key, type, detail })\n }\n companyName={scoreModal.row.name}\n opportunityUrl={`https://acme.lightning.force.com/lightning/r/Opportunity/006${scoreModal.row.id}/view`}\n onApprove={() => console.log(\"Approved signal — creating opportunity:\", { account: scoreModal.row.name, type: scoreModal.type })}\n onApproveFeedback={onScoreApproveFeedback\n ? (reasons, detail) => onScoreApproveFeedback(scoreModal.row.name, scoreModal.type, reasons, detail)\n : (reasons, detail) => console.log(\"Approval feedback:\", { account: scoreModal.row.name, reasons, detail })\n }\n onDismiss={onScoreDismissFeedback\n ? (reasons, detail) => onScoreDismissFeedback(scoreModal.row.name, scoreModal.type, reasons, detail)\n : (reasons, detail) => console.log(\"Dismissed signal:\", { account: scoreModal.row.name, reasons, detail })\n }\n />\n )\n })()}\n </div>\n )\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { ScoreFactor } from './score-breakdown.js';
|
|
3
|
+
import { ScoreIntent } from './score-semantics.js';
|
|
3
4
|
|
|
4
5
|
interface ScoreAnalysisModalProps {
|
|
5
6
|
open: boolean;
|
|
@@ -19,8 +20,13 @@ interface ScoreAnalysisModalProps {
|
|
|
19
20
|
onDismiss?: (reasons: string[], detail: string) => void;
|
|
20
21
|
/** When true, renders as an absolute-positioned inline panel instead of a Radix Sheet portal. Useful when the component is inside a container that should not be escaped. */
|
|
21
22
|
useInlinePanel?: boolean;
|
|
23
|
+
scoreIntent?: ScoreIntent;
|
|
22
24
|
}
|
|
23
|
-
declare function
|
|
25
|
+
declare function getScoreLabel(score: number, denominator: number, intent?: ScoreIntent): {
|
|
26
|
+
text: string;
|
|
27
|
+
className: string;
|
|
28
|
+
};
|
|
29
|
+
declare function ScoreAnalysisModal({ open, onOpenChange, title, description, score, denominator, whyNow, evidence, factors, onFactorFeedback, companyName, opportunityUrl, onApprove, onApproveFeedback, onDismiss, useInlinePanel, scoreIntent, }: ScoreAnalysisModalProps): React.JSX.Element | null;
|
|
24
30
|
declare const ScoreAnalysisPanel: typeof ScoreAnalysisModal;
|
|
25
31
|
|
|
26
|
-
export { ScoreAnalysisModal, type ScoreAnalysisModalProps, ScoreAnalysisPanel };
|
|
32
|
+
export { ScoreAnalysisModal, type ScoreAnalysisModalProps, ScoreAnalysisPanel, getScoreLabel };
|