@handled-ai/design-system 0.10.0 → 0.11.1

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.
@@ -0,0 +1,22 @@
1
+ import * as React from 'react';
2
+ import { SuggestedContact, SuggestedActionsIconMap } from './suggested-actions.js';
3
+
4
+ declare function BrandIcon({ src, alt, className }: {
5
+ src: string;
6
+ alt: string;
7
+ className?: string;
8
+ }): React.JSX.Element;
9
+ interface AccountContactsPopoverProps {
10
+ contacts: SuggestedContact[];
11
+ onSelect: (contact: SuggestedContact) => void;
12
+ onSelectTo?: (contact: SuggestedContact) => void;
13
+ onSelectCc?: (contact: SuggestedContact) => void;
14
+ onSelectBcc?: (contact: SuggestedContact) => void;
15
+ onViewAll?: () => void;
16
+ onOpenRecentActivity?: () => void;
17
+ trigger: React.ReactNode;
18
+ iconMap?: SuggestedActionsIconMap;
19
+ }
20
+ declare function AccountContactsPopover({ contacts, onSelect, onSelectTo, onSelectCc, onSelectBcc, onViewAll, onOpenRecentActivity, trigger, iconMap, }: AccountContactsPopoverProps): React.JSX.Element;
21
+
22
+ export { AccountContactsPopover, type AccountContactsPopoverProps, BrandIcon };
@@ -0,0 +1,180 @@
1
+ "use client"
2
+
3
+ "use client";
4
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
5
+ import * as React from "react";
6
+ import {
7
+ Clock,
8
+ ExternalLink
9
+ } from "lucide-react";
10
+ function BrandIcon({ src, alt, className }) {
11
+ return /* @__PURE__ */ jsx(
12
+ "img",
13
+ {
14
+ src,
15
+ alt,
16
+ className: `${className != null ? className : ""} object-contain`,
17
+ draggable: false
18
+ }
19
+ );
20
+ }
21
+ function AccountContactsPopover({
22
+ contacts,
23
+ onSelect,
24
+ onSelectTo,
25
+ onSelectCc,
26
+ onSelectBcc,
27
+ onViewAll,
28
+ onOpenRecentActivity,
29
+ trigger,
30
+ iconMap
31
+ }) {
32
+ const [open, setOpen] = React.useState(false);
33
+ const triggerRef = React.useRef(null);
34
+ const [popoverStyle, setPopoverStyle] = React.useState({});
35
+ React.useEffect(() => {
36
+ if (open && triggerRef.current) {
37
+ const rect = triggerRef.current.getBoundingClientRect();
38
+ const popoverWidth = Math.min(448, window.innerWidth - 32);
39
+ let left = rect.right - popoverWidth;
40
+ if (left < 16) left = 16;
41
+ if (left + popoverWidth > window.innerWidth - 16) left = window.innerWidth - 16 - popoverWidth;
42
+ setPopoverStyle({ position: "fixed", top: rect.bottom + 4, left });
43
+ }
44
+ }, [open]);
45
+ return /* @__PURE__ */ jsxs("div", { children: [
46
+ /* @__PURE__ */ jsx("div", { ref: triggerRef, onClick: () => setOpen(!open), children: trigger }),
47
+ open && /* @__PURE__ */ jsxs(Fragment, { children: [
48
+ /* @__PURE__ */ jsx("div", { className: "fixed inset-0 z-40", onClick: () => setOpen(false) }),
49
+ /* @__PURE__ */ jsxs("div", { style: popoverStyle, className: "fixed bg-background border border-border rounded-lg shadow-xl z-50 w-[28rem] max-w-[calc(100vw-2rem)] py-2 animate-in fade-in slide-in-from-top-1 duration-150", children: [
50
+ /* @__PURE__ */ jsx("div", { className: "px-3 py-1.5 text-[11px] font-medium text-muted-foreground/60 uppercase tracking-wide", children: "Account Contacts" }),
51
+ /* @__PURE__ */ jsx("div", { className: "max-h-48 overflow-y-auto", children: contacts.map((c, i) => {
52
+ var _a, _b, _c, _d, _e, _f;
53
+ return /* @__PURE__ */ jsxs(
54
+ "div",
55
+ {
56
+ role: "button",
57
+ onClick: () => {
58
+ (onSelectTo != null ? onSelectTo : onSelect)(c);
59
+ setOpen(false);
60
+ },
61
+ className: "flex items-center gap-3 w-full px-3 py-2 text-left hover:bg-muted/50 transition-colors cursor-pointer",
62
+ children: [
63
+ /* @__PURE__ */ jsx("div", { className: "w-7 h-7 rounded-full bg-muted flex items-center justify-center text-[10px] font-medium text-muted-foreground shrink-0", children: c.name.split(" ").map((n) => n[0]).join("") }),
64
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0 overflow-hidden", children: [
65
+ /* @__PURE__ */ jsx("div", { className: "truncate text-sm font-medium text-foreground", children: c.name }),
66
+ /* @__PURE__ */ jsxs("div", { className: "truncate text-xs text-muted-foreground leading-tight", children: [
67
+ c.role,
68
+ " \xB7 ",
69
+ (_f = (_e = (_c = (_b = c.email) != null ? _b : (_a = c.emails) == null ? void 0 : _a[0]) != null ? _c : c.phone) != null ? _e : (_d = c.phones) == null ? void 0 : _d[0]) != null ? _f : ""
70
+ ] }),
71
+ c.lastActivity && /* @__PURE__ */ jsxs(
72
+ "button",
73
+ {
74
+ type: "button",
75
+ onClick: (e) => {
76
+ e.stopPropagation();
77
+ onOpenRecentActivity == null ? void 0 : onOpenRecentActivity();
78
+ setOpen(false);
79
+ },
80
+ className: "mt-1.5 flex max-w-full items-center gap-1.5 overflow-hidden rounded-md border border-border/70 bg-muted/30 px-2 py-1 text-[11px] text-muted-foreground hover:text-foreground hover:bg-muted/50 transition-colors",
81
+ children: [
82
+ /* @__PURE__ */ jsx(Clock, { className: "w-3 h-3 shrink-0" }),
83
+ /* @__PURE__ */ jsx("span", { className: "shrink-0 font-medium", children: "Last activity" }),
84
+ /* @__PURE__ */ jsx("span", { className: "shrink-0 text-muted-foreground/60", children: "\xB7" }),
85
+ /* @__PURE__ */ jsx("span", { className: "shrink-0", children: c.lastActivity.date }),
86
+ /* @__PURE__ */ jsx("span", { className: "shrink-0 text-muted-foreground/60", children: "\xB7" }),
87
+ /* @__PURE__ */ jsx("span", { className: "truncate capitalize", children: c.lastActivity.type })
88
+ ]
89
+ }
90
+ )
91
+ ] }),
92
+ /* @__PURE__ */ jsxs("div", { className: "ml-2 flex items-center gap-1.5 shrink-0", children: [
93
+ onSelectTo && /* @__PURE__ */ jsx(
94
+ "button",
95
+ {
96
+ type: "button",
97
+ onClick: (e) => {
98
+ e.stopPropagation();
99
+ onSelectTo(c);
100
+ setOpen(false);
101
+ },
102
+ className: "h-6 rounded border border-border bg-background px-1.5 text-[10px] text-muted-foreground hover:text-foreground hover:bg-muted/40",
103
+ children: "To"
104
+ }
105
+ ),
106
+ onSelectCc && /* @__PURE__ */ jsx(
107
+ "button",
108
+ {
109
+ type: "button",
110
+ onClick: (e) => {
111
+ e.stopPropagation();
112
+ onSelectCc(c);
113
+ setOpen(false);
114
+ },
115
+ className: "h-6 rounded border border-border bg-background px-1.5 text-[10px] text-muted-foreground hover:text-foreground hover:bg-muted/40",
116
+ children: "Cc"
117
+ }
118
+ ),
119
+ onSelectBcc && /* @__PURE__ */ jsx(
120
+ "button",
121
+ {
122
+ type: "button",
123
+ onClick: (e) => {
124
+ e.stopPropagation();
125
+ onSelectBcc(c);
126
+ setOpen(false);
127
+ },
128
+ className: "h-6 rounded border border-border bg-background px-1.5 text-[10px] text-muted-foreground hover:text-foreground hover:bg-muted/40",
129
+ children: "Bcc"
130
+ }
131
+ ),
132
+ /* @__PURE__ */ jsx(
133
+ "button",
134
+ {
135
+ type: "button",
136
+ onClick: (e) => {
137
+ e.stopPropagation();
138
+ if (c.salesforceUrl) {
139
+ window.open(c.salesforceUrl, "_blank", "noopener,noreferrer");
140
+ } else {
141
+ onViewAll == null ? void 0 : onViewAll();
142
+ }
143
+ },
144
+ className: "h-7 w-7 inline-flex items-center justify-center rounded-md border border-border bg-background hover:bg-muted/40 transition-colors shrink-0",
145
+ "aria-label": `Open ${c.name} in Salesforce`,
146
+ children: (iconMap == null ? void 0 : iconMap.salesforce) ? /* @__PURE__ */ jsx(BrandIcon, { src: iconMap.salesforce, alt: "Salesforce", className: "w-3.5 h-3.5" }) : /* @__PURE__ */ jsx(ExternalLink, { className: "w-3.5 h-3.5 text-muted-foreground" })
147
+ }
148
+ )
149
+ ] })
150
+ ]
151
+ },
152
+ i
153
+ );
154
+ }) }),
155
+ onViewAll && /* @__PURE__ */ jsxs(Fragment, { children: [
156
+ /* @__PURE__ */ jsx("div", { className: "h-px bg-border mx-3 my-1" }),
157
+ /* @__PURE__ */ jsxs(
158
+ "button",
159
+ {
160
+ onClick: () => {
161
+ onViewAll();
162
+ setOpen(false);
163
+ },
164
+ className: "flex items-center gap-2 w-full px-3 py-2 text-left text-xs text-muted-foreground hover:text-foreground hover:bg-muted/50 transition-colors",
165
+ children: [
166
+ /* @__PURE__ */ jsx(ExternalLink, { className: "w-3 h-3" }),
167
+ "View all contacts"
168
+ ]
169
+ }
170
+ )
171
+ ] })
172
+ ] })
173
+ ] })
174
+ ] });
175
+ }
176
+ export {
177
+ AccountContactsPopover,
178
+ BrandIcon
179
+ };
180
+ //# sourceMappingURL=account-contacts-popover.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/account-contacts-popover.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport {\n Clock,\n ExternalLink,\n} from \"lucide-react\"\nimport type { SuggestedContact, SuggestedActionsIconMap } from \"./suggested-actions\"\n\n// ---------------------------------------------------------------------------\n// BrandIcon\n// ---------------------------------------------------------------------------\n\nexport function BrandIcon({ src, alt, className }: { src: string; alt: string; className?: string }) {\n return (\n <img\n src={src}\n alt={alt}\n className={`${className ?? \"\"} object-contain`}\n draggable={false}\n />\n )\n}\n\n// ---------------------------------------------------------------------------\n// AccountContactsPopover\n// ---------------------------------------------------------------------------\n\nexport interface AccountContactsPopoverProps {\n contacts: SuggestedContact[]\n onSelect: (contact: SuggestedContact) => void\n onSelectTo?: (contact: SuggestedContact) => void\n onSelectCc?: (contact: SuggestedContact) => void\n onSelectBcc?: (contact: SuggestedContact) => void\n onViewAll?: () => void\n onOpenRecentActivity?: () => void\n trigger: React.ReactNode\n iconMap?: SuggestedActionsIconMap\n}\n\nexport function AccountContactsPopover({\n contacts,\n onSelect,\n onSelectTo,\n onSelectCc,\n onSelectBcc,\n onViewAll,\n onOpenRecentActivity,\n trigger,\n iconMap,\n}: AccountContactsPopoverProps) {\n const [open, setOpen] = React.useState(false)\n const triggerRef = React.useRef<HTMLDivElement>(null)\n const [popoverStyle, setPopoverStyle] = React.useState<React.CSSProperties>({})\n\n React.useEffect(() => {\n if (open && triggerRef.current) {\n const rect = triggerRef.current.getBoundingClientRect()\n const popoverWidth = Math.min(448, window.innerWidth - 32)\n let left = rect.right - popoverWidth\n if (left < 16) left = 16\n if (left + popoverWidth > window.innerWidth - 16) left = window.innerWidth - 16 - popoverWidth\n setPopoverStyle({ position: \"fixed\", top: rect.bottom + 4, left })\n }\n }, [open])\n\n return (\n <div>\n <div ref={triggerRef} onClick={() => setOpen(!open)}>{trigger}</div>\n {open && (\n <>\n <div className=\"fixed inset-0 z-40\" onClick={() => setOpen(false)} />\n <div style={popoverStyle} className=\"fixed bg-background border border-border rounded-lg shadow-xl z-50 w-[28rem] max-w-[calc(100vw-2rem)] py-2 animate-in fade-in slide-in-from-top-1 duration-150\">\n <div className=\"px-3 py-1.5 text-[11px] font-medium text-muted-foreground/60 uppercase tracking-wide\">\n Account Contacts\n </div>\n <div className=\"max-h-48 overflow-y-auto\">\n {contacts.map((c, i) => (\n <div\n key={i}\n role=\"button\"\n onClick={() => { (onSelectTo ?? onSelect)(c); setOpen(false) }}\n className=\"flex items-center gap-3 w-full px-3 py-2 text-left hover:bg-muted/50 transition-colors cursor-pointer\"\n >\n <div className=\"w-7 h-7 rounded-full bg-muted flex items-center justify-center text-[10px] font-medium text-muted-foreground shrink-0\">\n {c.name.split(\" \").map((n) => n[0]).join(\"\")}\n </div>\n <div className=\"flex-1 min-w-0 overflow-hidden\">\n <div className=\"truncate text-sm font-medium text-foreground\">{c.name}</div>\n <div className=\"truncate text-xs text-muted-foreground leading-tight\">\n {c.role} · {c.email ?? c.emails?.[0] ?? c.phone ?? c.phones?.[0] ?? \"\"}\n </div>\n {c.lastActivity && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation()\n onOpenRecentActivity?.()\n setOpen(false)\n }}\n className=\"mt-1.5 flex max-w-full items-center gap-1.5 overflow-hidden rounded-md border border-border/70 bg-muted/30 px-2 py-1 text-[11px] text-muted-foreground hover:text-foreground hover:bg-muted/50 transition-colors\"\n >\n <Clock className=\"w-3 h-3 shrink-0\" />\n <span className=\"shrink-0 font-medium\">Last activity</span>\n <span className=\"shrink-0 text-muted-foreground/60\">·</span>\n <span className=\"shrink-0\">{c.lastActivity.date}</span>\n <span className=\"shrink-0 text-muted-foreground/60\">·</span>\n <span className=\"truncate capitalize\">{c.lastActivity.type}</span>\n </button>\n )}\n </div>\n <div className=\"ml-2 flex items-center gap-1.5 shrink-0\">\n {onSelectTo && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation()\n onSelectTo(c)\n setOpen(false)\n }}\n className=\"h-6 rounded border border-border bg-background px-1.5 text-[10px] text-muted-foreground hover:text-foreground hover:bg-muted/40\"\n >\n To\n </button>\n )}\n {onSelectCc && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation()\n onSelectCc(c)\n setOpen(false)\n }}\n className=\"h-6 rounded border border-border bg-background px-1.5 text-[10px] text-muted-foreground hover:text-foreground hover:bg-muted/40\"\n >\n Cc\n </button>\n )}\n {onSelectBcc && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation()\n onSelectBcc(c)\n setOpen(false)\n }}\n className=\"h-6 rounded border border-border bg-background px-1.5 text-[10px] text-muted-foreground hover:text-foreground hover:bg-muted/40\"\n >\n Bcc\n </button>\n )}\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation()\n if (c.salesforceUrl) {\n window.open(c.salesforceUrl, \"_blank\", \"noopener,noreferrer\")\n } else {\n onViewAll?.()\n }\n }}\n className=\"h-7 w-7 inline-flex items-center justify-center rounded-md border border-border bg-background hover:bg-muted/40 transition-colors shrink-0\"\n aria-label={`Open ${c.name} in Salesforce`}\n >\n {iconMap?.salesforce ? (\n <BrandIcon src={iconMap.salesforce} alt=\"Salesforce\" className=\"w-3.5 h-3.5\" />\n ) : (\n <ExternalLink className=\"w-3.5 h-3.5 text-muted-foreground\" />\n )}\n </button>\n </div>\n </div>\n ))}\n </div>\n {onViewAll && (\n <>\n <div className=\"h-px bg-border mx-3 my-1\" />\n <button\n onClick={() => { onViewAll(); setOpen(false) }}\n className=\"flex items-center gap-2 w-full px-3 py-2 text-left text-xs text-muted-foreground hover:text-foreground hover:bg-muted/50 transition-colors\"\n >\n <ExternalLink className=\"w-3 h-3\" />\n View all contacts\n </button>\n </>\n )}\n </div>\n </>\n )}\n </div>\n )\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,11 @@
1
+ import * as React from 'react';
2
+
3
+ interface DraftFeedbackInlineProps {
4
+ initialDirection?: 'up' | 'down' | null;
5
+ onRegenerateRequest?: (pills: string[], detail: string) => void;
6
+ onSubmitFeedback?: (type: "up" | "down", pills: string[], detail: string) => void;
7
+ onDiscardRequest?: (pills: string[], detail: string) => void;
8
+ }
9
+ declare function DraftFeedbackInline({ initialDirection, onRegenerateRequest, onSubmitFeedback, onDiscardRequest, }: DraftFeedbackInlineProps): React.JSX.Element;
10
+
11
+ export { DraftFeedbackInline, type DraftFeedbackInlineProps };
@@ -0,0 +1,153 @@
1
+ "use client"
2
+
3
+ "use client";
4
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
5
+ import * as React from "react";
6
+ import {
7
+ ThumbsUp,
8
+ ThumbsDown,
9
+ Check,
10
+ RefreshCw
11
+ } from "lucide-react";
12
+ const positivePills = ["Tone", "Personalization", "Length", "CTA", "Other"];
13
+ const negativePills = ["Too formal", "Too casual", "Too long", "Missing context", "Wrong angle", "Factual error", "Other"];
14
+ function DraftFeedbackInline({
15
+ initialDirection,
16
+ onRegenerateRequest,
17
+ onSubmitFeedback,
18
+ onDiscardRequest
19
+ }) {
20
+ const [thumbState, setThumbState] = React.useState(initialDirection != null ? initialDirection : null);
21
+ const [selectedPills, setSelectedPills] = React.useState([]);
22
+ const [detailText, setDetailText] = React.useState("");
23
+ const [noted, setNoted] = React.useState(false);
24
+ const [regenerated, setRegenerated] = React.useState(false);
25
+ const togglePill = React.useCallback((pill) => {
26
+ setSelectedPills((prev) => prev.includes(pill) ? prev.filter((p) => p !== pill) : [...prev, pill]);
27
+ }, []);
28
+ const handleSubmit = React.useCallback(() => {
29
+ if (!thumbState) return;
30
+ onSubmitFeedback == null ? void 0 : onSubmitFeedback(thumbState, selectedPills, detailText);
31
+ setNoted(true);
32
+ setTimeout(() => {
33
+ setThumbState(null);
34
+ setSelectedPills([]);
35
+ setDetailText("");
36
+ setNoted(false);
37
+ }, 3e3);
38
+ }, [thumbState, selectedPills, detailText, onSubmitFeedback]);
39
+ const handleRegenerate = React.useCallback(() => {
40
+ if (!thumbState) return;
41
+ onRegenerateRequest == null ? void 0 : onRegenerateRequest(selectedPills, detailText);
42
+ setRegenerated(true);
43
+ setTimeout(() => {
44
+ setThumbState(null);
45
+ setSelectedPills([]);
46
+ setDetailText("");
47
+ setRegenerated(false);
48
+ }, 3e3);
49
+ }, [thumbState, selectedPills, detailText, onRegenerateRequest]);
50
+ const handleDiscard = React.useCallback(() => {
51
+ if (!thumbState) return;
52
+ onDiscardRequest == null ? void 0 : onDiscardRequest(selectedPills, detailText);
53
+ }, [thumbState, selectedPills, detailText, onDiscardRequest]);
54
+ if (noted) {
55
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 py-1 animate-in fade-in slide-in-from-top-1 duration-200", children: [
56
+ /* @__PURE__ */ jsx(Check, { className: "w-3.5 h-3.5 text-emerald-500" }),
57
+ /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: "Feedback recorded" })
58
+ ] });
59
+ }
60
+ if (regenerated) {
61
+ return /* @__PURE__ */ jsx("div", { className: "py-2 animate-in fade-in slide-in-from-top-1 duration-200", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 px-3 py-2 rounded-md bg-indigo-50 dark:bg-indigo-950/30 border border-indigo-200 dark:border-indigo-800", children: [
62
+ /* @__PURE__ */ jsx(RefreshCw, { className: "w-3 h-3 text-indigo-500 animate-spin" }),
63
+ /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-indigo-600 dark:text-indigo-400", children: "Regenerating draft..." })
64
+ ] }) });
65
+ }
66
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-0", children: [
67
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
68
+ /* @__PURE__ */ jsx("span", { className: "text-sm text-foreground font-medium", children: "How's this draft?" }),
69
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-1", children: [
70
+ /* @__PURE__ */ jsx(
71
+ "button",
72
+ {
73
+ onClick: () => {
74
+ setThumbState(thumbState === "up" ? null : "up");
75
+ setSelectedPills([]);
76
+ setDetailText("");
77
+ },
78
+ className: `p-1.5 rounded transition-colors ${thumbState === "up" ? "bg-emerald-100 text-emerald-600 dark:bg-emerald-900/30 dark:text-emerald-400" : "hover:bg-muted text-muted-foreground hover:text-foreground"}`,
79
+ children: /* @__PURE__ */ jsx(ThumbsUp, { className: "w-4 h-4", fill: thumbState === "up" ? "currentColor" : "none" })
80
+ }
81
+ ),
82
+ /* @__PURE__ */ jsx(
83
+ "button",
84
+ {
85
+ onClick: () => {
86
+ setThumbState(thumbState === "down" ? null : "down");
87
+ setSelectedPills([]);
88
+ setDetailText("");
89
+ },
90
+ className: `p-1.5 rounded transition-colors ${thumbState === "down" ? "bg-red-100 text-red-600 dark:bg-red-900/30 dark:text-red-400" : "hover:bg-muted text-muted-foreground hover:text-foreground"}`,
91
+ children: /* @__PURE__ */ jsx(ThumbsDown, { className: "w-4 h-4", fill: thumbState === "down" ? "currentColor" : "none" })
92
+ }
93
+ )
94
+ ] })
95
+ ] }),
96
+ thumbState && /* @__PURE__ */ jsxs("div", { className: "pt-3 space-y-3 animate-in fade-in slide-in-from-top-2 duration-200", children: [
97
+ /* @__PURE__ */ jsxs("div", { children: [
98
+ /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground mb-2 block font-medium", children: thumbState === "up" ? "What worked well?" : "What needs improvement?" }),
99
+ /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1.5", children: (thumbState === "up" ? positivePills : negativePills).map((pill) => /* @__PURE__ */ jsx(
100
+ "button",
101
+ {
102
+ onClick: () => togglePill(pill),
103
+ className: `px-2.5 py-1 rounded-full text-[11px] font-medium border transition-colors ${selectedPills.includes(pill) ? thumbState === "up" ? "bg-emerald-100 text-emerald-700 border-emerald-200 dark:bg-emerald-900/30 dark:text-emerald-300 dark:border-emerald-800" : "bg-red-100 text-red-700 border-red-200 dark:bg-red-900/30 dark:text-red-300 dark:border-red-800" : "bg-background text-muted-foreground border-border hover:bg-muted/50 hover:text-foreground"}`,
104
+ children: pill
105
+ },
106
+ pill
107
+ )) })
108
+ ] }),
109
+ /* @__PURE__ */ jsx(
110
+ "textarea",
111
+ {
112
+ value: detailText,
113
+ onChange: (e) => setDetailText(e.target.value),
114
+ placeholder: thumbState === "up" ? "Add specific praise (optional)..." : "Provide specific instructions (optional)...",
115
+ className: "w-full text-xs bg-background border border-border rounded-md px-2.5 py-2 text-foreground placeholder:text-muted-foreground/50 focus:outline-none focus:ring-1 focus:ring-indigo-500/50 focus:border-indigo-500/50 resize-none min-h-[60px]"
116
+ }
117
+ ),
118
+ /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2 pt-1", children: thumbState === "down" ? /* @__PURE__ */ jsxs(Fragment, { children: [
119
+ /* @__PURE__ */ jsxs(
120
+ "button",
121
+ {
122
+ onClick: handleRegenerate,
123
+ disabled: selectedPills.length === 0 && detailText.length === 0,
124
+ className: `flex-1 py-1.5 rounded-md text-xs font-semibold transition-colors flex items-center justify-center gap-1.5 ${selectedPills.length > 0 || detailText.length > 0 ? "bg-foreground text-background hover:bg-foreground/90" : "bg-muted text-muted-foreground cursor-not-allowed"}`,
125
+ children: [
126
+ /* @__PURE__ */ jsx(RefreshCw, { className: "w-3 h-3" }),
127
+ "Regenerate draft"
128
+ ]
129
+ }
130
+ ),
131
+ /* @__PURE__ */ jsx(
132
+ "button",
133
+ {
134
+ onClick: handleDiscard,
135
+ className: "flex-1 py-1.5 rounded-md text-xs font-medium transition-colors border bg-background text-foreground border-border hover:bg-muted/50 flex items-center justify-center gap-1.5",
136
+ children: "Discard draft"
137
+ }
138
+ )
139
+ ] }) : /* @__PURE__ */ jsx(
140
+ "button",
141
+ {
142
+ onClick: handleSubmit,
143
+ className: "flex-1 py-1.5 rounded-md text-xs font-semibold transition-colors bg-foreground text-background hover:bg-foreground/90 border-transparent",
144
+ children: "Submit feedback"
145
+ }
146
+ ) })
147
+ ] })
148
+ ] });
149
+ }
150
+ export {
151
+ DraftFeedbackInline
152
+ };
153
+ //# sourceMappingURL=draft-feedback-inline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/draft-feedback-inline.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport {\n ThumbsUp,\n ThumbsDown,\n Check,\n RefreshCw,\n} from \"lucide-react\"\n\n// ---------------------------------------------------------------------------\n// DraftFeedbackInline\n// ---------------------------------------------------------------------------\n\nconst positivePills = [\"Tone\", \"Personalization\", \"Length\", \"CTA\", \"Other\"]\nconst negativePills = [\"Too formal\", \"Too casual\", \"Too long\", \"Missing context\", \"Wrong angle\", \"Factual error\", \"Other\"]\n\nexport interface DraftFeedbackInlineProps {\n initialDirection?: 'up' | 'down' | null\n onRegenerateRequest?: (pills: string[], detail: string) => void\n onSubmitFeedback?: (type: \"up\" | \"down\", pills: string[], detail: string) => void\n onDiscardRequest?: (pills: string[], detail: string) => void\n}\n\nexport function DraftFeedbackInline({\n initialDirection,\n onRegenerateRequest,\n onSubmitFeedback,\n onDiscardRequest,\n}: DraftFeedbackInlineProps) {\n const [thumbState, setThumbState] = React.useState<\"up\" | \"down\" | null>(initialDirection ?? null)\n const [selectedPills, setSelectedPills] = React.useState<string[]>([])\n const [detailText, setDetailText] = React.useState(\"\")\n const [noted, setNoted] = React.useState(false)\n const [regenerated, setRegenerated] = React.useState(false)\n\n const togglePill = React.useCallback((pill: string) => {\n setSelectedPills((prev) => (prev.includes(pill) ? prev.filter((p) => p !== pill) : [...prev, pill]))\n }, [])\n\n const handleSubmit = React.useCallback(() => {\n if (!thumbState) return\n onSubmitFeedback?.(thumbState, selectedPills, detailText)\n setNoted(true)\n setTimeout(() => {\n setThumbState(null)\n setSelectedPills([])\n setDetailText(\"\")\n setNoted(false)\n }, 3000)\n }, [thumbState, selectedPills, detailText, onSubmitFeedback])\n\n const handleRegenerate = React.useCallback(() => {\n if (!thumbState) return\n onRegenerateRequest?.(selectedPills, detailText)\n setRegenerated(true)\n setTimeout(() => {\n setThumbState(null)\n setSelectedPills([])\n setDetailText(\"\")\n setRegenerated(false)\n }, 3000)\n }, [thumbState, selectedPills, detailText, onRegenerateRequest])\n\n const handleDiscard = React.useCallback(() => {\n if (!thumbState) return\n onDiscardRequest?.(selectedPills, detailText)\n }, [thumbState, selectedPills, detailText, onDiscardRequest])\n\n if (noted) {\n return (\n <div className=\"flex items-center gap-1.5 py-1 animate-in fade-in slide-in-from-top-1 duration-200\">\n <Check className=\"w-3.5 h-3.5 text-emerald-500\" />\n <span className=\"text-xs text-muted-foreground\">Feedback recorded</span>\n </div>\n )\n }\n\n if (regenerated) {\n return (\n <div className=\"py-2 animate-in fade-in slide-in-from-top-1 duration-200\">\n <div className=\"flex items-center gap-2 px-3 py-2 rounded-md bg-indigo-50 dark:bg-indigo-950/30 border border-indigo-200 dark:border-indigo-800\">\n <RefreshCw className=\"w-3 h-3 text-indigo-500 animate-spin\" />\n <span className=\"text-xs font-medium text-indigo-600 dark:text-indigo-400\">Regenerating draft...</span>\n </div>\n </div>\n )\n }\n\n return (\n <div className=\"space-y-0\">\n <div className=\"flex items-center justify-between\">\n <span className=\"text-sm text-foreground font-medium\">How&apos;s this draft?</span>\n <div className=\"flex gap-1\">\n <button\n onClick={() => {\n setThumbState(thumbState === \"up\" ? null : \"up\")\n setSelectedPills([])\n setDetailText(\"\")\n }}\n className={`p-1.5 rounded transition-colors ${\n thumbState === \"up\"\n ? \"bg-emerald-100 text-emerald-600 dark:bg-emerald-900/30 dark:text-emerald-400\"\n : \"hover:bg-muted text-muted-foreground hover:text-foreground\"\n }`}\n >\n <ThumbsUp className=\"w-4 h-4\" fill={thumbState === \"up\" ? \"currentColor\" : \"none\"} />\n </button>\n <button\n onClick={() => {\n setThumbState(thumbState === \"down\" ? null : \"down\")\n setSelectedPills([])\n setDetailText(\"\")\n }}\n className={`p-1.5 rounded transition-colors ${\n thumbState === \"down\"\n ? \"bg-red-100 text-red-600 dark:bg-red-900/30 dark:text-red-400\"\n : \"hover:bg-muted text-muted-foreground hover:text-foreground\"\n }`}\n >\n <ThumbsDown className=\"w-4 h-4\" fill={thumbState === \"down\" ? \"currentColor\" : \"none\"} />\n </button>\n </div>\n </div>\n\n {thumbState && (\n <div className=\"pt-3 space-y-3 animate-in fade-in slide-in-from-top-2 duration-200\">\n <div>\n <span className=\"text-xs text-muted-foreground mb-2 block font-medium\">\n {thumbState === \"up\" ? \"What worked well?\" : \"What needs improvement?\"}\n </span>\n <div className=\"flex flex-wrap gap-1.5\">\n {(thumbState === \"up\" ? positivePills : negativePills).map((pill) => (\n <button\n key={pill}\n onClick={() => togglePill(pill)}\n className={`px-2.5 py-1 rounded-full text-[11px] font-medium border transition-colors ${\n selectedPills.includes(pill)\n ? thumbState === \"up\"\n ? \"bg-emerald-100 text-emerald-700 border-emerald-200 dark:bg-emerald-900/30 dark:text-emerald-300 dark:border-emerald-800\"\n : \"bg-red-100 text-red-700 border-red-200 dark:bg-red-900/30 dark:text-red-300 dark:border-red-800\"\n : \"bg-background text-muted-foreground border-border hover:bg-muted/50 hover:text-foreground\"\n }`}\n >\n {pill}\n </button>\n ))}\n </div>\n </div>\n\n <textarea\n value={detailText}\n onChange={(e) => setDetailText(e.target.value)}\n placeholder={thumbState === \"up\" ? \"Add specific praise (optional)...\" : \"Provide specific instructions (optional)...\"}\n className=\"w-full text-xs bg-background border border-border rounded-md px-2.5 py-2 text-foreground placeholder:text-muted-foreground/50 focus:outline-none focus:ring-1 focus:ring-indigo-500/50 focus:border-indigo-500/50 resize-none min-h-[60px]\"\n />\n\n <div className=\"flex items-center gap-2 pt-1\">\n {thumbState === \"down\" ? (\n <>\n <button\n onClick={handleRegenerate}\n disabled={selectedPills.length === 0 && detailText.length === 0}\n className={`flex-1 py-1.5 rounded-md text-xs font-semibold transition-colors flex items-center justify-center gap-1.5 ${\n selectedPills.length > 0 || detailText.length > 0\n ? \"bg-foreground text-background hover:bg-foreground/90\"\n : \"bg-muted text-muted-foreground cursor-not-allowed\"\n }`}\n >\n <RefreshCw className=\"w-3 h-3\" />\n Regenerate draft\n </button>\n <button\n onClick={handleDiscard}\n className=\"flex-1 py-1.5 rounded-md text-xs font-medium transition-colors border bg-background text-foreground border-border hover:bg-muted/50 flex items-center justify-center gap-1.5\"\n >\n Discard draft\n </button>\n </>\n ) : (\n <button\n onClick={handleSubmit}\n className=\"flex-1 py-1.5 rounded-md text-xs font-semibold transition-colors bg-foreground text-background hover:bg-foreground/90 border-transparent\"\n >\n Submit feedback\n </button>\n )}\n </div>\n </div>\n )}\n </div>\n )\n}\n"],"mappings":"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","names":[]}