@handled-ai/design-system 0.9.10 → 0.9.12

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.
@@ -13,6 +13,13 @@ interface SidebarNavSection {
13
13
  title?: string;
14
14
  /** Optional icon shown to the left of the section title (expanded sidebars only). */
15
15
  titleIconUrl?: string;
16
+ /**
17
+ * Size of the title icon. Default `"sm"` (14px).
18
+ * - `"sm"`: 14px, opacity 70 — secondary/decorative use
19
+ * - `"md"`: 20px, opacity 90
20
+ * - `"lg"`: 24px, full opacity — when the section icon is the primary brand mark
21
+ */
22
+ titleIconSize?: "sm" | "md" | "lg";
16
23
  items: SidebarNavItem[];
17
24
  moreItems?: SidebarNavItem[];
18
25
  }
@@ -70,6 +70,11 @@ import {
70
70
  TooltipTrigger
71
71
  } from "./tooltip.js";
72
72
  import { QuickActionModal } from "./quick-action-modal.js";
73
+ const SECTION_TITLE_ICON_SIZE_CLASSES = {
74
+ sm: "h-3.5 w-3.5 opacity-70",
75
+ md: "h-5 w-5 opacity-90",
76
+ lg: "h-6 w-6"
77
+ };
73
78
  const DEFAULT_NAV_SECTIONS = [
74
79
  {
75
80
  items: [
@@ -219,7 +224,7 @@ function NavSection({
219
224
  activeVariant = "default",
220
225
  onNavigate
221
226
  }) {
222
- var _a;
227
+ var _a, _b;
223
228
  const [isExpanded, setIsExpanded] = React.useState(true);
224
229
  const [expandedItems, setExpandedItems] = React.useState({});
225
230
  const hasTitle = !isCollapsed && section.title;
@@ -241,7 +246,10 @@ function NavSection({
241
246
  src: section.titleIconUrl,
242
247
  alt: "",
243
248
  "aria-hidden": "true",
244
- className: "h-3.5 w-3.5 shrink-0 object-contain opacity-70"
249
+ className: cn(
250
+ "shrink-0 object-contain",
251
+ SECTION_TITLE_ICON_SIZE_CLASSES[(_a = section.titleIconSize) != null ? _a : "sm"]
252
+ )
245
253
  }
246
254
  ),
247
255
  /* @__PURE__ */ jsx("span", { className: "text-xs font-bold tracking-widest text-sidebar-foreground/50 uppercase truncate", children: section.title })
@@ -292,7 +300,7 @@ function NavSection({
292
300
  item.id
293
301
  )) })
294
302
  ] }),
