@handled-ai/design-system 0.14.6 → 0.14.8

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.
@@ -1,12 +1,16 @@
1
1
  import * as React from 'react';
2
2
 
3
+ interface FilterOption {
4
+ label: string;
5
+ value: string;
6
+ }
3
7
  interface DataTableFilterCategory {
4
8
  id: string;
5
9
  label: string;
6
10
  icon: React.ComponentType<{
7
11
  className?: string;
8
12
  }>;
9
- options: string[];
13
+ options: (string | FilterOption)[];
10
14
  }
11
15
  interface DataTableFilterProps {
12
16
  categories: DataTableFilterCategory[];
@@ -16,4 +20,4 @@ interface DataTableFilterProps {
16
20
  }
17
21
  declare function DataTableFilter({ categories, selectedFilters, onToggleFilter, className, }: DataTableFilterProps): React.JSX.Element;
18
22
 
19
- export { DataTableFilter, type DataTableFilterCategory };
23
+ export { DataTableFilter, type DataTableFilterCategory, type FilterOption };
@@ -1,6 +1,25 @@
1
1
  "use client"
2
2
 
3
3
  "use client";
4
+ var __defProp = Object.defineProperty;
5
+ var __defProps = Object.defineProperties;
6
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
7
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
10
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
11
+ var __spreadValues = (a, b) => {
12
+ for (var prop in b || (b = {}))
13
+ if (__hasOwnProp.call(b, prop))
14
+ __defNormalProp(a, prop, b[prop]);
15
+ if (__getOwnPropSymbols)
16
+ for (var prop of __getOwnPropSymbols(b)) {
17
+ if (__propIsEnum.call(b, prop))
18
+ __defNormalProp(a, prop, b[prop]);
19
+ }
20
+ return a;
21
+ };
22
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
4
23
  import { jsx, jsxs } from "react/jsx-runtime";
5
24
  import * as React from "react";
6
25
  import { ListFilter, Search } from "lucide-react";
@@ -15,6 +34,12 @@ import {
15
34
  DropdownMenuSubTrigger,
16
35
  DropdownMenuTrigger
17
36
  } from "./dropdown-menu.js";
37
+ function getOptionValue(option) {
38
+ return typeof option === "string" ? option : option.value;
39
+ }
40
+ function getOptionLabel(option) {
41
+ return typeof option === "string" ? option : option.label;
42
+ }
18
43
  function DataTableFilter({
19
44
  categories,
20
45
  selectedFilters,
@@ -22,6 +47,7 @@ function DataTableFilter({
22
47
  className
23
48
  }) {
24
49
  const [query, setQuery] = React.useState("");
50
+ const [subQueries, setSubQueries] = React.useState({});
25
51
  const visibleCategories = React.useMemo(() => {
26
52
  const normalized = query.trim().toLowerCase();
27
53
  if (!normalized) {
@@ -32,7 +58,7 @@ function DataTableFilter({
32
58
  return true;
33
59
  }
34
60
  return category.options.some(
35
- (option) => option.toLowerCase().includes(normalized)
61
+ (option) => getOptionLabel(option).toLowerCase().includes(normalized)
36
62
  );
37
63
  });
38
64
  }, [categories, query]);
@@ -76,31 +102,72 @@ function DataTableFilter({
76
102
  )
77
103
  ] }) }),
78
104
  /* @__PURE__ */ jsxs("div", { className: "max-h-[320px] overflow-y-auto p-1", children: [
79
- visibleCategories.map((category) => /* @__PURE__ */ jsxs(DropdownMenuSub, { children: [
80
- /* @__PURE__ */ jsxs(DropdownMenuSubTrigger, { className: "cursor-pointer py-1.5 text-xs", children: [
81
- /* @__PURE__ */ jsx(category.icon, { className: "mr-2 h-3.5 w-3.5 text-muted-foreground" }),
82
- category.label
83
- ] }),
84
- /* @__PURE__ */ jsx(DropdownMenuSubContent, { className: "w-52 p-1", children: category.options.map((option) => {
85
- var _a, _b;
86
- const selected = (_b = (_a = selectedFilters[category.id]) == null ? void 0 : _a.includes(option)) != null ? _b : false;
87
- return /* @__PURE__ */ jsxs(
88
- DropdownMenuItem,
89
- {
90
- className: "cursor-pointer justify-between text-xs",
91
- onSelect: (event) => {
92
- event.preventDefault();
93
- onToggleFilter(category.id, option);
94
- },
95
- children: [
96
- option,
97
- selected ? /* @__PURE__ */ jsx("span", { className: "text-[10px] font-semibold text-brand-purple", children: "Applied" }) : null
98
- ]
105
+ visibleCategories.map((category) => {
106
+ var _a, _b;
107
+ const subQuery = ((_a = subQueries[category.id]) != null ? _a : "").trim().toLowerCase();
108
+ const filteredOptions = subQuery ? category.options.filter(
109
+ (opt) => getOptionLabel(opt).toLowerCase().includes(subQuery)
110
+ ) : category.options;
111
+ return /* @__PURE__ */ jsxs(
112
+ DropdownMenuSub,
113
+ {
114
+ onOpenChange: (open) => {
115
+ if (!open) {
116
+ setSubQueries((prev) => {
117
+ const next = __spreadValues({}, prev);
118
+ delete next[category.id];
119
+ return next;
120
+ });
121
+ }
99
122
  },
100
- option
101
- );
102
- }) })
103
- ] }, category.id)),
123
+ children: [
124
+ /* @__PURE__ */ jsxs(DropdownMenuSubTrigger, { className: "cursor-pointer py-1.5 text-xs", children: [
125
+ /* @__PURE__ */ jsx(category.icon, { className: "mr-2 h-3.5 w-3.5 text-muted-foreground" }),
126
+ category.label
127
+ ] }),
128
+ /* @__PURE__ */ jsxs(DropdownMenuSubContent, { className: "max-h-[320px] w-52 overflow-y-auto p-1", children: [
129
+ category.options.length > 7 && /* @__PURE__ */ jsx("div", { className: "sticky top-0 z-10 border-b border-border bg-popover p-1.5", children: /* @__PURE__ */ jsxs("div", { className: "relative", children: [
130
+ /* @__PURE__ */ jsx(Search, { className: "absolute left-2 top-1/2 h-3 w-3 -translate-y-1/2 text-muted-foreground" }),
131
+ /* @__PURE__ */ jsx(
132
+ "input",
133
+ {
134
+ className: "h-7 w-full rounded-md bg-muted/50 py-1 pr-2 pl-7 text-xs outline-none transition-colors placeholder:text-muted-foreground/70 focus:bg-muted",
135
+ placeholder: "Search...",
136
+ value: (_b = subQueries[category.id]) != null ? _b : "",
137
+ onChange: (e) => setSubQueries((prev) => __spreadProps(__spreadValues({}, prev), { [category.id]: e.target.value })),
138
+ onClick: (e) => e.stopPropagation(),
139
+ onKeyDown: (e) => e.stopPropagation()
140
+ }
141
+ )
142
+ ] }) }),
143
+ filteredOptions.map((option) => {
144
+ var _a2, _b2;
145
+ const value = getOptionValue(option);
146
+ const label = getOptionLabel(option);
147
+ const selected = (_b2 = (_a2 = selectedFilters[category.id]) == null ? void 0 : _a2.includes(value)) != null ? _b2 : false;
148
+ return /* @__PURE__ */ jsxs(
149
+ DropdownMenuItem,
150
+ {
151
+ className: "cursor-pointer justify-between text-xs",
152
+ onSelect: (event) => {
153
+ event.preventDefault();
154
+ onToggleFilter(category.id, value);
155
+ },
156
+ children: [
157
+ label,
158
+ selected ? /* @__PURE__ */ jsx("span", { className: "text-[10px] font-semibold text-brand-purple", children: "Applied" }) : null
159
+ ]
160
+ },
161
+ value
162
+ );
163
+ }),
164
+ filteredOptions.length === 0 && category.options.length > 0 && /* @__PURE__ */ jsx("div", { className: "p-2 text-center text-xs text-muted-foreground", children: "No matches" })
165
+ ] })
166
+ ]
167
+ },
168
+ category.id
169
+ );
170
+ }),
104
171
  visibleCategories.length === 0 ? /* @__PURE__ */ jsx("div", { className: "p-2 text-center text-xs text-muted-foreground", children: "No filters found" }) : null
105
172
  ] })
106
173
  ] })
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/data-table-filter.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport { ListFilter, Search } from \"lucide-react\"\n\nimport { cn } from \"../lib/utils\"\nimport { Button } from \"./button\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSub,\n DropdownMenuSubContent,\n DropdownMenuSubTrigger,\n DropdownMenuTrigger,\n} from \"./dropdown-menu\"\n\nexport interface DataTableFilterCategory {\n id: string\n label: string\n icon: React.ComponentType<{ className?: string }>\n options: string[]\n}\n\ninterface DataTableFilterProps {\n categories: DataTableFilterCategory[]\n selectedFilters: Record<string, string[]>\n onToggleFilter: (categoryId: string, option: string) => void\n className?: string\n}\n\nexport function DataTableFilter({\n categories,\n selectedFilters,\n onToggleFilter,\n className,\n}: DataTableFilterProps) {\n const [query, setQuery] = React.useState(\"\")\n\n const visibleCategories = React.useMemo(() => {\n const normalized = query.trim().toLowerCase()\n if (!normalized) {\n return categories\n }\n\n return categories.filter((category) => {\n if (category.label.toLowerCase().includes(normalized)) {\n return true\n }\n\n return category.options.some((option) =>\n option.toLowerCase().includes(normalized)\n )\n })\n }, [categories, query])\n\n const activeCount = React.useMemo(\n () =>\n Object.values(selectedFilters).reduce(\n (count, selected) => count + selected.length,\n 0\n ),\n [selectedFilters]\n )\n\n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"outline\"\n size=\"sm\"\n className={cn(\n \"h-8 gap-2 rounded-md border-border/60 bg-background text-xs font-normal shadow-none hover:bg-muted/50\",\n className\n )}\n >\n <ListFilter className=\"h-3.5 w-3.5\" />\n Filter\n {activeCount > 0 ? (\n <span className=\"rounded bg-muted px-1.5 py-0 text-[10px] font-semibold\">\n {activeCount}\n </span>\n ) : null}\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\" className=\"w-[240px] p-0\">\n <div className=\"sticky top-0 z-10 border-b border-border bg-popover p-2\">\n <div className=\"relative\">\n <Search className=\"absolute left-2 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-muted-foreground\" />\n <input\n className=\"h-8 w-full rounded-md bg-muted/50 py-1 pr-2 pl-7 text-xs outline-none transition-colors placeholder:text-muted-foreground/70 focus:bg-muted\"\n placeholder=\"Search filters...\"\n value={query}\n onChange={(event) => setQuery(event.target.value)}\n onClick={(event) => event.stopPropagation()}\n onKeyDown={(event) => event.stopPropagation()}\n />\n </div>\n </div>\n\n <div className=\"max-h-[320px] overflow-y-auto p-1\">\n {visibleCategories.map((category) => (\n <DropdownMenuSub key={category.id}>\n <DropdownMenuSubTrigger className=\"cursor-pointer py-1.5 text-xs\">\n <category.icon className=\"mr-2 h-3.5 w-3.5 text-muted-foreground\" />\n {category.label}\n </DropdownMenuSubTrigger>\n <DropdownMenuSubContent className=\"w-52 p-1\">\n {category.options.map((option) => {\n const selected =\n selectedFilters[category.id]?.includes(option) ?? false\n\n return (\n <DropdownMenuItem\n key={option}\n className=\"cursor-pointer justify-between text-xs\"\n onSelect={(event) => {\n event.preventDefault()\n onToggleFilter(category.id, option)\n }}\n >\n {option}\n {selected ? (\n <span className=\"text-[10px] font-semibold text-brand-purple\">\n Applied\n </span>\n ) : null}\n </DropdownMenuItem>\n )\n })}\n </DropdownMenuSubContent>\n </DropdownMenuSub>\n ))}\n\n {visibleCategories.length === 0 ? (\n <div className=\"p-2 text-center text-xs text-muted-foreground\">\n No filters found\n </div>\n ) : null}\n </div>\n </DropdownMenuContent>\n </DropdownMenu>\n )\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/components/data-table-filter.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport { ListFilter, Search } from \"lucide-react\"\n\nimport { cn } from \"../lib/utils\"\nimport { Button } from \"./button\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSub,\n DropdownMenuSubContent,\n DropdownMenuSubTrigger,\n DropdownMenuTrigger,\n} from \"./dropdown-menu\"\n\nexport interface FilterOption {\n label: string\n value: string\n}\n\nexport interface DataTableFilterCategory {\n id: string\n label: string\n icon: React.ComponentType<{ className?: string }>\n options: (string | FilterOption)[]\n}\n\nfunction getOptionValue(option: string | FilterOption): string {\n return typeof option === \"string\" ? option : option.value\n}\nfunction getOptionLabel(option: string | FilterOption): string {\n return typeof option === \"string\" ? option : option.label\n}\n\ninterface DataTableFilterProps {\n categories: DataTableFilterCategory[]\n selectedFilters: Record<string, string[]>\n onToggleFilter: (categoryId: string, option: string) => void\n className?: string\n}\n\nexport function DataTableFilter({\n categories,\n selectedFilters,\n onToggleFilter,\n className,\n}: DataTableFilterProps) {\n const [query, setQuery] = React.useState(\"\")\n const [subQueries, setSubQueries] = React.useState<Record<string, string>>({})\n\n const visibleCategories = React.useMemo(() => {\n const normalized = query.trim().toLowerCase()\n if (!normalized) {\n return categories\n }\n\n return categories.filter((category) => {\n if (category.label.toLowerCase().includes(normalized)) {\n return true\n }\n\n return category.options.some((option) =>\n getOptionLabel(option).toLowerCase().includes(normalized)\n )\n })\n }, [categories, query])\n\n const activeCount = React.useMemo(\n () =>\n Object.values(selectedFilters).reduce(\n (count, selected) => count + selected.length,\n 0\n ),\n [selectedFilters]\n )\n\n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"outline\"\n size=\"sm\"\n className={cn(\n \"h-8 gap-2 rounded-md border-border/60 bg-background text-xs font-normal shadow-none hover:bg-muted/50\",\n className\n )}\n >\n <ListFilter className=\"h-3.5 w-3.5\" />\n Filter\n {activeCount > 0 ? (\n <span className=\"rounded bg-muted px-1.5 py-0 text-[10px] font-semibold\">\n {activeCount}\n </span>\n ) : null}\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\" className=\"w-[240px] p-0\">\n <div className=\"sticky top-0 z-10 border-b border-border bg-popover p-2\">\n <div className=\"relative\">\n <Search className=\"absolute left-2 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-muted-foreground\" />\n <input\n className=\"h-8 w-full rounded-md bg-muted/50 py-1 pr-2 pl-7 text-xs outline-none transition-colors placeholder:text-muted-foreground/70 focus:bg-muted\"\n placeholder=\"Search filters...\"\n value={query}\n onChange={(event) => setQuery(event.target.value)}\n onClick={(event) => event.stopPropagation()}\n onKeyDown={(event) => event.stopPropagation()}\n />\n </div>\n </div>\n\n <div className=\"max-h-[320px] overflow-y-auto p-1\">\n {visibleCategories.map((category) => {\n const subQuery = (subQueries[category.id] ?? \"\").trim().toLowerCase()\n const filteredOptions = subQuery\n ? category.options.filter((opt) =>\n getOptionLabel(opt).toLowerCase().includes(subQuery)\n )\n : category.options\n\n return (\n <DropdownMenuSub\n key={category.id}\n onOpenChange={(open) => {\n if (!open) {\n setSubQueries((prev) => {\n const next = { ...prev }\n delete next[category.id]\n return next\n })\n }\n }}\n >\n <DropdownMenuSubTrigger className=\"cursor-pointer py-1.5 text-xs\">\n <category.icon className=\"mr-2 h-3.5 w-3.5 text-muted-foreground\" />\n {category.label}\n </DropdownMenuSubTrigger>\n <DropdownMenuSubContent className=\"max-h-[320px] w-52 overflow-y-auto p-1\">\n {/* Submenu search — only for categories with many options */}\n {category.options.length > 7 && (\n <div className=\"sticky top-0 z-10 border-b border-border bg-popover p-1.5\">\n <div className=\"relative\">\n <Search className=\"absolute left-2 top-1/2 h-3 w-3 -translate-y-1/2 text-muted-foreground\" />\n <input\n className=\"h-7 w-full rounded-md bg-muted/50 py-1 pr-2 pl-7 text-xs outline-none transition-colors placeholder:text-muted-foreground/70 focus:bg-muted\"\n placeholder=\"Search...\"\n value={subQueries[category.id] ?? \"\"}\n onChange={(e) =>\n setSubQueries((prev) => ({ ...prev, [category.id]: e.target.value }))\n }\n onClick={(e) => e.stopPropagation()}\n onKeyDown={(e) => e.stopPropagation()}\n />\n </div>\n </div>\n )}\n {/* Filtered options */}\n {filteredOptions.map((option) => {\n const value = getOptionValue(option)\n const label = getOptionLabel(option)\n const selected = selectedFilters[category.id]?.includes(value) ?? false\n return (\n <DropdownMenuItem\n key={value}\n className=\"cursor-pointer justify-between text-xs\"\n onSelect={(event) => {\n event.preventDefault()\n onToggleFilter(category.id, value)\n }}\n >\n {label}\n {selected ? (\n <span className=\"text-[10px] font-semibold text-brand-purple\">\n Applied\n </span>\n ) : null}\n </DropdownMenuItem>\n )\n })}\n {filteredOptions.length === 0 && category.options.length > 0 && (\n <div className=\"p-2 text-center text-xs text-muted-foreground\">\n No matches\n </div>\n )}\n </DropdownMenuSubContent>\n </DropdownMenuSub>\n )\n })}\n\n {visibleCategories.length === 0 ? (\n <div className=\"p-2 text-center text-xs text-muted-foreground\">\n No filters found\n </div>\n ) : null}\n </div>\n </DropdownMenuContent>\n </DropdownMenu>\n )\n}\n"],"mappings":"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","names":["_a","_b"]}
@@ -16,6 +16,7 @@ type DataRow = {
16
16
  headcount: string;
17
17
  lastFunding: string;
18
18
  owner: string;
19
+ ownerEmail?: string;
19
20
  opportunityCount: number;
20
21
  productAdoptionScore: number;
21
22
  sourceSystem?: string;
@@ -436,6 +436,7 @@ function toggleFilterValue(current, categoryId, option) {
436
436
  });
