@handled-ai/design-system 0.18.57 → 0.18.58

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.
@@ -3,7 +3,7 @@ import * as React from 'react';
3
3
  import { VariantProps } from 'class-variance-authority';
4
4
 
5
5
  declare const badgeVariants: (props?: ({
6
- variant?: "default" | "secondary" | "destructive" | "outline" | "ghost" | "link" | null | undefined;
6
+ variant?: "link" | "default" | "secondary" | "destructive" | "outline" | "ghost" | null | undefined;
7
7
  } & class_variance_authority_types.ClassProp) | undefined) => string;
8
8
  declare function Badge({ className, variant, asChild, ...props }: React.ComponentProps<"span"> & VariantProps<typeof badgeVariants> & {
9
9
  asChild?: boolean;
@@ -3,7 +3,7 @@ import * as React from 'react';
3
3
  import { VariantProps } from 'class-variance-authority';
4
4
 
5
5
  declare const buttonVariants: (props?: ({
6
- variant?: "default" | "secondary" | "destructive" | "outline" | "ghost" | "link" | null | undefined;
6
+ variant?: "link" | "default" | "secondary" | "destructive" | "outline" | "ghost" | null | undefined;
7
7
  size?: "default" | "sm" | "lg" | "icon" | null | undefined;
8
8
  } & class_variance_authority_types.ClassProp) | undefined) => string;
9
9
  declare function Button({ className, variant, size, asChild, ...props }: React.ComponentProps<"button"> & VariantProps<typeof buttonVariants> & {
@@ -12,7 +12,7 @@ import { VariantProps } from 'class-variance-authority';
12
12
  */
13
13
  type PillStatus = "success" | "warning" | "error" | "neutral" | "info";
14
14
  declare const pillVariants: (props?: ({
15
- variant?: "default" | "secondary" | "destructive" | "outline" | "ghost" | "error" | "neutral" | "info" | "success" | "warning" | null | undefined;
15
+ variant?: "error" | "default" | "secondary" | "destructive" | "outline" | "ghost" | "neutral" | "info" | "success" | "warning" | null | undefined;
16
16
  } & class_variance_authority_types.ClassProp) | undefined) => string;
17
17
  interface PillProps extends React.ComponentProps<"span">, VariantProps<typeof pillVariants> {
18
18
  }
@@ -24,7 +24,7 @@ interface OpportunityDraft {
24
24
  amount: string;
25
25
  description: string;
26
26
  churnType: string;
27
- nextStep: string;
27
+ nextStep?: string;
28
28
  }
29
29
  interface SignalApprovalLabels {
30
30
  approveButton?: string;
@@ -310,14 +310,17 @@ function formatAmountDraftValue(value) {
310
310
  return value;
311
311
  }
312
312
  function buildOpportunityDraft(preview) {
313
- var _a, _b, _c, _d, _e, _f;
314
- return {
313
+ var _a, _b, _c, _d, _e;
314
+ const draft = {
315
315
  closeDate: (_b = (_a = preview == null ? void 0 : preview.closeDateValue) != null ? _a : preview == null ? void 0 : preview.closeDate) != null ? _b : "",
316
316
  amount: (preview == null ? void 0 : preview.amountValue) === void 0 ? (_c = preview == null ? void 0 : preview.amount) != null ? _c : "" : formatAmountDraftValue(preview.amountValue),
317
317
  description: (_d = preview == null ? void 0 : preview.description) != null ? _d : "",
318
- churnType: (_e = preview == null ? void 0 : preview.churnType) != null ? _e : "",
319
- nextStep: (_f = preview == null ? void 0 : preview.nextStep) != null ? _f : ""
318
+ churnType: (_e = preview == null ? void 0 : preview.churnType) != null ? _e : ""
320
319
  };
320
+ if ((preview == null ? void 0 : preview.nextStep) != null) {
321
+ draft.nextStep = preview.nextStep;
322
+ }
323
+ return draft;
321
324
  }
322
325
  function hasEditableOpportunityPreview(preview) {
323
326
  var _a;
@@ -331,7 +334,7 @@ function isValidDateInput(value) {
331
334
  return parsed.toISOString().slice(0, 10) === value;
332
335
  }
333
336
  function Actions() {
334
- var _a;
337
+ var _a, _b;
335
338
  const { approvalState, companyName, opportunityUrl, scheduledTime, labels, hideApproveButton, approveButtonIconUrl, opportunityPreview, requestingApproval, approve, submitApproveFeedback, skipApproveFeedback, dismiss, requestApproval, requestDismiss, cancel } = useSignalApproval();
336
339
  const [selectedTopReason, setSelectedTopReason] = React.useState(null);
337
340
  const [selectedSubReason, setSelectedSubReason] = React.useState(null);
@@ -376,10 +379,10 @@ function Actions() {
376
379
  );
377
380
  };
378
381
  const startEditing = () => {
379
- var _a2, _b;
382
+ var _a2, _b2;
380
383
  if (submittedFeedback) {
381
384
  setSelectedTopReason((_a2 = submittedFeedback.reasons[0]) != null ? _a2 : null);
382
- setSelectedSubReason((_b = submittedFeedback.subReason) != null ? _b : null);
385
+ setSelectedSubReason((_b2 = submittedFeedback.subReason) != null ? _b2 : null);
383
386
  setSelectedReasons([...submittedFeedback.reasons]);
384
387
  setDetailText(submittedFeedback.detail);
385
388
  }
@@ -726,7 +729,7 @@ function Actions() {
726
729
  /* @__PURE__ */ jsx(
727
730
  "textarea",
728
731
  {
729
- value: opportunityDraft.nextStep,
732
+ value: (_b = opportunityDraft.nextStep) != null ? _b : "",
730
733
  onChange: (event) => setOpportunityDraft((draft) => __spreadProps(__spreadValues({}, draft), { nextStep: event.target.value })),
731
734
  rows: 2,
732
735
  placeholder: "No next step set",
@@ -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, Loader2, Lock, ThumbsDown } from \"lucide-react\"\n\ninterface DismissReasonNode {\n label: string\n subOptions?: string[]\n}\n\nconst dismissReasonTree: DismissReasonNode[] = [\n {\n label: \"Not relevant for this account\",\n subOptions: [\n \"Business as usual for this account\",\n \"Account in maintenance mode\",\n \"Wrong contact for this signal\",\n \"Other\",\n ],\n },\n {\n label: \"Bad timing\",\n subOptions: [\n \"Too early in the relationship\",\n \"Too soon after last outreach\",\n \"Wrong time of year for this account\",\n \"Other\",\n ],\n },\n {\n label: \"Inaccurate data\",\n subOptions: [\n \"Wrong amount or number\",\n \"Stale data\",\n \"Account info wrong\",\n \"Other\",\n ],\n },\n {\n label: \"Wrong account\",\n subOptions: [\n \"Different account meant\",\n \"Account not in scope\",\n \"Other\",\n ],\n },\n {\n label: \"Already handled\",\n subOptions: [\n \"Already in conversation\",\n \"Already an open Opportunity\",\n \"Already escalated\",\n \"Other\",\n ],\n },\n {\n label: \"Not actionable\",\n subOptions: [\n \"No clear next step\",\n \"Outside our remit\",\n \"Other\",\n ],\n },\n { label: \"Other\" },\n]\n\nconst approveReasons = [\n \"Right timing\",\n \"Accurate data\",\n \"Good prospect fit\",\n \"Actionable\",\n]\n\ntype ApprovalState = \"pending\" | \"confirming\" | \"creating\" | \"approving-feedback\" | \"dismissing\" | \"approved\" | \"dismissed\" | \"auto-approved\"\n\ninterface OpportunityPreviewOption {\n value: string\n label: string\n}\n\ninterface OpportunityPreview {\n name: string\n stage: string\n closeDate: string\n closeDateValue?: string\n amount: string\n /** Raw draft input value. Numeric values render as currency in the editable field. */\n amountValue?: string | number | null\n accountName: string\n description?: string | null\n churnType?: string | null\n churnTypeOptions?: Array<string | OpportunityPreviewOption>\n nextStep?: string | null\n}\n\ninterface OpportunityDraft {\n closeDate: string\n amount: string\n description: string\n churnType: string\n nextStep: string\n}\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 /** Label shown while the approve action is in progress (e.g. \"Creating Opportunity...\"). */\n creatingStatus?: 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 creatingStatus: \"Creating\\u2026\",\n}\n\ninterface SignalApprovalContextValue {\n approvalState: ApprovalState\n companyName: string\n opportunityUrl?: string\n scheduledTime?: string\n labels: Required<SignalApprovalLabels>\n hideApproveButton?: boolean\n approveButtonIconUrl?: string\n opportunityPreview?: OpportunityPreview\n requestingApproval: boolean\n approve: (draft?: OpportunityDraft) => void\n submitApproveFeedback: (reasons: string[], detail: string) => void\n skipApproveFeedback: () => void\n dismiss: (reasons: string[], detail: string, subReason?: 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 /** When true, the approve/create-opportunity button is hidden but the dismiss button remains. */\n hideApproveButton?: boolean\n /** Optional icon URL for the approve button. Renders an img instead of CirclePlus when provided. */\n approveButtonIconUrl?: string\n /** Optional structured preview data shown in the confirmation dialog. */\n opportunityPreview?: OpportunityPreview\n /**\n * Async callback fired when the user clicks the approve button, BEFORE\n * transitioning to the \"confirming\" state. While the promise is pending,\n * the button shows a loading spinner. On resolve, transitions to \"confirming\".\n * On reject, stays in \"pending\".\n */\n onRequestApproval?: () => Promise<void>\n /**\n * Called when the user confirms the approval action.\n *\n * - If the callback returns `void` (or `undefined`), the component transitions\n * directly to the feedback step (backward-compatible behavior).\n * - If the callback returns a `Promise<boolean>`, the component shows a\n * \"creating\" loading state while the promise is pending. On `true` it\n * transitions to the feedback step; on `false` it reverts to \"pending\".\n */\n onApprove?: (draft?: OpportunityDraft) => void | Promise<boolean>\n onApproveFeedback?: (reasons: string[], detail: string) => void\n onDismiss?: (reasons: string[], detail: string, subReason?: string) => void\n}\n\nfunction Root({ children, companyName, opportunityUrl, scheduledTime, initialApprovalState, labels: labelOverrides, hideApproveButton, approveButtonIconUrl, opportunityPreview, onRequestApproval, onApprove, onApproveFeedback, onDismiss }: RootProps) {\n const labels = React.useMemo(() => ({ ...DEFAULT_LABELS, ...labelOverrides }), [labelOverrides])\n const [approvalState, setApprovalState] = React.useState<ApprovalState>(initialApprovalState ?? \"pending\")\n const [requestingApproval, setRequestingApproval] = React.useState(false)\n\n // Guard against state updates after unmount (e.g. user navigates away while\n // an async onApprove promise is still in flight).\n const mountedRef = React.useRef(true)\n React.useEffect(() => {\n mountedRef.current = true\n return () => { mountedRef.current = false }\n }, [])\n\n const requestApproval = React.useCallback(() => {\n if (onRequestApproval) {\n setRequestingApproval(true)\n onRequestApproval()\n .then(() => {\n if (mountedRef.current) {\n setRequestingApproval(false)\n setApprovalState(\"confirming\")\n }\n })\n .catch(() => {\n if (mountedRef.current) {\n setRequestingApproval(false)\n }\n })\n } else {\n setApprovalState(\"confirming\")\n }\n }, [onRequestApproval])\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((draft?: OpportunityDraft) => {\n const result = onApprove?.(draft)\n // If the callback returns a Promise, show a loading state and wait for it.\n if (result && typeof (result as Promise<boolean>).then === \"function\") {\n setApprovalState(\"creating\")\n ;(result as Promise<boolean>).then((success) => {\n if (mountedRef.current) {\n setApprovalState(success ? \"approving-feedback\" : \"pending\")\n }\n }).catch(() => {\n if (mountedRef.current) {\n setApprovalState(\"pending\")\n }\n })\n } else {\n // Synchronous / void — transition immediately (backward-compatible).\n setApprovalState(\"approving-feedback\")\n }\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, subReason?: string) => {\n setApprovalState(\"dismissed\")\n onDismiss?.(reasons, detail, subReason)\n },\n [onDismiss]\n )\n\n return (\n <SignalApprovalCtx.Provider\n value={{ approvalState, companyName, opportunityUrl, scheduledTime, labels, hideApproveButton, approveButtonIconUrl, opportunityPreview, requestingApproval, approve, submitApproveFeedback, skipApproveFeedback, dismiss, requestApproval, requestDismiss, cancel }}\n >\n {children}\n </SignalApprovalCtx.Provider>\n )\n}\n\n/** Shared dismiss reason picker used in both the \"editing\" and \"initial dismiss\" paths. */\nfunction DismissReasonPicker({\n selectedTopReason,\n selectedSubReason,\n selectTopReason,\n selectSubReason,\n detailText,\n setDetailText,\n needsText,\n canSubmitDismiss,\n handleDismissSubmit,\n topNode,\n submitLabel,\n onCancel,\n}: {\n selectedTopReason: string | null\n selectedSubReason: string | null\n selectTopReason: (label: string) => void\n selectSubReason: (label: string) => void\n detailText: string\n setDetailText: (value: string) => void\n needsText: boolean\n canSubmitDismiss: boolean\n handleDismissSubmit: () => void\n topNode: DismissReasonNode | undefined\n submitLabel: string\n onCancel: () => void\n}) {\n return (\n <>\n <div className=\"flex flex-wrap gap-1.5\">\n {dismissReasonTree.map((node) => {\n const selected = selectedTopReason === node.label\n return (\n <button\n key={node.label}\n type=\"button\"\n onClick={() => selectTopReason(node.label)}\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 {node.label}\n </button>\n )\n })}\n </div>\n\n {topNode?.subOptions && (\n <div className=\"ml-3 border-l-2 border-muted pl-3\">\n <div className=\"flex flex-wrap gap-1.5\">\n {topNode.subOptions.map((sub) => {\n const selected = selectedSubReason === sub\n return (\n <button\n key={sub}\n type=\"button\"\n onClick={() => selectSubReason(sub)}\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 {sub}\n </button>\n )\n })}\n </div>\n </div>\n )}\n\n {selectedTopReason && (\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={needsText ? \"Please describe (required)\" : \"Add context (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\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 {submitLabel}\n </button>\n <button\n type=\"button\"\n onClick={onCancel}\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 </>\n )\n}\n\nfunction SubmittedFeedback({\n reasons,\n detail,\n subReason,\n variant,\n onEdit,\n}: {\n reasons: string[]\n detail: string\n subReason?: 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 {subReason && (\n <span\n className={`rounded-full border px-2 py-0.5 text-[10px] font-medium transition-colors group-hover:opacity-80 ${pillClass}`}\n >\n {subReason}\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 optionValue(option: string | OpportunityPreviewOption): string {\n return typeof option === \"string\" ? option : option.value\n}\n\nfunction optionLabel(option: string | OpportunityPreviewOption): string {\n return typeof option === \"string\" ? option : option.label\n}\n\nfunction formatAmountDraftValue(value: string | number | null | undefined): string {\n if (value == null || value === \"\") return \"\"\n if (typeof value === \"number\") {\n return new Intl.NumberFormat(\"en-US\", {\n style: \"currency\",\n currency: \"USD\",\n maximumFractionDigits: 0,\n }).format(value)\n }\n return value\n}\n\nfunction buildOpportunityDraft(preview?: OpportunityPreview): OpportunityDraft {\n return {\n closeDate: preview?.closeDateValue ?? preview?.closeDate ?? \"\",\n amount: preview?.amountValue === undefined\n ? preview?.amount ?? \"\"\n : formatAmountDraftValue(preview.amountValue),\n description: preview?.description ?? \"\",\n churnType: preview?.churnType ?? \"\",\n nextStep: preview?.nextStep ?? \"\",\n }\n}\n\nfunction hasEditableOpportunityPreview(preview?: OpportunityPreview): boolean {\n return !!preview && isValidDateInput(preview.closeDateValue ?? preview.closeDate)\n}\n\nfunction isValidDateInput(value: string): boolean {\n const match = /^(\\d{4})-(\\d{2})-(\\d{2})$/.exec(value)\n if (!match) return false\n const parsed = new Date(`${value}T00:00:00Z`)\n if (Number.isNaN(parsed.getTime())) return false\n return parsed.toISOString().slice(0, 10) === value\n}\n\nfunction Actions() {\n const { approvalState, companyName, opportunityUrl, scheduledTime, labels, hideApproveButton, approveButtonIconUrl, opportunityPreview, requestingApproval, approve, submitApproveFeedback, skipApproveFeedback, dismiss, requestApproval, requestDismiss, cancel } =\n useSignalApproval()\n const [selectedTopReason, setSelectedTopReason] = React.useState<string | null>(null)\n const [selectedSubReason, setSelectedSubReason] = React.useState<string | null>(null)\n const [selectedReasons, setSelectedReasons] = React.useState<string[]>([])\n const [detailText, setDetailText] = React.useState(\"\")\n const [submittedFeedback, setSubmittedFeedback] = React.useState<{ reasons: string[]; detail: string; subReason?: string } | null>(null)\n const [isEditing, setIsEditing] = React.useState(false)\n const [opportunityDraft, setOpportunityDraft] = React.useState<OpportunityDraft>(() => buildOpportunityDraft(opportunityPreview))\n\n React.useEffect(() => {\n if (approvalState === \"confirming\") {\n setOpportunityDraft(buildOpportunityDraft(opportunityPreview))\n }\n }, [approvalState, opportunityPreview])\n\n const churnTypeOptions = opportunityPreview?.churnTypeOptions ?? []\n const hasChurnTypeOptions = churnTypeOptions.length > 0\n\n const topNode = dismissReasonTree.find((n) => n.label === selectedTopReason)\n const hasSubOptions = !!(topNode?.subOptions && topNode.subOptions.length > 0)\n const isTopOther = selectedTopReason === \"Other\" && !hasSubOptions\n const isSubOther = selectedSubReason === \"Other\"\n const needsText = isTopOther || isSubOther\n const canSubmitDismiss =\n selectedTopReason !== null &&\n (!hasSubOptions || selectedSubReason !== null) &&\n (!needsText || detailText.trim().length > 0)\n\n const canSubmitApprove = selectedReasons.length > 0 || detailText.trim().length > 0\n const isEditableOpportunityPreview = hasEditableOpportunityPreview(opportunityPreview)\n const canConfirmOpportunity = !isEditableOpportunityPreview || isValidDateInput(opportunityDraft.closeDate)\n\n const selectTopReason = (label: string) => {\n if (selectedTopReason === label) {\n setSelectedTopReason(null)\n setSelectedSubReason(null)\n setDetailText(\"\")\n } else {\n setSelectedTopReason(label)\n setSelectedSubReason(null)\n setDetailText(\"\")\n }\n }\n\n const selectSubReason = (label: string) => {\n setSelectedSubReason(selectedSubReason === label ? null : label)\n }\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 setSelectedTopReason(submittedFeedback.reasons[0] ?? null)\n setSelectedSubReason(submittedFeedback.subReason ?? null)\n // Note: selectedReasons is only used by the approve editing path.\n // For dismiss feedback this is harmless but unused — the dismiss path\n // reads selectedTopReason/selectedSubReason instead.\n setSelectedReasons([...submittedFeedback.reasons])\n setDetailText(submittedFeedback.detail)\n }\n setIsEditing(true)\n }\n\n const handleDismissSubmit = () => {\n if (!canSubmitDismiss || !selectedTopReason) return\n const fb = { reasons: [selectedTopReason], detail: detailText.trim(), subReason: selectedSubReason ?? undefined }\n setSubmittedFeedback(fb)\n dismiss([selectedTopReason], detailText.trim(), selectedSubReason ?? undefined)\n setSelectedTopReason(null)\n setSelectedSubReason(null)\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 setSelectedTopReason(null)\n setSelectedSubReason(null)\n setSelectedReasons([])\n setDetailText(\"\")\n setIsEditing(false)\n }\n\n const handleCancel = () => {\n cancel()\n setSelectedTopReason(null)\n setSelectedSubReason(null)\n setSelectedReasons([])\n setDetailText(\"\")\n }\n\n if (approvalState === \"creating\") {\n return (\n <div className=\"flex items-center gap-2 text-xs font-medium text-muted-foreground\">\n <svg className=\"h-3.5 w-3.5 animate-spin\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle className=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" strokeWidth=\"4\" />\n <path className=\"opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\" />\n </svg>\n <span>{labels.creatingStatus}</span>\n </div>\n )\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 <DismissReasonPicker\n selectedTopReason={selectedTopReason}\n selectedSubReason={selectedSubReason}\n selectTopReason={selectTopReason}\n selectSubReason={selectSubReason}\n detailText={detailText}\n setDetailText={setDetailText}\n needsText={needsText}\n canSubmitDismiss={canSubmitDismiss}\n handleDismissSubmit={handleDismissSubmit}\n topNode={topNode}\n submitLabel=\"Save\"\n onCancel={handleEditCancel}\n />\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 subReason={submittedFeedback.subReason}\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 {opportunityPreview && !isEditableOpportunityPreview && (\n <div className=\"mt-3 space-y-2 border-t border-border/50 pt-3\">\n {[\n { label: \"Opportunity\", value: opportunityPreview.name },\n { label: \"Account\", value: opportunityPreview.accountName },\n { label: \"Stage\", value: opportunityPreview.stage },\n { label: \"Close Date\", value: opportunityPreview.closeDate },\n { label: \"Amount\", value: opportunityPreview.amount },\n ].map(({ label, value }) => (\n <div key={label} className=\"flex items-center justify-between gap-3 text-xs\">\n <span className=\"text-muted-foreground\">{label}</span>\n <span className=\"text-right font-medium text-foreground\">{value}</span>\n </div>\n ))}\n </div>\n )}\n {opportunityPreview && isEditableOpportunityPreview && (\n <div className=\"mt-3 space-y-3 border-t border-border/50 pt-3\">\n {[\n { label: \"Opportunity\", value: opportunityPreview.name },\n { label: \"Account\", value: opportunityPreview.accountName },\n { label: \"Stage\", value: opportunityPreview.stage },\n ].map(({ label, value }) => (\n <div key={label} className=\"flex items-center justify-between gap-3 text-xs\">\n <span className=\"text-muted-foreground\">{label}</span>\n <span className=\"text-right font-medium text-foreground\">{value}</span>\n </div>\n ))}\n\n <div className=\"grid gap-2 sm:grid-cols-2\">\n <label className=\"space-y-1 text-xs\">\n <span className=\"font-medium text-muted-foreground\">Close Date</span>\n <input\n type=\"date\"\n value={opportunityDraft.closeDate}\n onChange={(event) => setOpportunityDraft((draft) => ({ ...draft, closeDate: event.target.value }))}\n aria-invalid={!canConfirmOpportunity}\n className=\"h-8 w-full rounded-md border border-border bg-background px-2 text-xs text-foreground focus:outline-none focus:ring-1 focus:ring-ring\"\n />\n {!canConfirmOpportunity && (\n <span className=\"text-[11px] text-red-600\">Enter a valid close date.</span>\n )}\n </label>\n\n <label className=\"space-y-1 text-xs\">\n <span className=\"font-medium text-muted-foreground\">Amount</span>\n <input\n type=\"text\"\n inputMode=\"decimal\"\n value={opportunityDraft.amount}\n onChange={(event) => setOpportunityDraft((draft) => ({ ...draft, amount: event.target.value }))}\n placeholder={opportunityPreview.amount}\n className=\"h-8 w-full rounded-md border border-border bg-background px-2 text-xs text-foreground placeholder:text-muted-foreground/60 focus:outline-none focus:ring-1 focus:ring-ring\"\n />\n </label>\n </div>\n\n <label className=\"space-y-1 text-xs\">\n <span className=\"font-medium text-muted-foreground\">Churn Type</span>\n {hasChurnTypeOptions ? (\n <select\n value={opportunityDraft.churnType}\n onChange={(event) => setOpportunityDraft((draft) => ({ ...draft, churnType: event.target.value }))}\n className=\"h-8 w-full rounded-md border border-border bg-background px-2 text-xs text-foreground focus:outline-none focus:ring-1 focus:ring-ring\"\n >\n <option value=\"\">No churn type</option>\n {churnTypeOptions.map((option) => (\n <option key={optionValue(option)} value={optionValue(option)}>\n {optionLabel(option)}\n </option>\n ))}\n </select>\n ) : (\n <input\n type=\"text\"\n value={opportunityDraft.churnType}\n onChange={(event) => setOpportunityDraft((draft) => ({ ...draft, churnType: event.target.value }))}\n placeholder=\"No churn type\"\n className=\"h-8 w-full rounded-md border border-border bg-background px-2 text-xs text-foreground placeholder:text-muted-foreground/60 focus:outline-none focus:ring-1 focus:ring-ring\"\n />\n )}\n </label>\n\n <label className=\"space-y-1 text-xs\">\n <span className=\"font-medium text-muted-foreground\">Next Step</span>\n <textarea\n value={opportunityDraft.nextStep}\n onChange={(event) => setOpportunityDraft((draft) => ({ ...draft, nextStep: event.target.value }))}\n rows={2}\n placeholder=\"No next step set\"\n className=\"w-full resize-none rounded-md border border-border bg-background px-2 py-1.5 text-xs text-foreground placeholder:text-muted-foreground/60 focus:outline-none focus:ring-1 focus:ring-ring\"\n />\n </label>\n\n <label className=\"space-y-1 text-xs\">\n <span className=\"font-medium text-muted-foreground\">Description</span>\n <textarea\n value={opportunityDraft.description}\n onChange={(event) => setOpportunityDraft((draft) => ({ ...draft, description: event.target.value }))}\n rows={3}\n placeholder=\"Add a short description\"\n className=\"w-full resize-none rounded-md border border-border bg-background px-2 py-1.5 text-xs text-foreground placeholder:text-muted-foreground/60 focus:outline-none focus:ring-1 focus:ring-ring\"\n />\n </label>\n </div>\n )}\n </div>\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={() => {\n if (!opportunityPreview) {\n approve()\n return\n }\n approve(isEditableOpportunityPreview ? opportunityDraft : undefined)\n }}\n disabled={!canConfirmOpportunity}\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 disabled:cursor-not-allowed disabled:bg-muted disabled:text-muted-foreground\"\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 <DismissReasonPicker\n selectedTopReason={selectedTopReason}\n selectedSubReason={selectedSubReason}\n selectTopReason={selectTopReason}\n selectSubReason={selectSubReason}\n detailText={detailText}\n setDetailText={setDetailText}\n needsText={needsText}\n canSubmitDismiss={canSubmitDismiss}\n handleDismissSubmit={handleDismissSubmit}\n topNode={topNode}\n submitLabel=\"Submit\"\n onCancel={handleCancel}\n />\n </div>\n )\n }\n\n return (\n <div className=\"flex items-center gap-2\">\n {!hideApproveButton && (\n <button\n type=\"button\"\n onClick={requestApproval}\n disabled={requestingApproval}\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 disabled:opacity-50\"\n >\n {requestingApproval ? (\n <Loader2 className=\"h-3.5 w-3.5 animate-spin\" />\n ) : approveButtonIconUrl ? (\n <img src={approveButtonIconUrl} alt=\"\" className=\"h-3.5 w-3.5 object-contain\" draggable={false} />\n ) : (\n <CirclePlus className=\"h-3.5 w-3.5\" />\n )}\n {labels.approveButton}\n </button>\n )}\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, hideApproveButton } = useSignalApproval()\n // When the approve button is hidden, don't lock content behind approval\n const isLocked = !hideApproveButton &&\n (approvalState === \"pending\" || approvalState === \"confirming\" || approvalState === \"creating\" || 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, OpportunityPreview, OpportunityDraft, SignalApprovalLabels, SignalApprovalContextValue, RootProps as SignalApprovalRootProps }\n"],"mappings":"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","names":["_a"]}
1
+ {"version":3,"sources":["../../src/components/signal-feedback-inline.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport { Check, CirclePlus, ExternalLink, Loader2, Lock, ThumbsDown } from \"lucide-react\"\n\ninterface DismissReasonNode {\n label: string\n subOptions?: string[]\n}\n\nconst dismissReasonTree: DismissReasonNode[] = [\n {\n label: \"Not relevant for this account\",\n subOptions: [\n \"Business as usual for this account\",\n \"Account in maintenance mode\",\n \"Wrong contact for this signal\",\n \"Other\",\n ],\n },\n {\n label: \"Bad timing\",\n subOptions: [\n \"Too early in the relationship\",\n \"Too soon after last outreach\",\n \"Wrong time of year for this account\",\n \"Other\",\n ],\n },\n {\n label: \"Inaccurate data\",\n subOptions: [\n \"Wrong amount or number\",\n \"Stale data\",\n \"Account info wrong\",\n \"Other\",\n ],\n },\n {\n label: \"Wrong account\",\n subOptions: [\n \"Different account meant\",\n \"Account not in scope\",\n \"Other\",\n ],\n },\n {\n label: \"Already handled\",\n subOptions: [\n \"Already in conversation\",\n \"Already an open Opportunity\",\n \"Already escalated\",\n \"Other\",\n ],\n },\n {\n label: \"Not actionable\",\n subOptions: [\n \"No clear next step\",\n \"Outside our remit\",\n \"Other\",\n ],\n },\n { label: \"Other\" },\n]\n\nconst approveReasons = [\n \"Right timing\",\n \"Accurate data\",\n \"Good prospect fit\",\n \"Actionable\",\n]\n\ntype ApprovalState = \"pending\" | \"confirming\" | \"creating\" | \"approving-feedback\" | \"dismissing\" | \"approved\" | \"dismissed\" | \"auto-approved\"\n\ninterface OpportunityPreviewOption {\n value: string\n label: string\n}\n\ninterface OpportunityPreview {\n name: string\n stage: string\n closeDate: string\n closeDateValue?: string\n amount: string\n /** Raw draft input value. Numeric values render as currency in the editable field. */\n amountValue?: string | number | null\n accountName: string\n description?: string | null\n churnType?: string | null\n churnTypeOptions?: Array<string | OpportunityPreviewOption>\n nextStep?: string | null\n}\n\ninterface OpportunityDraft {\n closeDate: string\n amount: string\n description: string\n churnType: string\n nextStep?: string\n}\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 /** Label shown while the approve action is in progress (e.g. \"Creating Opportunity...\"). */\n creatingStatus?: 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 creatingStatus: \"Creating\\u2026\",\n}\n\ninterface SignalApprovalContextValue {\n approvalState: ApprovalState\n companyName: string\n opportunityUrl?: string\n scheduledTime?: string\n labels: Required<SignalApprovalLabels>\n hideApproveButton?: boolean\n approveButtonIconUrl?: string\n opportunityPreview?: OpportunityPreview\n requestingApproval: boolean\n approve: (draft?: OpportunityDraft) => void\n submitApproveFeedback: (reasons: string[], detail: string) => void\n skipApproveFeedback: () => void\n dismiss: (reasons: string[], detail: string, subReason?: 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 /** When true, the approve/create-opportunity button is hidden but the dismiss button remains. */\n hideApproveButton?: boolean\n /** Optional icon URL for the approve button. Renders an img instead of CirclePlus when provided. */\n approveButtonIconUrl?: string\n /** Optional structured preview data shown in the confirmation dialog. */\n opportunityPreview?: OpportunityPreview\n /**\n * Async callback fired when the user clicks the approve button, BEFORE\n * transitioning to the \"confirming\" state. While the promise is pending,\n * the button shows a loading spinner. On resolve, transitions to \"confirming\".\n * On reject, stays in \"pending\".\n */\n onRequestApproval?: () => Promise<void>\n /**\n * Called when the user confirms the approval action.\n *\n * - If the callback returns `void` (or `undefined`), the component transitions\n * directly to the feedback step (backward-compatible behavior).\n * - If the callback returns a `Promise<boolean>`, the component shows a\n * \"creating\" loading state while the promise is pending. On `true` it\n * transitions to the feedback step; on `false` it reverts to \"pending\".\n */\n onApprove?: (draft?: OpportunityDraft) => void | Promise<boolean>\n onApproveFeedback?: (reasons: string[], detail: string) => void\n onDismiss?: (reasons: string[], detail: string, subReason?: string) => void\n}\n\nfunction Root({ children, companyName, opportunityUrl, scheduledTime, initialApprovalState, labels: labelOverrides, hideApproveButton, approveButtonIconUrl, opportunityPreview, onRequestApproval, onApprove, onApproveFeedback, onDismiss }: RootProps) {\n const labels = React.useMemo(() => ({ ...DEFAULT_LABELS, ...labelOverrides }), [labelOverrides])\n const [approvalState, setApprovalState] = React.useState<ApprovalState>(initialApprovalState ?? \"pending\")\n const [requestingApproval, setRequestingApproval] = React.useState(false)\n\n // Guard against state updates after unmount (e.g. user navigates away while\n // an async onApprove promise is still in flight).\n const mountedRef = React.useRef(true)\n React.useEffect(() => {\n mountedRef.current = true\n return () => { mountedRef.current = false }\n }, [])\n\n const requestApproval = React.useCallback(() => {\n if (onRequestApproval) {\n setRequestingApproval(true)\n onRequestApproval()\n .then(() => {\n if (mountedRef.current) {\n setRequestingApproval(false)\n setApprovalState(\"confirming\")\n }\n })\n .catch(() => {\n if (mountedRef.current) {\n setRequestingApproval(false)\n }\n })\n } else {\n setApprovalState(\"confirming\")\n }\n }, [onRequestApproval])\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((draft?: OpportunityDraft) => {\n const result = onApprove?.(draft)\n // If the callback returns a Promise, show a loading state and wait for it.\n if (result && typeof (result as Promise<boolean>).then === \"function\") {\n setApprovalState(\"creating\")\n ;(result as Promise<boolean>).then((success) => {\n if (mountedRef.current) {\n setApprovalState(success ? \"approving-feedback\" : \"pending\")\n }\n }).catch(() => {\n if (mountedRef.current) {\n setApprovalState(\"pending\")\n }\n })\n } else {\n // Synchronous / void — transition immediately (backward-compatible).\n setApprovalState(\"approving-feedback\")\n }\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, subReason?: string) => {\n setApprovalState(\"dismissed\")\n onDismiss?.(reasons, detail, subReason)\n },\n [onDismiss]\n )\n\n return (\n <SignalApprovalCtx.Provider\n value={{ approvalState, companyName, opportunityUrl, scheduledTime, labels, hideApproveButton, approveButtonIconUrl, opportunityPreview, requestingApproval, approve, submitApproveFeedback, skipApproveFeedback, dismiss, requestApproval, requestDismiss, cancel }}\n >\n {children}\n </SignalApprovalCtx.Provider>\n )\n}\n\n/** Shared dismiss reason picker used in both the \"editing\" and \"initial dismiss\" paths. */\nfunction DismissReasonPicker({\n selectedTopReason,\n selectedSubReason,\n selectTopReason,\n selectSubReason,\n detailText,\n setDetailText,\n needsText,\n canSubmitDismiss,\n handleDismissSubmit,\n topNode,\n submitLabel,\n onCancel,\n}: {\n selectedTopReason: string | null\n selectedSubReason: string | null\n selectTopReason: (label: string) => void\n selectSubReason: (label: string) => void\n detailText: string\n setDetailText: (value: string) => void\n needsText: boolean\n canSubmitDismiss: boolean\n handleDismissSubmit: () => void\n topNode: DismissReasonNode | undefined\n submitLabel: string\n onCancel: () => void\n}) {\n return (\n <>\n <div className=\"flex flex-wrap gap-1.5\">\n {dismissReasonTree.map((node) => {\n const selected = selectedTopReason === node.label\n return (\n <button\n key={node.label}\n type=\"button\"\n onClick={() => selectTopReason(node.label)}\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 {node.label}\n </button>\n )\n })}\n </div>\n\n {topNode?.subOptions && (\n <div className=\"ml-3 border-l-2 border-muted pl-3\">\n <div className=\"flex flex-wrap gap-1.5\">\n {topNode.subOptions.map((sub) => {\n const selected = selectedSubReason === sub\n return (\n <button\n key={sub}\n type=\"button\"\n onClick={() => selectSubReason(sub)}\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 {sub}\n </button>\n )\n })}\n </div>\n </div>\n )}\n\n {selectedTopReason && (\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={needsText ? \"Please describe (required)\" : \"Add context (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\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 {submitLabel}\n </button>\n <button\n type=\"button\"\n onClick={onCancel}\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 </>\n )\n}\n\nfunction SubmittedFeedback({\n reasons,\n detail,\n subReason,\n variant,\n onEdit,\n}: {\n reasons: string[]\n detail: string\n subReason?: 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 {subReason && (\n <span\n className={`rounded-full border px-2 py-0.5 text-[10px] font-medium transition-colors group-hover:opacity-80 ${pillClass}`}\n >\n {subReason}\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 optionValue(option: string | OpportunityPreviewOption): string {\n return typeof option === \"string\" ? option : option.value\n}\n\nfunction optionLabel(option: string | OpportunityPreviewOption): string {\n return typeof option === \"string\" ? option : option.label\n}\n\nfunction formatAmountDraftValue(value: string | number | null | undefined): string {\n if (value == null || value === \"\") return \"\"\n if (typeof value === \"number\") {\n return new Intl.NumberFormat(\"en-US\", {\n style: \"currency\",\n currency: \"USD\",\n maximumFractionDigits: 0,\n }).format(value)\n }\n return value\n}\n\nfunction buildOpportunityDraft(preview?: OpportunityPreview): OpportunityDraft {\n const draft: OpportunityDraft = {\n closeDate: preview?.closeDateValue ?? preview?.closeDate ?? \"\",\n amount: preview?.amountValue === undefined\n ? preview?.amount ?? \"\"\n : formatAmountDraftValue(preview.amountValue),\n description: preview?.description ?? \"\",\n churnType: preview?.churnType ?? \"\",\n }\n if (preview?.nextStep != null) {\n draft.nextStep = preview.nextStep\n }\n return draft\n}\n\nfunction hasEditableOpportunityPreview(preview?: OpportunityPreview): boolean {\n return !!preview && isValidDateInput(preview.closeDateValue ?? preview.closeDate)\n}\n\nfunction isValidDateInput(value: string): boolean {\n const match = /^(\\d{4})-(\\d{2})-(\\d{2})$/.exec(value)\n if (!match) return false\n const parsed = new Date(`${value}T00:00:00Z`)\n if (Number.isNaN(parsed.getTime())) return false\n return parsed.toISOString().slice(0, 10) === value\n}\n\nfunction Actions() {\n const { approvalState, companyName, opportunityUrl, scheduledTime, labels, hideApproveButton, approveButtonIconUrl, opportunityPreview, requestingApproval, approve, submitApproveFeedback, skipApproveFeedback, dismiss, requestApproval, requestDismiss, cancel } =\n useSignalApproval()\n const [selectedTopReason, setSelectedTopReason] = React.useState<string | null>(null)\n const [selectedSubReason, setSelectedSubReason] = React.useState<string | null>(null)\n const [selectedReasons, setSelectedReasons] = React.useState<string[]>([])\n const [detailText, setDetailText] = React.useState(\"\")\n const [submittedFeedback, setSubmittedFeedback] = React.useState<{ reasons: string[]; detail: string; subReason?: string } | null>(null)\n const [isEditing, setIsEditing] = React.useState(false)\n const [opportunityDraft, setOpportunityDraft] = React.useState<OpportunityDraft>(() => buildOpportunityDraft(opportunityPreview))\n\n React.useEffect(() => {\n if (approvalState === \"confirming\") {\n setOpportunityDraft(buildOpportunityDraft(opportunityPreview))\n }\n }, [approvalState, opportunityPreview])\n\n const churnTypeOptions = opportunityPreview?.churnTypeOptions ?? []\n const hasChurnTypeOptions = churnTypeOptions.length > 0\n\n const topNode = dismissReasonTree.find((n) => n.label === selectedTopReason)\n const hasSubOptions = !!(topNode?.subOptions && topNode.subOptions.length > 0)\n const isTopOther = selectedTopReason === \"Other\" && !hasSubOptions\n const isSubOther = selectedSubReason === \"Other\"\n const needsText = isTopOther || isSubOther\n const canSubmitDismiss =\n selectedTopReason !== null &&\n (!hasSubOptions || selectedSubReason !== null) &&\n (!needsText || detailText.trim().length > 0)\n\n const canSubmitApprove = selectedReasons.length > 0 || detailText.trim().length > 0\n const isEditableOpportunityPreview = hasEditableOpportunityPreview(opportunityPreview)\n const canConfirmOpportunity = !isEditableOpportunityPreview || isValidDateInput(opportunityDraft.closeDate)\n\n const selectTopReason = (label: string) => {\n if (selectedTopReason === label) {\n setSelectedTopReason(null)\n setSelectedSubReason(null)\n setDetailText(\"\")\n } else {\n setSelectedTopReason(label)\n setSelectedSubReason(null)\n setDetailText(\"\")\n }\n }\n\n const selectSubReason = (label: string) => {\n setSelectedSubReason(selectedSubReason === label ? null : label)\n }\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 setSelectedTopReason(submittedFeedback.reasons[0] ?? null)\n setSelectedSubReason(submittedFeedback.subReason ?? null)\n // Note: selectedReasons is only used by the approve editing path.\n // For dismiss feedback this is harmless but unused — the dismiss path\n // reads selectedTopReason/selectedSubReason instead.\n setSelectedReasons([...submittedFeedback.reasons])\n setDetailText(submittedFeedback.detail)\n }\n setIsEditing(true)\n }\n\n const handleDismissSubmit = () => {\n if (!canSubmitDismiss || !selectedTopReason) return\n const fb = { reasons: [selectedTopReason], detail: detailText.trim(), subReason: selectedSubReason ?? undefined }\n setSubmittedFeedback(fb)\n dismiss([selectedTopReason], detailText.trim(), selectedSubReason ?? undefined)\n setSelectedTopReason(null)\n setSelectedSubReason(null)\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 setSelectedTopReason(null)\n setSelectedSubReason(null)\n setSelectedReasons([])\n setDetailText(\"\")\n setIsEditing(false)\n }\n\n const handleCancel = () => {\n cancel()\n setSelectedTopReason(null)\n setSelectedSubReason(null)\n setSelectedReasons([])\n setDetailText(\"\")\n }\n\n if (approvalState === \"creating\") {\n return (\n <div className=\"flex items-center gap-2 text-xs font-medium text-muted-foreground\">\n <svg className=\"h-3.5 w-3.5 animate-spin\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle className=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" strokeWidth=\"4\" />\n <path className=\"opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\" />\n </svg>\n <span>{labels.creatingStatus}</span>\n </div>\n )\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 <DismissReasonPicker\n selectedTopReason={selectedTopReason}\n selectedSubReason={selectedSubReason}\n selectTopReason={selectTopReason}\n selectSubReason={selectSubReason}\n detailText={detailText}\n setDetailText={setDetailText}\n needsText={needsText}\n canSubmitDismiss={canSubmitDismiss}\n handleDismissSubmit={handleDismissSubmit}\n topNode={topNode}\n submitLabel=\"Save\"\n onCancel={handleEditCancel}\n />\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 subReason={submittedFeedback.subReason}\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 {opportunityPreview && !isEditableOpportunityPreview && (\n <div className=\"mt-3 space-y-2 border-t border-border/50 pt-3\">\n {[\n { label: \"Opportunity\", value: opportunityPreview.name },\n { label: \"Account\", value: opportunityPreview.accountName },\n { label: \"Stage\", value: opportunityPreview.stage },\n { label: \"Close Date\", value: opportunityPreview.closeDate },\n { label: \"Amount\", value: opportunityPreview.amount },\n ].map(({ label, value }) => (\n <div key={label} className=\"flex items-center justify-between gap-3 text-xs\">\n <span className=\"text-muted-foreground\">{label}</span>\n <span className=\"text-right font-medium text-foreground\">{value}</span>\n </div>\n ))}\n </div>\n )}\n {opportunityPreview && isEditableOpportunityPreview && (\n <div className=\"mt-3 space-y-3 border-t border-border/50 pt-3\">\n {[\n { label: \"Opportunity\", value: opportunityPreview.name },\n { label: \"Account\", value: opportunityPreview.accountName },\n { label: \"Stage\", value: opportunityPreview.stage },\n ].map(({ label, value }) => (\n <div key={label} className=\"flex items-center justify-between gap-3 text-xs\">\n <span className=\"text-muted-foreground\">{label}</span>\n <span className=\"text-right font-medium text-foreground\">{value}</span>\n </div>\n ))}\n\n <div className=\"grid gap-2 sm:grid-cols-2\">\n <label className=\"space-y-1 text-xs\">\n <span className=\"font-medium text-muted-foreground\">Close Date</span>\n <input\n type=\"date\"\n value={opportunityDraft.closeDate}\n onChange={(event) => setOpportunityDraft((draft) => ({ ...draft, closeDate: event.target.value }))}\n aria-invalid={!canConfirmOpportunity}\n className=\"h-8 w-full rounded-md border border-border bg-background px-2 text-xs text-foreground focus:outline-none focus:ring-1 focus:ring-ring\"\n />\n {!canConfirmOpportunity && (\n <span className=\"text-[11px] text-red-600\">Enter a valid close date.</span>\n )}\n </label>\n\n <label className=\"space-y-1 text-xs\">\n <span className=\"font-medium text-muted-foreground\">Amount</span>\n <input\n type=\"text\"\n inputMode=\"decimal\"\n value={opportunityDraft.amount}\n onChange={(event) => setOpportunityDraft((draft) => ({ ...draft, amount: event.target.value }))}\n placeholder={opportunityPreview.amount}\n className=\"h-8 w-full rounded-md border border-border bg-background px-2 text-xs text-foreground placeholder:text-muted-foreground/60 focus:outline-none focus:ring-1 focus:ring-ring\"\n />\n </label>\n </div>\n\n <label className=\"space-y-1 text-xs\">\n <span className=\"font-medium text-muted-foreground\">Churn Type</span>\n {hasChurnTypeOptions ? (\n <select\n value={opportunityDraft.churnType}\n onChange={(event) => setOpportunityDraft((draft) => ({ ...draft, churnType: event.target.value }))}\n className=\"h-8 w-full rounded-md border border-border bg-background px-2 text-xs text-foreground focus:outline-none focus:ring-1 focus:ring-ring\"\n >\n <option value=\"\">No churn type</option>\n {churnTypeOptions.map((option) => (\n <option key={optionValue(option)} value={optionValue(option)}>\n {optionLabel(option)}\n </option>\n ))}\n </select>\n ) : (\n <input\n type=\"text\"\n value={opportunityDraft.churnType}\n onChange={(event) => setOpportunityDraft((draft) => ({ ...draft, churnType: event.target.value }))}\n placeholder=\"No churn type\"\n className=\"h-8 w-full rounded-md border border-border bg-background px-2 text-xs text-foreground placeholder:text-muted-foreground/60 focus:outline-none focus:ring-1 focus:ring-ring\"\n />\n )}\n </label>\n\n <label className=\"space-y-1 text-xs\">\n <span className=\"font-medium text-muted-foreground\">Next Step</span>\n <textarea\n value={opportunityDraft.nextStep ?? \"\"}\n onChange={(event) => setOpportunityDraft((draft) => ({ ...draft, nextStep: event.target.value }))}\n rows={2}\n placeholder=\"No next step set\"\n className=\"w-full resize-none rounded-md border border-border bg-background px-2 py-1.5 text-xs text-foreground placeholder:text-muted-foreground/60 focus:outline-none focus:ring-1 focus:ring-ring\"\n />\n </label>\n\n <label className=\"space-y-1 text-xs\">\n <span className=\"font-medium text-muted-foreground\">Description</span>\n <textarea\n value={opportunityDraft.description}\n onChange={(event) => setOpportunityDraft((draft) => ({ ...draft, description: event.target.value }))}\n rows={3}\n placeholder=\"Add a short description\"\n className=\"w-full resize-none rounded-md border border-border bg-background px-2 py-1.5 text-xs text-foreground placeholder:text-muted-foreground/60 focus:outline-none focus:ring-1 focus:ring-ring\"\n />\n </label>\n </div>\n )}\n </div>\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={() => {\n if (!opportunityPreview) {\n approve()\n return\n }\n approve(isEditableOpportunityPreview ? opportunityDraft : undefined)\n }}\n disabled={!canConfirmOpportunity}\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 disabled:cursor-not-allowed disabled:bg-muted disabled:text-muted-foreground\"\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 <DismissReasonPicker\n selectedTopReason={selectedTopReason}\n selectedSubReason={selectedSubReason}\n selectTopReason={selectTopReason}\n selectSubReason={selectSubReason}\n detailText={detailText}\n setDetailText={setDetailText}\n needsText={needsText}\n canSubmitDismiss={canSubmitDismiss}\n handleDismissSubmit={handleDismissSubmit}\n topNode={topNode}\n submitLabel=\"Submit\"\n onCancel={handleCancel}\n />\n </div>\n )\n }\n\n return (\n <div className=\"flex items-center gap-2\">\n {!hideApproveButton && (\n <button\n type=\"button\"\n onClick={requestApproval}\n disabled={requestingApproval}\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 disabled:opacity-50\"\n >\n {requestingApproval ? (\n <Loader2 className=\"h-3.5 w-3.5 animate-spin\" />\n ) : approveButtonIconUrl ? (\n <img src={approveButtonIconUrl} alt=\"\" className=\"h-3.5 w-3.5 object-contain\" draggable={false} />\n ) : (\n <CirclePlus className=\"h-3.5 w-3.5\" />\n )}\n {labels.approveButton}\n </button>\n )}\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, hideApproveButton } = useSignalApproval()\n // When the approve button is hidden, don't lock content behind approval\n const isLocked = !hideApproveButton &&\n (approvalState === \"pending\" || approvalState === \"confirming\" || approvalState === \"creating\" || 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, OpportunityPreview, OpportunityDraft, SignalApprovalLabels, SignalApprovalContextValue, RootProps as SignalApprovalRootProps }\n"],"mappings":"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","names":["_a","_b"]}
@@ -5,7 +5,7 @@ import { Tabs as Tabs$1 } from 'radix-ui';
5
5
 
6
6
  declare function Tabs({ className, orientation, ...props }: React.ComponentProps<typeof Tabs$1.Root>): React.JSX.Element;
7
7
  declare const tabsListVariants: (props?: ({
8
- variant?: "default" | "line" | null | undefined;
8
+ variant?: "line" | "default" | null | undefined;
9
9
  } & class_variance_authority_types.ClassProp) | undefined) => string;
10
10
  declare function TabsList({ className, variant, ...props }: React.ComponentProps<typeof Tabs$1.List> & VariantProps<typeof tabsListVariants>): React.JSX.Element;
11
11
  declare function TabsTrigger({ className, ...props }: React.ComponentProps<typeof Tabs$1.Trigger>): React.JSX.Element;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@handled-ai/design-system",
3
- "version": "0.18.57",
3
+ "version": "0.18.58",
4
4
  "description": "Handled UI component library (shadcn-style, New York)",
5
5
  "type": "module",
6
6
  "packageManager": "pnpm@9.12.0",
@@ -98,7 +98,7 @@ interface OpportunityDraft {
98
98
  amount: string
99
99
  description: string
100
100
  churnType: string
101
- nextStep: string
101
+ nextStep?: string
102
102
  }
103
103
 
104
104
  interface SignalApprovalLabels {
@@ -461,15 +461,18 @@ function formatAmountDraftValue(value: string | number | null | undefined): stri
461
461
  }
462
462
 
463
463
  function buildOpportunityDraft(preview?: OpportunityPreview): OpportunityDraft {
464
- return {
464
+ const draft: OpportunityDraft = {
465
465
  closeDate: preview?.closeDateValue ?? preview?.closeDate ?? "",
466
466
  amount: preview?.amountValue === undefined
467
467
  ? preview?.amount ?? ""
468
468
  : formatAmountDraftValue(preview.amountValue),
469
469
  description: preview?.description ?? "",
470
470
  churnType: preview?.churnType ?? "",
471
- nextStep: preview?.nextStep ?? "",
472
471
  }
472
+ if (preview?.nextStep != null) {
473
+ draft.nextStep = preview.nextStep
474
+ }
475
+ return draft
473
476
  }
474
477
 
475
478
  function hasEditableOpportunityPreview(preview?: OpportunityPreview): boolean {
@@ -904,7 +907,7 @@ function Actions() {
904
907
  <label className="space-y-1 text-xs">
905
908
  <span className="font-medium text-muted-foreground">Next Step</span>
906
909
  <textarea
907
- value={opportunityDraft.nextStep}
910
+ value={opportunityDraft.nextStep ?? ""}
908
911
  onChange={(event) => setOpportunityDraft((draft) => ({ ...draft, nextStep: event.target.value }))}
909
912
  rows={2}
910
913
  placeholder="No next step set"
@@ -127,4 +127,39 @@ describe("DetailView opportunity approval preview", () => {
127
127
  nextStep: "Schedule validation call",
128
128
  })
129
129
  })
130
+
131
+ it("omits untouched empty next step from the opportunity draft on confirm", async () => {
132
+ const onSignalApprove = vi.fn()
133
+
134
+ render(
135
+ <DetailView
136
+ {...baseProps({
137
+ getSignalApprovalState: () => "confirming",
138
+ opportunityPreview: {
139
+ name: "Churn Risk - WIT-825 Fixture Account",
140
+ accountName: "WIT-825 Fixture Account",
141
+ stage: "Prospecting",
142
+ closeDate: "Jun 30, 2026",
143
+ closeDateValue: "2026-06-30",
144
+ amount: "$75,000",
145
+ amountValue: 75000,
146
+ description: "Initial description",
147
+ churnType: "Churn Risk",
148
+ churnTypeOptions: ["Churn Risk", "Win Back"],
149
+ },
150
+ onSignalApprove,
151
+ })}
152
+ />,
153
+ )
154
+
155
+ expect((screen.getByLabelText("Next Step") as HTMLTextAreaElement).value).toBe("")
156
+ fireEvent.click(screen.getByRole("button", { name: /confirm/i }))
157
+
158
+ expect(onSignalApprove).toHaveBeenCalledWith(baseItem, {
159
+ closeDate: "2026-06-30",
160
+ amount: "$75,000",
161
+ churnType: "Churn Risk",
162
+ description: "Initial description",
163
+ })
164
+ })
130
165
  })