295
- isCollapsed && ((_a = section.moreItems) == null ? void 0 : _a.map((item) => /* @__PURE__ */ jsx(
303
+ isCollapsed && ((_b = section.moreItems) == null ? void 0 : _b.map((item) => /* @__PURE__ */ jsx(
296
304
  NavItemRow,
297
305
  {
298
306
  item,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/quick-action-sidebar-nav.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport {\n Activity,\n BarChart2,\n Building,\n ChevronDown,\n Code,\n Inbox,\n Link as LinkIcon,\n LogOut,\n MessageSquare,\n MoreHorizontal,\n MoreVertical,\n PanelLeftClose,\n PanelLeftOpen,\n Plus,\n Search,\n Settings,\n Users,\n} from \"lucide-react\"\n\nimport { cn } from \"../lib/utils\"\nimport { Avatar, AvatarFallback } from \"./avatar\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"./dropdown-menu\"\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from \"./tooltip\"\nimport { QuickActionModal, type QuickActionTaskDraft, type QuickActionTemplate } from \"./quick-action-modal\"\n\nexport interface SidebarNavItem {\n id: string\n label: string\n icon: React.ComponentType<{ className?: string }>\n children?: SidebarNavItem[]\n}\n\nexport interface SidebarNavSection {\n title?: string\n /** Optional icon shown to the left of the section title (expanded sidebars only). */\n titleIconUrl?: string\n items: SidebarNavItem[]\n moreItems?: SidebarNavItem[]\n}\n\nexport interface SidebarUserProfile {\n name: string\n email: string\n initials?: string\n}\n\nexport interface UserMenuItem {\n id: string\n label: string\n icon: React.ComponentType<{ className?: string }>\n destructive?: boolean\n}\n\nexport type ActiveVariant = \"default\" | \"gradient\"\n\ninterface QuickActionSidebarNavProps extends React.ComponentProps<\"aside\"> {\n brandLabel?: string\n brandSubtitle?: string\n brandImage?: string\n hideQuickAction?: boolean\n navSections?: SidebarNavSection[]\n activeItemId?: string\n activeVariant?: ActiveVariant\n onNavigate?: (itemId: string) => void\n user?: SidebarUserProfile\n userMenuItems?: UserMenuItem[]\n onUserMenuAction?: (itemId: string) => void\n onCreateTask?: (draft: QuickActionTaskDraft) => void\n defaultCollapsed?: boolean\n quickActionTemplates?: QuickActionTemplate[]\n quickActionTitle?: string\n quickActionDescription?: string\n}\n\nconst DEFAULT_NAV_SECTIONS: SidebarNavSection[] = [\n {\n items: [\n { id: \"home\", label: \"Home\", icon: Inbox },\n { id: \"inbox\", label: \"Inbox\", icon: Inbox },\n ],\n },\n {\n title: \"Focus\",\n items: [\n { id: \"inbox\", label: \"Unibox\", icon: Inbox },\n { id: \"accounts\", label: \"My Accounts\", icon: Building },\n { id: \"activity\", label: \"Activity\", icon: Activity },\n { id: \"dashboard\", label: \"Insights\", icon: BarChart2 },\n ],\n moreItems: [\n { id: \"search\", label: \"Search\", icon: Search },\n ],\n },\n {\n title: \"Assistant\",\n items: [\n { id: \"new-chat\", label: \"New chat\", icon: Plus },\n { id: \"chats\", label: \"Chats\", icon: MessageSquare },\n ],\n },\n {\n title: \"Your Teams\",\n items: [\n { id: \"team-a\", label: \"Team A\", icon: Users },\n { id: \"team-b\", label: \"Team B\", icon: Users },\n ],\n moreItems: [\n { id: \"more-teams\", label: \"More\", icon: MoreHorizontal },\n ],\n },\n]\n\nconst DEFAULT_USER: SidebarUserProfile = {\n name: \"John Doe\",\n email: \"jdoe@acmeco.com\",\n initials: \"JD\",\n}\n\nconst DEFAULT_USER_MENU: UserMenuItem[] = [\n { id: \"settings\", label: \"Settings\", icon: Settings },\n { id: \"dev\", label: \"Dev\", icon: Code },\n { id: \"integrations\", label: \"Integrations\", icon: LinkIcon },\n { id: \"sign-out\", label: \"Sign out\", icon: LogOut, destructive: true },\n]\n\nfunction NavItemRow({\n item,\n isActive,\n isCollapsed,\n activeVariant = \"default\",\n onClick,\n onNavigate,\n activeItemId,\n expandedItems,\n onToggleExpand,\n depth = 0,\n}: {\n item: SidebarNavItem\n isActive: boolean\n isCollapsed: boolean\n activeVariant?: ActiveVariant\n onClick?: () => void\n onNavigate?: (id: string) => void\n activeItemId?: string\n expandedItems?: Record<string, boolean>\n onToggleExpand?: (itemId: string) => void\n depth?: number\n}) {\n const activeClasses =\n activeVariant === \"gradient\"\n ? \"bg-gradient-to-r from-primary/10 to-transparent text-primary\"\n : \"bg-sidebar-accent text-sidebar-accent-foreground\"\n\n const iconActiveClasses =\n activeVariant === \"gradient\" ? \"text-primary\" : \"\"\n\n const hasChildren = item.children && item.children.length > 0\n const isExpanded = expandedItems?.[item.id] ?? false\n\n const content = (\n <div>\n <div className=\"flex items-center\">\n <button\n type=\"button\"\n onClick={onClick}\n className={cn(\n \"flex flex-1 items-center gap-3 rounded-lg text-sm font-medium transition-colors\",\n isCollapsed ? \"justify-center p-2\" : \"px-3 py-2\",\n isActive\n ? activeClasses\n : \"text-sidebar-foreground/70 hover:text-sidebar-foreground hover:bg-sidebar-accent\",\n )}\n style={depth > 0 && !isCollapsed ? { paddingLeft: `${0.75 + depth * 1}rem` } : undefined}\n >\n <item.icon className={cn(\"shrink-0\", isCollapsed ? \"w-5 h-5\" : \"w-4 h-4\", isActive && iconActiveClasses)} />\n {!isCollapsed && <span className=\"flex-1 truncate text-left\">{item.label}</span>}\n </button>\n {hasChildren && !isCollapsed && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation()\n onToggleExpand?.(item.id)\n }}\n className=\"p-1 mr-1 rounded text-sidebar-foreground/40 hover:text-sidebar-foreground hover:bg-sidebar-accent transition-colors\"\n >\n <ChevronDown\n className={cn(\n \"w-3.5 h-3.5 transition-transform duration-200\",\n !isExpanded && \"-rotate-90\",\n )}\n />\n </button>\n )}\n </div>\n {hasChildren && !isCollapsed && isExpanded && (\n <div className=\"space-y-0.5\">\n {item.children!.map((child) => (\n <NavItemRow\n key={child.id}\n item={child}\n isActive={activeItemId === child.id}\n isCollapsed={isCollapsed}\n activeVariant={activeVariant}\n activeItemId={activeItemId}\n onClick={() => onNavigate?.(child.id)}\n onNavigate={onNavigate}\n expandedItems={expandedItems}\n onToggleExpand={onToggleExpand}\n depth={depth + 1}\n />\n ))}\n </div>\n )}\n </div>\n )\n\n if (isCollapsed) {\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n onClick={onClick}\n className={cn(\n \"flex w-full items-center gap-3 rounded-lg text-sm font-medium transition-colors\",\n \"justify-center p-2\",\n isActive\n ? activeClasses\n : \"text-sidebar-foreground/70 hover:text-sidebar-foreground hover:bg-sidebar-accent\",\n )}\n >\n <item.icon className={cn(\"shrink-0 w-5 h-5\", isActive && iconActiveClasses)} />\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"right\">{item.label}</TooltipContent>\n </Tooltip>\n )\n }\n\n return content\n}\n\nfunction NavSection({\n section,\n activeItemId,\n isCollapsed,\n activeVariant = \"default\",\n onNavigate,\n}: {\n section: SidebarNavSection\n activeItemId?: string\n isCollapsed: boolean\n activeVariant?: ActiveVariant\n onNavigate?: (id: string) => void\n}) {\n const [isExpanded, setIsExpanded] = React.useState(true)\n const [expandedItems, setExpandedItems] = React.useState<Record<string, boolean>>({})\n const hasTitle = !isCollapsed && section.title\n\n const handleToggleExpand = React.useCallback((itemId: string) => {\n setExpandedItems((prev) => ({ ...prev, [itemId]: !prev[itemId] }))\n }, [])\n\n return (\n <div className=\"px-3 py-2\">\n {hasTitle && (\n <button\n type=\"button\"\n onClick={() => setIsExpanded(!isExpanded)}\n className=\"flex w-full items-center justify-between mb-1 px-3 group cursor-pointer\"\n >\n <span className=\"flex items-center gap-1.5 min-w-0\">\n {section.titleIconUrl && (\n <img\n src={section.titleIconUrl}\n alt=\"\"\n aria-hidden=\"true\"\n className=\"h-3.5 w-3.5 shrink-0 object-contain opacity-70\"\n />\n )}\n <span className=\"text-xs font-bold tracking-widest text-sidebar-foreground/50 uppercase truncate\">\n {section.title}\n </span>\n </span>\n <ChevronDown\n className={cn(\n \"w-3 h-3 text-sidebar-foreground/40 transition-transform duration-200\",\n !isExpanded && \"-rotate-90\",\n )}\n />\n </button>\n )}\n {(isExpanded || isCollapsed || !section.title) && (\n <div className=\"space-y-0.5\">\n {section.items.map((item) => (\n <NavItemRow\n key={item.id}\n item={item}\n isActive={activeItemId === item.id}\n isCollapsed={isCollapsed}\n activeVariant={activeVariant}\n activeItemId={activeItemId}\n onClick={() => onNavigate?.(item.id)}\n onNavigate={onNavigate}\n expandedItems={expandedItems}\n onToggleExpand={handleToggleExpand}\n />\n ))}\n {!isCollapsed && section.moreItems && section.moreItems.length > 0 && (\n <DropdownMenu>\n <DropdownMenuTrigger className=\"flex items-center gap-3 w-full px-3 py-2 rounded-lg text-sm font-medium text-sidebar-foreground/70 hover:text-sidebar-foreground hover:bg-sidebar-accent transition-colors outline-none\">\n <MoreHorizontal className=\"shrink-0 w-4 h-4\" />\n <span className=\"flex-1 text-left\">More</span>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\" side=\"bottom\" className=\"w-48\">\n {section.moreItems.map((item) => (\n <DropdownMenuItem\n key={item.id}\n onClick={() => onNavigate?.(item.id)}\n className=\"cursor-pointer\"\n >\n <item.icon className=\"mr-2 w-4 h-4 text-muted-foreground\" />\n <span>{item.label}</span>\n </DropdownMenuItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n {isCollapsed &&\n section.moreItems?.map((item) => (\n <NavItemRow\n key={item.id}\n item={item}\n isActive={activeItemId === item.id}\n isCollapsed={isCollapsed}\n activeVariant={activeVariant}\n onClick={() => onNavigate?.(item.id)}\n />\n ))}\n </div>\n )}\n </div>\n )\n}\n\nexport function QuickActionSidebarNav({\n className,\n brandLabel = \"ACME CO\",\n brandSubtitle = \"Placeholder\",\n brandImage,\n hideQuickAction,\n navSections = DEFAULT_NAV_SECTIONS,\n activeItemId = \"inbox\",\n activeVariant = \"default\",\n onNavigate,\n user = DEFAULT_USER,\n userMenuItems = DEFAULT_USER_MENU,\n onUserMenuAction,\n onCreateTask,\n defaultCollapsed = false,\n quickActionTemplates,\n quickActionTitle,\n quickActionDescription,\n ...props\n}: QuickActionSidebarNavProps) {\n const [isQuickActionOpen, setIsQuickActionOpen] = React.useState(false)\n const [isCollapsed, setIsCollapsed] = React.useState(defaultCollapsed)\n\n const initials =\n user.initials ??\n (user.name\n ? user.name.charAt(0).toUpperCase()\n : user.email\n ? user.email.charAt(0).toUpperCase()\n : \"U\")\n\n return (\n <TooltipProvider delayDuration={0}>\n <aside\n className={cn(\n \"flex h-full flex-col overflow-hidden bg-sidebar text-sidebar-foreground border-r border-sidebar-border transition-all duration-200\",\n isCollapsed ? \"w-16\" : \"w-64\",\n className,\n )}\n {...props}\n >\n {/* Header */}\n <div\n className={cn(\n \"relative flex shrink-0 items-center border-b border-sidebar-border\",\n isCollapsed ? \"justify-center h-16 px-2\" : \"px-6 py-4\",\n )}\n >\n {!isCollapsed && (\n <div className=\"flex items-center gap-2.5 pr-8\">\n {brandImage ? (\n <img src={brandImage} alt={brandLabel} className=\"h-10 object-contain\" />\n ) : (\n <>\n <div className=\"flex h-6 w-6 items-center justify-center rounded-full bg-sidebar-foreground text-sidebar\">\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\" className=\"w-3.5 h-3.5\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n </svg>\n </div>\n <div className=\"flex flex-col gap-0.5\">\n <span className=\"text-sm font-bold tracking-tight\">\n {brandLabel}\n </span>\n {brandSubtitle && (\n <span className=\"text-[10px] font-medium text-sidebar-foreground/50 uppercase tracking-wide\">\n {brandSubtitle}\n </span>\n )}\n </div>\n </>\n )}\n </div>\n )}\n\n <button\n type=\"button\"\n onClick={() => setIsCollapsed(!isCollapsed)}\n className={cn(\n \"p-1.5 rounded-md text-sidebar-foreground/50 hover:text-sidebar-foreground hover:bg-sidebar-accent transition-colors\",\n isCollapsed ? \"\" : \"absolute right-5 top-1/2 -translate-y-1/2\",\n )}\n title={isCollapsed ? \"Expand sidebar\" : \"Collapse sidebar\"}\n >\n {isCollapsed ? (\n <PanelLeftOpen className=\"w-4 h-4\" />\n ) : (\n <PanelLeftClose className=\"w-4 h-4\" />\n )}\n </button>\n </div>\n\n {/* Navigation */}\n <div className=\"flex-1 overflow-y-auto overflow-x-hidden py-3 space-y-1\">\n {navSections.map((section, idx) => (\n <React.Fragment key={section.title ?? idx}>\n {idx > 0 && <div className=\"mx-4 my-2 border-t border-sidebar-border\" />}\n <NavSection\n section={section}\n activeItemId={activeItemId}\n isCollapsed={isCollapsed}\n activeVariant={activeVariant}\n onNavigate={onNavigate}\n />\n </React.Fragment>\n ))}\n </div>\n\n {!hideQuickAction && (\n <div className={cn(\"px-3 pb-3\", isCollapsed ? \"hidden\" : \"block\")}>\n <button\n type=\"button\"\n onClick={() => setIsQuickActionOpen(true)}\n className=\"w-full flex items-center justify-between px-3 py-2.5 rounded-lg border border-sidebar-border bg-sidebar-primary text-sidebar-primary-foreground hover:bg-sidebar-primary/90 transition-colors group shadow-sm\"\n >\n <div className=\"flex items-center gap-2\">\n <svg\n className=\"w-4 h-4 text-sidebar-primary-foreground/80 group-hover:text-sidebar-primary-foreground transition-colors\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M13 10V3L4 14h7v7l9-11h-7z\"\n />\n </svg>\n <span className=\"text-sm font-medium\">Quick Action</span>\n </div>\n <kbd className=\"hidden sm:inline-flex items-center gap-0.5 px-1.5 py-0.5 text-[11px] font-mono rounded bg-sidebar-primary-foreground/20 text-sidebar-primary-foreground\">\n <span className=\"text-xs\">&#8984;</span>K\n </kbd>\n </button>\n </div>\n )}\n\n {isCollapsed && !hideQuickAction && (\n <div className=\"px-2 pb-3\">\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n onClick={() => setIsQuickActionOpen(true)}\n className=\"flex w-full items-center justify-center rounded-lg bg-sidebar-primary p-2.5 text-sidebar-primary-foreground shadow-sm transition-colors hover:bg-sidebar-primary/90\"\n title=\"Quick Action (⌘K)\"\n >\n <svg\n className=\"w-5 h-5\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M13 10V3L4 14h7v7l9-11h-7z\"\n />\n </svg>\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"right\">Quick Action (⌘K)</TooltipContent>\n </Tooltip>\n </div>\n )}\n\n {/* User Profile Footer */}\n <div className=\"p-3 border-t border-sidebar-border shrink-0\">\n <DropdownMenu>\n <DropdownMenuTrigger\n className={cn(\n \"flex items-center w-full rounded-lg hover:bg-sidebar-accent transition-colors outline-none\",\n isCollapsed ? \"justify-center p-1\" : \"p-2 gap-3\",\n )}\n >\n <Avatar className=\"h-8 w-8 rounded-md\">\n <AvatarFallback className=\"rounded-md bg-primary/10 text-primary text-xs font-medium\">\n {initials}\n </AvatarFallback>\n </Avatar>\n\n {!isCollapsed && (\n <div className=\"flex flex-col items-start flex-1 truncate\">\n <span className=\"text-sm font-medium leading-none truncate\">\n {user.name}\n </span>\n <span className=\"text-xs text-sidebar-foreground/50 truncate mt-0.5\">\n {user.email}\n </span>\n </div>\n )}\n\n {!isCollapsed && (\n <MoreVertical className=\"w-4 h-4 text-sidebar-foreground/50 shrink-0\" />\n )}\n </DropdownMenuTrigger>\n\n <DropdownMenuContent align=\"end\" side=\"right\" sideOffset={8} className=\"w-56\">\n <DropdownMenuLabel className=\"font-normal\">\n <div className=\"flex flex-col space-y-1\">\n <p className=\"text-sm font-medium leading-none\">{user.name}</p>\n <p className=\"text-xs leading-none text-muted-foreground\">{user.email}</p>\n </div>\n </DropdownMenuLabel>\n <DropdownMenuSeparator />\n {userMenuItems.map((item, idx) => {\n const showSepBefore = item.destructive && idx > 0\n return (\n <React.Fragment key={item.id}>\n {showSepBefore && <DropdownMenuSeparator />}\n <DropdownMenuItem\n onClick={() => onUserMenuAction?.(item.id)}\n className={cn(\n \"cursor-pointer\",\n item.destructive && \"text-destructive focus:text-destructive\",\n )}\n >\n <item.icon className=\"mr-2 h-4 w-4\" />\n <span>{item.label}</span>\n </DropdownMenuItem>\n </React.Fragment>\n )\n })}\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n </aside>\n\n {!hideQuickAction && (\n <QuickActionModal\n open={isQuickActionOpen}\n onOpenChange={setIsQuickActionOpen}\n onCreateTask={onCreateTask}\n templates={quickActionTemplates}\n title={quickActionTitle}\n description={quickActionDescription}\n />\n )}\n </TooltipProvider>\n )\n}\n"],"mappings":"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","names":["_a"]}
1
+ {"version":3,"sources":["../../src/components/quick-action-sidebar-nav.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport {\n Activity,\n BarChart2,\n Building,\n ChevronDown,\n Code,\n Inbox,\n Link as LinkIcon,\n LogOut,\n MessageSquare,\n MoreHorizontal,\n MoreVertical,\n PanelLeftClose,\n PanelLeftOpen,\n Plus,\n Search,\n Settings,\n Users,\n} from \"lucide-react\"\n\nimport { cn } from \"../lib/utils\"\nimport { Avatar, AvatarFallback } from \"./avatar\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"./dropdown-menu\"\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from \"./tooltip\"\nimport { QuickActionModal, type QuickActionTaskDraft, type QuickActionTemplate } from \"./quick-action-modal\"\n\nexport interface SidebarNavItem {\n id: string\n label: string\n icon: React.ComponentType<{ className?: string }>\n children?: SidebarNavItem[]\n}\n\nexport interface SidebarNavSection {\n title?: string\n /** Optional icon shown to the left of the section title (expanded sidebars only). */\n titleIconUrl?: string\n /**\n * Size of the title icon. Default `\"sm\"` (14px).\n * - `\"sm\"`: 14px, opacity 70 — secondary/decorative use\n * - `\"md\"`: 20px, opacity 90\n * - `\"lg\"`: 24px, full opacity — when the section icon is the primary brand mark\n */\n titleIconSize?: \"sm\" | \"md\" | \"lg\"\n items: SidebarNavItem[]\n moreItems?: SidebarNavItem[]\n}\n\nconst SECTION_TITLE_ICON_SIZE_CLASSES: Record<\n NonNullable<SidebarNavSection[\"titleIconSize\"]>,\n string\n> = {\n sm: \"h-3.5 w-3.5 opacity-70\",\n md: \"h-5 w-5 opacity-90\",\n lg: \"h-6 w-6\",\n}\n\nexport interface SidebarUserProfile {\n name: string\n email: string\n initials?: string\n}\n\nexport interface UserMenuItem {\n id: string\n label: string\n icon: React.ComponentType<{ className?: string }>\n destructive?: boolean\n}\n\nexport type ActiveVariant = \"default\" | \"gradient\"\n\ninterface QuickActionSidebarNavProps extends React.ComponentProps<\"aside\"> {\n brandLabel?: string\n brandSubtitle?: string\n brandImage?: string\n hideQuickAction?: boolean\n navSections?: SidebarNavSection[]\n activeItemId?: string\n activeVariant?: ActiveVariant\n onNavigate?: (itemId: string) => void\n user?: SidebarUserProfile\n userMenuItems?: UserMenuItem[]\n onUserMenuAction?: (itemId: string) => void\n onCreateTask?: (draft: QuickActionTaskDraft) => void\n defaultCollapsed?: boolean\n quickActionTemplates?: QuickActionTemplate[]\n quickActionTitle?: string\n quickActionDescription?: string\n}\n\nconst DEFAULT_NAV_SECTIONS: SidebarNavSection[] = [\n {\n items: [\n { id: \"home\", label: \"Home\", icon: Inbox },\n { id: \"inbox\", label: \"Inbox\", icon: Inbox },\n ],\n },\n {\n title: \"Focus\",\n items: [\n { id: \"inbox\", label: \"Unibox\", icon: Inbox },\n { id: \"accounts\", label: \"My Accounts\", icon: Building },\n { id: \"activity\", label: \"Activity\", icon: Activity },\n { id: \"dashboard\", label: \"Insights\", icon: BarChart2 },\n ],\n moreItems: [\n { id: \"search\", label: \"Search\", icon: Search },\n ],\n },\n {\n title: \"Assistant\",\n items: [\n { id: \"new-chat\", label: \"New chat\", icon: Plus },\n { id: \"chats\", label: \"Chats\", icon: MessageSquare },\n ],\n },\n {\n title: \"Your Teams\",\n items: [\n { id: \"team-a\", label: \"Team A\", icon: Users },\n { id: \"team-b\", label: \"Team B\", icon: Users },\n ],\n moreItems: [\n { id: \"more-teams\", label: \"More\", icon: MoreHorizontal },\n ],\n },\n]\n\nconst DEFAULT_USER: SidebarUserProfile = {\n name: \"John Doe\",\n email: \"jdoe@acmeco.com\",\n initials: \"JD\",\n}\n\nconst DEFAULT_USER_MENU: UserMenuItem[] = [\n { id: \"settings\", label: \"Settings\", icon: Settings },\n { id: \"dev\", label: \"Dev\", icon: Code },\n { id: \"integrations\", label: \"Integrations\", icon: LinkIcon },\n { id: \"sign-out\", label: \"Sign out\", icon: LogOut, destructive: true },\n]\n\nfunction NavItemRow({\n item,\n isActive,\n isCollapsed,\n activeVariant = \"default\",\n onClick,\n onNavigate,\n activeItemId,\n expandedItems,\n onToggleExpand,\n depth = 0,\n}: {\n item: SidebarNavItem\n isActive: boolean\n isCollapsed: boolean\n activeVariant?: ActiveVariant\n onClick?: () => void\n onNavigate?: (id: string) => void\n activeItemId?: string\n expandedItems?: Record<string, boolean>\n onToggleExpand?: (itemId: string) => void\n depth?: number\n}) {\n const activeClasses =\n activeVariant === \"gradient\"\n ? \"bg-gradient-to-r from-primary/10 to-transparent text-primary\"\n : \"bg-sidebar-accent text-sidebar-accent-foreground\"\n\n const iconActiveClasses =\n activeVariant === \"gradient\" ? \"text-primary\" : \"\"\n\n const hasChildren = item.children && item.children.length > 0\n const isExpanded = expandedItems?.[item.id] ?? false\n\n const content = (\n <div>\n <div className=\"flex items-center\">\n <button\n type=\"button\"\n onClick={onClick}\n className={cn(\n \"flex flex-1 items-center gap-3 rounded-lg text-sm font-medium transition-colors\",\n isCollapsed ? \"justify-center p-2\" : \"px-3 py-2\",\n isActive\n ? activeClasses\n : \"text-sidebar-foreground/70 hover:text-sidebar-foreground hover:bg-sidebar-accent\",\n )}\n style={depth > 0 && !isCollapsed ? { paddingLeft: `${0.75 + depth * 1}rem` } : undefined}\n >\n <item.icon className={cn(\"shrink-0\", isCollapsed ? \"w-5 h-5\" : \"w-4 h-4\", isActive && iconActiveClasses)} />\n {!isCollapsed && <span className=\"flex-1 truncate text-left\">{item.label}</span>}\n </button>\n {hasChildren && !isCollapsed && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation()\n onToggleExpand?.(item.id)\n }}\n className=\"p-1 mr-1 rounded text-sidebar-foreground/40 hover:text-sidebar-foreground hover:bg-sidebar-accent transition-colors\"\n >\n <ChevronDown\n className={cn(\n \"w-3.5 h-3.5 transition-transform duration-200\",\n !isExpanded && \"-rotate-90\",\n )}\n />\n </button>\n )}\n </div>\n {hasChildren && !isCollapsed && isExpanded && (\n <div className=\"space-y-0.5\">\n {item.children!.map((child) => (\n <NavItemRow\n key={child.id}\n item={child}\n isActive={activeItemId === child.id}\n isCollapsed={isCollapsed}\n activeVariant={activeVariant}\n activeItemId={activeItemId}\n onClick={() => onNavigate?.(child.id)}\n onNavigate={onNavigate}\n expandedItems={expandedItems}\n onToggleExpand={onToggleExpand}\n depth={depth + 1}\n />\n ))}\n </div>\n )}\n </div>\n )\n\n if (isCollapsed) {\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n onClick={onClick}\n className={cn(\n \"flex w-full items-center gap-3 rounded-lg text-sm font-medium transition-colors\",\n \"justify-center p-2\",\n isActive\n ? activeClasses\n : \"text-sidebar-foreground/70 hover:text-sidebar-foreground hover:bg-sidebar-accent\",\n )}\n >\n <item.icon className={cn(\"shrink-0 w-5 h-5\", isActive && iconActiveClasses)} />\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"right\">{item.label}</TooltipContent>\n </Tooltip>\n )\n }\n\n return content\n}\n\nfunction NavSection({\n section,\n activeItemId,\n isCollapsed,\n activeVariant = \"default\",\n onNavigate,\n}: {\n section: SidebarNavSection\n activeItemId?: string\n isCollapsed: boolean\n activeVariant?: ActiveVariant\n onNavigate?: (id: string) => void\n}) {\n const [isExpanded, setIsExpanded] = React.useState(true)\n const [expandedItems, setExpandedItems] = React.useState<Record<string, boolean>>({})\n const hasTitle = !isCollapsed && section.title\n\n const handleToggleExpand = React.useCallback((itemId: string) => {\n setExpandedItems((prev) => ({ ...prev, [itemId]: !prev[itemId] }))\n }, [])\n\n return (\n <div className=\"px-3 py-2\">\n {hasTitle && (\n <button\n type=\"button\"\n onClick={() => setIsExpanded(!isExpanded)}\n className=\"flex w-full items-center justify-between mb-1 px-3 group cursor-pointer\"\n >\n <span className=\"flex items-center gap-1.5 min-w-0\">\n {section.titleIconUrl && (\n <img\n src={section.titleIconUrl}\n alt=\"\"\n aria-hidden=\"true\"\n className={cn(\n \"shrink-0 object-contain\",\n SECTION_TITLE_ICON_SIZE_CLASSES[section.titleIconSize ?? \"sm\"],\n )}\n />\n )}\n <span className=\"text-xs font-bold tracking-widest text-sidebar-foreground/50 uppercase truncate\">\n {section.title}\n </span>\n </span>\n <ChevronDown\n className={cn(\n \"w-3 h-3 text-sidebar-foreground/40 transition-transform duration-200\",\n !isExpanded && \"-rotate-90\",\n )}\n />\n </button>\n )}\n {(isExpanded || isCollapsed || !section.title) && (\n <div className=\"space-y-0.5\">\n {section.items.map((item) => (\n <NavItemRow\n key={item.id}\n item={item}\n isActive={activeItemId === item.id}\n isCollapsed={isCollapsed}\n activeVariant={activeVariant}\n activeItemId={activeItemId}\n onClick={() => onNavigate?.(item.id)}\n onNavigate={onNavigate}\n expandedItems={expandedItems}\n onToggleExpand={handleToggleExpand}\n />\n ))}\n {!isCollapsed && section.moreItems && section.moreItems.length > 0 && (\n <DropdownMenu>\n <DropdownMenuTrigger className=\"flex items-center gap-3 w-full px-3 py-2 rounded-lg text-sm font-medium text-sidebar-foreground/70 hover:text-sidebar-foreground hover:bg-sidebar-accent transition-colors outline-none\">\n <MoreHorizontal className=\"shrink-0 w-4 h-4\" />\n <span className=\"flex-1 text-left\">More</span>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\" side=\"bottom\" className=\"w-48\">\n {section.moreItems.map((item) => (\n <DropdownMenuItem\n key={item.id}\n onClick={() => onNavigate?.(item.id)}\n className=\"cursor-pointer\"\n >\n <item.icon className=\"mr-2 w-4 h-4 text-muted-foreground\" />\n <span>{item.label}</span>\n </DropdownMenuItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n {isCollapsed &&\n section.moreItems?.map((item) => (\n <NavItemRow\n key={item.id}\n item={item}\n isActive={activeItemId === item.id}\n isCollapsed={isCollapsed}\n activeVariant={activeVariant}\n onClick={() => onNavigate?.(item.id)}\n />\n ))}\n </div>\n )}\n </div>\n )\n}\n\nexport function QuickActionSidebarNav({\n className,\n brandLabel = \"ACME CO\",\n brandSubtitle = \"Placeholder\",\n brandImage,\n hideQuickAction,\n navSections = DEFAULT_NAV_SECTIONS,\n activeItemId = \"inbox\",\n activeVariant = \"default\",\n onNavigate,\n user = DEFAULT_USER,\n userMenuItems = DEFAULT_USER_MENU,\n onUserMenuAction,\n onCreateTask,\n defaultCollapsed = false,\n quickActionTemplates,\n quickActionTitle,\n quickActionDescription,\n ...props\n}: QuickActionSidebarNavProps) {\n const [isQuickActionOpen, setIsQuickActionOpen] = React.useState(false)\n const [isCollapsed, setIsCollapsed] = React.useState(defaultCollapsed)\n\n const initials =\n user.initials ??\n (user.name\n ? user.name.charAt(0).toUpperCase()\n : user.email\n ? user.email.charAt(0).toUpperCase()\n : \"U\")\n\n return (\n <TooltipProvider delayDuration={0}>\n <aside\n className={cn(\n \"flex h-full flex-col overflow-hidden bg-sidebar text-sidebar-foreground border-r border-sidebar-border transition-all duration-200\",\n isCollapsed ? \"w-16\" : \"w-64\",\n className,\n )}\n {...props}\n >\n {/* Header */}\n <div\n className={cn(\n \"relative flex shrink-0 items-center border-b border-sidebar-border\",\n isCollapsed ? \"justify-center h-16 px-2\" : \"px-6 py-4\",\n )}\n >\n {!isCollapsed && (\n <div className=\"flex items-center gap-2.5 pr-8\">\n {brandImage ? (\n <img src={brandImage} alt={brandLabel} className=\"h-10 object-contain\" />\n ) : (\n <>\n <div className=\"flex h-6 w-6 items-center justify-center rounded-full bg-sidebar-foreground text-sidebar\">\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\" className=\"w-3.5 h-3.5\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n </svg>\n </div>\n <div className=\"flex flex-col gap-0.5\">\n <span className=\"text-sm font-bold tracking-tight\">\n {brandLabel}\n </span>\n {brandSubtitle && (\n <span className=\"text-[10px] font-medium text-sidebar-foreground/50 uppercase tracking-wide\">\n {brandSubtitle}\n </span>\n )}\n </div>\n </>\n )}\n </div>\n )}\n\n <button\n type=\"button\"\n onClick={() => setIsCollapsed(!isCollapsed)}\n className={cn(\n \"p-1.5 rounded-md text-sidebar-foreground/50 hover:text-sidebar-foreground hover:bg-sidebar-accent transition-colors\",\n isCollapsed ? \"\" : \"absolute right-5 top-1/2 -translate-y-1/2\",\n )}\n title={isCollapsed ? \"Expand sidebar\" : \"Collapse sidebar\"}\n >\n {isCollapsed ? (\n <PanelLeftOpen className=\"w-4 h-4\" />\n ) : (\n <PanelLeftClose className=\"w-4 h-4\" />\n )}\n </button>\n </div>\n\n {/* Navigation */}\n <div className=\"flex-1 overflow-y-auto overflow-x-hidden py-3 space-y-1\">\n {navSections.map((section, idx) => (\n <React.Fragment key={section.title ?? idx}>\n {idx > 0 && <div className=\"mx-4 my-2 border-t border-sidebar-border\" />}\n <NavSection\n section={section}\n activeItemId={activeItemId}\n isCollapsed={isCollapsed}\n activeVariant={activeVariant}\n onNavigate={onNavigate}\n />\n </React.Fragment>\n ))}\n </div>\n\n {!hideQuickAction && (\n <div className={cn(\"px-3 pb-3\", isCollapsed ? \"hidden\" : \"block\")}>\n <button\n type=\"button\"\n onClick={() => setIsQuickActionOpen(true)}\n className=\"w-full flex items-center justify-between px-3 py-2.5 rounded-lg border border-sidebar-border bg-sidebar-primary text-sidebar-primary-foreground hover:bg-sidebar-primary/90 transition-colors group shadow-sm\"\n >\n <div className=\"flex items-center gap-2\">\n <svg\n className=\"w-4 h-4 text-sidebar-primary-foreground/80 group-hover:text-sidebar-primary-foreground transition-colors\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M13 10V3L4 14h7v7l9-11h-7z\"\n />\n </svg>\n <span className=\"text-sm font-medium\">Quick Action</span>\n </div>\n <kbd className=\"hidden sm:inline-flex items-center gap-0.5 px-1.5 py-0.5 text-[11px] font-mono rounded bg-sidebar-primary-foreground/20 text-sidebar-primary-foreground\">\n <span className=\"text-xs\">&#8984;</span>K\n </kbd>\n </button>\n </div>\n )}\n\n {isCollapsed && !hideQuickAction && (\n <div className=\"px-2 pb-3\">\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n onClick={() => setIsQuickActionOpen(true)}\n className=\"flex w-full items-center justify-center rounded-lg bg-sidebar-primary p-2.5 text-sidebar-primary-foreground shadow-sm transition-colors hover:bg-sidebar-primary/90\"\n title=\"Quick Action (⌘K)\"\n >\n <svg\n className=\"w-5 h-5\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M13 10V3L4 14h7v7l9-11h-7z\"\n />\n </svg>\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"right\">Quick Action (⌘K)</TooltipContent>\n </Tooltip>\n </div>\n )}\n\n {/* User Profile Footer */}\n <div className=\"p-3 border-t border-sidebar-border shrink-0\">\n <DropdownMenu>\n <DropdownMenuTrigger\n className={cn(\n \"flex items-center w-full rounded-lg hover:bg-sidebar-accent transition-colors outline-none\",\n isCollapsed ? \"justify-center p-1\" : \"p-2 gap-3\",\n )}\n >\n <Avatar className=\"h-8 w-8 rounded-md\">\n <AvatarFallback className=\"rounded-md bg-primary/10 text-primary text-xs font-medium\">\n {initials}\n </AvatarFallback>\n </Avatar>\n\n {!isCollapsed && (\n <div className=\"flex flex-col items-start flex-1 truncate\">\n <span className=\"text-sm font-medium leading-none truncate\">\n {user.name}\n </span>\n <span className=\"text-xs text-sidebar-foreground/50 truncate mt-0.5\">\n {user.email}\n </span>\n </div>\n )}\n\n {!isCollapsed && (\n <MoreVertical className=\"w-4 h-4 text-sidebar-foreground/50 shrink-0\" />\n )}\n </DropdownMenuTrigger>\n\n <DropdownMenuContent align=\"end\" side=\"right\" sideOffset={8} className=\"w-56\">\n <DropdownMenuLabel className=\"font-normal\">\n <div className=\"flex flex-col space-y-1\">\n <p className=\"text-sm font-medium leading-none\">{user.name}</p>\n <p className=\"text-xs leading-none text-muted-foreground\">{user.email}</p>\n </div>\n </DropdownMenuLabel>\n <DropdownMenuSeparator />\n {userMenuItems.map((item, idx) => {\n const showSepBefore = item.destructive && idx > 0\n return (\n <React.Fragment key={item.id}>\n {showSepBefore && <DropdownMenuSeparator />}\n <DropdownMenuItem\n onClick={() => onUserMenuAction?.(item.id)}\n className={cn(\n \"cursor-pointer\",\n item.destructive && \"text-destructive focus:text-destructive\",\n )}\n >\n <item.icon className=\"mr-2 h-4 w-4\" />\n <span>{item.label}</span>\n </DropdownMenuItem>\n </React.Fragment>\n )\n })}\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n </aside>\n\n {!hideQuickAction && (\n <QuickActionModal\n open={isQuickActionOpen}\n onOpenChange={setIsQuickActionOpen}\n onCreateTask={onCreateTask}\n templates={quickActionTemplates}\n title={quickActionTitle}\n description={quickActionDescription}\n />\n )}\n </TooltipProvider>\n )\n}\n"],"mappings":"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","names":["_a"]}
@@ -6,6 +6,7 @@ interface SignalApprovalLabels {
6
6
  dismissButton?: string;
7
7
  approvedStatus?: string;
8
8
  dismissedStatus?: string;
9
+ opportunityCreated?: string;
9
10
  confirmPrompt?: string;
10
11
  dismissPrompt?: string;
11
12
  feedbackPrompt?: string;
@@ -39,6 +39,7 @@ const DEFAULT_LABELS = {
39
39
  dismissButton: "Not Helpful",
40
40
  approvedStatus: "Action Approved",
41
41
  dismissedStatus: "Action Dismissed",
42
+ opportunityCreated: "Opportunity Created",
42
43
  confirmPrompt: "This will approve this action for",
43
44
  dismissPrompt: "What\u2019s the issue with this action?",
44
45
  feedbackPrompt: "Quick feedback \u2014 what made this action useful?"
@@ -238,11 +239,11 @@ function Actions() {
238
239
  rel: "noopener noreferrer",
239
240
  className: "inline-flex items-center gap-1 hover:underline underline-offset-2",
240
241
  children: [
241
- "Opportunity Created",
242
+ labels.opportunityCreated,
242
243
  /* @__PURE__ */ jsx(ExternalLink, { className: "h-3 w-3" })
243
244
  ]
244
245
  }
245
- ) : /* @__PURE__ */ jsx("span", { children: "Opportunity Created" })
246
+ ) : /* @__PURE__ */ jsx("span", { children: labels.opportunityCreated })
246
247
  ] }),
247
248
  submittedFeedback && /* @__PURE__ */ jsx(
248
249
  SubmittedFeedback,
@@ -279,11 +280,11 @@ function Actions() {
279
280
  rel: "noopener noreferrer",
280
281
  className: "inline-flex items-center gap-1 hover:underline underline-offset-2",
281
282
  children: [
282
- "Opportunity Created",
283
+ labels.opportunityCreated,
283
284
  /* @__PURE__ */ jsx(ExternalLink, { className: "h-3 w-3" })
284
285
  ]
285
286
  }
286
- ) : /* @__PURE__ */ jsx("span", { children: "Opportunity Created" })
287
+ ) : /* @__PURE__ */ jsx("span", { children: labels.opportunityCreated })
287
288
  ] }),