437
437
  }
438
438
  function isRowMatchingCategoryFilter(row, categoryId, options) {
439
+ var _a;
439
440
  if (options.length === 0) {
440
441
  return true;
441
442
  }
@@ -453,7 +454,7 @@ function isRowMatchingCategoryFilter(row, categoryId, options) {
453
454
  case "lastFunding":
454
455
  return options.includes(row.lastFunding);
455
456
  case "owner":
456
- return options.includes(row.owner);
457
+ return options.includes((_a = row.ownerEmail) != null ? _a : row.owner);
457
458
  case "opportunityCount":
458
459
  return options.some((option) => {
459
460
  if (option === "3+") {
@@ -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 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 &rarr; 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.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":";;;;;;;;;;;;;;;;;;;;AA0VM,mBAAoB,KAApB;AAxVN,YAAY,WAAW;AACvB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAGK;AAEP,SAAS,UAAU;AACnB,SAAS,aAAa;AACtB;AAAA,EACE;AAAA,OAEK;AACP,SAAS,wBAAwB;AAEjC,SAAS,0BAA0B;AAEnC,SAAS,gBAAgC;AAuBzC,MAAM,cAAc;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,MAAM,mBAAmB;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,MAAM,oBAA+C;AAAA,EACnD;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,MAAM;AAAA,IACN,SAAS;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,MAAM;AAAA,IACN,SAAS,CAAC,aAAa,cAAc,cAAc,eAAe,cAAc;AAAA,EAClF;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,MAAM;AAAA,IACN,SAAS,CAAC,gBAAgB,gBAAgB,aAAa,WAAW;AAAA,EACpE;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,MAAM;AAAA,IACN,SAAS,CAAC,YAAY,cAAc,eAAe,OAAO;AAAA,EAC5D;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,MAAM;AAAA,IACN,SAAS,CAAC,SAAS,UAAU,WAAW,YAAY,OAAO;AAAA,EAC7D;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,MAAM;AAAA,IACN,SAAS,CAAC,QAAQ,YAAY,YAAY,aAAa,aAAa;AAAA,EACtE;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,MAAM;AAAA,IACN,SAAS,CAAC,WAAW,eAAe,eAAe,aAAa;AAAA,EAClE;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,MAAM;AAAA,IACN,SAAS,CAAC,KAAK,KAAK,KAAK,IAAI;AAAA,EAC/B;AACF;AAEA,MAAM,OAAkB;AAAA,EACtB;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,UAAU,CAAC,cAAc,iBAAiB,sBAAsB;AAAA,IAChE,cAAc,CAAC,eAAe,gBAAgB;AAAA,IAC9C,WAAW;AAAA,IACX,gBAAgB;AAAA,IAChB,kBAAkB,CAAC,gBAAgB,gBAAgB;AAAA,IACnD,iBAAiB;AAAA,IACjB,qBAAqB;AAAA,IACrB,WAAW;AAAA,IACX,SAAS;AAAA,IACT,WAAW;AAAA,IACX,aAAa;AAAA,IACb,OAAO;AAAA,IACP,kBAAkB;AAAA,IAClB,sBAAsB;AAAA,EACxB;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,UAAU,CAAC,UAAU;AAAA,IACrB,cAAc,CAAC,eAAe,gBAAgB;AAAA,IAC9C,WAAW;AAAA,IACX,gBAAgB;AAAA,IAChB,kBAAkB,CAAC;AAAA,IACnB,iBAAiB;AAAA,IACjB,qBAAqB;AAAA,IACrB,WAAW;AAAA,IACX,SAAS;AAAA,IACT,WAAW;AAAA,IACX,aAAa;AAAA,IACb,OAAO;AAAA,IACP,kBAAkB;AAAA,IAClB,sBAAsB;AAAA,EACxB;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,UAAU,CAAC,2BAA2B,mBAAmB;AAAA,IACzD,cAAc,CAAC,kBAAkB,uBAAuB;AAAA,IACxD,WAAW;AAAA,IACX,gBAAgB;AAAA,IAChB,kBAAkB,CAAC,kBAAkB,qBAAqB;AAAA,IAC1D,iBAAiB;AAAA,IACjB,qBAAqB;AAAA,IACrB,WAAW;AAAA,IACX,SAAS;AAAA,IACT,WAAW;AAAA,IACX,aAAa;AAAA,IACb,OAAO;AAAA,IACP,kBAAkB;AAAA,IAClB,sBAAsB;AAAA,EACxB;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,UAAU,CAAC,UAAU;AAAA,IACrB,cAAc,CAAC;AAAA,IACf,WAAW;AAAA,IACX,gBAAgB;AAAA,IAChB,kBAAkB,CAAC,kBAAkB,qBAAqB;AAAA,IAC1D,iBAAiB;AAAA,IACjB,qBAAqB;AAAA,IACrB,WAAW;AAAA,IACX,SAAS;AAAA,IACT,WAAW;AAAA,IACX,aAAa;AAAA,IACb,OAAO;AAAA,IACP,kBAAkB;AAAA,IAClB,sBAAsB;AAAA,EACxB;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,UAAU,CAAC,UAAU;AAAA,IACrB,cAAc,CAAC;AAAA,IACf,WAAW;AAAA,IACX,gBAAgB;AAAA,IAChB,kBAAkB,CAAC,kBAAkB,gBAAgB;AAAA,IACrD,iBAAiB;AAAA,IACjB,qBAAqB;AAAA,IACrB,WAAW;AAAA,IACX,SAAS;AAAA,IACT,WAAW;AAAA,IACX,aAAa;AAAA,IACb,OAAO;AAAA,IACP,kBAAkB;AAAA,IAClB,sBAAsB;AAAA,EACxB;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,UAAU,CAAC,sBAAsB;AAAA,IACjC,cAAc,CAAC;AAAA,IACf,WAAW;AAAA,IACX,gBAAgB;AAAA,IAChB,kBAAkB,CAAC,kBAAkB,qBAAqB;AAAA,IAC1D,iBAAiB;AAAA,IACjB,qBAAqB;AAAA,IACrB,WAAW;AAAA,IACX,SAAS;AAAA,IACT,WAAW;AAAA,IACX,aAAa;AAAA,IACb,OAAO;AAAA,IACP,kBAAkB;AAAA,IAClB,sBAAsB;AAAA,EACxB;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,UAAU,CAAC,UAAU,UAAU;AAAA,IAC/B,cAAc,CAAC;AAAA,IACf,WAAW;AAAA,IACX,gBAAgB;AAAA,IAChB,kBAAkB,CAAC,uBAAuB,cAAc;AAAA,IACxD,iBAAiB;AAAA,IACjB,qBAAqB;AAAA,IACrB,WAAW;AAAA,IACX,SAAS;AAAA,IACT,WAAW;AAAA,IACX,aAAa;AAAA,IACb,OAAO;AAAA,IACP,kBAAkB;AAAA,IAClB,sBAAsB;AAAA,EACxB;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,UAAU,CAAC,UAAU;AAAA,IACrB,cAAc,CAAC,uBAAuB;AAAA,IACtC,WAAW;AAAA,IACX,gBAAgB;AAAA,IAChB,kBAAkB,CAAC,uBAAuB,cAAc;AAAA,IACxD,iBAAiB;AAAA,IACjB,qBAAqB;AAAA,IACrB,WAAW;AAAA,IACX,SAAS;AAAA,IACT,WAAW;AAAA,IACX,aAAa;AAAA,IACb,OAAO;AAAA,IACP,kBAAkB;AAAA,IAClB,sBAAsB;AAAA,EACxB;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,UAAU,CAAC,UAAU;AAAA,IACrB,cAAc,CAAC;AAAA,IACf,WAAW;AAAA,IACX,gBAAgB;AAAA,IAChB,kBAAkB,CAAC;AAAA,IACnB,iBAAiB;AAAA,IACjB,qBAAqB;AAAA,IACrB,WAAW;AAAA,IACX,SAAS;AAAA,IACT,WAAW;AAAA,IACX,aAAa;AAAA,IACb,OAAO;AAAA,IACP,kBAAkB;AAAA,IAClB,sBAAsB;AAAA,EACxB;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,UAAU,CAAC,UAAU;AAAA,IACrB,cAAc,CAAC;AAAA,IACf,WAAW;AAAA,IACX,gBAAgB;AAAA,IAChB,kBAAkB,CAAC,kBAAkB,qBAAqB;AAAA,IAC1D,iBAAiB;AAAA,IACjB,qBAAqB;AAAA,IACrB,WAAW;AAAA,IACX,SAAS;AAAA,IACT,WAAW;AAAA,IACX,aAAa;AAAA,IACb,OAAO;AAAA,IACP,kBAAkB;AAAA,IAClB,sBAAsB;AAAA,EACxB;AACF;AAUA,MAAM,eAA4B;AAAA,EAChC,EAAE,IAAI,GAAG,SAAS,kFAAkF,MAAM,gCAAkC;AAAA,EAC5I,EAAE,IAAI,GAAG,SAAS,wEAAwE,MAAM,sBAAwB;AAAA,EACxH,EAAE,IAAI,GAAG,SAAS,qFAAqF,MAAM,2BAA6B;AAC5I;AAEA,MAAM,oBAAiC;AAAA,EACrC,EAAE,IAAI,GAAG,SAAS,wFAAwF,MAAM,gCAAkC;AAAA,EAClJ,EAAE,IAAI,GAAG,SAAS,8EAA8E,MAAM,sBAAwB;AAAA,EAC9H,EAAE,IAAI,GAAG,SAAS,uEAAuE,MAAM,8BAAgC;AACjI;AAEA,MAAM,iBAAsE;AAAA,EAC1E,MAAM,CAAC,SAAS;AAAA,IACd,OAAO;AAAA,IACP,aACE;AAAA,IACF,QACE,IAAI,aAAa,KACb,sFACA;AAAA,IACN,UAAU;AAAA,MACR,iCAAE;AAAA;AAAA,QAAkB,oBAAC,UAAK,WAAU,+BAA8B,wCAA0B;AAAA,QAAO;AAAA,QAAuB,oBAAC,YAAS,QAAQ,GAAG,QAAQ,aAAa,CAAC,GAAG;AAAA,SAAE;AAAA,MAC1K,iCAAE;AAAA;AAAA,QAAW,oBAAC,UAAK,WAAU,+BAA8B,qCAAuB;AAAA,QAAO;AAAA,QAAuB,oBAAC,YAAS,QAAQ,GAAG,QAAQ,aAAa,CAAC,GAAG;AAAA,SAAE;AAAA,MAChK,iCAAE;AAAA;AAAA,QAAsE,oBAAC,YAAS,QAAQ,GAAG,QAAQ,aAAa,CAAC,GAAG;AAAA,SAAE;AAAA,IAC1H;AAAA,IACA,SAAS;AAAA,MACP,EAAE,KAAK,cAAc,OAAO,mBAAmB,OAAO,KAAK,IAAI,IAAI,YAAY,IAAI,GAAG,GAAG,KAAK,qDAAqD;AAAA,MACnJ,EAAE,KAAK,WAAW,OAAO,gBAAgB,OAAO,KAAK,IAAI,IAAI,YAAY,GAAG,GAAG,GAAG,KAAK,2CAA2C;AAAA,MAClI,EAAE,KAAK,eAAe,OAAO,oBAAoB,OAAO,MAAM,MAAM,IAAI,aAAa,KAAK,SAAkB,OAAgB,KAAK,uDAAuD;AAAA,MACxL,EAAE,KAAK,SAAS,OAAO,iBAAiB,OAAO,KAAK,IAAI,MAAM,IAAI,WAAW,EAAE,GAAG,KAAK,2CAA2C;AAAA,IACpI;AAAA,EACF;AAAA,EACA,WAAW,CAAC,SAAS;AAAA,IACnB,OAAO;AAAA,IACP,aACE;AAAA,IACF,QACE,IAAI,kBAAkB,KAClB,0FACA;AAAA,IACN,UAAU;AAAA,MACR,iCAAE;AAAA;AAAA,QAA2B,oBAAC,UAAK,WAAU,+BAA8B,6BAAe;AAAA,QAAO;AAAA,QAAiB,oBAAC,YAAS,QAAQ,GAAG,QAAQ,kBAAkB,CAAC,GAAG;AAAA,SAAE;AAAA,MACvK,iCAAE;AAAA;AAAA,QAAS,oBAAC,UAAK,WAAU,+BAA8B,8BAAgB;AAAA,QAAO;AAAA,QAAsC,oBAAC,YAAS,QAAQ,GAAG,QAAQ,kBAAkB,CAAC,GAAG;AAAA,SAAE;AAAA,MAC3K,iCAAE;AAAA;AAAA,QAAO,oBAAC,UAAK,WAAU,+BAA8B,4BAAc;AAAA,QAAO;AAAA,QAAoC,oBAAC,YAAS,QAAQ,GAAG,QAAQ,kBAAkB,CAAC,GAAG;AAAA,SAAE;AAAA,IACvK;AAAA,IACA,SAAS;AAAA,MACP,EAAE,KAAK,eAAe,OAAO,eAAe,OAAO,KAAK,IAAI,IAAI,iBAAiB,GAAG,GAAG,GAAG,KAAK,+CAA+C;AAAA,MAC9I,EAAE,KAAK,UAAU,OAAO,kBAAkB,OAAO,IAAI,gBAAgB,KAAK,IAAI,iBAAiB,SAAS,IAAI,IAAI,iBAAiB,KAAK,IAAI,IAAI,cAAc,2BAA2B;AAAA,MACvL,EAAE,KAAK,OAAO,OAAO,eAAe,OAAO,KAAK,IAAI,IAAI,iBAAiB,IAAI,GAAG,GAAG,KAAK,6CAA6C;AAAA,MACrI,EAAE,KAAK,UAAU,OAAO,UAAU,OAAO,MAAM,MAAM,IAAI,kBAAkB,KAAK,QAAiB,UAAmB,KAAK,8CAA8C;AAAA,IACzK;AAAA,EACF;AACF;AAEA,MAAM,qBAAgE;AAAA,EACpE,2BAA2B,CAAC,QAAQ,IAAI,aAAa;AAAA,EACrD,2BAA2B,CAAC,QAAQ,IAAI,uBAAuB;AAAA,EAC/D,6BAA6B,CAAC,QAC5B,IAAI,mBAAmB,KAAK,IAAI,uBAAuB;AAAA,EACzD,0BAA0B,CAAC,QAAQ,IAAI,kBAAkB;AAAA,EACzD,wBAAwB,CAAC,QAAQ,IAAI,wBAAwB;AAAA,EAC7D,4BAA4B,CAAC,QAAQ,IAAI,uBAAuB;AAAA,EAChE,yBAAyB,CAAC,QAAQ,IAAI,aAAa;AAAA,EACnD,wBAAwB,CAAC,QACvB,IAAI,aAAa,KAAK,CAAC,SAAS,KAAK,YAAY,EAAE,SAAS,SAAS,CAAC;AAAA,EACxE,uBAAuB,CAAC,QAAQ,IAAI,kBAAkB;AAAA,EACtD,yBAAyB,CAAC,QAAQ,IAAI,qBAAqB;AAAA,EAC3D,4BAA4B,CAAC,QAC3B,IAAI,aAAa,KAAK,CAAC,SAAS,KAAK,YAAY,EAAE,SAAS,YAAY,CAAC;AAC7E;AAEA,MAAM,eAAe,mBAA4B;AAEjD,MAAM,4BAA6C;AAAA,EACjD,UAAU;AAAA,EACV,iBAAiB;AAAA,EACjB,SAAS;AAAA,EACT,WAAW;AAAA,EACX,aAAa;AAAA,EACb,OAAO;AAAA,EACP,kBAAkB;AACpB;AAEA,SAAS,eAAe,MAAc;AACpC,QAAM,SAAS;AAAA,IACb;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,MAAI,OAAO;AACX,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK,GAAG;AACvC,WAAO,KAAK,WAAW,CAAC,MAAM,QAAQ,KAAK;AAAA,EAC7C;AACA,SAAO,OAAO,KAAK,IAAI,IAAI,IAAI,OAAO,MAAM;AAC9C;AAEA,SAAS,iBAAiB,UAAkB;AAza5C;AA0aE,QAAM,SAAiC;AAAA,IACrC,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,wBAAwB;AAAA,IACxB,wBAAwB;AAAA,IACxB,2BAA2B;AAAA,IAC3B,qBAAqB;AAAA,IACrB,UAAU;AAAA,EACZ;AAEA,UAAO,YAAO,QAAQ,MAAf,YAAoB;AAC7B;AAEA,SAAS,kBACP,SACA,YACA,QACA;AA3bF;AA4bE,QAAM,iBAAgB,aAAQ,UAAU,MAAlB,YAAuB,CAAC;AAC9C,QAAM,WAAW,cAAc,SAAS,MAAM;AAC9C,QAAM,aAAa,WACf,cAAc,OAAO,CAAC,UAAU,UAAU,MAAM,IAChD,CAAC,GAAG,eAAe,MAAM;AAE7B,SAAO,iCACF,UADE;AAAA,IAEL,CAAC,UAAU,GAAG;AAAA,EAChB;AACF;AAEA,SAAS,4BACP,KACA,YACA,SACA;AACA,MAAI,QAAQ,WAAW,GAAG;AACxB,WAAO;AAAA,EACT;AAEA,UAAQ,YAAY;AAAA,IAClB,KAAK;AACH,aAAO,QAAQ,KAAK,CAAC,WAAW,IAAI,SAAS,SAAS,MAAM,CAAC;AAAA,IAC/D,KAAK;AACH,aAAO,QAAQ,SAAS,IAAI,eAAe;AAAA,IAC7C,KAAK;AACH,aAAO,QAAQ,SAAS,IAAI,SAAS;AAAA,IACvC,KAAK;AACH,aAAO,QAAQ,SAAS,IAAI,OAAO;AAAA,IACrC,KAAK;AACH,aAAO,QAAQ,SAAS,IAAI,SAAS;AAAA,IACvC,KAAK;AACH,aAAO,QAAQ,SAAS,IAAI,WAAW;AAAA,IACzC,KAAK;AACH,aAAO,QAAQ,SAAS,IAAI,KAAK;AAAA,IACnC,KAAK;AACH,aAAO,QAAQ,KAAK,CAAC,WAAW;AAC9B,YAAI,WAAW,MAAM;AACnB,iBAAO,IAAI,oBAAoB;AAAA,QACjC;AACA,eAAO,IAAI,qBAAqB,OAAO,MAAM;AAAA,MAC/C,CAAC;AAAA,IACH;AACE,aAAO;AAAA,EACX;AACF;AAgBO,SAAS,UAAU;AAAA,EACxB;AAAA,EACA,MAAM;AAAA,EACN,kBAAkB;AAAA,EAClB,YAAY;AAAA,EACZ,gBAAgB;AAAA,EAChB,kBAAkB;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,IAAoB,CAAC,GAAG;AACtB,QAAM,eAAe,8BAAY;AACjC,QAAM,2BAA2B,sDAAwB;AACzD,QAAM,qBAAqB,0CAAkB;AAC7C,QAAM,yBAAyB,kDAAsB;AACrD,QAAM,2BAA2B,sDAAwB;AAEzD,QAAM,CAAC,SAAS,UAAU,IAAI,MAAM,SAAuB,CAAC,CAAC;AAC7D,QAAM,CAAC,kBAAkB,mBAAmB,IAAI,MAAM;AAAA,IACpD;AAAA,EACF;AACA,QAAM,CAAC,iBAAiB,kBAAkB,IAAI,MAAM;AAAA,IAClD,CAAC;AAAA,EACH;AACA,QAAM,CAAC,iBAAiB,kBAAkB,IACxC,MAAM,SAAkC,IAAI;AAC9C,QAAM,CAAC,YAAY,aAAa,IAAI,MAAM,SAGhC,IAAI;AAEd,QAAM,UAAU,MAAM;AACpB,QAAI,CAAC,iBAAiB;AACpB;AAAA,IACF;AAEA,wBAAoB,CAAC,aAAa;AAChC,YAAM,OAAO,mBAAK;AAClB,UAAI,gBAAgB,SAAS,SAAS,GAAG;AACvC,aAAK,kBAAkB;AAAA,MACzB;AACA,UAAI,gBAAgB,SAAS,QAAQ,GAAG;AACtC,aAAK,iBAAiB;AAAA,MACxB;AACA,UAAI,gBAAgB,SAAS,MAAM,KAAK,gBAAgB,SAAS,MAAM,GAAG;AACxE,aAAK,YAAY;AAAA,MACnB;AACA,aAAO;AAAA,IACT,CAAC;AAAA,EACH,GAAG,CAAC,eAAe,CAAC;AAEpB,QAAM,eAAe,MAAM,QAAQ,MAAM;AACvC,WAAO,aAAa,OAAO,CAAC,QAAQ;AAhjBxC;AAijBM,YAAM,mBAAmB,mBACpB,oCAAyB,qBAAzB,kDAA4C,SAA5C,YAAoD,OACrD;AAEJ,UAAI,CAAC,kBAAkB;AACrB,eAAO;AAAA,MACT;AAEA,aAAO,OAAO,QAAQ,eAAe,EAAE;AAAA,QAAM,CAAC,CAAC,YAAY,OAAO,MAChE,4BAA4B,KAAK,YAAY,OAAO;AAAA,MACtD;AAAA,IACF,CAAC;AAAA,EACH,GAAG,CAAC,iBAAiB,iBAAiB,cAAc,wBAAwB,CAAC;AAE7E,QAAM,UAAU,MAAM;AAAA,IACpB,MAAM;AAAA,MACJ,aAAa,SAAS,QAAQ;AAAA,QAC5B,QAAQ;AAAA,QACR,MAAM,CAAC,SAAS;AACd,gBAAM,MAAM,KAAK,IAAI;AACrB,gBAAM,QAAQ,qDAAmB;AACjC,iBACE,qBAAC,SAAI,WAAU,2BACb;AAAA;AAAA,cAAC;AAAA;AAAA,gBACC,WAAW;AAAA,kBACT;AAAA,kBACA,eAAe,IAAI,IAAI;AAAA,gBACzB;AAAA,gBAEC,cAAI,KAAK,MAAM,GAAG,CAAC;AAAA;AAAA,YACtB;AAAA,YACA,oBAAC,UAAK,WAAU,uCACb,cAAI,MACP;AAAA,aACC,mCAAS,eACR;AAAA,cAAC;AAAA;AAAA,gBACC,MAAM,wBAAS;AAAA,gBACf,QAAO;AAAA,gBACP,KAAI;AAAA,gBACJ,SAAS,CAAC,MAAM,EAAE,gBAAgB;AAAA,gBAClC,WAAU;AAAA,gBAEV,8BAAC,SAAI,KAAK,QAAQ,YAAY,KAAI,cAAa,WAAU,0BAAyB;AAAA;AAAA,YACpF;AAAA,aAEJ;AAAA,QAEJ;AAAA,MACF,CAAC;AAAA,MACD,aAAa,SAAS,gBAAgB;AAAA,QACpC,QAAQ;AAAA,QACR,MAAM,CAAC,SAAS;AACd,gBAAM,QAAQ,KAAK,SAAS;AAC5B,cAAI,CAAC,MAAM,QAAQ;AACjB,mBAAO,oBAAC,UAAK,WAAU,iCAAgC,kBAAI;AAAA,UAC7D;AAEA,iBACE,oBAAC,SAAI,WAAU,6BACZ,gBAAM,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,SACtB;AAAA,YAAC;AAAA;AAAA,cAEC,SAAQ;AAAA,cACR,WAAU;AAAA,cAET;AAAA;AAAA,YAJI;AAAA,UAKP,CACD,GACH;AAAA,QAEJ;AAAA,MACF,CAAC;AAAA,MACD,aAAa,SAAS,aAAa;AAAA,QACjC,IAAI;AAAA,QACJ,QAAQ;AAAA,QACR,MAAM,CAAC,SACL;AAAA,UAAC;AAAA;AAAA,YACC,WAAU;AAAA,YACV,SAAS,CAAC,MAAM;AACd,gBAAE,gBAAgB;AAClB,4BAAc,EAAE,KAAK,KAAK,IAAI,UAAU,MAAM,OAAO,CAAC;AAAA,YACxD;AAAA,YAEA;AAAA,cAAC;AAAA;AAAA,gBACC,SAAQ;AAAA,gBACR,WAAW;AAAA,kBACT;AAAA,kBACA,KAAK,SAAS,KAAK,KACf,0CACA;AAAA,gBACN;AAAA,gBAEC;AAAA,uBAAK,SAAS;AAAA,kBAAE;AAAA;AAAA;AAAA,YACnB;AAAA;AAAA,QACF;AAAA,MAEJ,CAAC;AAAA,MACD,aAAa,SAAS,kBAAkB;AAAA,QACtC,IAAI;AAAA,QACJ,QAAQ;AAAA,QACR,MAAM,CAAC,SACL;AAAA,UAAC;AAAA;AAAA,YACC,WAAU;AAAA,YACV,SAAS,CAAC,MAAM;AACd,gBAAE,gBAAgB;AAClB,4BAAc,EAAE,KAAK,KAAK,IAAI,UAAU,MAAM,YAAY,CAAC;AAAA,YAC7D;AAAA,YAEA;AAAA,cAAC;AAAA;AAAA,gBACC,SAAQ;AAAA,gBACR,WAAW;AAAA,kBACT;AAAA,kBACA,KAAK,SAAS,KAAK,KACf,6CACA;AAAA,gBACN;AAAA,gBAEC;AAAA,uBAAK,SAAS;AAAA,kBAAE;AAAA;AAAA;AAAA,YACnB;AAAA;AAAA,QACF;AAAA,MAEJ,CAAC;AAAA,MACD,aAAa,SAAS,oBAAoB;AAAA,QACxC,QAAQ;AAAA,QACR,MAAM,CAAC,SAAS;AACd,gBAAM,aAAa,KAAK,SAAS;AACjC,cAAI,CAAC,WAAW,QAAQ;AACtB,mBAAO,oBAAC,UAAK,WAAU,iCAAgC,kBAAI;AAAA,UAC7D;AACA,iBACE,oBAAC,SAAI,WAAU,6BACZ,qBAAW,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,cAC3B;AAAA,YAAC;AAAA;AAAA,cAEC,SAAQ;AAAA,cACR,WAAU;AAAA,cAET;AAAA;AAAA,YAJI;AAAA,UAKP,CACD,GACH;AAAA,QAEJ;AAAA,MACF,CAAC;AAAA,MACD,aAAa,SAAS,YAAY;AAAA,QAChC,QAAQ;AAAA,QACR,MAAM,CAAC,SACL,oBAAC,SAAI,WAAU,6BACZ,eAAK,SAAS,EAAE,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,aAChC;AAAA,UAAC;AAAA;AAAA,YAEC,SAAQ;AAAA,YACR,WAAW;AAAA,cACT;AAAA,cACA,iBAAiB,QAAQ;AAAA,YAC3B;AAAA,YAEC;AAAA;AAAA,UAPI;AAAA,QAQP,CACD,GACH;AAAA,MAEJ,CAAC;AAAA,MACD,aAAa,SAAS,mBAAmB;AAAA,QACvC,QAAQ;AAAA,QACR,MAAM,CAAC,SAAS,oBAAC,UAAK,WAAU,WAAW,eAAK,SAAS,GAAE;AAAA,MAC7D,CAAC;AAAA,MACD,aAAa,SAAS,WAAW;AAAA,QAC/B,QAAQ;AAAA,QACR,MAAM,CAAC,SACL,oBAAC,UAAK,WAAU,0DACb,eAAK,SAAS,GACjB;AAAA,MAEJ,CAAC;AAAA,MACD,aAAa,SAAS,aAAa;AAAA,QACjC,QAAQ;AAAA,QACR,MAAM,CAAC,SACL,oBAAC,UAAK,WAAU,0DACb,eAAK,SAAS,GACjB;AAAA,MAEJ,CAAC;AAAA,MACD,aAAa,SAAS,eAAe;AAAA,QACnC,QAAQ;AAAA,QACR,MAAM,CAAC,SACL,oBAAC,UAAK,WAAU,0DACb,eAAK,SAAS,GACjB;AAAA,MAEJ,CAAC;AAAA,MACD,aAAa,SAAS,SAAS;AAAA,QAC7B,QAAQ;AAAA,QACR,MAAM,CAAC,SAAS,oBAAC,UAAK,WAAU,WAAW,eAAK,SAAS,GAAE;AAAA,MAC7D,CAAC;AAAA,MACD,aAAa,SAAS,oBAAoB;AAAA,QACxC,QAAQ;AAAA,QACR,MAAM,CAAC,SACL,oBAAC,UAAK,WAAU,0DACb,eAAK,SAAS,GACjB;AAAA,MAEJ,CAAC;AAAA,IACH;AAAA,IACA,CAAC,SAAS,gBAAgB;AAAA,EAC5B;AAEA,QAAM,QAAQ,cAAc;AAAA,IAC1B,MAAM;AAAA,IACN;AAAA,IACA,OAAO;AAAA,MACL;AAAA,MACA;AAAA,IACF;AAAA,IACA,iBAAiB;AAAA,IACjB,0BAA0B;AAAA,IAC1B,iBAAiB,gBAAgB;AAAA,IACjC,mBAAmB,kBAAkB;AAAA,EACvC,CAAC;AAED,QAAM,iBAAiB,MAAM,kBAAkB,EAAE,IAAI,CAAC,WAAW;AAC/D,UAAM,SAAS,OAAO,UAAU;AAChC,UAAM,QAAQ,OAAO,WAAW,WAAW,SAAS,OAAO;AAE3D,WAAO;AAAA,MACL,IAAI,OAAO;AAAA,MACX;AAAA,MACA,SAAS,OAAO,aAAa;AAAA,MAC7B,SAAS,OAAO,WAAW;AAAA,IAC7B;AAAA,EACF,CAAC;AAED,QAAM,uBAAuB,CAAC,YAAoB,WAAmB;AACnE,uBAAmB,CAAC,aAAa,kBAAkB,UAAU,YAAY,MAAM,CAAC;AAAA,EAClF;AAEA,SACE,qBAAC,SAAI,WAAU,6DACb;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,YAAY;AAAA,QACZ;AAAA,QACA,gBAAgB;AAAA,QAChB;AAAA,QACA,iBAAiB;AAAA,QACjB;AAAA,QACA,gBAAgB,CAAC,aAAU;AAtyBnC;AAsyBsC,6BAAM,UAAU,QAAQ,MAAxB,mBAA2B;AAAA;AAAA,QACzD,gBAAgB,MAAM,oBAAoB,yBAAyB;AAAA;AAAA,IACrE;AAAA,IAEA;AAAA,MAAC;AAAA;AAAA,QACC,YAAY;AAAA,QACZ,WAAW;AAAA,QACX,YAAY;AAAA,QACZ,cAAc;AAAA;AAAA,IAChB;AAAA,IAEA,oBAAC,SAAI,WAAU,gEACb,+BAAC,WAAM,WAAU,4CACf;AAAA,0BAAC,WAAM,WAAU,mCACd,gBAAM,gBAAgB,EAAE,IAAI,CAAC,gBAC5B,oBAAC,QAAwB,WAAU,0BAChC,sBAAY,QAAQ,IAAI,CAAC,WACxB;AAAA,QAAC;AAAA;AAAA,UAEC,WAAU;AAAA,UAET,iBAAO,gBACJ,OACA;AAAA,YACE,OAAO,OAAO,UAAU;AAAA,YACxB,OAAO,WAAW;AAAA,UACpB;AAAA;AAAA,QARC,OAAO;AAAA,MASd,CACD,KAbM,YAAY,EAcrB,CACD,GACH;AAAA,MACA,oBAAC,WACE,gBAAM,YAAY,EAAE,KAAK,SAAS,IACjC,iCACG;AAAA,cAAM,YAAY,EAAE,KAAK,IAAI,CAAC,QAC7B;AAAA,UAAC;AAAA;AAAA,YAEC,SAAS,MAAM,yCAAa,IAAI;AAAA,YAChC,WAAW;AAAA,cACT;AAAA,cACA,cAAc;AAAA,YAChB;AAAA,YAEC,cAAI,gBAAgB,EAAE,IAAI,CAAC,SAC1B;AAAA,cAAC;AAAA;AAAA,gBAEC,WAAU;AAAA,gBAET,qBAAW,KAAK,OAAO,UAAU,MAAM,KAAK,WAAW,CAAC;AAAA;AAAA,cAHpD,KAAK;AAAA,YAIZ,CACD;AAAA;AAAA,UAdI,IAAI;AAAA,QAeX,CACD;AAAA,QACD,oBAAC,QACC;AAAA,UAAC;AAAA;AAAA,YACC,WAAU;AAAA,YACV,SAAS,QAAQ;AAAA,YAEhB;AAAA,oBAAM,YAAY,EAAE,KAAK;AAAA,cAAO;AAAA;AAAA;AAAA,QACnC,GACF;AAAA,SACF,IAEA,oBAAC,QACC,8BAAC,QAAG,SAAS,QAAQ,QAAQ,WAAU,yBACrC,+BAAC,SAAI,WAAU,0DACb;AAAA,4BAAC,WAAQ,WAAU,sBAAqB;AAAA,QACxC,oBAAC,OAAE,WAAU,uBAAsB,2BAAa;AAAA,QAChD,oBAAC,OAAE,WAAU,WAAU,uDAAyC;AAAA,SAClE,GACF,GACF,GAEJ;AAAA,OACF,GACF;AAAA,IAEC,eAAe,MAAM;AACpB,YAAM,OAAO,eAAe,WAAW,IAAI,EAAE,WAAW,GAAG;AAC3D,aACE;AAAA,QAAC;AAAA;AAAA,UACC,MAAI;AAAA,UACJ,cAAc,CAAC,SAAS;AAAE,gBAAI,CAAC,KAAM,eAAc,IAAI;AAAA,UAAE;AAAA,UACzD,OAAO,KAAK;AAAA,UACZ,aAAa,KAAK;AAAA,UAClB,OAAO,WAAW,SAAS,SAAS,WAAW,IAAI,YAAY,WAAW,IAAI;AAAA,UAC9E,QAAQ,KAAK;AAAA,UACb,UAAU,KAAK;AAAA,UACf,SAAS,KAAK;AAAA,UACd,kBAAkB,wBACd,CAAC,KAAK,MAAM,WAAW,sBAAsB,WAAW,IAAI,MAAM,WAAW,MAAM,KAAK,MAAM,MAAM,IACpG,CAAC,KAAK,MAAM,WAAW,QAAQ,IAAI,oBAAoB,EAAE,SAAS,WAAW,IAAI,MAAM,QAAQ,KAAK,MAAM,OAAO,CAAC;AAAA,UAEtH,aAAa,WAAW,IAAI;AAAA,UAC5B,gBAAgB,+DAA+D,WAAW,IAAI,EAAE;AAAA,UAChG,WAAW,MAAM,QAAQ,IAAI,gDAA2C,EAAE,SAAS,WAAW,IAAI,MAAM,MAAM,WAAW,KAAK,CAAC;AAAA,UAC/H,mBAAmB,yBACf,CAAC,SAAS,WAAW,uBAAuB,WAAW,IAAI,MAAM,WAAW,MAAM,SAAS,MAAM,IACjG,CAAC,SAAS,WAAW,QAAQ,IAAI,sBAAsB,EAAE,SAAS,WAAW,IAAI,MAAM,SAAS,OAAO,CAAC;AAAA,UAE5G,WAAW,yBACP,CAAC,SAAS,WAAW,uBAAuB,WAAW,IAAI,MAAM,WAAW,MAAM,SAAS,MAAM,IACjG,CAAC,SAAS,WAAW,QAAQ,IAAI,qBAAqB,EAAE,SAAS,WAAW,IAAI,MAAM,SAAS,OAAO,CAAC;AAAA;AAAA,MAE7G;AAAA,IAEJ,GAAG;AAAA,KACL;AAEJ;","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 &rarr; 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":[]}
package/dist/index.d.ts CHANGED
@@ -15,7 +15,7 @@ export { ContactChannel, ContactItem, ContactList, ContactListProps } from './co
15
15
  export { CheckInsCard, RecentlyCompletedCard, TopTasksCard, UpcomingMeetingsCard } from './components/dashboard-cards.js';
16
16
  export { DataRow, DataTable, DataTableProps } from './components/data-table.js';
17
17
  export { DataTableDisplay, DataTableDisplayColumn } from './components/data-table-display.js';
18
- export { DataTableFilter, DataTableFilterCategory } from './components/data-table-filter.js';
18
+ export { DataTableFilter, DataTableFilterCategory, FilterOption } from './components/data-table-filter.js';
19
19
  export { DataTableQuickViewValue, DataTableQuickViews } from './components/data-table-quick-views.js';
20
20
  export { DataTableToolbar } from './components/data-table-toolbar.js';
21
21
  export { Citation, DetailViewHeader, DetailViewSummary, DetailViewThread, SourceDef, SourceList, ThreadMessage } from './components/detail-view.js';
@@ -37,8 +37,7 @@ import {
37
37
  LayoutList,
38
38
  Columns2,
39
39
  Square,
40
- Tag,
41
- Sparkles
40
+ Tag
42
41
  } from "lucide-react";
43
42
  import {
44
43
  DropdownMenu,
@@ -248,10 +247,7 @@ function DetailView({
248
247
  return /* @__PURE__ */ jsxs("div", { className: "mb-8", children: [
249
248
  briefHeading ? /* @__PURE__ */ jsx("h3", { className: "text-xs font-bold text-muted-foreground uppercase tracking-wider mb-3", children: briefHeading }) : null,
250
249
  briefIntro && !signalData.signalBrief ? /* @__PURE__ */ jsx("p", { className: isProminent ? "text-sm text-foreground/70 leading-relaxed mb-2" : "text-sm text-muted-foreground leading-relaxed mb-2", children: briefIntro }) : null,
251
- signalData.signalBrief ? /* @__PURE__ */ jsxs("div", { className: isProminent ? "flex items-start gap-2 text-base text-foreground leading-relaxed mb-4" : "flex items-start gap-2 text-sm text-foreground/90 leading-relaxed mb-4", children: [
252
- /* @__PURE__ */ jsx(Sparkles, { className: isProminent ? "h-5 w-5 mt-0.5 shrink-0 text-primary" : "h-4 w-4 mt-0.5 shrink-0 text-primary" }),
253
- /* @__PURE__ */ jsx("span", { children: signalData.signalBrief })
254
- ] }) : /* @__PURE__ */ jsx("p", { className: isProminent ? "text-base text-foreground leading-relaxed mb-4" : "text-sm text-foreground/90 leading-relaxed mb-4", children: signalData.whyNow }),
250
+ signalData.signalBrief ? /* @__PURE__ */ jsx("p", { className: isProminent ? "text-base text-foreground leading-relaxed mb-4" : "text-sm text-foreground/90 leading-relaxed mb-4", children: signalData.signalBrief }) : /* @__PURE__ */ jsx("p", { className: isProminent ? "text-base text-foreground leading-relaxed mb-4" : "text-sm text-foreground/90 leading-relaxed mb-4", children: signalData.whyNow }),
255
251
  renderBeforeScore == null ? void 0 : renderBeforeScore(item),
256
252
  /* @__PURE__ */ jsx(
257
253
  ScoreFeedback.Root,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/prototype/prototype-inbox-view.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport {\n ArrowLeft,\n ArrowUpDown,\n ChevronDown,\n ChevronRight,\n Filter,\n FileText,\n Clock,\n CheckSquare,\n Eye,\n Plus,\n\n Building,\n LayoutList,\n Columns2,\n Square,\n Tag,\n Sparkles,\n} from \"lucide-react\"\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuTrigger,\n} from \"../components/dropdown-menu\"\nimport { Button } from \"../components/button\"\nimport { Badge } from \"../components/badge\"\nimport { Input } from \"../components/input\"\nimport { ViewModeToggle } from \"../components/view-mode-toggle\"\nimport {\n InboxToolbar,\n type AssigneeFilter,\n type InboxFilterCategory,\n} from \"../components/inbox-toolbar\"\nimport { GroupedListView, type GroupedListGroup } from \"../components/item-list\"\nimport { SignalApproval, type ApprovalState, type OpportunityPreview } from \"../components/signal-feedback-inline\"\nimport { ScoreFeedback } from \"../components/score-feedback\"\nimport { ScoreBreakdown } from \"../components/score-breakdown\"\nimport { Citation, type SourceDef } from \"../components/detail-view\"\nimport {\n SuggestedActions,\n type SuggestedAction,\n type SuggestedContact,\n} from \"../components/suggested-actions\"\nimport { TimelineActivity, type TimelineEvent } from \"../components/timeline-activity\"\nimport type {\n QueueItem,\n InboxViewConfig,\n InboxDetailSections,\n SignalScoreData,\n BriefStyleVariant,\n} from \"./prototype-config\"\n\n// ---------------------------------------------------------------------------\n// Dot color utility — maps statusColor to a Tailwind background class.\n// Centralised here so the list row and split-view card stay in sync and\n// future color additions are a single-edit change.\n// ---------------------------------------------------------------------------\n\nfunction dotColorClass(statusColor: string): string {\n if (statusColor === \"red\") return \"bg-[#f43f5e]\"\n if (statusColor === \"yellow\" || statusColor === \"amber\" || statusColor === \"orange\") return \"bg-[#eab308]\"\n if (statusColor === \"green\") return \"bg-[#22c55e]\"\n return \"bg-[#9ca3af]\"\n}\n\n// ---------------------------------------------------------------------------\n// Props\n// ---------------------------------------------------------------------------\n\nexport interface PrototypeInboxViewProps extends InboxViewConfig {\n /** Extra ReactNode rendered at the end of the header bar (e.g. exit button). */\n headerActions?: React.ReactNode\n onOpenEntityPanel?: () => void\n onOpenRecentActivity?: () => void\n onNavigateToInbox?: () => void\n onItemSelect?: (item: QueueItem) => void\n defaultViewMode?: \"list\" | \"split\"\n}\n\n// ---------------------------------------------------------------------------\n// Default detail sections\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_DETAIL_SECTIONS: InboxDetailSections = {\n signalBrief: true,\n suggestedActions: true,\n timeline: true,\n}\n\nconst DEFAULT_SIGNAL_SCORE: SignalScoreData = {\n score: 65,\n factors: [\n { key: \"trigger\", label: \"Trigger strength\", score: 70, why: \"Moderate signal detected based on account activity\" },\n { key: \"fit\", label: \"Company fit\", score: 65, why: \"Reasonable fit based on company profile\" },\n { key: \"timing\", label: \"Timing\", score: 58, why: \"Within general evaluation window\" },\n ],\n whyNow: \"Moderate signals detected that warrant review and potential outreach.\",\n evidence: [\n \"Activity patterns suggest potential opportunity\",\n \"Company profile aligns with target segment\",\n ],\n confidence: 72,\n}\n\n// ---------------------------------------------------------------------------\n// Detail View\n// ---------------------------------------------------------------------------\n\nexport interface DetailViewProps {\n item: QueueItem\n sections: InboxDetailSections\n getSignalScore: (company: string, item?: QueueItem) => SignalScoreData\n buildSuggestedActions: (item: QueueItem) => SuggestedAction[]\n buildSourceItems: (item: QueueItem) => SourceDef[]\n getTimelineEvents?: (item: QueueItem) => TimelineEvent[]\n accountContacts: SuggestedContact[]\n emailSignature: string | React.ReactNode\n iconMap: Record<string, string>\n onOpenEntityPanel?: () => void\n onOpenRecentActivity?: () => void\n onSuggestedActionFeedback?: (actionId: number | string, feedback: string, actionTitle?: string) => void\n onSignalApprove?: (item: QueueItem) => void | Promise<boolean>\n getSignalApprovalState?: (item: QueueItem) => ApprovalState | undefined\n signalLabels?: InboxViewConfig[\"signalLabels\"]\n hideApproveButton?: boolean\n signalBriefCopy?: InboxViewConfig[\"signalBriefCopy\"]\n briefStyleVariant?: BriefStyleVariant\n renderDetailExtra?: (item: QueueItem) => React.ReactNode\n /** Render content between the signal brief text and the signal score bar (e.g. \"Signals on Case\" chips). */\n renderBeforeScore?: (item: QueueItem) => React.ReactNode\n /** Render content between the signal score section and the activity timeline. */\n renderAfterScore?: (item: QueueItem) => React.ReactNode\n lastActivityTime?: string\n /** Render extra metadata chips (e.g. assignee) inside the chips row below the title. */\n renderMetadataExtra?: (item: QueueItem) => React.ReactNode\n onScoreFeedback?: (type: \"up\" | \"down\", pills: string[], detail: string) => void\n approveButtonIconUrl?: string\n opportunityPreview?: OpportunityPreview\n onRequestApproval?: () => Promise<void>\n}\n\nexport function DetailView({\n item,\n sections,\n getSignalScore,\n buildSuggestedActions,\n buildSourceItems,\n getTimelineEvents,\n accountContacts,\n emailSignature,\n iconMap,\n onOpenEntityPanel,\n onOpenRecentActivity,\n onSuggestedActionFeedback: _onSuggestedActionFeedback,\n onSignalApprove,\n getSignalApprovalState,\n signalLabels,\n hideApproveButton,\n signalBriefCopy,\n briefStyleVariant = \"default\",\n renderDetailExtra,\n renderBeforeScore,\n renderAfterScore,\n lastActivityTime,\n renderMetadataExtra,\n onScoreFeedback,\n approveButtonIconUrl,\n opportunityPreview,\n onRequestApproval,\n}: DetailViewProps) {\n const [evidenceExpanded, setEvidenceExpanded] = React.useState(false)\n const [showTimeline, setShowTimeline] = React.useState(false)\n const [extraActions, setExtraActions] = React.useState<SuggestedAction[]>([])\n\n React.useEffect(() => {\n setShowTimeline(false)\n setEvidenceExpanded(false)\n setExtraActions([])\n }, [item.id])\n\n const signalData = React.useMemo(\n () => getSignalScore(item.company, item),\n [getSignalScore, item.company, item],\n )\n\n const suggestedActions = React.useMemo(\n () => [...buildSuggestedActions(item), ...extraActions],\n [buildSuggestedActions, item, extraActions],\n )\n const sourceItems = React.useMemo(() => buildSourceItems(item), [buildSourceItems, item])\n const timelineEvents = React.useMemo(\n () => getTimelineEvents?.(item) ?? [],\n [getTimelineEvents, item],\n )\n\n const handleDuplicate = React.useCallback(\n (id: number | string) => {\n const base = suggestedActions.find((a) => a.id === id)\n if (!base || base.type !== \"email\") return\n const clone: SuggestedAction = {\n ...base,\n id: `${base.id}-dup-${Date.now()}`,\n emailMeta: base.emailMeta ? { ...base.emailMeta, to: undefined } : undefined,\n }\n setExtraActions((prev) => [...prev, clone])\n },\n [suggestedActions],\n )\n\n return (\n <SignalApproval.Root\n key={item.id}\n companyName={item.company}\n labels={signalLabels}\n hideApproveButton={hideApproveButton}\n approveButtonIconUrl={approveButtonIconUrl}\n opportunityPreview={opportunityPreview}\n onRequestApproval={onRequestApproval}\n initialApprovalState={getSignalApprovalState?.(item)}\n onApprove={() => onSignalApprove?.(item)}\n onApproveFeedback={(reasons, detail) => {\n signalData.onApproveFeedback?.(reasons, detail)\n console.log(\"Approval feedback:\", { taskId: item.id, company: item.company, reasons, detail })\n }}\n onDismiss={(reasons, detail, subReason) => {\n signalData.onDismissFeedback?.(reasons, detail, subReason)\n }}\n >\n <div className=\"mx-auto w-full max-w-3xl p-6 pb-12 md:p-8\">\n <div className=\"pb-8\">\n {/* Header */}\n <div className=\"mb-4 flex items-center gap-2\">\n <button\n type=\"button\"\n className=\"flex items-center gap-1.5 text-xs font-medium text-muted-foreground transition-colors hover:text-foreground\"\n >\n <ArrowLeft className=\"h-3.5 w-3.5\" />\n Back\n </button>\n <span className=\"text-muted-foreground/40\">&middot;</span>\n <span className=\"text-xs text-muted-foreground\">{item.company}</span>\n </div>\n\n <h1 className=\"mb-3 text-2xl font-bold tracking-tight text-foreground\">{item.title}</h1>\n\n <div className=\"mb-6 flex flex-wrap items-center gap-2\">\n {(item.statusColor === \"red\" || item.statusColor === \"orange\") && (\n <div className={`inline-flex items-center gap-1 rounded-md px-2.5 py-1 text-xs font-semibold ${\n item.statusColor === \"red\"\n ? \"bg-red-50 text-red-700\"\n : \"bg-orange-50 text-orange-700\"\n }`}>\n <span className=\"text-[10px] font-bold\">!</span> {item.tag1.charAt(0).toUpperCase() + item.tag1.slice(1)}\n </div>\n )}\n <div className=\"inline-flex items-center gap-1 rounded-md bg-muted px-2.5 py-1 text-xs font-medium text-muted-foreground\">\n {item.tag1}\n </div>\n {signalData.timeChipLabel && (\n <Badge variant=\"outline\" title={signalData.timeChipDetail ?? undefined}>\n {signalData.timeChipLabel}\n </Badge>\n )}\n <button\n type=\"button\"\n onClick={onOpenEntityPanel}\n className=\"ml-1 inline-flex items-center gap-1.5 rounded-md border border-border/60 bg-muted/30 px-2 py-1 transition-colors hover:bg-muted/50\"\n >\n <div className=\"flex h-4 w-4 items-center justify-center rounded bg-muted-foreground/10 text-[9px] font-semibold text-muted-foreground\">\n {item.company.substring(0, 1)}\n </div>\n <span className=\"text-xs font-medium text-foreground\">{item.company}</span>\n <ChevronRight className=\"h-3 w-3 text-muted-foreground/50\" />\n </button>\n {renderMetadataExtra?.(item)}\n </div>\n\n {/* Signal Brief */}\n {sections.signalBrief && (() => {\n const pct = signalData.score\n const scoreColor = pct >= 70 ? \"text-emerald-600\" : pct >= 40 ? \"text-amber-600\" : \"text-red-600\"\n const barColor = pct >= 70 ? \"bg-emerald-500\" : pct >= 40 ? \"bg-amber-500\" : \"bg-red-500\"\n const scoreLabel = pct >= 70 ? \"HIGH\" : pct >= 40 ? \"MEDIUM\" : \"LOW\"\n\n const evidenceWithCitations: React.ReactNode[] =\n sourceItems.length >= 4\n ? [\n <>\n There are <span className=\"font-medium text-foreground\">3 unusual signals</span> including a large balance\n outflow and reduced login frequency\n <Citation number={1} source={sourceItems[0]} />\n <Citation number={2} source={sourceItems[1]} />\n <Citation number={3} source={sourceItems[2]} />\n </>,\n <>\n Scott mentioned in <span className=\"font-medium text-foreground\">#treasury-questions</span> that they are actively\n looking for treasury management options\n <Citation number={4} source={sourceItems[2]} />\n </>,\n <>\n You have a recent email thread regarding optimization options that hasn&apos;t been replied to\n <Citation number={5} source={sourceItems[3]} />\n </>,\n ]\n : signalData.evidence.map((ev, i) => (\n <span key={i}>{ev}</span>\n ))\n\n const briefHeading = signalBriefCopy?.heading ?? \"Signal brief\"\n const introOpt = signalBriefCopy?.intro\n const briefIntro =\n introOpt === null\n ? null\n : typeof introOpt === \"function\"\n ? introOpt(item)\n : introOpt ?? `Signals indicate a potential opportunity for ${item.company}.`\n const isProminent = briefStyleVariant === \"prominent\";\n return (\n <div className=\"mb-8\">\n {briefHeading ? (\n <h3 className=\"text-xs font-bold text-muted-foreground uppercase tracking-wider mb-3\">{briefHeading}</h3>\n ) : null}\n {briefIntro && !signalData.signalBrief ? (\n <p className={isProminent\n ? \"text-sm text-foreground/70 leading-relaxed mb-2\"\n : \"text-sm text-muted-foreground leading-relaxed mb-2\"\n }>\n {briefIntro}\n </p>\n ) : null}\n {signalData.signalBrief ? (\n <div className={isProminent\n ? \"flex items-start gap-2 text-base text-foreground leading-relaxed mb-4\"\n : \"flex items-start gap-2 text-sm text-foreground/90 leading-relaxed mb-4\"\n }>\n <Sparkles className={isProminent ? \"h-5 w-5 mt-0.5 shrink-0 text-primary\" : \"h-4 w-4 mt-0.5 shrink-0 text-primary\"} />\n <span>{signalData.signalBrief}</span>\n </div>\n ) : (\n <p className={isProminent\n ? \"text-base text-foreground leading-relaxed mb-4\"\n : \"text-sm text-foreground/90 leading-relaxed mb-4\"\n }>\n {signalData.whyNow}\n </p>\n )}\n\n {/* Before-score content slot (e.g. \"Signals on Case\" chips) */}\n {renderBeforeScore?.(item)}\n\n <ScoreFeedback.Root\n onSubmitFeedback={(type, pills, detail) => (signalData.onScoreFeedback ?? onScoreFeedback)?.(type, pills, detail)}\n initialFeedback={signalData.initialScoreFeedback}\n >\n <div className=\"mb-5 rounded-md border border-border bg-muted/20 p-3\">\n <div className=\"flex items-center justify-between mb-1.5\">\n <span className=\"text-[10px] font-bold text-muted-foreground uppercase tracking-wider\">Signal Score</span>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm font-bold text-foreground\">{signalData.score}/100</span>\n <span className={`text-[10px] font-bold uppercase ${scoreColor}`}>{scoreLabel}</span>\n <ScoreFeedback.Trigger />\n </div>\n </div>\n <ScoreFeedback.Panel />\n <div className=\"h-1.5 bg-muted rounded-full overflow-hidden mb-2\">\n <div\n className={`h-full rounded-full transition-all duration-500 ${barColor}`}\n style={{ width: `${signalData.score}%` }}\n />\n </div>\n <button\n type=\"button\"\n onClick={() => setEvidenceExpanded((prev) => !prev)}\n className=\"flex items-center gap-1 text-[11px] font-medium text-muted-foreground hover:text-foreground transition-colors\"\n >\n <ChevronDown className={`h-3 w-3 transition-transform duration-200 ${evidenceExpanded ? \"rotate-180\" : \"\"}`} />\n View more\n </button>\n\n {evidenceExpanded && (\n <div className=\"mt-3 space-y-3\">\n <ul className=\"space-y-2\">\n {evidenceWithCitations.map((ev, index) => (\n <li key={index} className=\"flex items-start gap-2 text-sm\">\n <div className=\"w-1.5 h-1.5 bg-primary rounded-full mt-2 flex-shrink-0\" />\n <span className=\"text-muted-foreground leading-relaxed\">{ev}</span>\n </li>\n ))}\n </ul>\n <ScoreBreakdown\n factors={signalData.factors}\n onFactorFeedback={signalData.onFactorFeedback ?? ((key, type, detail) =>\n console.log(\"Signal factor feedback:\", { company: item.company, factor: key, type, detail })\n )}\n initialFeedback={signalData.initialFactorFeedback}\n />\n <SignalApproval.Actions />\n </div>\n )}\n </div>\n </ScoreFeedback.Root>\n\n {!evidenceExpanded && <SignalApproval.Actions />}\n </div>\n )\n })()}\n\n {/* After-score content slot (e.g. OpportunityPanel) */}\n {renderAfterScore?.(item)}\n\n {/* Activity Timeline */}\n {sections.timeline && timelineEvents.length > 0 && (\n <div className=\"mb-8\">\n <button\n type=\"button\"\n onClick={() => setShowTimeline((prev) => !prev)}\n className=\"group/timeline flex w-full items-center justify-between gap-2 py-2 rounded-md transition-colors hover:bg-muted/40 -mx-2 px-2 cursor-pointer\"\n >\n <div className=\"flex items-center gap-2\">\n <h3 className=\"text-xs font-bold text-muted-foreground uppercase tracking-wider group-hover/timeline:text-foreground transition-colors\">Activity timeline</h3>\n {!showTimeline && (lastActivityTime || (timelineEvents.length > 0 && timelineEvents[0].time)) && (\n <span className=\"text-[11px] text-muted-foreground/60\">\n &middot; Last activity {lastActivityTime ?? timelineEvents[0]?.time ?? ''}\n </span>\n )}\n </div>\n <div className=\"flex items-center gap-1.5\">\n <span className=\"text-[11px] font-medium text-muted-foreground\">{timelineEvents.length} events</span>\n <ChevronDown className={`h-3.5 w-3.5 text-muted-foreground transition-transform duration-200 ${showTimeline ? \"rotate-180\" : \"\"}`} />\n </div>\n </button>\n {showTimeline && (\n <div className=\"mt-3\">\n <TimelineActivity events={timelineEvents} />\n </div>\n )}\n </div>\n )}\n </div>\n\n {/* Suggested Actions */}\n {sections.suggestedActions && (\n <SignalApproval.Gate>\n <SuggestedActions\n actions={suggestedActions}\n accountContacts={accountContacts}\n signature={emailSignature}\n iconMap={iconMap}\n onDismiss={(id) => console.log(\"Dismiss action:\", id)}\n onSend={(id) => console.log(\"Send action:\", id)}\n onSaveDraft={(id) => console.log(\"Save draft:\", id)}\n onDuplicate={handleDuplicate}\n onOpenAccountDetails={onOpenEntityPanel}\n onOpenRecentActivity={onOpenRecentActivity}\n onMarkComplete={(id) => console.log(\"Mark complete:\", id)}\n onDispatchAgent={(id) => console.log(\"Dispatch agent:\", id)}\n />\n </SignalApproval.Gate>\n )}\n {renderDetailExtra?.(item)}\n </div>\n </SignalApproval.Root>\n )\n}\n\n// ---------------------------------------------------------------------------\n// Main Component\n// ---------------------------------------------------------------------------\n\nexport function PrototypeInboxView({\n items,\n filterCategories,\n detailSections,\n accountContacts = [],\n buildAccountContacts,\n emailSignature = \"\",\n buildSuggestedActions: buildSuggestedActionsProp,\n buildSourceItems: buildSourceItemsProp,\n getSignalScore: getSignalScoreProp,\n getTimelineEvents,\n iconMap = {},\n hideToolbarActions,\n hideHoverActions,\n onSuggestedActionFeedback,\n onScoreFeedback,\n headerActions,\n onOpenEntityPanel,\n onOpenRecentActivity,\n onItemSelect,\n defaultViewMode,\n buildEntityChips,\n quickFilterTabs,\n hideAccountsButton,\n accountDetailsLabel,\n onSignalApprove,\n getSignalApprovalState,\n signalLabels,\n hideApproveButton,\n signalBriefCopy,\n briefStyleVariant,\n renderDetailExtra,\n renderBeforeScore,\n renderAfterScore,\n lastActivityTime,\n sortOptions,\n activeSortId,\n onSortChange,\n}: PrototypeInboxViewProps) {\n const [inboxViewMode, setInboxViewMode] = React.useState<\"inbox\" | \"list\" | \"detail\">(\n defaultViewMode === \"list\" ? \"list\" : defaultViewMode === \"split\" ? \"inbox\" : \"inbox\"\n )\n const [previousViewMode, setPreviousViewMode] = React.useState<\"inbox\" | \"list\">(\"inbox\")\n const [selectedTask, setSelectedTask] = React.useState(items[0])\n const [inboxAssignee, setInboxAssignee] = React.useState<AssigneeFilter>(\"me\")\n const [inboxFilters, setInboxFilters] = React.useState<Record<string, string>>({})\n const [activeQuickFilter, setActiveQuickFilter] = React.useState<string>(\"all\")\n const [splitViewSearch, setSplitViewSearch] = React.useState(\"\")\n\n const sections = React.useMemo(\n () => ({ ...DEFAULT_DETAIL_SECTIONS, ...detailSections }),\n [detailSections],\n )\n\n const resolvedFilterCategories: InboxFilterCategory[] = React.useMemo(\n () =>\n filterCategories ?? [\n {\n id: \"category\",\n label: \"Category\",\n icon: <Tag className=\"h-3.5 w-3.5 text-muted-foreground\" />,\n options: [...new Set(items.map((i) => i.tag1))],\n },\n {\n id: \"account\",\n label: \"Account\",\n icon: <Building className=\"h-3.5 w-3.5 text-muted-foreground\" />,\n options: [...new Set(items.map((i) => i.company))],\n },\n ],\n [filterCategories, items],\n )\n\n const buildSuggestedActions = React.useMemo(\n () => buildSuggestedActionsProp ?? (() => []),\n [buildSuggestedActionsProp],\n )\n\n const buildSourceItems = React.useMemo(\n () => buildSourceItemsProp ?? (() => []),\n [buildSourceItemsProp],\n )\n\n const getSignalScore = React.useMemo(\n () => getSignalScoreProp ?? (() => DEFAULT_SIGNAL_SCORE),\n [getSignalScoreProp],\n )\n\n // Build a map from filter category id → QueueItem field for targeted filtering.\n // Known category ids are mapped explicitly; unknown categories fall back to a\n // broad search across display fields so consumer-defined filters still work.\n const filterFieldMap = React.useMemo<\n Record<string, (item: QueueItem, value: string) => boolean>\n >(() => {\n const map: Record<string, (item: QueueItem, value: string) => boolean> = {}\n for (const cat of resolvedFilterCategories) {\n switch (cat.id) {\n case \"category\":\n case \"signalType\":\n map[cat.id] = (item, v) => item.tag1.toLowerCase() === v.toLowerCase()\n break\n case \"account\":\n map[cat.id] = (item, v) => item.company.toLowerCase() === v.toLowerCase()\n break\n default:\n // Fallback: check all display fields\n map[cat.id] = (item, v) => {\n const lv = v.toLowerCase()\n return (\n item.tag1.toLowerCase() === lv ||\n item.company.toLowerCase() === lv ||\n item.title.toLowerCase().includes(lv) ||\n item.details.toLowerCase().includes(lv)\n )\n }\n }\n }\n return map\n }, [resolvedFilterCategories])\n\n // Filter items for list view based on toolbar filters\n const filteredItems = React.useMemo(() => {\n const activeFilters = Object.entries(inboxFilters).filter(\n ([, value]) => value && value !== \"all\"\n )\n if (activeFilters.length === 0) return items\n return items.filter((item) =>\n activeFilters.every(([key, value]) => {\n const matcher = filterFieldMap[key]\n return matcher ? matcher(item, value) : true\n })\n )\n }, [items, inboxFilters, filterFieldMap])\n\n // Resolve quick filter tabs once — used by both the split view filter and\n // the tab bar render. Each tab's `matchValue` (falling back to `label`) is\n // compared against `item.tag1` so consumer labels can differ from data values.\n type QuickFilterTab = { id: string; label: string; matchValue?: string; count?: number }\n const resolvedQuickFilterTabs = React.useMemo<QuickFilterTab[]>(() => {\n if (quickFilterTabs) return quickFilterTabs\n // Derive default tabs from the actual item tag1 values\n const uniqueTags = [...new Set(items.map((i) => i.tag1))]\n return uniqueTags.map((tag) => ({\n id: tag.toLowerCase().replace(/\\s+/g, \"-\"),\n label: tag,\n }))\n }, [quickFilterTabs, items])\n\n // Compute per-tab counts once so they can be displayed in the tab bar\n const quickFilterTabCounts = React.useMemo(() => {\n const counts: Record<string, number> = {}\n for (const tab of resolvedQuickFilterTabs) {\n const match = (tab.matchValue ?? tab.label).toLowerCase()\n counts[tab.id] = items.filter((i) => i.tag1.toLowerCase() === match).length\n }\n return counts\n }, [resolvedQuickFilterTabs, items])\n\n // Filter items for split view based on quick filter tabs and search\n const splitViewItems = React.useMemo(() => {\n let filtered = items\n // Apply quick filter tab\n if (activeQuickFilter !== \"all\") {\n const activeTab = resolvedQuickFilterTabs.find((t) => t.id === activeQuickFilter)\n if (activeTab) {\n const match = (activeTab.matchValue ?? activeTab.label).toLowerCase()\n filtered = filtered.filter(\n (item) => item.tag1.toLowerCase() === match\n )\n }\n }\n // Apply search input\n if (splitViewSearch.trim()) {\n const q = splitViewSearch.trim().toLowerCase()\n filtered = filtered.filter(\n (item) =>\n item.tag1.toLowerCase().includes(q) ||\n item.company.toLowerCase().includes(q) ||\n item.title.toLowerCase().includes(q)\n )\n }\n return filtered\n }, [items, activeQuickFilter, resolvedQuickFilterTabs, splitViewSearch])\n\n // Grouped items for list view — one group per severity tier so items\n // are labelled correctly (e.g. \"Urgent\", \"High\", \"Active\").\n const inboxGroups = React.useMemo<GroupedListGroup<QueueItem>[]>(() => {\n const urgent = filteredItems.filter((i) => i.statusColor === \"red\")\n const high = filteredItems.filter((i) => i.statusColor === \"orange\")\n const active = filteredItems.filter((i) => i.statusColor !== \"red\" && i.statusColor !== \"orange\")\n return [\n { key: \"urgent\", label: \"Urgent\", items: urgent },\n { key: \"high\", label: \"High\", items: high },\n { key: \"active\", label: \"Active\", items: active },\n ].filter((g) => g.items.length > 0)\n }, [filteredItems])\n\n const renderInboxRow = React.useCallback(\n (item: QueueItem) => (\n <>\n <span className={`h-2 w-2 shrink-0 rounded-full ${dotColorClass(item.statusColor)}`} />\n <span className=\"w-[80px] shrink-0 font-mono text-xs text-muted-foreground/80\">{item.id}</span>\n <span className=\"shrink-0 rounded-md border border-border bg-muted px-1.5 py-0.5 text-[10px] font-medium text-muted-foreground whitespace-nowrap\">{item.tag1}</span>\n <span className=\"min-w-0 flex-1 truncate text-sm font-semibold text-foreground\">{item.title}</span>\n <span className=\"w-[120px] shrink-0 truncate text-xs font-medium text-foreground\">{item.company}</span>\n <span className=\"w-[80px] shrink-0 text-right text-xs text-muted-foreground\">{item.time}</span>\n </>\n ),\n [],\n )\n\n const handleInboxItemSelect = React.useCallback(\n (item: QueueItem) => {\n setSelectedTask(item)\n if (onItemSelect) {\n onItemSelect(item)\n } else if (inboxViewMode === \"list\") {\n setPreviousViewMode(\"list\")\n setInboxViewMode(\"detail\")\n }\n },\n [inboxViewMode, onItemSelect],\n )\n\n const handleBackFromDetail = React.useCallback(() => {\n setInboxViewMode(previousViewMode)\n }, [previousViewMode])\n\n const handleViewModeChange = React.useCallback((id: string) => {\n const mode = id as \"inbox\" | \"list\" | \"detail\"\n if (mode !== \"detail\") {\n setPreviousViewMode(mode)\n }\n setInboxViewMode(mode)\n }, [])\n\n React.useEffect(() => {\n const mql = window.matchMedia(\"(max-width: 768px)\")\n function handleChange(e: MediaQueryListEvent | MediaQueryList) {\n if (e.matches && inboxViewMode === \"inbox\") {\n setPreviousViewMode(\"inbox\")\n setInboxViewMode(\"detail\")\n }\n }\n handleChange(mql)\n mql.addEventListener(\"change\", handleChange)\n return () => mql.removeEventListener(\"change\", handleChange)\n }, [inboxViewMode])\n\n const detailViewProps: DetailViewProps = {\n item: selectedTask,\n sections,\n getSignalScore,\n buildSuggestedActions,\n buildSourceItems,\n getTimelineEvents,\n accountContacts: buildAccountContacts?.(selectedTask) ?? accountContacts,\n emailSignature,\n iconMap,\n onOpenEntityPanel,\n onOpenRecentActivity,\n onSuggestedActionFeedback,\n onSignalApprove,\n getSignalApprovalState,\n signalLabels,\n hideApproveButton,\n signalBriefCopy,\n briefStyleVariant,\n renderDetailExtra,\n renderBeforeScore,\n renderAfterScore,\n lastActivityTime,\n onScoreFeedback,\n }\n\n return (\n <div className=\"flex h-full w-full flex-col\">\n {/* Toolbar */}\n <div className=\"flex items-center justify-between border-b border-border bg-background px-4 py-3 shrink-0\">\n <div className=\"flex items-center gap-3\">\n {inboxViewMode === \"detail\" ? (\n <button\n type=\"button\"\n onClick={handleBackFromDetail}\n className=\"flex items-center gap-2 text-sm font-medium text-muted-foreground hover:text-foreground transition-colors\"\n >\n <ArrowLeft className=\"h-4 w-4\" />\n Back\n </button>\n ) : null}\n <h2 className=\"text-lg font-semibold text-foreground\">Inbox</h2>\n <Badge variant=\"secondary\" className=\"bg-muted text-muted-foreground hover:bg-muted font-medium text-[11px] px-2 py-0.5 rounded-md\">\n {items.length}\n </Badge>\n </div>\n <div className=\"flex items-center gap-3\">\n <ViewModeToggle\n modes={[\n { id: \"inbox\", icon: <Columns2 className=\"h-3.5 w-3.5\" />, label: \"Split View\" },\n { id: \"list\", icon: <LayoutList className=\"h-3.5 w-3.5\" />, label: \"List View\" },\n { id: \"detail\", icon: <Square className=\"h-3.5 w-3.5\" />, label: \"Detail View\" },\n ]}\n activeMode={inboxViewMode}\n onModeChange={handleViewModeChange}\n />\n {headerActions}\n </div>\n </div>\n\n {/* View modes */}\n {inboxViewMode === \"detail\" ? (\n <div className=\"flex h-full flex-1 flex-col overflow-hidden bg-background\">\n <div className=\"flex-1 overflow-y-auto\">\n <DetailView {...detailViewProps} />\n </div>\n </div>\n ) : inboxViewMode === \"list\" ? (\n <div className=\"flex-1 overflow-y-auto bg-background\">\n <InboxToolbar\n assignee={inboxAssignee}\n onAssigneeChange={setInboxAssignee}\n filterCategories={resolvedFilterCategories}\n selectedFilters={inboxFilters}\n onFilterChange={(catId, val) =>\n setInboxFilters((prev) => ({ ...prev, [catId]: val }))\n }\n onClearFilters={() => setInboxFilters({})}\n />\n <GroupedListView<QueueItem>\n groups={inboxGroups}\n renderRow={renderInboxRow}\n getItemKey={(item) => item.id}\n selectedKey={selectedTask.id}\n onItemClick={handleInboxItemSelect}\n emptyMessage=\"No inbox items\"\n />\n </div>\n ) : (\n /* Split view */\n <div className=\"flex h-full min-h-0 w-full flex-1\">\n <div className=\"flex h-full min-w-[380px] w-[380px] flex-col border-r border-border bg-background shadow-sm z-10\">\n <div className=\"flex flex-col gap-4 border-b border-border p-4 shrink-0\">\n {!hideToolbarActions && (\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-1\">\n <Button variant=\"outline\" size=\"icon\" className=\"h-8 w-8 text-muted-foreground\"><Eye className=\"w-4 h-4\" /></Button>\n <Button variant=\"outline\" size=\"icon\" className=\"h-8 w-8 text-muted-foreground\"><FileText className=\"w-4 h-4\" /></Button>\n <Button variant=\"outline\" size=\"icon\" className=\"h-8 w-8 text-muted-foreground\"><Clock className=\"w-4 h-4\" /></Button>\n <Button variant=\"outline\" size=\"icon\" className=\"h-8 w-8 text-muted-foreground\"><CheckSquare className=\"w-4 h-4\" /></Button>\n </div>\n <Button size=\"sm\" className=\"h-8 px-4 bg-foreground text-background hover:bg-foreground/90 text-xs font-semibold gap-1.5 rounded-md\">\n <Plus className=\"w-4 h-4\" /> Add Task\n </Button>\n </div>\n )}\n <div className=\"flex items-center gap-2\">\n <div className=\"relative flex-1\">\n <Filter className=\"absolute left-2.5 top-1.5 w-4 h-4 text-muted-foreground\" />\n <Input\n className=\"h-8 pl-8 text-xs bg-background border-border rounded-md shadow-none\"\n placeholder=\"Filter by category...\"\n value={splitViewSearch}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) => setSplitViewSearch(e.target.value)}\n />\n </div>\n {sortOptions && sortOptions.length > 0 && (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button variant=\"outline\" size=\"sm\" className=\"h-8 text-xs font-medium rounded-md shadow-none gap-1.5\">\n <ArrowUpDown className=\"w-3.5 h-3.5\" />\n {sortOptions.find(o => o.id === activeSortId)?.label ?? 'Sort'}\n <ChevronDown className=\"w-3 h-3\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuRadioGroup value={activeSortId ?? ''} onValueChange={(val) => onSortChange?.(val)}>\n {sortOptions.map(option => (\n <DropdownMenuRadioItem key={option.id} value={option.id}>\n {option.label}\n </DropdownMenuRadioItem>\n ))}\n </DropdownMenuRadioGroup>\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n {!hideAccountsButton && (\n <Button variant=\"outline\" size=\"sm\" className=\"h-8 text-xs font-medium rounded-md shadow-none\">\n <Building className=\"w-3.5 h-3.5 mr-1.5\" /> {accountDetailsLabel ?? \"Accounts\"}\n </Button>\n )}\n </div>\n <div className=\"flex items-center gap-1.5 overflow-x-auto pb-1 mt-1 scrollbar-hide\">\n <Button\n size=\"sm\"\n variant={activeQuickFilter === \"all\" ? \"default\" : \"outline\"}\n className={`h-7 rounded-full px-3.5 text-[11px] font-semibold shadow-none ${\n activeQuickFilter === \"all\"\n ? \"bg-foreground text-background hover:bg-foreground/90\"\n : \"bg-transparent border-border text-muted-foreground hover:text-foreground\"\n }`}\n onClick={() => setActiveQuickFilter(\"all\")}\n >\n All\n </Button>\n {resolvedQuickFilterTabs.map((tab) => {\n const count = tab.count ?? quickFilterTabCounts[tab.id]\n return (\n <Button\n key={tab.id}\n size=\"sm\"\n variant={activeQuickFilter === tab.id ? \"default\" : \"outline\"}\n className={`h-7 rounded-full px-3.5 text-[11px] font-medium shadow-none ${\n activeQuickFilter === tab.id\n ? \"bg-foreground text-background hover:bg-foreground/90\"\n : \"bg-transparent border-border text-muted-foreground hover:text-foreground\"\n }`}\n onClick={() => setActiveQuickFilter(tab.id)}\n >\n {tab.label}{count != null && count > 0 ? ` (${count})` : \"\"}\n </Button>\n )\n })}\n </div>\n </div>\n\n <div className=\"flex-1 overflow-y-auto\">\n {splitViewItems.map((item) => (\n <div\n key={item.id}\n onClick={() => { setSelectedTask(item); onItemSelect?.(item) }}\n className={`cursor-pointer border-b border-border p-4 transition-colors group relative border-l-2 ${\n selectedTask.id === item.id\n ? \"bg-muted/30 border-l-brand-purple\"\n : \"bg-transparent border-l-transparent hover:bg-muted/10\"\n }`}\n >\n <div className=\"mb-1.5 flex items-center gap-2\">\n <span className=\"min-w-0 truncate text-[13px] font-semibold text-foreground leading-tight\">{item.title}</span>\n {selectedTask.id !== item.id && item.tag1 && (\n <span className=\"shrink-0 rounded-md border border-border bg-muted/60 px-2 py-0.5 text-[10px] font-medium text-muted-foreground\">\n {item.tag1}\n </span>\n )}\n <span className=\"ml-auto shrink-0 text-[10px] font-medium text-muted-foreground/80\">{item.time}</span>\n </div>\n <div className=\"flex items-start gap-2 mt-2\">\n <span className={`w-1.5 h-1.5 rounded-full shrink-0 mt-1.5 ${dotColorClass(item.statusColor)}`} />\n <span className=\"text-xs text-muted-foreground leading-tight\">{item.details}</span>\n </div>\n {buildEntityChips && (() => {\n const chips = buildEntityChips(item)\n if (!chips.length) return null\n return (\n <div className=\"flex items-center gap-1.5 mt-2 flex-wrap\">\n {chips.map((chip) => (\n <button\n key={chip.id}\n type=\"button\"\n onClick={(e) => { e.stopPropagation(); chip.onClick?.() }}\n className=\"inline-flex items-center gap-1 rounded-md border border-border/60 bg-muted/30 px-1.5 py-0.5 text-[10px] font-medium text-muted-foreground transition-colors hover:bg-muted/50 hover:text-foreground\"\n >\n <span className=\"flex h-3.5 w-3.5 items-center justify-center rounded bg-muted-foreground/10 text-[8px] font-semibold\">{chip.avatarLetter}</span>\n {chip.label}\n </button>\n ))}\n </div>\n )\n })()}\n {!hideHoverActions && (\n <div className={`absolute right-4 bottom-4 flex items-center gap-1.5 bg-background shadow-sm rounded-md px-1 py-0.5 border border-border ${\n selectedTask.id === item.id ? \"opacity-100\" : \"opacity-0 group-hover:opacity-100 transition-opacity\"\n }`}>\n <Button variant=\"ghost\" size=\"icon\" className=\"h-6 w-6 rounded text-muted-foreground hover:text-foreground\"><CheckSquare className=\"w-3.5 h-3.5\" /></Button>\n <Button variant=\"ghost\" size=\"icon\" className=\"h-6 w-6 rounded text-muted-foreground hover:text-foreground\"><Clock className=\"w-3.5 h-3.5\" /></Button>\n </div>\n )}\n </div>\n ))}\n <div className=\"p-4\">\n <Button variant=\"outline\" size=\"sm\" className=\"h-8 text-xs font-semibold rounded-md shadow-none\">See more</Button>\n </div>\n </div>\n </div>\n\n <div className=\"flex h-full flex-1 flex-col overflow-hidden bg-background\">\n <div className=\"flex-1 overflow-y-auto\">\n <DetailView {...detailViewProps} />\n </div>\n </div>\n </div>\n )}\n </div>\n )\n}\n"],"mappings":"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","names":["_a","_b"]}
1
+ {"version":3,"sources":["../../src/prototype/prototype-inbox-view.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport {\n ArrowLeft,\n ArrowUpDown,\n ChevronDown,\n ChevronRight,\n Filter,\n FileText,\n Clock,\n CheckSquare,\n Eye,\n Plus,\n\n Building,\n LayoutList,\n Columns2,\n Square,\n Tag,\n} from \"lucide-react\"\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuTrigger,\n} from \"../components/dropdown-menu\"\nimport { Button } from \"../components/button\"\nimport { Badge } from \"../components/badge\"\nimport { Input } from \"../components/input\"\nimport { ViewModeToggle } from \"../components/view-mode-toggle\"\nimport {\n InboxToolbar,\n type AssigneeFilter,\n type InboxFilterCategory,\n} from \"../components/inbox-toolbar\"\nimport { GroupedListView, type GroupedListGroup } from \"../components/item-list\"\nimport { SignalApproval, type ApprovalState, type OpportunityPreview } from \"../components/signal-feedback-inline\"\nimport { ScoreFeedback } from \"../components/score-feedback\"\nimport { ScoreBreakdown } from \"../components/score-breakdown\"\nimport { Citation, type SourceDef } from \"../components/detail-view\"\nimport {\n SuggestedActions,\n type SuggestedAction,\n type SuggestedContact,\n} from \"../components/suggested-actions\"\nimport { TimelineActivity, type TimelineEvent } from \"../components/timeline-activity\"\nimport type {\n QueueItem,\n InboxViewConfig,\n InboxDetailSections,\n SignalScoreData,\n BriefStyleVariant,\n} from \"./prototype-config\"\n\n// ---------------------------------------------------------------------------\n// Dot color utility — maps statusColor to a Tailwind background class.\n// Centralised here so the list row and split-view card stay in sync and\n// future color additions are a single-edit change.\n// ---------------------------------------------------------------------------\n\nfunction dotColorClass(statusColor: string): string {\n if (statusColor === \"red\") return \"bg-[#f43f5e]\"\n if (statusColor === \"yellow\" || statusColor === \"amber\" || statusColor === \"orange\") return \"bg-[#eab308]\"\n if (statusColor === \"green\") return \"bg-[#22c55e]\"\n return \"bg-[#9ca3af]\"\n}\n\n// ---------------------------------------------------------------------------\n// Props\n// ---------------------------------------------------------------------------\n\nexport interface PrototypeInboxViewProps extends InboxViewConfig {\n /** Extra ReactNode rendered at the end of the header bar (e.g. exit button). */\n headerActions?: React.ReactNode\n onOpenEntityPanel?: () => void\n onOpenRecentActivity?: () => void\n onNavigateToInbox?: () => void\n onItemSelect?: (item: QueueItem) => void\n defaultViewMode?: \"list\" | \"split\"\n}\n\n// ---------------------------------------------------------------------------\n// Default detail sections\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_DETAIL_SECTIONS: InboxDetailSections = {\n signalBrief: true,\n suggestedActions: true,\n timeline: true,\n}\n\nconst DEFAULT_SIGNAL_SCORE: SignalScoreData = {\n score: 65,\n factors: [\n { key: \"trigger\", label: \"Trigger strength\", score: 70, why: \"Moderate signal detected based on account activity\" },\n { key: \"fit\", label: \"Company fit\", score: 65, why: \"Reasonable fit based on company profile\" },\n { key: \"timing\", label: \"Timing\", score: 58, why: \"Within general evaluation window\" },\n ],\n whyNow: \"Moderate signals detected that warrant review and potential outreach.\",\n evidence: [\n \"Activity patterns suggest potential opportunity\",\n \"Company profile aligns with target segment\",\n ],\n confidence: 72,\n}\n\n// ---------------------------------------------------------------------------\n// Detail View\n// ---------------------------------------------------------------------------\n\nexport interface DetailViewProps {\n item: QueueItem\n sections: InboxDetailSections\n getSignalScore: (company: string, item?: QueueItem) => SignalScoreData\n buildSuggestedActions: (item: QueueItem) => SuggestedAction[]\n buildSourceItems: (item: QueueItem) => SourceDef[]\n getTimelineEvents?: (item: QueueItem) => TimelineEvent[]\n accountContacts: SuggestedContact[]\n emailSignature: string | React.ReactNode\n iconMap: Record<string, string>\n onOpenEntityPanel?: () => void\n onOpenRecentActivity?: () => void\n onSuggestedActionFeedback?: (actionId: number | string, feedback: string, actionTitle?: string) => void\n onSignalApprove?: (item: QueueItem) => void | Promise<boolean>\n getSignalApprovalState?: (item: QueueItem) => ApprovalState | undefined\n signalLabels?: InboxViewConfig[\"signalLabels\"]\n hideApproveButton?: boolean\n signalBriefCopy?: InboxViewConfig[\"signalBriefCopy\"]\n briefStyleVariant?: BriefStyleVariant\n renderDetailExtra?: (item: QueueItem) => React.ReactNode\n /** Render content between the signal brief text and the signal score bar (e.g. \"Signals on Case\" chips). */\n renderBeforeScore?: (item: QueueItem) => React.ReactNode\n /** Render content between the signal score section and the activity timeline. */\n renderAfterScore?: (item: QueueItem) => React.ReactNode\n lastActivityTime?: string\n /** Render extra metadata chips (e.g. assignee) inside the chips row below the title. */\n renderMetadataExtra?: (item: QueueItem) => React.ReactNode\n onScoreFeedback?: (type: \"up\" | \"down\", pills: string[], detail: string) => void\n approveButtonIconUrl?: string\n opportunityPreview?: OpportunityPreview\n onRequestApproval?: () => Promise<void>\n}\n\nexport function DetailView({\n item,\n sections,\n getSignalScore,\n buildSuggestedActions,\n buildSourceItems,\n getTimelineEvents,\n accountContacts,\n emailSignature,\n iconMap,\n onOpenEntityPanel,\n onOpenRecentActivity,\n onSuggestedActionFeedback: _onSuggestedActionFeedback,\n onSignalApprove,\n getSignalApprovalState,\n signalLabels,\n hideApproveButton,\n signalBriefCopy,\n briefStyleVariant = \"default\",\n renderDetailExtra,\n renderBeforeScore,\n renderAfterScore,\n lastActivityTime,\n renderMetadataExtra,\n onScoreFeedback,\n approveButtonIconUrl,\n opportunityPreview,\n onRequestApproval,\n}: DetailViewProps) {\n const [evidenceExpanded, setEvidenceExpanded] = React.useState(false)\n const [showTimeline, setShowTimeline] = React.useState(false)\n const [extraActions, setExtraActions] = React.useState<SuggestedAction[]>([])\n\n React.useEffect(() => {\n setShowTimeline(false)\n setEvidenceExpanded(false)\n setExtraActions([])\n }, [item.id])\n\n const signalData = React.useMemo(\n () => getSignalScore(item.company, item),\n [getSignalScore, item.company, item],\n )\n\n const suggestedActions = React.useMemo(\n () => [...buildSuggestedActions(item), ...extraActions],\n [buildSuggestedActions, item, extraActions],\n )\n const sourceItems = React.useMemo(() => buildSourceItems(item), [buildSourceItems, item])\n const timelineEvents = React.useMemo(\n () => getTimelineEvents?.(item) ?? [],\n [getTimelineEvents, item],\n )\n\n const handleDuplicate = React.useCallback(\n (id: number | string) => {\n const base = suggestedActions.find((a) => a.id === id)\n if (!base || base.type !== \"email\") return\n const clone: SuggestedAction = {\n ...base,\n id: `${base.id}-dup-${Date.now()}`,\n emailMeta: base.emailMeta ? { ...base.emailMeta, to: undefined } : undefined,\n }\n setExtraActions((prev) => [...prev, clone])\n },\n [suggestedActions],\n )\n\n return (\n <SignalApproval.Root\n key={item.id}\n companyName={item.company}\n labels={signalLabels}\n hideApproveButton={hideApproveButton}\n approveButtonIconUrl={approveButtonIconUrl}\n opportunityPreview={opportunityPreview}\n onRequestApproval={onRequestApproval}\n initialApprovalState={getSignalApprovalState?.(item)}\n onApprove={() => onSignalApprove?.(item)}\n onApproveFeedback={(reasons, detail) => {\n signalData.onApproveFeedback?.(reasons, detail)\n console.log(\"Approval feedback:\", { taskId: item.id, company: item.company, reasons, detail })\n }}\n onDismiss={(reasons, detail, subReason) => {\n signalData.onDismissFeedback?.(reasons, detail, subReason)\n }}\n >\n <div className=\"mx-auto w-full max-w-3xl p-6 pb-12 md:p-8\">\n <div className=\"pb-8\">\n {/* Header */}\n <div className=\"mb-4 flex items-center gap-2\">\n <button\n type=\"button\"\n className=\"flex items-center gap-1.5 text-xs font-medium text-muted-foreground transition-colors hover:text-foreground\"\n >\n <ArrowLeft className=\"h-3.5 w-3.5\" />\n Back\n </button>\n <span className=\"text-muted-foreground/40\">&middot;</span>\n <span className=\"text-xs text-muted-foreground\">{item.company}</span>\n </div>\n\n <h1 className=\"mb-3 text-2xl font-bold tracking-tight text-foreground\">{item.title}</h1>\n\n <div className=\"mb-6 flex flex-wrap items-center gap-2\">\n {(item.statusColor === \"red\" || item.statusColor === \"orange\") && (\n <div className={`inline-flex items-center gap-1 rounded-md px-2.5 py-1 text-xs font-semibold ${\n item.statusColor === \"red\"\n ? \"bg-red-50 text-red-700\"\n : \"bg-orange-50 text-orange-700\"\n }`}>\n <span className=\"text-[10px] font-bold\">!</span> {item.tag1.charAt(0).toUpperCase() + item.tag1.slice(1)}\n </div>\n )}\n <div className=\"inline-flex items-center gap-1 rounded-md bg-muted px-2.5 py-1 text-xs font-medium text-muted-foreground\">\n {item.tag1}\n </div>\n {signalData.timeChipLabel && (\n <Badge variant=\"outline\" title={signalData.timeChipDetail ?? undefined}>\n {signalData.timeChipLabel}\n </Badge>\n )}\n <button\n type=\"button\"\n onClick={onOpenEntityPanel}\n className=\"ml-1 inline-flex items-center gap-1.5 rounded-md border border-border/60 bg-muted/30 px-2 py-1 transition-colors hover:bg-muted/50\"\n >\n <div className=\"flex h-4 w-4 items-center justify-center rounded bg-muted-foreground/10 text-[9px] font-semibold text-muted-foreground\">\n {item.company.substring(0, 1)}\n </div>\n <span className=\"text-xs font-medium text-foreground\">{item.company}</span>\n <ChevronRight className=\"h-3 w-3 text-muted-foreground/50\" />\n </button>\n {renderMetadataExtra?.(item)}\n </div>\n\n {/* Signal Brief */}\n {sections.signalBrief && (() => {\n const pct = signalData.score\n const scoreColor = pct >= 70 ? \"text-emerald-600\" : pct >= 40 ? \"text-amber-600\" : \"text-red-600\"\n const barColor = pct >= 70 ? \"bg-emerald-500\" : pct >= 40 ? \"bg-amber-500\" : \"bg-red-500\"\n const scoreLabel = pct >= 70 ? \"HIGH\" : pct >= 40 ? \"MEDIUM\" : \"LOW\"\n\n const evidenceWithCitations: React.ReactNode[] =\n sourceItems.length >= 4\n ? [\n <>\n There are <span className=\"font-medium text-foreground\">3 unusual signals</span> including a large balance\n outflow and reduced login frequency\n <Citation number={1} source={sourceItems[0]} />\n <Citation number={2} source={sourceItems[1]} />\n <Citation number={3} source={sourceItems[2]} />\n </>,\n <>\n Scott mentioned in <span className=\"font-medium text-foreground\">#treasury-questions</span> that they are actively\n looking for treasury management options\n <Citation number={4} source={sourceItems[2]} />\n </>,\n <>\n You have a recent email thread regarding optimization options that hasn&apos;t been replied to\n <Citation number={5} source={sourceItems[3]} />\n </>,\n ]\n : signalData.evidence.map((ev, i) => (\n <span key={i}>{ev}</span>\n ))\n\n const briefHeading = signalBriefCopy?.heading ?? \"Signal brief\"\n const introOpt = signalBriefCopy?.intro\n const briefIntro =\n introOpt === null\n ? null\n : typeof introOpt === \"function\"\n ? introOpt(item)\n : introOpt ?? `Signals indicate a potential opportunity for ${item.company}.`\n const isProminent = briefStyleVariant === \"prominent\";\n return (\n <div className=\"mb-8\">\n {briefHeading ? (\n <h3 className=\"text-xs font-bold text-muted-foreground uppercase tracking-wider mb-3\">{briefHeading}</h3>\n ) : null}\n {briefIntro && !signalData.signalBrief ? (\n <p className={isProminent\n ? \"text-sm text-foreground/70 leading-relaxed mb-2\"\n : \"text-sm text-muted-foreground leading-relaxed mb-2\"\n }>\n {briefIntro}\n </p>\n ) : null}\n {signalData.signalBrief ? (\n <p className={isProminent\n ? \"text-base text-foreground leading-relaxed mb-4\"\n : \"text-sm text-foreground/90 leading-relaxed mb-4\"\n }>\n {signalData.signalBrief}\n </p>\n ) : (\n <p className={isProminent\n ? \"text-base text-foreground leading-relaxed mb-4\"\n : \"text-sm text-foreground/90 leading-relaxed mb-4\"\n }>\n {signalData.whyNow}\n </p>\n )}\n\n {/* Before-score content slot (e.g. \"Signals on Case\" chips) */}\n {renderBeforeScore?.(item)}\n\n <ScoreFeedback.Root\n onSubmitFeedback={(type, pills, detail) => (signalData.onScoreFeedback ?? onScoreFeedback)?.(type, pills, detail)}\n initialFeedback={signalData.initialScoreFeedback}\n >\n <div className=\"mb-5 rounded-md border border-border bg-muted/20 p-3\">\n <div className=\"flex items-center justify-between mb-1.5\">\n <span className=\"text-[10px] font-bold text-muted-foreground uppercase tracking-wider\">Signal Score</span>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm font-bold text-foreground\">{signalData.score}/100</span>\n <span className={`text-[10px] font-bold uppercase ${scoreColor}`}>{scoreLabel}</span>\n <ScoreFeedback.Trigger />\n </div>\n </div>\n <ScoreFeedback.Panel />\n <div className=\"h-1.5 bg-muted rounded-full overflow-hidden mb-2\">\n <div\n className={`h-full rounded-full transition-all duration-500 ${barColor}`}\n style={{ width: `${signalData.score}%` }}\n />\n </div>\n <button\n type=\"button\"\n onClick={() => setEvidenceExpanded((prev) => !prev)}\n className=\"flex items-center gap-1 text-[11px] font-medium text-muted-foreground hover:text-foreground transition-colors\"\n >\n <ChevronDown className={`h-3 w-3 transition-transform duration-200 ${evidenceExpanded ? \"rotate-180\" : \"\"}`} />\n View more\n </button>\n\n {evidenceExpanded && (\n <div className=\"mt-3 space-y-3\">\n <ul className=\"space-y-2\">\n {evidenceWithCitations.map((ev, index) => (\n <li key={index} className=\"flex items-start gap-2 text-sm\">\n <div className=\"w-1.5 h-1.5 bg-primary rounded-full mt-2 flex-shrink-0\" />\n <span className=\"text-muted-foreground leading-relaxed\">{ev}</span>\n </li>\n ))}\n </ul>\n <ScoreBreakdown\n factors={signalData.factors}\n onFactorFeedback={signalData.onFactorFeedback ?? ((key, type, detail) =>\n console.log(\"Signal factor feedback:\", { company: item.company, factor: key, type, detail })\n )}\n initialFeedback={signalData.initialFactorFeedback}\n />\n <SignalApproval.Actions />\n </div>\n )}\n </div>\n </ScoreFeedback.Root>\n\n {!evidenceExpanded && <SignalApproval.Actions />}\n </div>\n )\n })()}\n\n {/* After-score content slot (e.g. OpportunityPanel) */}\n {renderAfterScore?.(item)}\n\n {/* Activity Timeline */}\n {sections.timeline && timelineEvents.length > 0 && (\n <div className=\"mb-8\">\n <button\n type=\"button\"\n onClick={() => setShowTimeline((prev) => !prev)}\n className=\"group/timeline flex w-full items-center justify-between gap-2 py-2 rounded-md transition-colors hover:bg-muted/40 -mx-2 px-2 cursor-pointer\"\n >\n <div className=\"flex items-center gap-2\">\n <h3 className=\"text-xs font-bold text-muted-foreground uppercase tracking-wider group-hover/timeline:text-foreground transition-colors\">Activity timeline</h3>\n {!showTimeline && (lastActivityTime || (timelineEvents.length > 0 && timelineEvents[0].time)) && (\n <span className=\"text-[11px] text-muted-foreground/60\">\n &middot; Last activity {lastActivityTime ?? timelineEvents[0]?.time ?? ''}\n </span>\n )}\n </div>\n <div className=\"flex items-center gap-1.5\">\n <span className=\"text-[11px] font-medium text-muted-foreground\">{timelineEvents.length} events</span>\n <ChevronDown className={`h-3.5 w-3.5 text-muted-foreground transition-transform duration-200 ${showTimeline ? \"rotate-180\" : \"\"}`} />\n </div>\n </button>\n {showTimeline && (\n <div className=\"mt-3\">\n <TimelineActivity events={timelineEvents} />\n </div>\n )}\n </div>\n )}\n </div>\n\n {/* Suggested Actions */}\n {sections.suggestedActions && (\n <SignalApproval.Gate>\n <SuggestedActions\n actions={suggestedActions}\n accountContacts={accountContacts}\n signature={emailSignature}\n iconMap={iconMap}\n onDismiss={(id) => console.log(\"Dismiss action:\", id)}\n onSend={(id) => console.log(\"Send action:\", id)}\n onSaveDraft={(id) => console.log(\"Save draft:\", id)}\n onDuplicate={handleDuplicate}\n onOpenAccountDetails={onOpenEntityPanel}\n onOpenRecentActivity={onOpenRecentActivity}\n onMarkComplete={(id) => console.log(\"Mark complete:\", id)}\n onDispatchAgent={(id) => console.log(\"Dispatch agent:\", id)}\n />\n </SignalApproval.Gate>\n )}\n {renderDetailExtra?.(item)}\n </div>\n </SignalApproval.Root>\n )\n}\n\n// ---------------------------------------------------------------------------\n// Main Component\n// ---------------------------------------------------------------------------\n\nexport function PrototypeInboxView({\n items,\n filterCategories,\n detailSections,\n accountContacts = [],\n buildAccountContacts,\n emailSignature = \"\",\n buildSuggestedActions: buildSuggestedActionsProp,\n buildSourceItems: buildSourceItemsProp,\n getSignalScore: getSignalScoreProp,\n getTimelineEvents,\n iconMap = {},\n hideToolbarActions,\n hideHoverActions,\n onSuggestedActionFeedback,\n onScoreFeedback,\n headerActions,\n onOpenEntityPanel,\n onOpenRecentActivity,\n onItemSelect,\n defaultViewMode,\n buildEntityChips,\n quickFilterTabs,\n hideAccountsButton,\n accountDetailsLabel,\n onSignalApprove,\n getSignalApprovalState,\n signalLabels,\n hideApproveButton,\n signalBriefCopy,\n briefStyleVariant,\n renderDetailExtra,\n renderBeforeScore,\n renderAfterScore,\n lastActivityTime,\n sortOptions,\n activeSortId,\n onSortChange,\n}: PrototypeInboxViewProps) {\n const [inboxViewMode, setInboxViewMode] = React.useState<\"inbox\" | \"list\" | \"detail\">(\n defaultViewMode === \"list\" ? \"list\" : defaultViewMode === \"split\" ? \"inbox\" : \"inbox\"\n )\n const [previousViewMode, setPreviousViewMode] = React.useState<\"inbox\" | \"list\">(\"inbox\")\n const [selectedTask, setSelectedTask] = React.useState(items[0])\n const [inboxAssignee, setInboxAssignee] = React.useState<AssigneeFilter>(\"me\")\n const [inboxFilters, setInboxFilters] = React.useState<Record<string, string>>({})\n const [activeQuickFilter, setActiveQuickFilter] = React.useState<string>(\"all\")\n const [splitViewSearch, setSplitViewSearch] = React.useState(\"\")\n\n const sections = React.useMemo(\n () => ({ ...DEFAULT_DETAIL_SECTIONS, ...detailSections }),\n [detailSections],\n )\n\n const resolvedFilterCategories: InboxFilterCategory[] = React.useMemo(\n () =>\n filterCategories ?? [\n {\n id: \"category\",\n label: \"Category\",\n icon: <Tag className=\"h-3.5 w-3.5 text-muted-foreground\" />,\n options: [...new Set(items.map((i) => i.tag1))],\n },\n {\n id: \"account\",\n label: \"Account\",\n icon: <Building className=\"h-3.5 w-3.5 text-muted-foreground\" />,\n options: [...new Set(items.map((i) => i.company))],\n },\n ],\n [filterCategories, items],\n )\n\n const buildSuggestedActions = React.useMemo(\n () => buildSuggestedActionsProp ?? (() => []),\n [buildSuggestedActionsProp],\n )\n\n const buildSourceItems = React.useMemo(\n () => buildSourceItemsProp ?? (() => []),\n [buildSourceItemsProp],\n )\n\n const getSignalScore = React.useMemo(\n () => getSignalScoreProp ?? (() => DEFAULT_SIGNAL_SCORE),\n [getSignalScoreProp],\n )\n\n // Build a map from filter category id → QueueItem field for targeted filtering.\n // Known category ids are mapped explicitly; unknown categories fall back to a\n // broad search across display fields so consumer-defined filters still work.\n const filterFieldMap = React.useMemo<\n Record<string, (item: QueueItem, value: string) => boolean>\n >(() => {\n const map: Record<string, (item: QueueItem, value: string) => boolean> = {}\n for (const cat of resolvedFilterCategories) {\n switch (cat.id) {\n case \"category\":\n case \"signalType\":\n map[cat.id] = (item, v) => item.tag1.toLowerCase() === v.toLowerCase()\n break\n case \"account\":\n map[cat.id] = (item, v) => item.company.toLowerCase() === v.toLowerCase()\n break\n default:\n // Fallback: check all display fields\n map[cat.id] = (item, v) => {\n const lv = v.toLowerCase()\n return (\n item.tag1.toLowerCase() === lv ||\n item.company.toLowerCase() === lv ||\n item.title.toLowerCase().includes(lv) ||\n item.details.toLowerCase().includes(lv)\n )\n }\n }\n }\n return map\n }, [resolvedFilterCategories])\n\n // Filter items for list view based on toolbar filters\n const filteredItems = React.useMemo(() => {\n const activeFilters = Object.entries(inboxFilters).filter(\n ([, value]) => value && value !== \"all\"\n )\n if (activeFilters.length === 0) return items\n return items.filter((item) =>\n activeFilters.every(([key, value]) => {\n const matcher = filterFieldMap[key]\n return matcher ? matcher(item, value) : true\n })\n )\n }, [items, inboxFilters, filterFieldMap])\n\n // Resolve quick filter tabs once — used by both the split view filter and\n // the tab bar render. Each tab's `matchValue` (falling back to `label`) is\n // compared against `item.tag1` so consumer labels can differ from data values.\n type QuickFilterTab = { id: string; label: string; matchValue?: string; count?: number }\n const resolvedQuickFilterTabs = React.useMemo<QuickFilterTab[]>(() => {\n if (quickFilterTabs) return quickFilterTabs\n // Derive default tabs from the actual item tag1 values\n const uniqueTags = [...new Set(items.map((i) => i.tag1))]\n return uniqueTags.map((tag) => ({\n id: tag.toLowerCase().replace(/\\s+/g, \"-\"),\n label: tag,\n }))\n }, [quickFilterTabs, items])\n\n // Compute per-tab counts once so they can be displayed in the tab bar\n const quickFilterTabCounts = React.useMemo(() => {\n const counts: Record<string, number> = {}\n for (const tab of resolvedQuickFilterTabs) {\n const match = (tab.matchValue ?? tab.label).toLowerCase()\n counts[tab.id] = items.filter((i) => i.tag1.toLowerCase() === match).length\n }\n return counts\n }, [resolvedQuickFilterTabs, items])\n\n // Filter items for split view based on quick filter tabs and search\n const splitViewItems = React.useMemo(() => {\n let filtered = items\n // Apply quick filter tab\n if (activeQuickFilter !== \"all\") {\n const activeTab = resolvedQuickFilterTabs.find((t) => t.id === activeQuickFilter)\n if (activeTab) {\n const match = (activeTab.matchValue ?? activeTab.label).toLowerCase()\n filtered = filtered.filter(\n (item) => item.tag1.toLowerCase() === match\n )\n }\n }\n // Apply search input\n if (splitViewSearch.trim()) {\n const q = splitViewSearch.trim().toLowerCase()\n filtered = filtered.filter(\n (item) =>\n item.tag1.toLowerCase().includes(q) ||\n item.company.toLowerCase().includes(q) ||\n item.title.toLowerCase().includes(q)\n )\n }\n return filtered\n }, [items, activeQuickFilter, resolvedQuickFilterTabs, splitViewSearch])\n\n // Grouped items for list view — one group per severity tier so items\n // are labelled correctly (e.g. \"Urgent\", \"High\", \"Active\").\n const inboxGroups = React.useMemo<GroupedListGroup<QueueItem>[]>(() => {\n const urgent = filteredItems.filter((i) => i.statusColor === \"red\")\n const high = filteredItems.filter((i) => i.statusColor === \"orange\")\n const active = filteredItems.filter((i) => i.statusColor !== \"red\" && i.statusColor !== \"orange\")\n return [\n { key: \"urgent\", label: \"Urgent\", items: urgent },\n { key: \"high\", label: \"High\", items: high },\n { key: \"active\", label: \"Active\", items: active },\n ].filter((g) => g.items.length > 0)\n }, [filteredItems])\n\n const renderInboxRow = React.useCallback(\n (item: QueueItem) => (\n <>\n <span className={`h-2 w-2 shrink-0 rounded-full ${dotColorClass(item.statusColor)}`} />\n <span className=\"w-[80px] shrink-0 font-mono text-xs text-muted-foreground/80\">{item.id}</span>\n <span className=\"shrink-0 rounded-md border border-border bg-muted px-1.5 py-0.5 text-[10px] font-medium text-muted-foreground whitespace-nowrap\">{item.tag1}</span>\n <span className=\"min-w-0 flex-1 truncate text-sm font-semibold text-foreground\">{item.title}</span>\n <span className=\"w-[120px] shrink-0 truncate text-xs font-medium text-foreground\">{item.company}</span>\n <span className=\"w-[80px] shrink-0 text-right text-xs text-muted-foreground\">{item.time}</span>\n </>\n ),\n [],\n )\n\n const handleInboxItemSelect = React.useCallback(\n (item: QueueItem) => {\n setSelectedTask(item)\n if (onItemSelect) {\n onItemSelect(item)\n } else if (inboxViewMode === \"list\") {\n setPreviousViewMode(\"list\")\n setInboxViewMode(\"detail\")\n }\n },\n [inboxViewMode, onItemSelect],\n )\n\n const handleBackFromDetail = React.useCallback(() => {\n setInboxViewMode(previousViewMode)\n }, [previousViewMode])\n\n const handleViewModeChange = React.useCallback((id: string) => {\n const mode = id as \"inbox\" | \"list\" | \"detail\"\n if (mode !== \"detail\") {\n setPreviousViewMode(mode)\n }\n setInboxViewMode(mode)\n }, [])\n\n React.useEffect(() => {\n const mql = window.matchMedia(\"(max-width: 768px)\")\n function handleChange(e: MediaQueryListEvent | MediaQueryList) {\n if (e.matches && inboxViewMode === \"inbox\") {\n setPreviousViewMode(\"inbox\")\n setInboxViewMode(\"detail\")\n }\n }\n handleChange(mql)\n mql.addEventListener(\"change\", handleChange)\n return () => mql.removeEventListener(\"change\", handleChange)\n }, [inboxViewMode])\n\n const detailViewProps: DetailViewProps = {\n item: selectedTask,\n sections,\n getSignalScore,\n buildSuggestedActions,\n buildSourceItems,\n getTimelineEvents,\n accountContacts: buildAccountContacts?.(selectedTask) ?? accountContacts,\n emailSignature,\n iconMap,\n onOpenEntityPanel,\n onOpenRecentActivity,\n onSuggestedActionFeedback,\n onSignalApprove,\n getSignalApprovalState,\n signalLabels,\n hideApproveButton,\n signalBriefCopy,\n briefStyleVariant,\n renderDetailExtra,\n renderBeforeScore,\n renderAfterScore,\n lastActivityTime,\n onScoreFeedback,\n }\n\n return (\n <div className=\"flex h-full w-full flex-col\">\n {/* Toolbar */}\n <div className=\"flex items-center justify-between border-b border-border bg-background px-4 py-3 shrink-0\">\n <div className=\"flex items-center gap-3\">\n {inboxViewMode === \"detail\" ? (\n <button\n type=\"button\"\n onClick={handleBackFromDetail}\n className=\"flex items-center gap-2 text-sm font-medium text-muted-foreground hover:text-foreground transition-colors\"\n >\n <ArrowLeft className=\"h-4 w-4\" />\n Back\n </button>\n ) : null}\n <h2 className=\"text-lg font-semibold text-foreground\">Inbox</h2>\n <Badge variant=\"secondary\" className=\"bg-muted text-muted-foreground hover:bg-muted font-medium text-[11px] px-2 py-0.5 rounded-md\">\n {items.length}\n </Badge>\n </div>\n <div className=\"flex items-center gap-3\">\n <ViewModeToggle\n modes={[\n { id: \"inbox\", icon: <Columns2 className=\"h-3.5 w-3.5\" />, label: \"Split View\" },\n { id: \"list\", icon: <LayoutList className=\"h-3.5 w-3.5\" />, label: \"List View\" },\n { id: \"detail\", icon: <Square className=\"h-3.5 w-3.5\" />, label: \"Detail View\" },\n ]}\n activeMode={inboxViewMode}\n onModeChange={handleViewModeChange}\n />\n {headerActions}\n </div>\n </div>\n\n {/* View modes */}\n {inboxViewMode === \"detail\" ? (\n <div className=\"flex h-full flex-1 flex-col overflow-hidden bg-background\">\n <div className=\"flex-1 overflow-y-auto\">\n <DetailView {...detailViewProps} />\n </div>\n </div>\n ) : inboxViewMode === \"list\" ? (\n <div className=\"flex-1 overflow-y-auto bg-background\">\n <InboxToolbar\n assignee={inboxAssignee}\n onAssigneeChange={setInboxAssignee}\n filterCategories={resolvedFilterCategories}\n selectedFilters={inboxFilters}\n onFilterChange={(catId, val) =>\n setInboxFilters((prev) => ({ ...prev, [catId]: val }))\n }\n onClearFilters={() => setInboxFilters({})}\n />\n <GroupedListView<QueueItem>\n groups={inboxGroups}\n renderRow={renderInboxRow}\n getItemKey={(item) => item.id}\n selectedKey={selectedTask.id}\n onItemClick={handleInboxItemSelect}\n emptyMessage=\"No inbox items\"\n />\n </div>\n ) : (\n /* Split view */\n <div className=\"flex h-full min-h-0 w-full flex-1\">\n <div className=\"flex h-full min-w-[380px] w-[380px] flex-col border-r border-border bg-background shadow-sm z-10\">\n <div className=\"flex flex-col gap-4 border-b border-border p-4 shrink-0\">\n {!hideToolbarActions && (\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-1\">\n <Button variant=\"outline\" size=\"icon\" className=\"h-8 w-8 text-muted-foreground\"><Eye className=\"w-4 h-4\" /></Button>\n <Button variant=\"outline\" size=\"icon\" className=\"h-8 w-8 text-muted-foreground\"><FileText className=\"w-4 h-4\" /></Button>\n <Button variant=\"outline\" size=\"icon\" className=\"h-8 w-8 text-muted-foreground\"><Clock className=\"w-4 h-4\" /></Button>\n <Button variant=\"outline\" size=\"icon\" className=\"h-8 w-8 text-muted-foreground\"><CheckSquare className=\"w-4 h-4\" /></Button>\n </div>\n <Button size=\"sm\" className=\"h-8 px-4 bg-foreground text-background hover:bg-foreground/90 text-xs font-semibold gap-1.5 rounded-md\">\n <Plus className=\"w-4 h-4\" /> Add Task\n </Button>\n </div>\n )}\n <div className=\"flex items-center gap-2\">\n <div className=\"relative flex-1\">\n <Filter className=\"absolute left-2.5 top-1.5 w-4 h-4 text-muted-foreground\" />\n <Input\n className=\"h-8 pl-8 text-xs bg-background border-border rounded-md shadow-none\"\n placeholder=\"Filter by category...\"\n value={splitViewSearch}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) => setSplitViewSearch(e.target.value)}\n />\n </div>\n {sortOptions && sortOptions.length > 0 && (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button variant=\"outline\" size=\"sm\" className=\"h-8 text-xs font-medium rounded-md shadow-none gap-1.5\">\n <ArrowUpDown className=\"w-3.5 h-3.5\" />\n {sortOptions.find(o => o.id === activeSortId)?.label ?? 'Sort'}\n <ChevronDown className=\"w-3 h-3\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuRadioGroup value={activeSortId ?? ''} onValueChange={(val) => onSortChange?.(val)}>\n {sortOptions.map(option => (\n <DropdownMenuRadioItem key={option.id} value={option.id}>\n {option.label}\n </DropdownMenuRadioItem>\n ))}\n </DropdownMenuRadioGroup>\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n {!hideAccountsButton && (\n <Button variant=\"outline\" size=\"sm\" className=\"h-8 text-xs font-medium rounded-md shadow-none\">\n <Building className=\"w-3.5 h-3.5 mr-1.5\" /> {accountDetailsLabel ?? \"Accounts\"}\n </Button>\n )}\n </div>\n <div className=\"flex items-center gap-1.5 overflow-x-auto pb-1 mt-1 scrollbar-hide\">\n <Button\n size=\"sm\"\n variant={activeQuickFilter === \"all\" ? \"default\" : \"outline\"}\n className={`h-7 rounded-full px-3.5 text-[11px] font-semibold shadow-none ${\n activeQuickFilter === \"all\"\n ? \"bg-foreground text-background hover:bg-foreground/90\"\n : \"bg-transparent border-border text-muted-foreground hover:text-foreground\"\n }`}\n onClick={() => setActiveQuickFilter(\"all\")}\n >\n All\n </Button>\n {resolvedQuickFilterTabs.map((tab) => {\n const count = tab.count ?? quickFilterTabCounts[tab.id]\n return (\n <Button\n key={tab.id}\n size=\"sm\"\n variant={activeQuickFilter === tab.id ? \"default\" : \"outline\"}\n className={`h-7 rounded-full px-3.5 text-[11px] font-medium shadow-none ${\n activeQuickFilter === tab.id\n ? \"bg-foreground text-background hover:bg-foreground/90\"\n : \"bg-transparent border-border text-muted-foreground hover:text-foreground\"\n }`}\n onClick={() => setActiveQuickFilter(tab.id)}\n >\n {tab.label}{count != null && count > 0 ? ` (${count})` : \"\"}\n </Button>\n )\n })}\n </div>\n </div>\n\n <div className=\"flex-1 overflow-y-auto\">\n {splitViewItems.map((item) => (\n <div\n key={item.id}\n onClick={() => { setSelectedTask(item); onItemSelect?.(item) }}\n className={`cursor-pointer border-b border-border p-4 transition-colors group relative border-l-2 ${\n selectedTask.id === item.id\n ? \"bg-muted/30 border-l-brand-purple\"\n : \"bg-transparent border-l-transparent hover:bg-muted/10\"\n }`}\n >\n <div className=\"mb-1.5 flex items-center gap-2\">\n <span className=\"min-w-0 truncate text-[13px] font-semibold text-foreground leading-tight\">{item.title}</span>\n {selectedTask.id !== item.id && item.tag1 && (\n <span className=\"shrink-0 rounded-md border border-border bg-muted/60 px-2 py-0.5 text-[10px] font-medium text-muted-foreground\">\n {item.tag1}\n </span>\n )}\n <span className=\"ml-auto shrink-0 text-[10px] font-medium text-muted-foreground/80\">{item.time}</span>\n </div>\n <div className=\"flex items-start gap-2 mt-2\">\n <span className={`w-1.5 h-1.5 rounded-full shrink-0 mt-1.5 ${dotColorClass(item.statusColor)}`} />\n <span className=\"text-xs text-muted-foreground leading-tight\">{item.details}</span>\n </div>\n {buildEntityChips && (() => {\n const chips = buildEntityChips(item)\n if (!chips.length) return null\n return (\n <div className=\"flex items-center gap-1.5 mt-2 flex-wrap\">\n {chips.map((chip) => (\n <button\n key={chip.id}\n type=\"button\"\n onClick={(e) => { e.stopPropagation(); chip.onClick?.() }}\n className=\"inline-flex items-center gap-1 rounded-md border border-border/60 bg-muted/30 px-1.5 py-0.5 text-[10px] font-medium text-muted-foreground transition-colors hover:bg-muted/50 hover:text-foreground\"\n >\n <span className=\"flex h-3.5 w-3.5 items-center justify-center rounded bg-muted-foreground/10 text-[8px] font-semibold\">{chip.avatarLetter}</span>\n {chip.label}\n </button>\n ))}\n </div>\n )\n })()}\n {!hideHoverActions && (\n <div className={`absolute right-4 bottom-4 flex items-center gap-1.5 bg-background shadow-sm rounded-md px-1 py-0.5 border border-border ${\n selectedTask.id === item.id ? \"opacity-100\" : \"opacity-0 group-hover:opacity-100 transition-opacity\"\n }`}>\n <Button variant=\"ghost\" size=\"icon\" className=\"h-6 w-6 rounded text-muted-foreground hover:text-foreground\"><CheckSquare className=\"w-3.5 h-3.5\" /></Button>\n <Button variant=\"ghost\" size=\"icon\" className=\"h-6 w-6 rounded text-muted-foreground hover:text-foreground\"><Clock className=\"w-3.5 h-3.5\" /></Button>\n </div>\n )}\n </div>\n ))}\n <div className=\"p-4\">\n <Button variant=\"outline\" size=\"sm\" className=\"h-8 text-xs font-semibold rounded-md shadow-none\">See more</Button>\n </div>\n </div>\n </div>\n\n <div className=\"flex h-full flex-1 flex-col overflow-hidden bg-background\">\n <div className=\"flex-1 overflow-y-auto\">\n <DetailView {...detailViewProps} />\n </div>\n </div>\n </div>\n )}\n </div>\n )\n}\n"],"mappings":"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","names":["_a","_b"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@handled-ai/design-system",
3
- "version": "0.14.6",
3
+ "version": "0.14.8",
4
4
  "description": "Handled UI component library (shadcn-style, New York)",
5
5
  "type": "module",
6
6
  "packageManager": "pnpm@9.12.0",
@@ -15,11 +15,23 @@ import {
15
15
  DropdownMenuTrigger,
16
16
  } from "./dropdown-menu"
17
17
 
18
+ export interface FilterOption {
19
+ label: string
20
+ value: string
21
+ }
22
+
18
23
  export interface DataTableFilterCategory {
19
24
  id: string
20
25
  label: string
21
26
  icon: React.ComponentType<{ className?: string }>
22
- options: string[]
27
+ options: (string | FilterOption)[]
28
+ }
29
+
30
+ function getOptionValue(option: string | FilterOption): string {
31
+ return typeof option === "string" ? option : option.value
32
+ }
33
+ function getOptionLabel(option: string | FilterOption): string {
34
+ return typeof option === "string" ? option : option.label
23
35
  }
24
36
 
25
37
  interface DataTableFilterProps {
@@ -36,6 +48,7 @@ export function DataTableFilter({
36
48
  className,
37
49
  }: DataTableFilterProps) {
38
50
  const [query, setQuery] = React.useState("")
51
+ const [subQueries, setSubQueries] = React.useState<Record<string, string>>({})
39
52
 
40
53
  const visibleCategories = React.useMemo(() => {
41
54
  const normalized = query.trim().toLowerCase()
@@ -49,7 +62,7 @@ export function DataTableFilter({
49
62
  }
50
63
 
51
64
  return category.options.some((option) =>
52
- option.toLowerCase().includes(normalized)
65
+ getOptionLabel(option).toLowerCase().includes(normalized)
53
66
  )
54
67
  })
55
68
  }, [categories, query])
@@ -99,38 +112,82 @@ export function DataTableFilter({
99
112
  </div>
100
113
 
101
114
  <div className="max-h-[320px] overflow-y-auto p-1">
102
- {visibleCategories.map((category) => (
103
- <DropdownMenuSub key={category.id}>
104
- <DropdownMenuSubTrigger className="cursor-pointer py-1.5 text-xs">
105
- <category.icon className="mr-2 h-3.5 w-3.5 text-muted-foreground" />
106
- {category.label}
107
- </DropdownMenuSubTrigger>
108
- <DropdownMenuSubContent className="w-52 p-1">
109
- {category.options.map((option) => {
110
- const selected =
111
- selectedFilters[category.id]?.includes(option) ?? false
115
+ {visibleCategories.map((category) => {
116
+ const subQuery = (subQueries[category.id] ?? "").trim().toLowerCase()
117
+ const filteredOptions = subQuery
118
+ ? category.options.filter((opt) =>
119
+ getOptionLabel(opt).toLowerCase().includes(subQuery)
120
+ )
121
+ : category.options
112
122
 
113
- return (
114
- <DropdownMenuItem
115
- key={option}
116
- className="cursor-pointer justify-between text-xs"
117
- onSelect={(event) => {
118
- event.preventDefault()
119
- onToggleFilter(category.id, option)
120
- }}
121
- >
122
- {option}
123
- {selected ? (
124
- <span className="text-[10px] font-semibold text-brand-purple">
125
- Applied
126
- </span>
127
- ) : null}
128
- </DropdownMenuItem>
129
- )
130
- })}
131
- </DropdownMenuSubContent>
132
- </DropdownMenuSub>
133
- ))}
123
+ return (
124
+ <DropdownMenuSub
125
+ key={category.id}
126
+ onOpenChange={(open) => {
127
+ if (!open) {
128
+ setSubQueries((prev) => {
129
+ const next = { ...prev }
130
+ delete next[category.id]
131
+ return next
132
+ })
133
+ }
134
+ }}
135
+ >
136
+ <DropdownMenuSubTrigger className="cursor-pointer py-1.5 text-xs">
137
+ <category.icon className="mr-2 h-3.5 w-3.5 text-muted-foreground" />
138
+ {category.label}
139
+ </DropdownMenuSubTrigger>
140
+ <DropdownMenuSubContent className="max-h-[320px] w-52 overflow-y-auto p-1">
141
+ {/* Submenu search — only for categories with many options */}
142
+ {category.options.length > 7 && (
143
+ <div className="sticky top-0 z-10 border-b border-border bg-popover p-1.5">
144
+ <div className="relative">
145
+ <Search className="absolute left-2 top-1/2 h-3 w-3 -translate-y-1/2 text-muted-foreground" />
146
+ <input
147
+ className="h-7 w-full rounded-md bg-muted/50 py-1 pr-2 pl-7 text-xs outline-none transition-colors placeholder:text-muted-foreground/70 focus:bg-muted"
148
+ placeholder="Search..."
149
+ value={subQueries[category.id] ?? ""}
150
+ onChange={(e) =>
151
+ setSubQueries((prev) => ({ ...prev, [category.id]: e.target.value }))
152
+ }
153
+ onClick={(e) => e.stopPropagation()}
154
+ onKeyDown={(e) => e.stopPropagation()}
155
+ />
156
+ </div>
157
+ </div>
158
+ )}
159
+ {/* Filtered options */}
160
+ {filteredOptions.map((option) => {
161
+ const value = getOptionValue(option)
162
+ const label = getOptionLabel(option)
163
+ const selected = selectedFilters[category.id]?.includes(value) ?? false
164
+ return (
165
+ <DropdownMenuItem
166
+ key={value}
167
+ className="cursor-pointer justify-between text-xs"
168
+ onSelect={(event) => {
169
+ event.preventDefault()
170
+ onToggleFilter(category.id, value)
171
+ }}
172
+ >
173
+ {label}
174
+ {selected ? (
175
+ <span className="text-[10px] font-semibold text-brand-purple">
176
+ Applied
177
+ </span>
178
+ ) : null}
179
+ </DropdownMenuItem>
180
+ )
181
+ })}
182
+ {filteredOptions.length === 0 && category.options.length > 0 && (
183
+ <div className="p-2 text-center text-xs text-muted-foreground">
184
+ No matches
185
+ </div>
186
+ )}
187
+ </DropdownMenuSubContent>
188
+ </DropdownMenuSub>
189
+ )
190
+ })}
134
191
 
135
192
  {visibleCategories.length === 0 ? (
136
193
  <div className="p-2 text-center text-xs text-muted-foreground">
@@ -49,6 +49,7 @@ export type DataRow = {
49
49
  headcount: string
50
50
  lastFunding: string
51
51
  owner: string
52
+ ownerEmail?: string
52
53
  opportunityCount: number
53
54
  productAdoptionScore: number
54
55
  sourceSystem?: string
@@ -477,7 +478,7 @@ function isRowMatchingCategoryFilter(
477
478
  case "lastFunding":
478
479
  return options.includes(row.lastFunding)
479
480
  case "owner":
480
- return options.includes(row.owner)
481
+ return options.includes(row.ownerEmail ?? row.owner)
481
482
  case "opportunityCount":
482
483
  return options.some((option) => {
483
484
  if (option === "3+") {
@@ -65,10 +65,10 @@ describe("DetailView briefStyleVariant", () => {
65
65
  getSignalScore: () => makeSignalScore({ signalBrief: "AI generated brief" }),
66
66
  });
67
67
  const { container } = render(<DetailView {...props} />);
68
- const briefDiv = findByClass(container, "div", "text-foreground/90");
69
- expect(briefDiv).not.toBeUndefined();
70
- expect(briefDiv!.className).toContain("text-sm");
71
- expect(briefDiv!.className).toContain("text-foreground/90");
68
+ const briefEl = findByClass(container, "p", "text-foreground/90");
69
+ expect(briefEl).not.toBeUndefined();
70
+ expect(briefEl!.className).toContain("text-sm");
71
+ expect(briefEl!.className).toContain("text-foreground/90");
72
72
  });
73
73
 
74
74
  it("prominent variant: brief text has class text-base text-foreground", () => {
@@ -77,20 +77,20 @@ describe("DetailView briefStyleVariant", () => {
77
77
  getSignalScore: () => makeSignalScore({ signalBrief: "AI generated brief" }),
78
78
  });
79
79
  const { container } = render(<DetailView {...props} />);
80
- // Find a div with text-base that has text-foreground but NOT text-foreground/
81
- const els = container.querySelectorAll("div");
82
- let briefDiv: HTMLElement | undefined;
80
+ // Find a p with text-base that has text-foreground but NOT text-foreground/
81
+ const els = container.querySelectorAll("p");
82
+ let briefEl: HTMLElement | undefined;
83
83
  for (let i = 0; i < els.length; i++) {
84
84
  const el = els[i] as HTMLElement;
85
85
  if (el.className && el.className.includes("text-base") && el.className.includes("text-foreground") && !el.className.includes("text-foreground/")) {
86
- briefDiv = el;
86
+ briefEl = el;
87
87
  break;
88
88
  }
89
89
  }
90
- expect(briefDiv).not.toBeUndefined();
91
- expect(briefDiv!.className).toContain("text-base");
92
- expect(briefDiv!.className).toContain("text-foreground");
93
- expect(briefDiv!.className).not.toContain("text-foreground/90");
90
+ expect(briefEl).not.toBeUndefined();
91
+ expect(briefEl!.className).toContain("text-base");
92
+ expect(briefEl!.className).toContain("text-foreground");
93
+ expect(briefEl!.className).not.toContain("text-foreground/90");
94
94
  });
95
95
 
96
96
  it("prominent variant: intro text has class text-foreground/70", () => {
@@ -18,7 +18,6 @@ import {
18
18
  Columns2,
19
19
  Square,
20
20
  Tag,
21
- Sparkles,
22
21
  } from "lucide-react"
23
22
 
24
23
  import {
@@ -335,13 +334,12 @@ export function DetailView({
335
334
  </p>
336
335
  ) : null}
337
336
  {signalData.signalBrief ? (
338
- <div className={isProminent
339
- ? "flex items-start gap-2 text-base text-foreground leading-relaxed mb-4"
340
- : "flex items-start gap-2 text-sm text-foreground/90 leading-relaxed mb-4"
337
+ <p className={isProminent
338
+ ? "text-base text-foreground leading-relaxed mb-4"
339
+ : "text-sm text-foreground/90 leading-relaxed mb-4"
341
340
  }>
342
- <Sparkles className={isProminent ? "h-5 w-5 mt-0.5 shrink-0 text-primary" : "h-4 w-4 mt-0.5 shrink-0 text-primary"} />
343
- <span>{signalData.signalBrief}</span>
344
- </div>
341
+ {signalData.signalBrief}
342
+ </p>
345
343
  ) : (
346
344
  <p className={isProminent
347
345
  ? "text-base text-foreground leading-relaxed mb-4"