@handled-ai/design-system 0.18.49 → 0.18.50
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/score-why-chips.d.ts +1 -1
- package/dist/components/signal-feedback-inline.d.ts +12 -28
- package/dist/components/signal-feedback-inline.js +10 -146
- package/dist/components/signal-feedback-inline.js.map +1 -1
- package/dist/components/signal-priority-popover.d.ts +1 -1
- package/dist/components/signal-priority-popover.js +15 -7
- package/dist/components/signal-priority-popover.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/prototype/index.d.ts +1 -1
- package/dist/prototype/prototype-accounts-view.d.ts +1 -1
- package/dist/prototype/prototype-admin-view.d.ts +1 -1
- package/dist/prototype/prototype-config.d.ts +1 -1
- package/dist/prototype/prototype-inbox-view.d.ts +3 -3
- package/dist/prototype/prototype-inbox-view.js +2 -1
- package/dist/prototype/prototype-inbox-view.js.map +1 -1
- package/dist/prototype/prototype-insights-view.d.ts +1 -1
- package/dist/prototype/prototype-shell.d.ts +1 -1
- package/dist/{signal-priority-popover-QJngMAj7.d.ts → signal-priority-popover-Cl98xw1n.d.ts} +9 -4
- package/package.json +1 -1
- package/src/components/__tests__/case-panel-why.test.tsx +0 -126
- package/src/components/__tests__/signal-priority-popover.test.tsx +27 -4
- package/src/components/signal-feedback-inline.tsx +20 -181
- package/src/components/signal-priority-popover.tsx +16 -6
- package/src/prototype/__tests__/detail-view-score-why.test.tsx +32 -0
- package/src/prototype/prototype-config.ts +5 -3
- package/src/prototype/prototype-inbox-view.tsx +4 -3
- package/src/prototype/__tests__/detail-view-opportunity-preview.test.tsx +0 -90
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { Q as QueueItem, l as SignalScoreData, o as SignalScoreUrgencyLabel } from '../signal-priority-popover-
|
|
2
|
+
import { Q as QueueItem, l as SignalScoreData, o as SignalScoreUrgencyLabel } from '../signal-priority-popover-Cl98xw1n.js';
|
|
3
3
|
import './feedback-primitives.js';
|
|
4
4
|
import './quick-action-sidebar-nav.js';
|
|
5
5
|
import './quick-action-modal.js';
|
|
@@ -1,29 +1,6 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
|
|
3
3
|
type ApprovalState = "pending" | "confirming" | "creating" | "approving-feedback" | "dismissing" | "approved" | "dismissed" | "auto-approved";
|
|
4
|
-
interface OpportunityPreviewOption {
|
|
5
|
-
value: string;
|
|
6
|
-
label: string;
|
|
7
|
-
}
|
|
8
|
-
interface OpportunityPreview {
|
|
9
|
-
name: string;
|
|
10
|
-
stage: string;
|
|
11
|
-
closeDate: string;
|
|
12
|
-
closeDateValue?: string;
|
|
13
|
-
amount: string;
|
|
14
|
-
/** Raw draft input value. Numeric values render as currency in the editable field. */
|
|
15
|
-
amountValue?: string | number | null;
|
|
16
|
-
accountName: string;
|
|
17
|
-
description?: string | null;
|
|
18
|
-
churnType?: string | null;
|
|
19
|
-
churnTypeOptions?: Array<string | OpportunityPreviewOption>;
|
|
20
|
-
}
|
|
21
|
-
interface OpportunityDraft {
|
|
22
|
-
closeDate: string;
|
|
23
|
-
amount: string;
|
|
24
|
-
description: string;
|
|
25
|
-
churnType: string;
|
|
26
|
-
}
|
|
27
4
|
interface SignalApprovalLabels {
|
|
28
5
|
approveButton?: string;
|
|
29
6
|
dismissButton?: string;
|
|
@@ -44,9 +21,9 @@ interface SignalApprovalContextValue {
|
|
|
44
21
|
labels: Required<SignalApprovalLabels>;
|
|
45
22
|
hideApproveButton?: boolean;
|
|
46
23
|
approveButtonIconUrl?: string;
|
|
47
|
-
opportunityPreview?:
|
|
24
|
+
opportunityPreview?: RootProps['opportunityPreview'];
|
|
48
25
|
requestingApproval: boolean;
|
|
49
|
-
approve: (
|
|
26
|
+
approve: () => void;
|
|
50
27
|
submitApproveFeedback: (reasons: string[], detail: string) => void;
|
|
51
28
|
skipApproveFeedback: () => void;
|
|
52
29
|
dismiss: (reasons: string[], detail: string, subReason?: string) => void;
|
|
@@ -67,7 +44,13 @@ interface RootProps {
|
|
|
67
44
|
/** Optional icon URL for the approve button. Renders an img instead of CirclePlus when provided. */
|
|
68
45
|
approveButtonIconUrl?: string;
|
|
69
46
|
/** Optional structured preview data shown in the confirmation dialog. */
|
|
70
|
-
opportunityPreview?:
|
|
47
|
+
opportunityPreview?: {
|
|
48
|
+
name: string;
|
|
49
|
+
stage: string;
|
|
50
|
+
closeDate: string;
|
|
51
|
+
amount: string;
|
|
52
|
+
accountName: string;
|
|
53
|
+
};
|
|
71
54
|
/**
|
|
72
55
|
* Async callback fired when the user clicks the approve button, BEFORE
|
|
73
56
|
* transitioning to the "confirming" state. While the promise is pending,
|
|
@@ -84,7 +67,7 @@ interface RootProps {
|
|
|
84
67
|
* "creating" loading state while the promise is pending. On `true` it
|
|
85
68
|
* transitions to the feedback step; on `false` it reverts to "pending".
|
|
86
69
|
*/
|
|
87
|
-
onApprove?: (
|
|
70
|
+
onApprove?: () => void | Promise<boolean>;
|
|
88
71
|
onApproveFeedback?: (reasons: string[], detail: string) => void;
|
|
89
72
|
onDismiss?: (reasons: string[], detail: string, subReason?: string) => void;
|
|
90
73
|
}
|
|
@@ -99,5 +82,6 @@ declare const SignalApproval: {
|
|
|
99
82
|
Actions: typeof Actions;
|
|
100
83
|
Gate: typeof Gate;
|
|
101
84
|
};
|
|
85
|
+
type OpportunityPreview = NonNullable<RootProps['opportunityPreview']>;
|
|
102
86
|
|
|
103
|
-
export { type ApprovalState, type
|
|
87
|
+
export { type ApprovalState, type OpportunityPreview, SignalApproval, Actions as SignalApprovalActions, type SignalApprovalContextValue, Gate as SignalApprovalGate, type SignalApprovalLabels, Root as SignalApprovalRoot, type RootProps as SignalApprovalRootProps, useSignalApproval };
|
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
"use client";
|
|
4
4
|
var __defProp = Object.defineProperty;
|
|
5
|
-
var __defProps = Object.defineProperties;
|
|
6
|
-
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
7
5
|
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
8
6
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
7
|
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
@@ -19,7 +17,6 @@ var __spreadValues = (a, b) => {
|
|
|
19
17
|
}
|
|
20
18
|
return a;
|
|
21
19
|
};
|
|
22
|
-
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
23
20
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
24
21
|
import * as React from "react";
|
|
25
22
|
import { Check, CirclePlus, ExternalLink, Loader2, Lock, ThumbsDown } from "lucide-react";
|
|
@@ -107,7 +104,6 @@ function Root({ children, companyName, opportunityUrl, scheduledTime, initialApp
|
|
|
107
104
|
const [requestingApproval, setRequestingApproval] = React.useState(false);
|
|
108
105
|
const mountedRef = React.useRef(true);
|
|
109
106
|
React.useEffect(() => {
|
|
110
|
-
mountedRef.current = true;
|
|
111
107
|
return () => {
|
|
112
108
|
mountedRef.current = false;
|
|
113
109
|
};
|
|
@@ -135,8 +131,8 @@ function Root({ children, companyName, opportunityUrl, scheduledTime, initialApp
|
|
|
135
131
|
const cancel = React.useCallback(() => {
|
|
136
132
|
setApprovalState("pending");
|
|
137
133
|
}, []);
|
|
138
|
-
const approve = React.useCallback((
|
|
139
|
-
const result = onApprove == null ? void 0 : onApprove(
|
|
134
|
+
const approve = React.useCallback(() => {
|
|
135
|
+
const result = onApprove == null ? void 0 : onApprove();
|
|
140
136
|
if (result && typeof result.then === "function") {
|
|
141
137
|
setApprovalState("creating");
|
|
142
138
|
result.then((success) => {
|
|
@@ -292,45 +288,7 @@ function SubmittedFeedback({
|
|
|
292
288
|
}
|
|
293
289
|
);
|
|
294
290
|
}
|
|
295
|
-
function optionValue(option) {
|
|
296
|
-
return typeof option === "string" ? option : option.value;
|
|
297
|
-
}
|
|
298
|
-
function optionLabel(option) {
|
|
299
|
-
return typeof option === "string" ? option : option.label;
|
|
300
|
-
}
|
|
301
|
-
function formatAmountDraftValue(value) {
|
|
302
|
-
if (value == null || value === "") return "";
|
|
303
|
-
if (typeof value === "number") {
|
|
304
|
-
return new Intl.NumberFormat("en-US", {
|
|
305
|
-
style: "currency",
|
|
306
|
-
currency: "USD",
|
|
307
|
-
maximumFractionDigits: 0
|
|
308
|
-
}).format(value);
|
|
309
|
-
}
|
|
310
|
-
return value;
|
|
311
|
-
}
|
|
312
|
-
function buildOpportunityDraft(preview) {
|
|
313
|
-
var _a, _b, _c, _d, _e;
|
|
314
|
-
return {
|
|
315
|
-
closeDate: (_b = (_a = preview == null ? void 0 : preview.closeDateValue) != null ? _a : preview == null ? void 0 : preview.closeDate) != null ? _b : "",
|
|
316
|
-
amount: (preview == null ? void 0 : preview.amountValue) === void 0 ? (_c = preview == null ? void 0 : preview.amount) != null ? _c : "" : formatAmountDraftValue(preview.amountValue),
|
|
317
|
-
description: (_d = preview == null ? void 0 : preview.description) != null ? _d : "",
|
|
318
|
-
churnType: (_e = preview == null ? void 0 : preview.churnType) != null ? _e : ""
|
|
319
|
-
};
|
|
320
|
-
}
|
|
321
|
-
function hasEditableOpportunityPreview(preview) {
|
|
322
|
-
var _a;
|
|
323
|
-
return !!preview && isValidDateInput((_a = preview.closeDateValue) != null ? _a : preview.closeDate);
|
|
324
|
-
}
|
|
325
|
-
function isValidDateInput(value) {
|
|
326
|
-
const match = /^(\d{4})-(\d{2})-(\d{2})$/.exec(value);
|
|
327
|
-
if (!match) return false;
|
|
328
|
-
const parsed = /* @__PURE__ */ new Date(`${value}T00:00:00Z`);
|
|
329
|
-
if (Number.isNaN(parsed.getTime())) return false;
|
|
330
|
-
return parsed.toISOString().slice(0, 10) === value;
|
|
331
|
-
}
|
|
332
291
|
function Actions() {
|
|
333
|
-
var _a;
|
|
334
292
|
const { approvalState, companyName, opportunityUrl, scheduledTime, labels, hideApproveButton, approveButtonIconUrl, opportunityPreview, requestingApproval, approve, submitApproveFeedback, skipApproveFeedback, dismiss, requestApproval, requestDismiss, cancel } = useSignalApproval();
|
|
335
293
|
const [selectedTopReason, setSelectedTopReason] = React.useState(null);
|
|
336
294
|
const [selectedSubReason, setSelectedSubReason] = React.useState(null);
|
|
@@ -338,14 +296,6 @@ function Actions() {
|
|
|
338
296
|
const [detailText, setDetailText] = React.useState("");
|
|
339
297
|
const [submittedFeedback, setSubmittedFeedback] = React.useState(null);
|
|
340
298
|
const [isEditing, setIsEditing] = React.useState(false);
|
|
341
|
-
const [opportunityDraft, setOpportunityDraft] = React.useState(() => buildOpportunityDraft(opportunityPreview));
|
|
342
|
-
React.useEffect(() => {
|
|
343
|
-
if (approvalState === "confirming") {
|
|
344
|
-
setOpportunityDraft(buildOpportunityDraft(opportunityPreview));
|
|
345
|
-
}
|
|
346
|
-
}, [approvalState, opportunityPreview]);
|
|
347
|
-
const churnTypeOptions = (_a = opportunityPreview == null ? void 0 : opportunityPreview.churnTypeOptions) != null ? _a : [];
|
|
348
|
-
const hasChurnTypeOptions = churnTypeOptions.length > 0;
|
|
349
299
|
const topNode = dismissReasonTree.find((n) => n.label === selectedTopReason);
|
|
350
300
|
const hasSubOptions = !!((topNode == null ? void 0 : topNode.subOptions) && topNode.subOptions.length > 0);
|
|
351
301
|
const isTopOther = selectedTopReason === "Other" && !hasSubOptions;
|
|
@@ -353,8 +303,6 @@ function Actions() {
|
|
|
353
303
|
const needsText = isTopOther || isSubOther;
|
|
354
304
|
const canSubmitDismiss = selectedTopReason !== null && (!hasSubOptions || selectedSubReason !== null) && (!needsText || detailText.trim().length > 0);
|
|
355
305
|
const canSubmitApprove = selectedReasons.length > 0 || detailText.trim().length > 0;
|
|
356
|
-
const isEditableOpportunityPreview = hasEditableOpportunityPreview(opportunityPreview);
|
|
357
|
-
const canConfirmOpportunity = !isEditableOpportunityPreview || isValidDateInput(opportunityDraft.closeDate);
|
|
358
306
|
const selectTopReason = (label) => {
|
|
359
307
|
if (selectedTopReason === label) {
|
|
360
308
|
setSelectedTopReason(null);
|
|
@@ -375,9 +323,9 @@ function Actions() {
|
|
|
375
323
|
);
|
|
376
324
|
};
|
|
377
325
|
const startEditing = () => {
|
|
378
|
-
var
|
|
326
|
+
var _a, _b;
|
|
379
327
|
if (submittedFeedback) {
|
|
380
|
-
setSelectedTopReason((
|
|
328
|
+
setSelectedTopReason((_a = submittedFeedback.reasons[0]) != null ? _a : null);
|
|
381
329
|
setSelectedSubReason((_b = submittedFeedback.subReason) != null ? _b : null);
|
|
382
330
|
setSelectedReasons([...submittedFeedback.reasons]);
|
|
383
331
|
setDetailText(submittedFeedback.detail);
|
|
@@ -647,108 +595,24 @@ function Actions() {
|
|
|
647
595
|
/* @__PURE__ */ jsx("strong", { children: companyName }),
|
|
648
596
|
". Confirm?"
|
|
649
597
|
] }),
|
|
650
|
-
opportunityPreview &&
|
|
598
|
+
opportunityPreview && /* @__PURE__ */ jsx("div", { className: "mt-3 space-y-1.5 border-t border-border/50 pt-3", children: [
|
|
651
599
|
{ label: "Opportunity", value: opportunityPreview.name },
|
|
652
600
|
{ label: "Account", value: opportunityPreview.accountName },
|
|
653
601
|
{ label: "Stage", value: opportunityPreview.stage },
|
|
654
602
|
{ label: "Close Date", value: opportunityPreview.closeDate },
|
|
655
603
|
{ label: "Amount", value: opportunityPreview.amount }
|
|
656
|
-
].map(({ label, value }) => /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between
|
|
604
|
+
].map(({ label, value }) => /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between text-xs", children: [
|
|
657
605
|
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: label }),
|
|
658
|
-
/* @__PURE__ */ jsx("span", { className: "
|
|
659
|
-
] }, label)) })
|
|
660
|
-
opportunityPreview && isEditableOpportunityPreview && /* @__PURE__ */ jsxs("div", { className: "mt-3 space-y-3 border-t border-border/50 pt-3", children: [
|
|
661
|
-
[
|
|
662
|
-
{ label: "Opportunity", value: opportunityPreview.name },
|
|
663
|
-
{ label: "Account", value: opportunityPreview.accountName },
|
|
664
|
-
{ label: "Stage", value: opportunityPreview.stage }
|
|
665
|
-
].map(({ label, value }) => /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3 text-xs", children: [
|
|
666
|
-
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: label }),
|
|
667
|
-
/* @__PURE__ */ jsx("span", { className: "text-right font-medium text-foreground", children: value })
|
|
668
|
-
] }, label)),
|
|
669
|
-
/* @__PURE__ */ jsxs("div", { className: "grid gap-2 sm:grid-cols-2", children: [
|
|
670
|
-
/* @__PURE__ */ jsxs("label", { className: "space-y-1 text-xs", children: [
|
|
671
|
-
/* @__PURE__ */ jsx("span", { className: "font-medium text-muted-foreground", children: "Close Date" }),
|
|
672
|
-
/* @__PURE__ */ jsx(
|
|
673
|
-
"input",
|
|
674
|
-
{
|
|
675
|
-
type: "date",
|
|
676
|
-
value: opportunityDraft.closeDate,
|
|
677
|
-
onChange: (event) => setOpportunityDraft((draft) => __spreadProps(__spreadValues({}, draft), { closeDate: event.target.value })),
|
|
678
|
-
"aria-invalid": !canConfirmOpportunity,
|
|
679
|
-
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"
|
|
680
|
-
}
|
|
681
|
-
),
|
|
682
|
-
!canConfirmOpportunity && /* @__PURE__ */ jsx("span", { className: "text-[11px] text-red-600", children: "Enter a valid close date." })
|
|
683
|
-
] }),
|
|
684
|
-
/* @__PURE__ */ jsxs("label", { className: "space-y-1 text-xs", children: [
|
|
685
|
-
/* @__PURE__ */ jsx("span", { className: "font-medium text-muted-foreground", children: "Amount" }),
|
|
686
|
-
/* @__PURE__ */ jsx(
|
|
687
|
-
"input",
|
|
688
|
-
{
|
|
689
|
-
type: "text",
|
|
690
|
-
inputMode: "decimal",
|
|
691
|
-
value: opportunityDraft.amount,
|
|
692
|
-
onChange: (event) => setOpportunityDraft((draft) => __spreadProps(__spreadValues({}, draft), { amount: event.target.value })),
|
|
693
|
-
placeholder: opportunityPreview.amount,
|
|
694
|
-
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"
|
|
695
|
-
}
|
|
696
|
-
)
|
|
697
|
-
] })
|
|
698
|
-
] }),
|
|
699
|
-
/* @__PURE__ */ jsxs("label", { className: "space-y-1 text-xs", children: [
|
|
700
|
-
/* @__PURE__ */ jsx("span", { className: "font-medium text-muted-foreground", children: "Churn Type" }),
|
|
701
|
-
hasChurnTypeOptions ? /* @__PURE__ */ jsxs(
|
|
702
|
-
"select",
|
|
703
|
-
{
|
|
704
|
-
value: opportunityDraft.churnType,
|
|
705
|
-
onChange: (event) => setOpportunityDraft((draft) => __spreadProps(__spreadValues({}, draft), { churnType: event.target.value })),
|
|
706
|
-
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",
|
|
707
|
-
children: [
|
|
708
|
-
/* @__PURE__ */ jsx("option", { value: "", children: "No churn type" }),
|
|
709
|
-
churnTypeOptions.map((option) => /* @__PURE__ */ jsx("option", { value: optionValue(option), children: optionLabel(option) }, optionValue(option)))
|
|
710
|
-
]
|
|
711
|
-
}
|
|
712
|
-
) : /* @__PURE__ */ jsx(
|
|
713
|
-
"input",
|
|
714
|
-
{
|
|
715
|
-
type: "text",
|
|
716
|
-
value: opportunityDraft.churnType,
|
|
717
|
-
onChange: (event) => setOpportunityDraft((draft) => __spreadProps(__spreadValues({}, draft), { churnType: event.target.value })),
|
|
718
|
-
placeholder: "No churn type",
|
|
719
|
-
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"
|
|
720
|
-
}
|
|
721
|
-
)
|
|
722
|
-
] }),
|
|
723
|
-
/* @__PURE__ */ jsxs("label", { className: "space-y-1 text-xs", children: [
|
|
724
|
-
/* @__PURE__ */ jsx("span", { className: "font-medium text-muted-foreground", children: "Description" }),
|
|
725
|
-
/* @__PURE__ */ jsx(
|
|
726
|
-
"textarea",
|
|
727
|
-
{
|
|
728
|
-
value: opportunityDraft.description,
|
|
729
|
-
onChange: (event) => setOpportunityDraft((draft) => __spreadProps(__spreadValues({}, draft), { description: event.target.value })),
|
|
730
|
-
rows: 3,
|
|
731
|
-
placeholder: "Add a short description",
|
|
732
|
-
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"
|
|
733
|
-
}
|
|
734
|
-
)
|
|
735
|
-
] })
|
|
736
|
-
] })
|
|
606
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium text-foreground", children: value })
|
|
607
|
+
] }, label)) })
|
|
737
608
|
] }),
|
|
738
609
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
739
610
|
/* @__PURE__ */ jsxs(
|
|
740
611
|
"button",
|
|
741
612
|
{
|
|
742
613
|
type: "button",
|
|
743
|
-
onClick:
|
|
744
|
-
|
|
745
|
-
approve();
|
|
746
|
-
return;
|
|
747
|
-
}
|
|
748
|
-
approve(isEditableOpportunityPreview ? opportunityDraft : void 0);
|
|
749
|
-
},
|
|
750
|
-
disabled: !canConfirmOpportunity,
|
|
751
|
-
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",
|
|
614
|
+
onClick: approve,
|
|
615
|
+
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",
|
|
752
616
|
children: [
|
|
753
617
|
/* @__PURE__ */ jsx(Check, { className: "h-3 w-3" }),
|
|
754
618
|
"Confirm"
|
|
@@ -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}\n\ninterface OpportunityDraft {\n closeDate: string\n amount: string\n description: string\n churnType: 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 }\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\">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 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?: RootProps['opportunityPreview']\n requestingApproval: boolean\n approve: () => 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?: {\n name: string\n stage: string\n closeDate: string\n amount: string\n accountName: string\n }\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?: () => 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 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(() => {\n const result = onApprove?.()\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 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\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\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 && (\n <div className=\"mt-3 space-y-1.5 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 text-xs\">\n <span className=\"text-muted-foreground\">{label}</span>\n <span className=\"font-medium text-foreground\">{value}</span>\n </div>\n ))}\n </div>\n )}\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 <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 OpportunityPreview = NonNullable<RootProps['opportunityPreview']>\nexport type { ApprovalState, SignalApprovalLabels, SignalApprovalContextValue, RootProps as SignalApprovalRootProps }\n"],"mappings":"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","names":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import 'react';
|
|
2
2
|
import './feedback-primitives.js';
|
|
3
|
-
export { P as PriorityFactor, S as SignalPriorityPopover, k as SignalPriorityPopoverProps } from '../signal-priority-popover-
|
|
3
|
+
export { P as PriorityFactor, S as SignalPriorityPopover, k as SignalPriorityPopoverProps, p as SignalPriorityScoreDisplay } from '../signal-priority-popover-Cl98xw1n.js';
|
|
4
4
|
import './quick-action-sidebar-nav.js';
|
|
5
5
|
import './quick-action-modal.js';
|
|
6
6
|
import './score-breakdown.js';
|