288
289
  /* @__PURE__ */ jsx("p", { className: "text-xs font-medium text-muted-foreground", children: labels.feedbackPrompt }),
289
290
  /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1.5", children: approveReasons.map((reason) => {
@@ -395,7 +396,7 @@ function Actions() {
395
396
  return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
396
397
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 text-xs text-muted-foreground", children: [
397
398
  /* @__PURE__ */ jsx(ThumbsDown, { className: "h-3.5 w-3.5" }),
398
- /* @__PURE__ */ jsx("span", { children: "Signal Dismissed" })
399
+ /* @__PURE__ */ jsx("span", { children: labels.dismissedStatus })
399
400
  ] }),
400
401
  submittedFeedback && /* @__PURE__ */ jsx(
401
402
  SubmittedFeedback,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/signal-feedback-inline.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport { Check, CirclePlus, ExternalLink, Lock, ThumbsDown } from \"lucide-react\"\n\nconst dismissReasons = [\n \"Bad timing\",\n \"Inaccurate data\",\n \"Wrong account\",\n \"Already handled\",\n \"Not actionable\",\n \"Other\",\n]\n\nconst approveReasons = [\n \"Right timing\",\n \"Accurate data\",\n \"Good prospect fit\",\n \"Actionable\",\n]\n\ntype ApprovalState = \"pending\" | \"confirming\" | \"approving-feedback\" | \"dismissing\" | \"approved\" | \"dismissed\" | \"auto-approved\"\n\ninterface SignalApprovalLabels {\n approveButton?: string\n dismissButton?: string\n approvedStatus?: string\n dismissedStatus?: string\n confirmPrompt?: string\n dismissPrompt?: string\n feedbackPrompt?: string\n}\n\nconst DEFAULT_LABELS: Required<SignalApprovalLabels> = {\n approveButton: \"Approve action\",\n dismissButton: \"Not Helpful\",\n approvedStatus: \"Action Approved\",\n dismissedStatus: \"Action Dismissed\",\n confirmPrompt: \"This will approve this action for\",\n dismissPrompt: \"What\\u2019s the issue with this action?\",\n feedbackPrompt: \"Quick feedback \\u2014 what made this action useful?\",\n}\n\ninterface SignalApprovalContextValue {\n approvalState: ApprovalState\n companyName: string\n opportunityUrl?: string\n scheduledTime?: string\n labels: Required<SignalApprovalLabels>\n approve: () => void\n submitApproveFeedback: (reasons: string[], detail: string) => void\n skipApproveFeedback: () => void\n dismiss: (reasons: string[], detail: string) => void\n requestApproval: () => void\n requestDismiss: () => void\n cancel: () => void\n}\n\nconst SignalApprovalCtx = React.createContext<SignalApprovalContextValue | null>(null)\n\nexport function useSignalApproval() {\n const ctx = React.useContext(SignalApprovalCtx)\n if (!ctx) throw new Error(\"SignalApproval components must be used within SignalApproval.Root\")\n return ctx\n}\n\ninterface RootProps {\n children: React.ReactNode\n companyName: string\n opportunityUrl?: string\n scheduledTime?: string\n initialApprovalState?: ApprovalState\n labels?: SignalApprovalLabels\n onApprove?: () => void\n onApproveFeedback?: (reasons: string[], detail: string) => void\n onDismiss?: (reasons: string[], detail: string) => void\n}\n\nfunction Root({ children, companyName, opportunityUrl, scheduledTime, initialApprovalState, labels: labelOverrides, onApprove, onApproveFeedback, onDismiss }: RootProps) {\n const labels = React.useMemo(() => ({ ...DEFAULT_LABELS, ...labelOverrides }), [labelOverrides])\n const [approvalState, setApprovalState] = React.useState<ApprovalState>(initialApprovalState ?? \"pending\")\n\n const requestApproval = React.useCallback(() => {\n setApprovalState(\"confirming\")\n }, [])\n\n const requestDismiss = React.useCallback(() => {\n setApprovalState(\"dismissing\")\n }, [])\n\n const cancel = React.useCallback(() => {\n setApprovalState(\"pending\")\n }, [])\n\n const approve = React.useCallback(() => {\n setApprovalState(\"approving-feedback\")\n onApprove?.()\n }, [onApprove])\n\n const submitApproveFeedback = React.useCallback(\n (reasons: string[], detail: string) => {\n setApprovalState(\"approved\")\n onApproveFeedback?.(reasons, detail)\n },\n [onApproveFeedback]\n )\n\n const skipApproveFeedback = React.useCallback(() => {\n setApprovalState(\"approved\")\n }, [])\n\n const dismiss = React.useCallback(\n (reasons: string[], detail: string) => {\n setApprovalState(\"dismissed\")\n onDismiss?.(reasons, detail)\n },\n [onDismiss]\n )\n\n return (\n <SignalApprovalCtx.Provider\n value={{ approvalState, companyName, opportunityUrl, scheduledTime, labels, approve, submitApproveFeedback, skipApproveFeedback, dismiss, requestApproval, requestDismiss, cancel }}\n >\n {children}\n </SignalApprovalCtx.Provider>\n )\n}\n\nfunction SubmittedFeedback({\n reasons,\n detail,\n variant,\n onEdit,\n}: {\n reasons: string[]\n detail: string\n variant: \"approve\" | \"dismiss\"\n onEdit: () => void\n}) {\n if (reasons.length === 0 && !detail) return null\n const pillClass =\n variant === \"approve\"\n ? \"border-emerald-200/60 bg-emerald-50/50 text-emerald-700/70\"\n : \"border-red-200/60 bg-red-50/50 text-red-700/70\"\n\n return (\n <button\n type=\"button\"\n onClick={onEdit}\n className=\"w-full text-left space-y-1.5 group cursor-pointer\"\n >\n {reasons.length > 0 && (\n <div className=\"flex flex-wrap gap-1\">\n {reasons.map((r) => (\n <span\n key={r}\n className={`rounded-full border px-2 py-0.5 text-[10px] font-medium transition-colors group-hover:opacity-80 ${pillClass}`}\n >\n {r}\n </span>\n ))}\n </div>\n )}\n {detail && (\n <p className=\"text-[11px] text-muted-foreground/70 leading-snug group-hover:text-muted-foreground transition-colors\">{detail}</p>\n )}\n </button>\n )\n}\n\nfunction Actions() {\n const { approvalState, companyName, opportunityUrl, scheduledTime, labels, approve, submitApproveFeedback, skipApproveFeedback, dismiss, requestApproval, requestDismiss, cancel } =\n useSignalApproval()\n const [selectedReasons, setSelectedReasons] = React.useState<string[]>([])\n const [detailText, setDetailText] = React.useState(\"\")\n const [submittedFeedback, setSubmittedFeedback] = React.useState<{ reasons: string[]; detail: string } | null>(null)\n const [isEditing, setIsEditing] = React.useState(false)\n\n const otherSelected = selectedReasons.includes(\"Other\")\n const canSubmitDismiss = selectedReasons.length > 0 && (!otherSelected || detailText.trim().length > 0)\n const canSubmitApprove = selectedReasons.length > 0 || detailText.trim().length > 0\n\n const toggleReason = (reason: string) => {\n setSelectedReasons((prev) =>\n prev.includes(reason) ? prev.filter((r) => r !== reason) : [...prev, reason]\n )\n }\n\n const startEditing = () => {\n if (submittedFeedback) {\n setSelectedReasons([...submittedFeedback.reasons])\n setDetailText(submittedFeedback.detail)\n }\n setIsEditing(true)\n }\n\n const handleDismissSubmit = () => {\n if (!canSubmitDismiss) return\n const fb = { reasons: [...selectedReasons], detail: detailText.trim() }\n setSubmittedFeedback(fb)\n dismiss(selectedReasons, detailText.trim())\n setSelectedReasons([])\n setDetailText(\"\")\n setIsEditing(false)\n }\n\n const handleApproveSubmit = () => {\n const fb = { reasons: [...selectedReasons], detail: detailText.trim() }\n setSubmittedFeedback(fb)\n submitApproveFeedback(selectedReasons, detailText.trim())\n setSelectedReasons([])\n setDetailText(\"\")\n setIsEditing(false)\n }\n\n const handleEditCancel = () => {\n setSelectedReasons([])\n setDetailText(\"\")\n setIsEditing(false)\n }\n\n const handleCancel = () => {\n cancel()\n setSelectedReasons([])\n setDetailText(\"\")\n }\n\n if (approvalState === \"approved\") {\n if (isEditing) {\n return (\n <div className=\"space-y-3\">\n <div className=\"flex items-center gap-1.5 text-xs font-medium text-emerald-600 mb-2\">\n <Check className=\"h-3.5 w-3.5\" />\n {opportunityUrl ? (\n <a href={opportunityUrl} target=\"_blank\" rel=\"noopener noreferrer\" className=\"inline-flex items-center gap-1 hover:underline underline-offset-2\">\n {labels.approvedStatus} <ExternalLink className=\"h-3 w-3\" />\n </a>\n ) : (\n <span>{labels.approvedStatus}</span>\n )}\n </div>\n <p className=\"text-xs font-medium text-muted-foreground\">Edit your feedback</p>\n <div className=\"flex flex-wrap gap-1.5\">\n {approveReasons.map((reason) => {\n const selected = selectedReasons.includes(reason)\n return (\n <button key={reason} type=\"button\" onClick={() => toggleReason(reason)}\n className={`rounded-full border px-2.5 py-1 text-[11px] font-medium transition-colors ${\n selected ? \"border-emerald-200 bg-emerald-100 text-emerald-700\" : \"border-border bg-background text-muted-foreground hover:bg-muted/50 hover:text-foreground\"\n }`}>{reason}</button>\n )\n })}\n </div>\n <input type=\"text\" value={detailText} onChange={(e) => setDetailText(e.target.value)}\n onKeyDown={(e) => { if (e.key === \"Enter\" && canSubmitApprove) handleApproveSubmit() }}\n placeholder=\"Tell us more (optional)\"\n className=\"h-7 w-full rounded-md border border-border bg-muted/20 px-2.5 text-xs text-foreground placeholder:text-muted-foreground/60 focus:outline-none focus:ring-1 focus:ring-ring\" />\n <div className=\"flex items-center gap-2\">\n <button type=\"button\" onClick={handleApproveSubmit} disabled={!canSubmitApprove}\n className={`inline-flex h-7 items-center gap-1.5 rounded-md px-3 text-xs font-semibold transition-colors ${canSubmitApprove ? \"bg-foreground text-background hover:bg-foreground/90\" : \"cursor-not-allowed bg-muted text-muted-foreground\"}`}>\n Save\n </button>\n <button type=\"button\" onClick={handleEditCancel}\n className=\"inline-flex h-7 items-center rounded-md border border-border px-3 text-xs font-medium text-muted-foreground transition-colors hover:bg-muted hover:text-foreground\">\n Cancel\n </button>\n </div>\n </div>\n )\n }\n\n return (\n <div className=\"space-y-2\">\n <div className=\"flex items-center gap-1.5 text-xs font-medium text-emerald-600\">\n <Check className=\"h-3.5 w-3.5\" />\n {opportunityUrl ? (\n <a\n href={opportunityUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"inline-flex items-center gap-1 hover:underline underline-offset-2\"\n >\n Opportunity Created\n <ExternalLink className=\"h-3 w-3\" />\n </a>\n ) : (\n <span>Opportunity Created</span>\n )}\n </div>\n {submittedFeedback && (\n <SubmittedFeedback\n reasons={submittedFeedback.reasons}\n detail={submittedFeedback.detail}\n variant=\"approve\"\n onEdit={startEditing}\n />\n )}\n </div>\n )\n }\n\n if (approvalState === \"auto-approved\") {\n return (\n <div className=\"space-y-2\">\n <div className=\"flex items-center gap-1.5 text-xs font-medium text-emerald-600\">\n <Check className=\"h-3.5 w-3.5\" />\n <span>{labels.approvedStatus}</span>\n </div>\n {scheduledTime && (\n <p className=\"text-[11px] text-muted-foreground\">Scheduled: {scheduledTime}</p>\n )}\n </div>\n )\n }\n\n if (approvalState === \"approving-feedback\") {\n return (\n <div className=\"space-y-3\">\n <div className=\"flex items-center gap-1.5 text-xs font-medium text-emerald-600 mb-2\">\n <Check className=\"h-3.5 w-3.5\" />\n {opportunityUrl ? (\n <a\n href={opportunityUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"inline-flex items-center gap-1 hover:underline underline-offset-2\"\n >\n Opportunity Created\n <ExternalLink className=\"h-3 w-3\" />\n </a>\n ) : (\n <span>Opportunity Created</span>\n )}\n </div>\n <p className=\"text-xs font-medium text-muted-foreground\">{labels.feedbackPrompt}</p>\n <div className=\"flex flex-wrap gap-1.5\">\n {approveReasons.map((reason) => {\n const selected = selectedReasons.includes(reason)\n return (\n <button\n key={reason}\n type=\"button\"\n onClick={() => toggleReason(reason)}\n className={`rounded-full border px-2.5 py-1 text-[11px] font-medium transition-colors ${\n selected\n ? \"border-emerald-200 bg-emerald-100 text-emerald-700\"\n : \"border-border bg-background text-muted-foreground hover:bg-muted/50 hover:text-foreground\"\n }`}\n >\n {reason}\n </button>\n )\n })}\n </div>\n\n <input\n type=\"text\"\n value={detailText}\n onChange={(e) => setDetailText(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" && canSubmitApprove) handleApproveSubmit()\n }}\n placeholder=\"Tell us more (optional)\"\n className=\"h-7 w-full rounded-md border border-border bg-muted/20 px-2.5 text-xs text-foreground placeholder:text-muted-foreground/60 focus:outline-none focus:ring-1 focus:ring-ring\"\n />\n\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={handleApproveSubmit}\n disabled={!canSubmitApprove}\n className={`inline-flex h-7 items-center gap-1.5 rounded-md px-3 text-xs font-semibold transition-colors ${\n canSubmitApprove\n ? \"bg-foreground text-background hover:bg-foreground/90\"\n : \"cursor-not-allowed bg-muted text-muted-foreground\"\n }`}\n >\n Submit\n </button>\n <button\n type=\"button\"\n onClick={skipApproveFeedback}\n className=\"inline-flex h-7 items-center rounded-md border border-border px-3 text-xs font-medium text-muted-foreground transition-colors hover:bg-muted hover:text-foreground\"\n >\n Skip\n </button>\n </div>\n </div>\n )\n }\n\n if (approvalState === \"dismissed\") {\n if (isEditing) {\n return (\n <div className=\"space-y-3\">\n <div className=\"flex items-center gap-1.5 text-xs text-muted-foreground mb-2\">\n <ThumbsDown className=\"h-3.5 w-3.5\" />\n <span>{labels.dismissedStatus}</span>\n </div>\n <p className=\"text-xs font-medium text-muted-foreground\">Edit your feedback</p>\n <div className=\"flex flex-wrap gap-1.5\">\n {dismissReasons.map((reason) => {\n const selected = selectedReasons.includes(reason)\n return (\n <button key={reason} type=\"button\" onClick={() => toggleReason(reason)}\n className={`rounded-full border px-2.5 py-1 text-[11px] font-medium transition-colors ${\n selected ? \"border-red-200 bg-red-100 text-red-700\" : \"border-border bg-background text-muted-foreground hover:bg-muted/50 hover:text-foreground\"\n }`}>{reason}</button>\n )\n })}\n </div>\n <input type=\"text\" value={detailText} onChange={(e) => setDetailText(e.target.value)}\n onKeyDown={(e) => { if (e.key === \"Enter\" && canSubmitDismiss) handleDismissSubmit() }}\n placeholder={otherSelected ? \"Please describe (required)\" : \"Provide additional feedback...\"}\n className=\"h-7 w-full rounded-md border border-border bg-muted/20 px-2.5 text-xs text-foreground placeholder:text-muted-foreground/60 focus:outline-none focus:ring-1 focus:ring-ring\" />\n <div className=\"flex items-center gap-2\">\n <button type=\"button\" onClick={handleDismissSubmit} disabled={!canSubmitDismiss}\n className={`inline-flex h-7 items-center gap-1.5 rounded-md px-3 text-xs font-semibold transition-colors ${canSubmitDismiss ? \"bg-foreground text-background hover:bg-foreground/90\" : \"cursor-not-allowed bg-muted text-muted-foreground\"}`}>\n Save\n </button>\n <button type=\"button\" onClick={handleEditCancel}\n className=\"inline-flex h-7 items-center rounded-md border border-border px-3 text-xs font-medium text-muted-foreground transition-colors hover:bg-muted hover:text-foreground\">\n Cancel\n </button>\n </div>\n </div>\n )\n }\n\n return (\n <div className=\"space-y-2\">\n <div className=\"flex items-center gap-1.5 text-xs text-muted-foreground\">\n <ThumbsDown className=\"h-3.5 w-3.5\" />\n <span>Signal Dismissed</span>\n </div>\n {submittedFeedback && (\n <SubmittedFeedback\n reasons={submittedFeedback.reasons}\n detail={submittedFeedback.detail}\n variant=\"dismiss\"\n onEdit={startEditing}\n />\n )}\n </div>\n )\n }\n\n if (approvalState === \"confirming\") {\n return (\n <div className=\"space-y-3\">\n <div className=\"rounded-md border border-border bg-muted/30 p-3\">\n <p className=\"text-sm text-foreground\">\n {labels.confirmPrompt} <strong>{companyName}</strong>. Confirm?\n </p>\n </div>\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={approve}\n className=\"inline-flex h-7 items-center gap-1.5 rounded-md bg-foreground px-3 text-xs font-semibold text-background transition-colors hover:bg-foreground/90\"\n >\n <Check className=\"h-3 w-3\" />\n Confirm\n </button>\n <button\n type=\"button\"\n onClick={handleCancel}\n className=\"inline-flex h-7 items-center rounded-md border border-border px-3 text-xs font-medium text-muted-foreground transition-colors hover:bg-muted hover:text-foreground\"\n >\n Cancel\n </button>\n </div>\n </div>\n )\n }\n\n if (approvalState === \"dismissing\") {\n return (\n <div className=\"space-y-3\">\n <p className=\"text-xs font-medium text-muted-foreground\">{labels.dismissPrompt}</p>\n <div className=\"flex flex-wrap gap-1.5\">\n {dismissReasons.map((reason) => {\n const selected = selectedReasons.includes(reason)\n return (\n <button\n key={reason}\n type=\"button\"\n onClick={() => toggleReason(reason)}\n className={`rounded-full border px-2.5 py-1 text-[11px] font-medium transition-colors ${\n selected\n ? \"border-red-200 bg-red-100 text-red-700\"\n : \"border-border bg-background text-muted-foreground hover:bg-muted/50 hover:text-foreground\"\n }`}\n >\n {reason}\n </button>\n )\n })}\n </div>\n\n {(selectedReasons.length > 0 || otherSelected) && (\n <input\n type=\"text\"\n value={detailText}\n onChange={(e) => setDetailText(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" && canSubmitDismiss) handleDismissSubmit()\n }}\n placeholder={otherSelected ? \"Please describe (required)\" : \"Provide additional feedback...\"}\n className=\"h-7 w-full rounded-md border border-border bg-muted/20 px-2.5 text-xs text-foreground placeholder:text-muted-foreground/60 focus:outline-none focus:ring-1 focus:ring-ring\"\n />\n )}\n\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={handleDismissSubmit}\n disabled={!canSubmitDismiss}\n className={`inline-flex h-7 items-center gap-1.5 rounded-md px-3 text-xs font-semibold transition-colors ${\n canSubmitDismiss\n ? \"bg-foreground text-background hover:bg-foreground/90\"\n : \"cursor-not-allowed bg-muted text-muted-foreground\"\n }`}\n >\n Submit\n </button>\n <button\n type=\"button\"\n onClick={handleCancel}\n className=\"inline-flex h-7 items-center rounded-md border border-border px-3 text-xs font-medium text-muted-foreground transition-colors hover:bg-muted hover:text-foreground\"\n >\n Cancel\n </button>\n </div>\n </div>\n )\n }\n\n return (\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={requestApproval}\n className=\"inline-flex h-7 items-center gap-1.5 rounded-md border border-border bg-foreground px-3 text-xs font-semibold text-background shadow-none transition-colors hover:bg-foreground/90\"\n >\n <CirclePlus className=\"h-3.5 w-3.5\" />\n {labels.approveButton}\n </button>\n <button\n type=\"button\"\n onClick={requestDismiss}\n className=\"inline-flex h-7 items-center gap-1.5 rounded-md border border-border px-3 text-xs font-medium text-muted-foreground shadow-none transition-colors hover:bg-muted hover:text-foreground\"\n >\n <ThumbsDown className=\"h-3.5 w-3.5\" />\n {labels.dismissButton}\n </button>\n </div>\n )\n}\n\nfunction Gate({ children }: { children: React.ReactNode }) {\n const { approvalState } = useSignalApproval()\n const isLocked =\n approvalState === \"pending\" || approvalState === \"confirming\" || approvalState === \"dismissing\"\n\n return (\n <div className=\"relative\">\n {isLocked && (\n <div className=\"pointer-events-none absolute inset-x-0 top-4 z-10 flex justify-center\">\n <div className=\"flex items-center gap-1.5 rounded-full border border-border bg-background px-3 py-1.5 text-xs text-muted-foreground shadow-sm\">\n <Lock className=\"h-3 w-3\" />\n Approve or dismiss the signal above to unlock\n </div>\n </div>\n )}\n <div\n className={`transition-opacity duration-300 ${isLocked ? \"pointer-events-none select-none opacity-40\" : \"opacity-100\"}`}\n >\n {children}\n </div>\n </div>\n )\n}\n\nexport {\n Root as SignalApprovalRoot,\n Actions as SignalApprovalActions,\n Gate as SignalApprovalGate,\n}\nexport const SignalApproval = { Root, Actions, Gate }\nexport type { ApprovalState, SignalApprovalLabels, SignalApprovalContextValue, RootProps as SignalApprovalRootProps }\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/components/signal-feedback-inline.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport { Check, CirclePlus, ExternalLink, Lock, ThumbsDown } from \"lucide-react\"\n\nconst dismissReasons = [\n \"Bad timing\",\n \"Inaccurate data\",\n \"Wrong account\",\n \"Already handled\",\n \"Not actionable\",\n \"Other\",\n]\n\nconst approveReasons = [\n \"Right timing\",\n \"Accurate data\",\n \"Good prospect fit\",\n \"Actionable\",\n]\n\ntype ApprovalState = \"pending\" | \"confirming\" | \"approving-feedback\" | \"dismissing\" | \"approved\" | \"dismissed\" | \"auto-approved\"\n\ninterface SignalApprovalLabels {\n approveButton?: string\n dismissButton?: string\n approvedStatus?: string\n dismissedStatus?: string\n opportunityCreated?: string\n confirmPrompt?: string\n dismissPrompt?: string\n feedbackPrompt?: string\n}\n\nconst DEFAULT_LABELS: Required<SignalApprovalLabels> = {\n approveButton: \"Approve action\",\n dismissButton: \"Not Helpful\",\n approvedStatus: \"Action Approved\",\n dismissedStatus: \"Action Dismissed\",\n opportunityCreated: \"Opportunity Created\",\n confirmPrompt: \"This will approve this action for\",\n dismissPrompt: \"What\\u2019s the issue with this action?\",\n feedbackPrompt: \"Quick feedback \\u2014 what made this action useful?\",\n}\n\ninterface SignalApprovalContextValue {\n approvalState: ApprovalState\n companyName: string\n opportunityUrl?: string\n scheduledTime?: string\n labels: Required<SignalApprovalLabels>\n approve: () => void\n submitApproveFeedback: (reasons: string[], detail: string) => void\n skipApproveFeedback: () => void\n dismiss: (reasons: string[], detail: string) => void\n requestApproval: () => void\n requestDismiss: () => void\n cancel: () => void\n}\n\nconst SignalApprovalCtx = React.createContext<SignalApprovalContextValue | null>(null)\n\nexport function useSignalApproval() {\n const ctx = React.useContext(SignalApprovalCtx)\n if (!ctx) throw new Error(\"SignalApproval components must be used within SignalApproval.Root\")\n return ctx\n}\n\ninterface RootProps {\n children: React.ReactNode\n companyName: string\n opportunityUrl?: string\n scheduledTime?: string\n initialApprovalState?: ApprovalState\n labels?: SignalApprovalLabels\n onApprove?: () => void\n onApproveFeedback?: (reasons: string[], detail: string) => void\n onDismiss?: (reasons: string[], detail: string) => void\n}\n\nfunction Root({ children, companyName, opportunityUrl, scheduledTime, initialApprovalState, labels: labelOverrides, onApprove, onApproveFeedback, onDismiss }: RootProps) {\n const labels = React.useMemo(() => ({ ...DEFAULT_LABELS, ...labelOverrides }), [labelOverrides])\n const [approvalState, setApprovalState] = React.useState<ApprovalState>(initialApprovalState ?? \"pending\")\n\n const requestApproval = React.useCallback(() => {\n setApprovalState(\"confirming\")\n }, [])\n\n const requestDismiss = React.useCallback(() => {\n setApprovalState(\"dismissing\")\n }, [])\n\n const cancel = React.useCallback(() => {\n setApprovalState(\"pending\")\n }, [])\n\n const approve = React.useCallback(() => {\n setApprovalState(\"approving-feedback\")\n onApprove?.()\n }, [onApprove])\n\n const submitApproveFeedback = React.useCallback(\n (reasons: string[], detail: string) => {\n setApprovalState(\"approved\")\n onApproveFeedback?.(reasons, detail)\n },\n [onApproveFeedback]\n )\n\n const skipApproveFeedback = React.useCallback(() => {\n setApprovalState(\"approved\")\n }, [])\n\n const dismiss = React.useCallback(\n (reasons: string[], detail: string) => {\n setApprovalState(\"dismissed\")\n onDismiss?.(reasons, detail)\n },\n [onDismiss]\n )\n\n return (\n <SignalApprovalCtx.Provider\n value={{ approvalState, companyName, opportunityUrl, scheduledTime, labels, approve, submitApproveFeedback, skipApproveFeedback, dismiss, requestApproval, requestDismiss, cancel }}\n >\n {children}\n </SignalApprovalCtx.Provider>\n )\n}\n\nfunction SubmittedFeedback({\n reasons,\n detail,\n variant,\n onEdit,\n}: {\n reasons: string[]\n detail: string\n variant: \"approve\" | \"dismiss\"\n onEdit: () => void\n}) {\n if (reasons.length === 0 && !detail) return null\n const pillClass =\n variant === \"approve\"\n ? \"border-emerald-200/60 bg-emerald-50/50 text-emerald-700/70\"\n : \"border-red-200/60 bg-red-50/50 text-red-700/70\"\n\n return (\n <button\n type=\"button\"\n onClick={onEdit}\n className=\"w-full text-left space-y-1.5 group cursor-pointer\"\n >\n {reasons.length > 0 && (\n <div className=\"flex flex-wrap gap-1\">\n {reasons.map((r) => (\n <span\n key={r}\n className={`rounded-full border px-2 py-0.5 text-[10px] font-medium transition-colors group-hover:opacity-80 ${pillClass}`}\n >\n {r}\n </span>\n ))}\n </div>\n )}\n {detail && (\n <p className=\"text-[11px] text-muted-foreground/70 leading-snug group-hover:text-muted-foreground transition-colors\">{detail}</p>\n )}\n </button>\n )\n}\n\nfunction Actions() {\n const { approvalState, companyName, opportunityUrl, scheduledTime, labels, approve, submitApproveFeedback, skipApproveFeedback, dismiss, requestApproval, requestDismiss, cancel } =\n useSignalApproval()\n const [selectedReasons, setSelectedReasons] = React.useState<string[]>([])\n const [detailText, setDetailText] = React.useState(\"\")\n const [submittedFeedback, setSubmittedFeedback] = React.useState<{ reasons: string[]; detail: string } | null>(null)\n const [isEditing, setIsEditing] = React.useState(false)\n\n const otherSelected = selectedReasons.includes(\"Other\")\n const canSubmitDismiss = selectedReasons.length > 0 && (!otherSelected || detailText.trim().length > 0)\n const canSubmitApprove = selectedReasons.length > 0 || detailText.trim().length > 0\n\n const toggleReason = (reason: string) => {\n setSelectedReasons((prev) =>\n prev.includes(reason) ? prev.filter((r) => r !== reason) : [...prev, reason]\n )\n }\n\n const startEditing = () => {\n if (submittedFeedback) {\n setSelectedReasons([...submittedFeedback.reasons])\n setDetailText(submittedFeedback.detail)\n }\n setIsEditing(true)\n }\n\n const handleDismissSubmit = () => {\n if (!canSubmitDismiss) return\n const fb = { reasons: [...selectedReasons], detail: detailText.trim() }\n setSubmittedFeedback(fb)\n dismiss(selectedReasons, detailText.trim())\n setSelectedReasons([])\n setDetailText(\"\")\n setIsEditing(false)\n }\n\n const handleApproveSubmit = () => {\n const fb = { reasons: [...selectedReasons], detail: detailText.trim() }\n setSubmittedFeedback(fb)\n submitApproveFeedback(selectedReasons, detailText.trim())\n setSelectedReasons([])\n setDetailText(\"\")\n setIsEditing(false)\n }\n\n const handleEditCancel = () => {\n setSelectedReasons([])\n setDetailText(\"\")\n setIsEditing(false)\n }\n\n const handleCancel = () => {\n cancel()\n setSelectedReasons([])\n setDetailText(\"\")\n }\n\n if (approvalState === \"approved\") {\n if (isEditing) {\n return (\n <div className=\"space-y-3\">\n <div className=\"flex items-center gap-1.5 text-xs font-medium text-emerald-600 mb-2\">\n <Check className=\"h-3.5 w-3.5\" />\n {opportunityUrl ? (\n <a href={opportunityUrl} target=\"_blank\" rel=\"noopener noreferrer\" className=\"inline-flex items-center gap-1 hover:underline underline-offset-2\">\n {labels.approvedStatus} <ExternalLink className=\"h-3 w-3\" />\n </a>\n ) : (\n <span>{labels.approvedStatus}</span>\n )}\n </div>\n <p className=\"text-xs font-medium text-muted-foreground\">Edit your feedback</p>\n <div className=\"flex flex-wrap gap-1.5\">\n {approveReasons.map((reason) => {\n const selected = selectedReasons.includes(reason)\n return (\n <button key={reason} type=\"button\" onClick={() => toggleReason(reason)}\n className={`rounded-full border px-2.5 py-1 text-[11px] font-medium transition-colors ${\n selected ? \"border-emerald-200 bg-emerald-100 text-emerald-700\" : \"border-border bg-background text-muted-foreground hover:bg-muted/50 hover:text-foreground\"\n }`}>{reason}</button>\n )\n })}\n </div>\n <input type=\"text\" value={detailText} onChange={(e) => setDetailText(e.target.value)}\n onKeyDown={(e) => { if (e.key === \"Enter\" && canSubmitApprove) handleApproveSubmit() }}\n placeholder=\"Tell us more (optional)\"\n className=\"h-7 w-full rounded-md border border-border bg-muted/20 px-2.5 text-xs text-foreground placeholder:text-muted-foreground/60 focus:outline-none focus:ring-1 focus:ring-ring\" />\n <div className=\"flex items-center gap-2\">\n <button type=\"button\" onClick={handleApproveSubmit} disabled={!canSubmitApprove}\n className={`inline-flex h-7 items-center gap-1.5 rounded-md px-3 text-xs font-semibold transition-colors ${canSubmitApprove ? \"bg-foreground text-background hover:bg-foreground/90\" : \"cursor-not-allowed bg-muted text-muted-foreground\"}`}>\n Save\n </button>\n <button type=\"button\" onClick={handleEditCancel}\n className=\"inline-flex h-7 items-center rounded-md border border-border px-3 text-xs font-medium text-muted-foreground transition-colors hover:bg-muted hover:text-foreground\">\n Cancel\n </button>\n </div>\n </div>\n )\n }\n\n return (\n <div className=\"space-y-2\">\n <div className=\"flex items-center gap-1.5 text-xs font-medium text-emerald-600\">\n <Check className=\"h-3.5 w-3.5\" />\n {opportunityUrl ? (\n <a\n href={opportunityUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"inline-flex items-center gap-1 hover:underline underline-offset-2\"\n >\n {labels.opportunityCreated}\n <ExternalLink className=\"h-3 w-3\" />\n </a>\n ) : (\n <span>{labels.opportunityCreated}</span>\n )}\n </div>\n {submittedFeedback && (\n <SubmittedFeedback\n reasons={submittedFeedback.reasons}\n detail={submittedFeedback.detail}\n variant=\"approve\"\n onEdit={startEditing}\n />\n )}\n </div>\n )\n }\n\n if (approvalState === \"auto-approved\") {\n return (\n <div className=\"space-y-2\">\n <div className=\"flex items-center gap-1.5 text-xs font-medium text-emerald-600\">\n <Check className=\"h-3.5 w-3.5\" />\n <span>{labels.approvedStatus}</span>\n </div>\n {scheduledTime && (\n <p className=\"text-[11px] text-muted-foreground\">Scheduled: {scheduledTime}</p>\n )}\n </div>\n )\n }\n\n if (approvalState === \"approving-feedback\") {\n return (\n <div className=\"space-y-3\">\n <div className=\"flex items-center gap-1.5 text-xs font-medium text-emerald-600 mb-2\">\n <Check className=\"h-3.5 w-3.5\" />\n {opportunityUrl ? (\n <a\n href={opportunityUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"inline-flex items-center gap-1 hover:underline underline-offset-2\"\n >\n {labels.opportunityCreated}\n <ExternalLink className=\"h-3 w-3\" />\n </a>\n ) : (\n <span>{labels.opportunityCreated}</span>\n )}\n </div>\n <p className=\"text-xs font-medium text-muted-foreground\">{labels.feedbackPrompt}</p>\n <div className=\"flex flex-wrap gap-1.5\">\n {approveReasons.map((reason) => {\n const selected = selectedReasons.includes(reason)\n return (\n <button\n key={reason}\n type=\"button\"\n onClick={() => toggleReason(reason)}\n className={`rounded-full border px-2.5 py-1 text-[11px] font-medium transition-colors ${\n selected\n ? \"border-emerald-200 bg-emerald-100 text-emerald-700\"\n : \"border-border bg-background text-muted-foreground hover:bg-muted/50 hover:text-foreground\"\n }`}\n >\n {reason}\n </button>\n )\n })}\n </div>\n\n <input\n type=\"text\"\n value={detailText}\n onChange={(e) => setDetailText(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" && canSubmitApprove) handleApproveSubmit()\n }}\n placeholder=\"Tell us more (optional)\"\n className=\"h-7 w-full rounded-md border border-border bg-muted/20 px-2.5 text-xs text-foreground placeholder:text-muted-foreground/60 focus:outline-none focus:ring-1 focus:ring-ring\"\n />\n\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={handleApproveSubmit}\n disabled={!canSubmitApprove}\n className={`inline-flex h-7 items-center gap-1.5 rounded-md px-3 text-xs font-semibold transition-colors ${\n canSubmitApprove\n ? \"bg-foreground text-background hover:bg-foreground/90\"\n : \"cursor-not-allowed bg-muted text-muted-foreground\"\n }`}\n >\n Submit\n </button>\n <button\n type=\"button\"\n onClick={skipApproveFeedback}\n className=\"inline-flex h-7 items-center rounded-md border border-border px-3 text-xs font-medium text-muted-foreground transition-colors hover:bg-muted hover:text-foreground\"\n >\n Skip\n </button>\n </div>\n </div>\n )\n }\n\n if (approvalState === \"dismissed\") {\n if (isEditing) {\n return (\n <div className=\"space-y-3\">\n <div className=\"flex items-center gap-1.5 text-xs text-muted-foreground mb-2\">\n <ThumbsDown className=\"h-3.5 w-3.5\" />\n <span>{labels.dismissedStatus}</span>\n </div>\n <p className=\"text-xs font-medium text-muted-foreground\">Edit your feedback</p>\n <div className=\"flex flex-wrap gap-1.5\">\n {dismissReasons.map((reason) => {\n const selected = selectedReasons.includes(reason)\n return (\n <button key={reason} type=\"button\" onClick={() => toggleReason(reason)}\n className={`rounded-full border px-2.5 py-1 text-[11px] font-medium transition-colors ${\n selected ? \"border-red-200 bg-red-100 text-red-700\" : \"border-border bg-background text-muted-foreground hover:bg-muted/50 hover:text-foreground\"\n }`}>{reason}</button>\n )\n })}\n </div>\n <input type=\"text\" value={detailText} onChange={(e) => setDetailText(e.target.value)}\n onKeyDown={(e) => { if (e.key === \"Enter\" && canSubmitDismiss) handleDismissSubmit() }}\n placeholder={otherSelected ? \"Please describe (required)\" : \"Provide additional feedback...\"}\n className=\"h-7 w-full rounded-md border border-border bg-muted/20 px-2.5 text-xs text-foreground placeholder:text-muted-foreground/60 focus:outline-none focus:ring-1 focus:ring-ring\" />\n <div className=\"flex items-center gap-2\">\n <button type=\"button\" onClick={handleDismissSubmit} disabled={!canSubmitDismiss}\n className={`inline-flex h-7 items-center gap-1.5 rounded-md px-3 text-xs font-semibold transition-colors ${canSubmitDismiss ? \"bg-foreground text-background hover:bg-foreground/90\" : \"cursor-not-allowed bg-muted text-muted-foreground\"}`}>\n Save\n </button>\n <button type=\"button\" onClick={handleEditCancel}\n className=\"inline-flex h-7 items-center rounded-md border border-border px-3 text-xs font-medium text-muted-foreground transition-colors hover:bg-muted hover:text-foreground\">\n Cancel\n </button>\n </div>\n </div>\n )\n }\n\n return (\n <div className=\"space-y-2\">\n <div className=\"flex items-center gap-1.5 text-xs text-muted-foreground\">\n <ThumbsDown className=\"h-3.5 w-3.5\" />\n <span>{labels.dismissedStatus}</span>\n </div>\n {submittedFeedback && (\n <SubmittedFeedback\n reasons={submittedFeedback.reasons}\n detail={submittedFeedback.detail}\n variant=\"dismiss\"\n onEdit={startEditing}\n />\n )}\n </div>\n )\n }\n\n if (approvalState === \"confirming\") {\n return (\n <div className=\"space-y-3\">\n <div className=\"rounded-md border border-border bg-muted/30 p-3\">\n <p className=\"text-sm text-foreground\">\n {labels.confirmPrompt} <strong>{companyName}</strong>. Confirm?\n </p>\n </div>\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={approve}\n className=\"inline-flex h-7 items-center gap-1.5 rounded-md bg-foreground px-3 text-xs font-semibold text-background transition-colors hover:bg-foreground/90\"\n >\n <Check className=\"h-3 w-3\" />\n Confirm\n </button>\n <button\n type=\"button\"\n onClick={handleCancel}\n className=\"inline-flex h-7 items-center rounded-md border border-border px-3 text-xs font-medium text-muted-foreground transition-colors hover:bg-muted hover:text-foreground\"\n >\n Cancel\n </button>\n </div>\n </div>\n )\n }\n\n if (approvalState === \"dismissing\") {\n return (\n <div className=\"space-y-3\">\n <p className=\"text-xs font-medium text-muted-foreground\">{labels.dismissPrompt}</p>\n <div className=\"flex flex-wrap gap-1.5\">\n {dismissReasons.map((reason) => {\n const selected = selectedReasons.includes(reason)\n return (\n <button\n key={reason}\n type=\"button\"\n onClick={() => toggleReason(reason)}\n className={`rounded-full border px-2.5 py-1 text-[11px] font-medium transition-colors ${\n selected\n ? \"border-red-200 bg-red-100 text-red-700\"\n : \"border-border bg-background text-muted-foreground hover:bg-muted/50 hover:text-foreground\"\n }`}\n >\n {reason}\n </button>\n )\n })}\n </div>\n\n {(selectedReasons.length > 0 || otherSelected) && (\n <input\n type=\"text\"\n value={detailText}\n onChange={(e) => setDetailText(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" && canSubmitDismiss) handleDismissSubmit()\n }}\n placeholder={otherSelected ? \"Please describe (required)\" : \"Provide additional feedback...\"}\n className=\"h-7 w-full rounded-md border border-border bg-muted/20 px-2.5 text-xs text-foreground placeholder:text-muted-foreground/60 focus:outline-none focus:ring-1 focus:ring-ring\"\n />\n )}\n\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={handleDismissSubmit}\n disabled={!canSubmitDismiss}\n className={`inline-flex h-7 items-center gap-1.5 rounded-md px-3 text-xs font-semibold transition-colors ${\n canSubmitDismiss\n ? \"bg-foreground text-background hover:bg-foreground/90\"\n : \"cursor-not-allowed bg-muted text-muted-foreground\"\n }`}\n >\n Submit\n </button>\n <button\n type=\"button\"\n onClick={handleCancel}\n className=\"inline-flex h-7 items-center rounded-md border border-border px-3 text-xs font-medium text-muted-foreground transition-colors hover:bg-muted hover:text-foreground\"\n >\n Cancel\n </button>\n </div>\n </div>\n )\n }\n\n return (\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={requestApproval}\n className=\"inline-flex h-7 items-center gap-1.5 rounded-md border border-border bg-foreground px-3 text-xs font-semibold text-background shadow-none transition-colors hover:bg-foreground/90\"\n >\n <CirclePlus className=\"h-3.5 w-3.5\" />\n {labels.approveButton}\n </button>\n <button\n type=\"button\"\n onClick={requestDismiss}\n className=\"inline-flex h-7 items-center gap-1.5 rounded-md border border-border px-3 text-xs font-medium text-muted-foreground shadow-none transition-colors hover:bg-muted hover:text-foreground\"\n >\n <ThumbsDown className=\"h-3.5 w-3.5\" />\n {labels.dismissButton}\n </button>\n </div>\n )\n}\n\nfunction Gate({ children }: { children: React.ReactNode }) {\n const { approvalState } = useSignalApproval()\n const isLocked =\n approvalState === \"pending\" || approvalState === \"confirming\" || approvalState === \"dismissing\"\n\n return (\n <div className=\"relative\">\n {isLocked && (\n <div className=\"pointer-events-none absolute inset-x-0 top-4 z-10 flex justify-center\">\n <div className=\"flex items-center gap-1.5 rounded-full border border-border bg-background px-3 py-1.5 text-xs text-muted-foreground shadow-sm\">\n <Lock className=\"h-3 w-3\" />\n Approve or dismiss the signal above to unlock\n </div>\n </div>\n )}\n <div\n className={`transition-opacity duration-300 ${isLocked ? \"pointer-events-none select-none opacity-40\" : \"opacity-100\"}`}\n >\n {children}\n </div>\n </div>\n )\n}\n\nexport {\n Root as SignalApprovalRoot,\n Actions as SignalApprovalActions,\n Gate as SignalApprovalGate,\n}\nexport const SignalApproval = { Root, Actions, Gate }\nexport type { ApprovalState, SignalApprovalLabels, SignalApprovalContextValue, RootProps as SignalApprovalRootProps }\n"],"mappings":"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","names":[]}
@@ -107,7 +107,11 @@ function VirtualizedDataTable({
107
107
  hasMore,
108
108
  reachBottomThreshold
109
109
  ]);
110
- return /* @__PURE__ */ jsx("div", { className: cn("w-full", className), children: /* @__PURE__ */ jsxs(
110
+ return /* @__PURE__ */ jsx("div", { className: cn(
111
+ "w-full",
112
+ typeof height === "string" && height.trim().endsWith("%") && "h-full",
113
+ className
114
+ ), children: /* @__PURE__ */ jsxs(
111
115
  "div",
112
116
  {
113
117
  ref: scrollContainerRef,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/virtualized-data-table.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport { useVirtualizer } from \"@tanstack/react-virtual\"\nimport {\n useReactTable,\n getCoreRowModel,\n flexRender,\n type ColumnDef,\n type SortingState,\n type ColumnFiltersState,\n type VisibilityState,\n type OnChangeFn,\n} from \"@tanstack/react-table\"\nimport { ArrowDown, ArrowUp, ArrowUpDown, SearchX, Loader2 } from \"lucide-react\"\n\nimport { cn } from \"../lib/utils\"\n\nexport interface VirtualizedDataTableProps<TData> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n columns: ColumnDef<TData, any>[]\n data: TData[]\n\n // Virtualization\n height?: number | string\n estimateRowHeight?: number\n overscan?: number\n\n // Row interaction\n onRowClick?: (row: TData) => void\n getRowId?: (original: TData, index: number) => string\n\n // Infinite scroll\n onReachBottom?: () => void\n reachBottomThreshold?: number\n hasMore?: boolean\n isFetchingMore?: boolean\n\n // Server-driven state (controlled) — omit for internal state\n sorting?: SortingState\n onSortingChange?: OnChangeFn<SortingState>\n columnFilters?: ColumnFiltersState\n onColumnFiltersChange?: OnChangeFn<ColumnFiltersState>\n columnVisibility?: VisibilityState\n onColumnVisibilityChange?: OnChangeFn<VisibilityState>\n\n // Empty state\n emptyIcon?: React.ReactNode\n emptyMessage?: string\n emptyDescription?: string\n\n // Styling\n className?: string\n}\n\nexport function VirtualizedDataTable<TData>({\n columns,\n data,\n height = 600,\n estimateRowHeight = 48,\n overscan = 8,\n onRowClick,\n getRowId,\n onReachBottom,\n reachBottomThreshold = 5,\n hasMore = true,\n isFetchingMore,\n sorting,\n onSortingChange,\n columnFilters,\n onColumnFiltersChange,\n columnVisibility,\n onColumnVisibilityChange,\n emptyIcon,\n emptyMessage = \"No rows found\",\n emptyDescription = \"Try adjusting your filters\",\n className,\n}: VirtualizedDataTableProps<TData>) {\n // Controlled/uncontrolled state for sorting\n const [internalSorting, setInternalSorting] = React.useState<SortingState>([])\n const resolvedSorting = sorting ?? internalSorting\n const resolvedOnSortingChange = onSortingChange ?? setInternalSorting\n\n // Controlled/uncontrolled state for column filters\n const [internalColumnFilters, setInternalColumnFilters] =\n React.useState<ColumnFiltersState>([])\n const resolvedColumnFilters = columnFilters ?? internalColumnFilters\n const resolvedOnColumnFiltersChange =\n onColumnFiltersChange ?? setInternalColumnFilters\n\n // Controlled/uncontrolled state for column visibility\n const [internalColumnVisibility, setInternalColumnVisibility] =\n React.useState<VisibilityState>({})\n const resolvedColumnVisibility = columnVisibility ?? internalColumnVisibility\n const resolvedOnColumnVisibilityChange =\n onColumnVisibilityChange ?? setInternalColumnVisibility\n\n // TanStack Table setup\n const table = useReactTable({\n data,\n columns,\n ...(getRowId ? { getRowId } : {}),\n state: {\n sorting: resolvedSorting,\n columnFilters: resolvedColumnFilters,\n columnVisibility: resolvedColumnVisibility,\n },\n onSortingChange: resolvedOnSortingChange,\n onColumnFiltersChange: resolvedOnColumnFiltersChange,\n onColumnVisibilityChange: resolvedOnColumnVisibilityChange,\n manualSorting: true,\n manualFiltering: true,\n manualPagination: true,\n getCoreRowModel: getCoreRowModel(),\n })\n\n // Virtualizer setup\n const scrollContainerRef = React.useRef<HTMLDivElement>(null)\n const rows = table.getRowModel().rows\n\n const virtualizer = useVirtualizer({\n count: rows.length,\n getScrollElement: () => scrollContainerRef.current,\n estimateSize: () => estimateRowHeight,\n overscan,\n measureElement: (element) => element.getBoundingClientRect().height,\n })\n\n // Infinite scroll detection\n const lastTriggeredDataLengthRef = React.useRef<number>(0)\n\n // Derive a stable primitive for the last visible virtual-item index so the\n // effect below doesn't re-run on every render (getVirtualItems() returns a\n // new array reference each call).\n const virtualItems = virtualizer.getVirtualItems()\n const lastVirtualItemIndex =\n virtualItems.length > 0\n ? virtualItems[virtualItems.length - 1].index\n : -1\n\n React.useEffect(() => {\n if (!onReachBottom || isFetchingMore || hasMore === false) return\n if (lastVirtualItemIndex < 0) return\n if (lastVirtualItemIndex < rows.length - reachBottomThreshold) return\n\n // Prevent re-firing until data.length changes (i.e. new page loaded).\n if (lastTriggeredDataLengthRef.current === data.length) return\n lastTriggeredDataLengthRef.current = data.length\n\n onReachBottom()\n }, [\n lastVirtualItemIndex,\n rows.length,\n data.length,\n onReachBottom,\n isFetchingMore,\n hasMore,\n reachBottomThreshold,\n ])\n\n return (\n <div className={cn(\"w-full\", className)}>\n <div\n ref={scrollContainerRef}\n className=\"relative overflow-auto\"\n style={{\n height: typeof height === \"number\" ? `${height}px` : height,\n contain: \"strict\",\n }}\n role=\"table\"\n aria-rowcount={data.length}\n aria-colcount={table.getVisibleLeafColumns().length}\n >\n {/* Sticky header */}\n <div className=\"sticky top-0 z-10 bg-background\" role=\"rowgroup\">\n {table.getHeaderGroups().map((headerGroup) => (\n <div\n key={headerGroup.id}\n className=\"flex w-max min-w-full border-b border-border/50\"\n role=\"row\"\n >\n {headerGroup.headers.map((header, colIdx) => (\n <div\n key={header.id}\n className=\"h-9 px-3 flex items-center text-xs font-medium text-muted-foreground whitespace-nowrap\"\n style={{\n width: header.getSize(),\n minWidth: header.getSize(),\n }}\n role=\"columnheader\"\n aria-colindex={colIdx + 1}\n aria-sort={\n header.column.getIsSorted() === \"asc\"\n ? \"ascending\"\n : header.column.getIsSorted() === \"desc\"\n ? \"descending\"\n : header.column.getCanSort()\n ? \"none\"\n : undefined\n }\n >\n {header.isPlaceholder ? null : header.column.getCanSort() ? (\n <button\n type=\"button\"\n className=\"inline-flex items-center gap-1 hover:text-foreground transition-colors\"\n onClick={header.column.getToggleSortingHandler()}\n >\n {flexRender(\n header.column.columnDef.header,\n header.getContext(),\n )}\n {header.column.getIsSorted() === \"asc\" ? (\n <ArrowUp className=\"w-3 h-3\" />\n ) : header.column.getIsSorted() === \"desc\" ? (\n <ArrowDown className=\"w-3 h-3\" />\n ) : (\n <ArrowUpDown className=\"w-3 h-3 opacity-40\" />\n )}\n </button>\n ) : (\n flexRender(\n header.column.columnDef.header,\n header.getContext(),\n )\n )}\n </div>\n ))}\n </div>\n ))}\n </div>\n\n {/* Virtualized body or empty state */}\n {rows.length > 0 ? (\n <div\n role=\"rowgroup\"\n style={{\n height: virtualizer.getTotalSize(),\n width: \"100%\",\n position: \"relative\",\n }}\n >\n {virtualizer.getVirtualItems().map((virtualRow) => {\n const row = rows[virtualRow.index]\n return (\n <div\n key={row.id}\n data-index={virtualRow.index}\n ref={virtualizer.measureElement}\n className={cn(\n \"absolute left-0 w-max min-w-full flex group transition-colors\",\n onRowClick && \"cursor-pointer\",\n )}\n style={{\n transform: `translateY(${virtualRow.start}px)`,\n }}\n role=\"row\"\n aria-rowindex={virtualRow.index + 2}\n onClick={() => onRowClick?.(row.original)}\n tabIndex={onRowClick ? 0 : undefined}\n onKeyDown={\n onRowClick\n ? (e: React.KeyboardEvent) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault()\n onRowClick(row.original)\n }\n }\n : undefined\n }\n >\n {row.getVisibleCells().map((cell, colIdx) => (\n <div\n key={cell.id}\n className=\"px-3 py-3 flex items-center whitespace-nowrap group-hover:bg-muted/50\"\n style={{\n width: cell.column.getSize(),\n minWidth: cell.column.getSize(),\n }}\n role=\"cell\"\n aria-colindex={colIdx + 1}\n >\n {flexRender(\n cell.column.columnDef.cell,\n cell.getContext(),\n )}\n </div>\n ))}\n </div>\n )\n })}\n </div>\n ) : (\n <div className=\"flex flex-col items-center justify-center gap-1 text-muted-foreground py-20\">\n {emptyIcon ?? <SearchX className=\"h-7 w-7 opacity-40\" />}\n <p className=\"text-sm font-medium\">{emptyMessage}</p>\n <p className=\"text-xs\">{emptyDescription}</p>\n </div>\n )}\n\n {/* Loading indicator */}\n {isFetchingMore && (\n <div className=\"flex items-center justify-center py-4\">\n <Loader2 className=\"h-5 w-5 animate-spin text-muted-foreground\" />\n </div>\n )}\n </div>\n </div>\n )\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/components/virtualized-data-table.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport { useVirtualizer } from \"@tanstack/react-virtual\"\nimport {\n useReactTable,\n getCoreRowModel,\n flexRender,\n type ColumnDef,\n type SortingState,\n type ColumnFiltersState,\n type VisibilityState,\n type OnChangeFn,\n} from \"@tanstack/react-table\"\nimport { ArrowDown, ArrowUp, ArrowUpDown, SearchX, Loader2 } from \"lucide-react\"\n\nimport { cn } from \"../lib/utils\"\n\nexport interface VirtualizedDataTableProps<TData> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n columns: ColumnDef<TData, any>[]\n data: TData[]\n\n // Virtualization\n height?: number | string\n estimateRowHeight?: number\n overscan?: number\n\n // Row interaction\n onRowClick?: (row: TData) => void\n getRowId?: (original: TData, index: number) => string\n\n // Infinite scroll\n onReachBottom?: () => void\n reachBottomThreshold?: number\n hasMore?: boolean\n isFetchingMore?: boolean\n\n // Server-driven state (controlled) — omit for internal state\n sorting?: SortingState\n onSortingChange?: OnChangeFn<SortingState>\n columnFilters?: ColumnFiltersState\n onColumnFiltersChange?: OnChangeFn<ColumnFiltersState>\n columnVisibility?: VisibilityState\n onColumnVisibilityChange?: OnChangeFn<VisibilityState>\n\n // Empty state\n emptyIcon?: React.ReactNode\n emptyMessage?: string\n emptyDescription?: string\n\n // Styling\n className?: string\n}\n\nexport function VirtualizedDataTable<TData>({\n columns,\n data,\n height = 600,\n estimateRowHeight = 48,\n overscan = 8,\n onRowClick,\n getRowId,\n onReachBottom,\n reachBottomThreshold = 5,\n hasMore = true,\n isFetchingMore,\n sorting,\n onSortingChange,\n columnFilters,\n onColumnFiltersChange,\n columnVisibility,\n onColumnVisibilityChange,\n emptyIcon,\n emptyMessage = \"No rows found\",\n emptyDescription = \"Try adjusting your filters\",\n className,\n}: VirtualizedDataTableProps<TData>) {\n // Controlled/uncontrolled state for sorting\n const [internalSorting, setInternalSorting] = React.useState<SortingState>([])\n const resolvedSorting = sorting ?? internalSorting\n const resolvedOnSortingChange = onSortingChange ?? setInternalSorting\n\n // Controlled/uncontrolled state for column filters\n const [internalColumnFilters, setInternalColumnFilters] =\n React.useState<ColumnFiltersState>([])\n const resolvedColumnFilters = columnFilters ?? internalColumnFilters\n const resolvedOnColumnFiltersChange =\n onColumnFiltersChange ?? setInternalColumnFilters\n\n // Controlled/uncontrolled state for column visibility\n const [internalColumnVisibility, setInternalColumnVisibility] =\n React.useState<VisibilityState>({})\n const resolvedColumnVisibility = columnVisibility ?? internalColumnVisibility\n const resolvedOnColumnVisibilityChange =\n onColumnVisibilityChange ?? setInternalColumnVisibility\n\n // TanStack Table setup\n const table = useReactTable({\n data,\n columns,\n ...(getRowId ? { getRowId } : {}),\n state: {\n sorting: resolvedSorting,\n columnFilters: resolvedColumnFilters,\n columnVisibility: resolvedColumnVisibility,\n },\n onSortingChange: resolvedOnSortingChange,\n onColumnFiltersChange: resolvedOnColumnFiltersChange,\n onColumnVisibilityChange: resolvedOnColumnVisibilityChange,\n manualSorting: true,\n manualFiltering: true,\n manualPagination: true,\n getCoreRowModel: getCoreRowModel(),\n })\n\n // Virtualizer setup\n const scrollContainerRef = React.useRef<HTMLDivElement>(null)\n const rows = table.getRowModel().rows\n\n const virtualizer = useVirtualizer({\n count: rows.length,\n getScrollElement: () => scrollContainerRef.current,\n estimateSize: () => estimateRowHeight,\n overscan,\n measureElement: (element) => element.getBoundingClientRect().height,\n })\n\n // Infinite scroll detection\n const lastTriggeredDataLengthRef = React.useRef<number>(0)\n\n // Derive a stable primitive for the last visible virtual-item index so the\n // effect below doesn't re-run on every render (getVirtualItems() returns a\n // new array reference each call).\n const virtualItems = virtualizer.getVirtualItems()\n const lastVirtualItemIndex =\n virtualItems.length > 0\n ? virtualItems[virtualItems.length - 1].index\n : -1\n\n React.useEffect(() => {\n if (!onReachBottom || isFetchingMore || hasMore === false) return\n if (lastVirtualItemIndex < 0) return\n if (lastVirtualItemIndex < rows.length - reachBottomThreshold) return\n\n // Prevent re-firing until data.length changes (i.e. new page loaded).\n if (lastTriggeredDataLengthRef.current === data.length) return\n lastTriggeredDataLengthRef.current = data.length\n\n onReachBottom()\n }, [\n lastVirtualItemIndex,\n rows.length,\n data.length,\n onReachBottom,\n isFetchingMore,\n hasMore,\n reachBottomThreshold,\n ])\n\n return (\n <div className={cn(\n \"w-full\",\n typeof height === \"string\" && height.trim().endsWith(\"%\") && \"h-full\",\n className,\n )}>\n <div\n ref={scrollContainerRef}\n className=\"relative overflow-auto\"\n style={{\n height: typeof height === \"number\" ? `${height}px` : height,\n contain: \"strict\",\n }}\n role=\"table\"\n aria-rowcount={data.length}\n aria-colcount={table.getVisibleLeafColumns().length}\n >\n {/* Sticky header */}\n <div className=\"sticky top-0 z-10 bg-background\" role=\"rowgroup\">\n {table.getHeaderGroups().map((headerGroup) => (\n <div\n key={headerGroup.id}\n className=\"flex w-max min-w-full border-b border-border/50\"\n role=\"row\"\n >\n {headerGroup.headers.map((header, colIdx) => (\n <div\n key={header.id}\n className=\"h-9 px-3 flex items-center text-xs font-medium text-muted-foreground whitespace-nowrap\"\n style={{\n width: header.getSize(),\n minWidth: header.getSize(),\n }}\n role=\"columnheader\"\n aria-colindex={colIdx + 1}\n aria-sort={\n header.column.getIsSorted() === \"asc\"\n ? \"ascending\"\n : header.column.getIsSorted() === \"desc\"\n ? \"descending\"\n : header.column.getCanSort()\n ? \"none\"\n : undefined\n }\n >\n {header.isPlaceholder ? null : header.column.getCanSort() ? (\n <button\n type=\"button\"\n className=\"inline-flex items-center gap-1 hover:text-foreground transition-colors\"\n onClick={header.column.getToggleSortingHandler()}\n >\n {flexRender(\n header.column.columnDef.header,\n header.getContext(),\n )}\n {header.column.getIsSorted() === \"asc\" ? (\n <ArrowUp className=\"w-3 h-3\" />\n ) : header.column.getIsSorted() === \"desc\" ? (\n <ArrowDown className=\"w-3 h-3\" />\n ) : (\n <ArrowUpDown className=\"w-3 h-3 opacity-40\" />\n )}\n </button>\n ) : (\n flexRender(\n header.column.columnDef.header,\n header.getContext(),\n )\n )}\n </div>\n ))}\n </div>\n ))}\n </div>\n\n {/* Virtualized body or empty state */}\n {rows.length > 0 ? (\n <div\n role=\"rowgroup\"\n style={{\n height: virtualizer.getTotalSize(),\n width: \"100%\",\n position: \"relative\",\n }}\n >\n {virtualizer.getVirtualItems().map((virtualRow) => {\n const row = rows[virtualRow.index]\n return (\n <div\n key={row.id}\n data-index={virtualRow.index}\n ref={virtualizer.measureElement}\n className={cn(\n \"absolute left-0 w-max min-w-full flex group transition-colors\",\n onRowClick && \"cursor-pointer\",\n )}\n style={{\n transform: `translateY(${virtualRow.start}px)`,\n }}\n role=\"row\"\n aria-rowindex={virtualRow.index + 2}\n onClick={() => onRowClick?.(row.original)}\n tabIndex={onRowClick ? 0 : undefined}\n onKeyDown={\n onRowClick\n ? (e: React.KeyboardEvent) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault()\n onRowClick(row.original)\n }\n }\n : undefined\n }\n >\n {row.getVisibleCells().map((cell, colIdx) => (\n <div\n key={cell.id}\n className=\"px-3 py-3 flex items-center whitespace-nowrap group-hover:bg-muted/50\"\n style={{\n width: cell.column.getSize(),\n minWidth: cell.column.getSize(),\n }}\n role=\"cell\"\n aria-colindex={colIdx + 1}\n >\n {flexRender(\n cell.column.columnDef.cell,\n cell.getContext(),\n )}\n </div>\n ))}\n </div>\n )\n })}\n </div>\n ) : (\n <div className=\"flex flex-col items-center justify-center gap-1 text-muted-foreground py-20\">\n {emptyIcon ?? <SearchX className=\"h-7 w-7 opacity-40\" />}\n <p className=\"text-sm font-medium\">{emptyMessage}</p>\n <p className=\"text-xs\">{emptyDescription}</p>\n </div>\n )}\n\n {/* Loading indicator */}\n {isFetchingMore && (\n <div className=\"flex items-center justify-center py-4\">\n <Loader2 className=\"h-5 w-5 animate-spin text-muted-foreground\" />\n </div>\n )}\n </div>\n </div>\n )\n}\n"],"mappings":"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","names":[]}
@@ -17,4 +17,5 @@ import '../components/data-table.js';
17
17
  import '../components/metric-card.js';
18
18
  import '../charts/pipeline-overview.js';
19
19
  import '../components/timeline-activity.js';
20
+ import '../components/signal-feedback-inline.js';
20
21
  import 'lucide-react';
@@ -11,6 +11,7 @@ import '../components/data-table-filter.js';
11
11
  import '../components/metric-card.js';
12
12
  import '../charts/pipeline-overview.js';
13
13
  import '../components/timeline-activity.js';
14
+ import '../components/signal-feedback-inline.js';
14
15
  import 'lucide-react';
15
16
 
16
17
  interface PrototypeAccountsViewProps extends AccountsViewConfig {
@@ -11,6 +11,7 @@ import '../components/data-table.js';
11
11
  import '../components/metric-card.js';
12
12
  import '../charts/pipeline-overview.js';
13
13
  import '../components/timeline-activity.js';
14
+ import '../components/signal-feedback-inline.js';
14
15
  import 'lucide-react';
15
16
 
16
17
  interface PrototypeAdminViewProps extends AdminViewConfig {
@@ -9,6 +9,7 @@ import { DataRow } from '../components/data-table.js';
9
9
  import { MetricCardProps } from '../components/metric-card.js';
10
10
  import { PipelineStage, PipelineStageMetrics, PipelineStageTiming } from '../charts/pipeline-overview.js';
11
11
  import { TimelineEvent } from '../components/timeline-activity.js';
12
+ import { ApprovalState } from '../components/signal-feedback-inline.js';
12
13
  import { LucideIcon } from 'lucide-react';
13
14
  import '../components/quick-action-modal.js';
14
15
 
@@ -50,7 +51,7 @@ interface InboxViewConfig {
50
51
  emailSignature?: string | React.ReactNode;
51
52
  buildSuggestedActions?: (item: QueueItem) => SuggestedAction[];
52
53
  buildSourceItems?: (item: QueueItem) => SourceDef[];
53
- getSignalScore?: (company: string) => SignalScoreData;
54
+ getSignalScore?: (company: string, item?: QueueItem) => SignalScoreData;
54
55
  getTimelineEvents?: (item: QueueItem) => TimelineEvent[];
55
56
  iconMap?: Record<string, string>;
56
57
  hideToolbarActions?: boolean;
@@ -70,6 +71,8 @@ interface InboxViewConfig {
70
71
  }>;
71
72
  hideAccountsButton?: boolean;
72
73
  accountDetailsLabel?: string;
74
+ onSignalApprove?: (item: QueueItem) => void;
75
+ getSignalApprovalState?: (item: QueueItem) => ApprovalState | undefined;
73
76
  signalLabels?: {
74
77
  approveButton?: string;
75
78
  dismissButton?: string;
@@ -1,4 +1,5 @@
1
1
  import * as React from 'react';
2
+ import { ApprovalState } from '../components/signal-feedback-inline.js';
2
3
  import { SourceDef } from '../components/detail-view.js';
3
4
  import { SuggestedAction, SuggestedContact } from '../components/suggested-actions.js';
4
5
  import { TimelineEvent } from '../components/timeline-activity.js';
@@ -25,7 +26,7 @@ interface PrototypeInboxViewProps extends InboxViewConfig {
25
26
  interface DetailViewProps {
26
27
  item: QueueItem;
27
28
  sections: InboxDetailSections;
28
- getSignalScore: (company: string) => SignalScoreData;
29
+ getSignalScore: (company: string, item?: QueueItem) => SignalScoreData;
29
30
  buildSuggestedActions: (item: QueueItem) => SuggestedAction[];
30
31
  buildSourceItems: (item: QueueItem) => SourceDef[];
31
32
  getTimelineEvents?: (item: QueueItem) => TimelineEvent[];
@@ -35,6 +36,8 @@ interface DetailViewProps {
35
36
  onOpenEntityPanel?: () => void;
36
37
  onOpenRecentActivity?: () => void;
37
38
  onSuggestedActionFeedback?: (actionId: number | string, feedback: string, actionTitle?: string) => void;
39
+ onSignalApprove?: (item: QueueItem) => void;
40
+ getSignalApprovalState?: (item: QueueItem) => ApprovalState | undefined;
38
41
  signalLabels?: {
39
42
  approveButton?: string;
40
43
  dismissButton?: string;
@@ -43,7 +46,7 @@ interface DetailViewProps {
43
46
  };
44
47
  signalBriefCopy?: InboxViewConfig["signalBriefCopy"];
45
48
  }
46
- declare function DetailView({ item, sections, getSignalScore, buildSuggestedActions, buildSourceItems, getTimelineEvents, accountContacts, emailSignature, iconMap, onOpenEntityPanel, onOpenRecentActivity, onSuggestedActionFeedback: _onSuggestedActionFeedback, signalLabels, signalBriefCopy, }: DetailViewProps): React.JSX.Element;
47
- declare function PrototypeInboxView({ items, filterCategories, detailSections, accountContacts, buildAccountContacts, emailSignature, buildSuggestedActions: buildSuggestedActionsProp, buildSourceItems: buildSourceItemsProp, getSignalScore: getSignalScoreProp, getTimelineEvents, iconMap, hideToolbarActions, hideHoverActions, onSuggestedActionFeedback, headerActions, onOpenEntityPanel, onOpenRecentActivity, onItemSelect, defaultViewMode, buildEntityChips, quickFilterTabs, hideAccountsButton, accountDetailsLabel, signalLabels, signalBriefCopy, }: PrototypeInboxViewProps): React.JSX.Element;
49
+ declare function DetailView({ item, sections, getSignalScore, buildSuggestedActions, buildSourceItems, getTimelineEvents, accountContacts, emailSignature, iconMap, onOpenEntityPanel, onOpenRecentActivity, onSuggestedActionFeedback: _onSuggestedActionFeedback, onSignalApprove, getSignalApprovalState, signalLabels, signalBriefCopy, }: DetailViewProps): React.JSX.Element;
50
+ declare function PrototypeInboxView({ items, filterCategories, detailSections, accountContacts, buildAccountContacts, emailSignature, buildSuggestedActions: buildSuggestedActionsProp, buildSourceItems: buildSourceItemsProp, getSignalScore: getSignalScoreProp, getTimelineEvents, iconMap, hideToolbarActions, hideHoverActions, onSuggestedActionFeedback, headerActions, onOpenEntityPanel, onOpenRecentActivity, onItemSelect, defaultViewMode, buildEntityChips, quickFilterTabs, hideAccountsButton, accountDetailsLabel, onSignalApprove, getSignalApprovalState, signalLabels, signalBriefCopy, }: PrototypeInboxViewProps): React.JSX.Element;
48
51
 
49
52
  export { DetailView, type DetailViewProps, PrototypeInboxView, type PrototypeInboxViewProps };
@@ -85,6 +85,8 @@ function DetailView({
85
85
  onOpenEntityPanel,
86
86
  onOpenRecentActivity,
87
87
  onSuggestedActionFeedback: _onSuggestedActionFeedback,
88
+ onSignalApprove,
89
+ getSignalApprovalState,
88
90
  signalLabels,
89
91
  signalBriefCopy
90
92
  }) {
@@ -97,8 +99,8 @@ function DetailView({
97
99
  setExtraActions([]);
98
100
  }, [item.id]);
99
101
  const signalData = React.useMemo(
100
- () => getSignalScore(item.company),
101
- [getSignalScore, item.company]
102
+ () => getSignalScore(item.company, item),
103
+ [getSignalScore, item.company, item]
102
104
  );
103
105
  const suggestedActions = React.useMemo(
104
106
  () => [...buildSuggestedActions(item), ...extraActions],
@@ -130,9 +132,8 @@ function DetailView({
130
132
  companyName: item.company,
131
133
  opportunityUrl: `https://acme.lightning.force.com/lightning/r/Opportunity/006${item.id}/view`,
132
134
  labels: signalLabels,
133
- onApprove: () => {
134
- console.log("Approved signal:", { taskId: item.id, company: item.company });
135
- },
135
+ initialApprovalState: getSignalApprovalState == null ? void 0 : getSignalApprovalState(item),
136
+ onApprove: () => onSignalApprove == null ? void 0 : onSignalApprove(item),
136
137
  onApproveFeedback: (reasons, detail) => {
137
138
  var _a;
138
139
  (_a = signalData.onApproveFeedback) == null ? void 0 : _a.call(signalData, reasons, detail);
@@ -332,6 +333,8 @@ function PrototypeInboxView({
332
333
  quickFilterTabs,
333
334
  hideAccountsButton,
334
335
  accountDetailsLabel,
336
+ onSignalApprove,
337
+ getSignalApprovalState,
335
338
  signalLabels,
336
339
  signalBriefCopy
337
340
  }) {
@@ -513,6 +516,8 @@ function PrototypeInboxView({
513
516
  onOpenEntityPanel,
514
517
  onOpenRecentActivity,
515
518
  onSuggestedActionFeedback,
519
+ onSignalApprove,
520
+ getSignalApprovalState,
516
521
  signalLabels,
517
522
  signalBriefCopy
518
523
  };
@@ -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 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 { 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 } from \"../components/signal-feedback-inline\"\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} from \"./prototype-config\"\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) => 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 signalLabels?: { approveButton?: string; dismissButton?: string; approvedStatus?: string; dismissedStatus?: string }\n signalBriefCopy?: InboxViewConfig[\"signalBriefCopy\"]\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 signalLabels,\n signalBriefCopy,\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),\n [getSignalScore, item.company],\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 companyName={item.company}\n opportunityUrl={`https://acme.lightning.force.com/lightning/r/Opportunity/006${item.id}/view`}\n labels={signalLabels}\n onApprove={() => {\n console.log(\"Approved signal:\", { taskId: item.id, company: item.company })\n }}\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) => {\n signalData.onDismissFeedback?.(reasons, detail)\n console.log(\"Dismissed signal:\", { taskId: item.id, reasons, detail })\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\" && (\n <div className=\"inline-flex items-center gap-1 rounded-md bg-red-50 px-2.5 py-1 text-xs font-semibold text-red-700\">\n <span className=\"text-[10px] font-bold\">!</span> Urgent\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 <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 </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 ?? `We detected signals that suggest a potential opportunity with ${item.company}.`\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 ? (\n <p className=\"text-sm text-muted-foreground leading-relaxed mb-2\">\n {briefIntro}\n </p>\n ) : null}\n <p className=\"text-sm text-foreground/90 leading-relaxed mb-4\">\n {signalData.whyNow}\n </p>\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 </div>\n </div>\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 />\n <SignalApproval.Actions />\n </div>\n )}\n </div>\n\n {!evidenceExpanded && <SignalApproval.Actions />}\n </div>\n )\n })()}\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 && (\n <span className=\"text-[11px] text-muted-foreground/60\">&middot; Last activity 1d ago</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 </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 headerActions,\n onOpenEntityPanel,\n onOpenRecentActivity,\n onItemSelect,\n defaultViewMode,\n buildEntityChips,\n quickFilterTabs,\n hideAccountsButton,\n accountDetailsLabel,\n signalLabels,\n signalBriefCopy,\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\n const inboxGroups = React.useMemo<GroupedListGroup<QueueItem>[]>(() => {\n const urgent = filteredItems.filter((i) => i.statusColor === \"red\")\n const active = filteredItems.filter((i) => i.statusColor !== \"red\")\n return [\n { key: \"urgent\", label: \"Urgent\", items: urgent },\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 ${item.statusColor === \"red\" ? \"bg-[#f43f5e]\" : \"bg-[#3b82f6]\"}`} />\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 signalLabels,\n signalBriefCopy,\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 {!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 ${item.statusColor === \"red\" ? \"bg-[#f43f5e]\" : \"bg-[#3b82f6]\"}`} />\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"]}
1
+ {"version":3,"sources":["../../src/prototype/prototype-inbox-view.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport {\n ArrowLeft,\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 { 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 } from \"../components/signal-feedback-inline\"\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} from \"./prototype-config\"\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\n getSignalApprovalState?: (item: QueueItem) => ApprovalState | undefined\n signalLabels?: { approveButton?: string; dismissButton?: string; approvedStatus?: string; dismissedStatus?: string }\n signalBriefCopy?: InboxViewConfig[\"signalBriefCopy\"]\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 signalBriefCopy,\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 companyName={item.company}\n opportunityUrl={`https://acme.lightning.force.com/lightning/r/Opportunity/006${item.id}/view`}\n labels={signalLabels}\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) => {\n signalData.onDismissFeedback?.(reasons, detail)\n console.log(\"Dismissed signal:\", { taskId: item.id, reasons, detail })\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\" && (\n <div className=\"inline-flex items-center gap-1 rounded-md bg-red-50 px-2.5 py-1 text-xs font-semibold text-red-700\">\n <span className=\"text-[10px] font-bold\">!</span> Urgent\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 <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 </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 ?? `We detected signals that suggest a potential opportunity with ${item.company}.`\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 ? (\n <p className=\"text-sm text-muted-foreground leading-relaxed mb-2\">\n {briefIntro}\n </p>\n ) : null}\n <p className=\"text-sm text-foreground/90 leading-relaxed mb-4\">\n {signalData.whyNow}\n </p>\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 </div>\n </div>\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 />\n <SignalApproval.Actions />\n </div>\n )}\n </div>\n\n {!evidenceExpanded && <SignalApproval.Actions />}\n </div>\n )\n })()}\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 && (\n <span className=\"text-[11px] text-muted-foreground/60\">&middot; Last activity 1d ago</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 </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 headerActions,\n onOpenEntityPanel,\n onOpenRecentActivity,\n onItemSelect,\n defaultViewMode,\n buildEntityChips,\n quickFilterTabs,\n hideAccountsButton,\n accountDetailsLabel,\n onSignalApprove,\n getSignalApprovalState,\n signalLabels,\n signalBriefCopy,\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\n const inboxGroups = React.useMemo<GroupedListGroup<QueueItem>[]>(() => {\n const urgent = filteredItems.filter((i) => i.statusColor === \"red\")\n const active = filteredItems.filter((i) => i.statusColor !== \"red\")\n return [\n { key: \"urgent\", label: \"Urgent\", items: urgent },\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 ${item.statusColor === \"red\" ? \"bg-[#f43f5e]\" : \"bg-[#3b82f6]\"}`} />\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 signalBriefCopy,\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 {!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 ${item.statusColor === \"red\" ? \"bg-[#f43f5e]\" : \"bg-[#3b82f6]\"}`} />\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"]}
@@ -11,6 +11,7 @@ import '../components/data-table.js';
11
11
  import '../components/metric-card.js';
12
12
  import '../charts/pipeline-overview.js';
13
13
  import '../components/timeline-activity.js';
14
+ import '../components/signal-feedback-inline.js';
14
15
  import 'lucide-react';
15
16
 
16
17
  interface PrototypeInsightsViewProps extends InsightsViewConfig {
@@ -11,6 +11,7 @@ import '../components/data-table.js';
11
11
  import '../components/metric-card.js';
12
12
  import '../charts/pipeline-overview.js';
13
13
  import '../components/timeline-activity.js';
14
+ import '../components/signal-feedback-inline.js';
14
15
  import 'lucide-react';
15
16
 
16
17
  interface PrototypeShellProps {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@handled-ai/design-system",
3
- "version": "0.9.10",
3
+ "version": "0.9.12",
4
4
  "description": "Handled UI component library (shadcn-style, New York)",
5
5
  "type": "module",
6
6
  "packageManager": "pnpm@9.12.0",
@@ -50,10 +50,26 @@ export interface SidebarNavSection {
50
50
  title?: string
51
51
  /** Optional icon shown to the left of the section title (expanded sidebars only). */
52
52
  titleIconUrl?: string
53
+ /**
54
+ * Size of the title icon. Default `"sm"` (14px).
55
+ * - `"sm"`: 14px, opacity 70 — secondary/decorative use
56
+ * - `"md"`: 20px, opacity 90
57
+ * - `"lg"`: 24px, full opacity — when the section icon is the primary brand mark
58
+ */
59
+ titleIconSize?: "sm" | "md" | "lg"
53
60
  items: SidebarNavItem[]
54
61
  moreItems?: SidebarNavItem[]
55
62
  }
56
63
 
64
+ const SECTION_TITLE_ICON_SIZE_CLASSES: Record<
65
+ NonNullable<SidebarNavSection["titleIconSize"]>,
66
+ string
67
+ > = {
68
+ sm: "h-3.5 w-3.5 opacity-70",
69
+ md: "h-5 w-5 opacity-90",
70
+ lg: "h-6 w-6",
71
+ }
72
+
57
73
  export interface SidebarUserProfile {
58
74
  name: string
59
75
  email: string
@@ -292,7 +308,10 @@ function NavSection({
292
308
  src={section.titleIconUrl}
293
309
  alt=""
294
310
  aria-hidden="true"
295
- className="h-3.5 w-3.5 shrink-0 object-contain opacity-70"
311
+ className={cn(
312
+ "shrink-0 object-contain",
313
+ SECTION_TITLE_ICON_SIZE_CLASSES[section.titleIconSize ?? "sm"],
314
+ )}
296
315
  />
297
316
  )}
298
317
  <span className="text-xs font-bold tracking-widest text-sidebar-foreground/50 uppercase truncate">
@@ -26,6 +26,7 @@ interface SignalApprovalLabels {
26
26
  dismissButton?: string
27
27
  approvedStatus?: string
28
28
  dismissedStatus?: string
29
+ opportunityCreated?: string
29
30
  confirmPrompt?: string
30
31
  dismissPrompt?: string
31
32
  feedbackPrompt?: string
@@ -36,6 +37,7 @@ const DEFAULT_LABELS: Required<SignalApprovalLabels> = {
36
37
  dismissButton: "Not Helpful",
37
38
  approvedStatus: "Action Approved",
38
39
  dismissedStatus: "Action Dismissed",
40
+ opportunityCreated: "Opportunity Created",
39
41
  confirmPrompt: "This will approve this action for",
40
42
  dismissPrompt: "What\u2019s the issue with this action?",
41
43
  feedbackPrompt: "Quick feedback \u2014 what made this action useful?",
@@ -280,11 +282,11 @@ function Actions() {
280
282
  rel="noopener noreferrer"
281
283
  className="inline-flex items-center gap-1 hover:underline underline-offset-2"
282
284
  >
283
- Opportunity Created
285
+ {labels.opportunityCreated}
284
286
  <ExternalLink className="h-3 w-3" />
285
287
  </a>
286
288
  ) : (
287
- <span>Opportunity Created</span>
289
+ <span>{labels.opportunityCreated}</span>
288
290
  )}
289
291
  </div>
290
292
  {submittedFeedback && (
@@ -325,11 +327,11 @@ function Actions() {
325
327
  rel="noopener noreferrer"
326
328
  className="inline-flex items-center gap-1 hover:underline underline-offset-2"
327
329
  >
328
- Opportunity Created
330
+ {labels.opportunityCreated}
329
331
  <ExternalLink className="h-3 w-3" />
330
332
  </a>
331
333
  ) : (
332
- <span>Opportunity Created</span>
334
+ <span>{labels.opportunityCreated}</span>
333
335
  )}
334
336
  </div>
335
337
  <p className="text-xs font-medium text-muted-foreground">{labels.feedbackPrompt}</p>
@@ -431,7 +433,7 @@ function Actions() {
431
433
  <div className="space-y-2">
432
434
  <div className="flex items-center gap-1.5 text-xs text-muted-foreground">
433
435
  <ThumbsDown className="h-3.5 w-3.5" />
434
- <span>Signal Dismissed</span>
436
+ <span>{labels.dismissedStatus}</span>
435
437
  </div>
436
438
  {submittedFeedback && (
437
439
  <SubmittedFeedback
@@ -159,7 +159,11 @@ export function VirtualizedDataTable<TData>({
159
159
  ])
160
160
 
161
161
  return (
162
- <div className={cn("w-full", className)}>
162
+ <div className={cn(
163
+ "w-full",
164
+ typeof height === "string" && height.trim().endsWith("%") && "h-full",
165
+ className,
166
+ )}>
163
167
  <div
164
168
  ref={scrollContainerRef}
165
169
  className="relative overflow-auto"
@@ -13,6 +13,7 @@ import type {
13
13
  PipelineStageTiming,
14
14
  } from "../charts/pipeline-overview"
15
15
  import type { TimelineEvent } from "../components/timeline-activity"
16
+ import type { ApprovalState } from "../components/signal-feedback-inline"
16
17
  import type { LucideIcon } from "lucide-react"
17
18
 
18
19
  // ---------------------------------------------------------------------------
@@ -65,7 +66,7 @@ export interface InboxViewConfig {
65
66
  emailSignature?: string | React.ReactNode
66
67
  buildSuggestedActions?: (item: QueueItem) => SuggestedAction[]
67
68
  buildSourceItems?: (item: QueueItem) => SourceDef[]
68
- getSignalScore?: (company: string) => SignalScoreData
69
+ getSignalScore?: (company: string, item?: QueueItem) => SignalScoreData
69
70
  getTimelineEvents?: (item: QueueItem) => TimelineEvent[]
70
71
  iconMap?: Record<string, string>
71
72
  hideToolbarActions?: boolean
@@ -75,6 +76,8 @@ export interface InboxViewConfig {
75
76
  quickFilterTabs?: Array<{ id: string; label: string; matchValue?: string; count?: number }>
76
77
  hideAccountsButton?: boolean
77
78
  accountDetailsLabel?: string
79
+ onSignalApprove?: (item: QueueItem) => void
80
+ getSignalApprovalState?: (item: QueueItem) => ApprovalState | undefined
78
81
  signalLabels?: {
79
82
  approveButton?: string
80
83
  dismissButton?: string
@@ -29,7 +29,7 @@ import {
29
29
  type InboxFilterCategory,
30
30
  } from "../components/inbox-toolbar"
31
31
  import { GroupedListView, type GroupedListGroup } from "../components/item-list"
32
- import { SignalApproval } from "../components/signal-feedback-inline"
32
+ import { SignalApproval, type ApprovalState } from "../components/signal-feedback-inline"
33
33
  import { ScoreBreakdown } from "../components/score-breakdown"
34
34
  import { Citation, type SourceDef } from "../components/detail-view"
35
35
  import {
@@ -91,7 +91,7 @@ const DEFAULT_SIGNAL_SCORE: SignalScoreData = {
91
91
  export interface DetailViewProps {
92
92
  item: QueueItem
93
93
  sections: InboxDetailSections
94
- getSignalScore: (company: string) => SignalScoreData
94
+ getSignalScore: (company: string, item?: QueueItem) => SignalScoreData
95
95
  buildSuggestedActions: (item: QueueItem) => SuggestedAction[]
96
96
  buildSourceItems: (item: QueueItem) => SourceDef[]
97
97
  getTimelineEvents?: (item: QueueItem) => TimelineEvent[]
@@ -101,6 +101,8 @@ export interface DetailViewProps {
101
101
  onOpenEntityPanel?: () => void
102
102
  onOpenRecentActivity?: () => void
103
103
  onSuggestedActionFeedback?: (actionId: number | string, feedback: string, actionTitle?: string) => void
104
+ onSignalApprove?: (item: QueueItem) => void
105
+ getSignalApprovalState?: (item: QueueItem) => ApprovalState | undefined
104
106
  signalLabels?: { approveButton?: string; dismissButton?: string; approvedStatus?: string; dismissedStatus?: string }
105
107
  signalBriefCopy?: InboxViewConfig["signalBriefCopy"]
106
108
  }
@@ -118,6 +120,8 @@ export function DetailView({
118
120
  onOpenEntityPanel,
119
121
  onOpenRecentActivity,
120
122
  onSuggestedActionFeedback: _onSuggestedActionFeedback,
123
+ onSignalApprove,
124
+ getSignalApprovalState,
121
125
  signalLabels,
122
126
  signalBriefCopy,
123
127
  }: DetailViewProps) {
@@ -132,8 +136,8 @@ export function DetailView({
132
136
  }, [item.id])
133
137
 
134
138
  const signalData = React.useMemo(
135
- () => getSignalScore(item.company),
136
- [getSignalScore, item.company],
139
+ () => getSignalScore(item.company, item),
140
+ [getSignalScore, item.company, item],
137
141
  )
138
142
 
139
143
  const suggestedActions = React.useMemo(
@@ -165,9 +169,8 @@ export function DetailView({
165
169
  companyName={item.company}
166
170
  opportunityUrl={`https://acme.lightning.force.com/lightning/r/Opportunity/006${item.id}/view`}
167
171
  labels={signalLabels}
168
- onApprove={() => {
169
- console.log("Approved signal:", { taskId: item.id, company: item.company })
170
- }}
172
+ initialApprovalState={getSignalApprovalState?.(item)}
173
+ onApprove={() => onSignalApprove?.(item)}
171
174
  onApproveFeedback={(reasons, detail) => {
172
175
  signalData.onApproveFeedback?.(reasons, detail)
173
176
  console.log("Approval feedback:", { taskId: item.id, company: item.company, reasons, detail })
@@ -398,6 +401,8 @@ export function PrototypeInboxView({
398
401
  quickFilterTabs,
399
402
  hideAccountsButton,
400
403
  accountDetailsLabel,
404
+ onSignalApprove,
405
+ getSignalApprovalState,
401
406
  signalLabels,
402
407
  signalBriefCopy,
403
408
  }: PrototypeInboxViewProps) {
@@ -621,6 +626,8 @@ export function PrototypeInboxView({
621
626
  onOpenEntityPanel,
622
627
  onOpenRecentActivity,
623
628
  onSuggestedActionFeedback,
629
+ onSignalApprove,
630
+ getSignalApprovalState,
624
631
  signalLabels,
625
632
  signalBriefCopy,
626
633
  }