@wealthx/shadcn 1.5.37 → 1.5.39
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/.turbo/turbo-build.log +142 -133
- package/CHANGELOG.md +12 -0
- package/dist/{chunk-LSSIWLYU.mjs → chunk-6XNEHTII.mjs} +1 -1
- package/dist/{chunk-ULQ53FRJ.mjs → chunk-7NQKFPXE.mjs} +1 -1
- package/dist/{chunk-734FOOJC.mjs → chunk-B5PSUONN.mjs} +25 -58
- package/dist/{chunk-DSVKEVX6.mjs → chunk-CZOGJC76.mjs} +1 -1
- package/dist/chunk-EFHPSKVF.mjs +192 -0
- package/dist/{chunk-JPGL36WQ.mjs → chunk-FL7DEYUA.mjs} +6 -7
- package/dist/{chunk-2CHH5QOA.mjs → chunk-FQUT5XD6.mjs} +1 -1
- package/dist/chunk-MGIDYXOP.mjs +814 -0
- package/dist/{chunk-OG2VM34K.mjs → chunk-MHBQJVHE.mjs} +1 -1
- package/dist/{chunk-NB3ZL36B.mjs → chunk-MZI77ZMX.mjs} +17 -2
- package/dist/chunk-R7M657QL.mjs +587 -0
- package/dist/{chunk-DIH2NZZ3.mjs → chunk-RRROLESJ.mjs} +33 -23
- package/dist/components/ui/ai-assistant-drawer.js +269 -121
- package/dist/components/ui/ai-assistant-drawer.mjs +2 -1
- package/dist/components/ui/ai-conversations/index.js +474 -286
- package/dist/components/ui/ai-conversations/index.mjs +2 -1
- package/dist/components/ui/chat-input-area.js +429 -0
- package/dist/components/ui/chat-input-area.mjs +11 -0
- package/dist/components/ui/file-preview-dialog.js +6 -7
- package/dist/components/ui/file-preview-dialog.mjs +2 -2
- package/dist/components/ui/kanban-column.js +6 -7
- package/dist/components/ui/kanban-column.mjs +3 -3
- package/dist/components/ui/opportunity-card.js +6 -7
- package/dist/components/ui/opportunity-card.mjs +2 -2
- package/dist/components/ui/page-top-bar.js +182 -5
- package/dist/components/ui/page-top-bar.mjs +3 -1
- package/dist/components/ui/pipeline-board.js +6 -7
- package/dist/components/ui/pipeline-board.mjs +4 -4
- package/dist/components/ui/policy-ai/index.js +1636 -0
- package/dist/components/ui/policy-ai/index.mjs +36 -0
- package/dist/components/ui/progress.js +6 -7
- package/dist/components/ui/progress.mjs +1 -1
- package/dist/components/ui/stage-timeline.js +6 -7
- package/dist/components/ui/stage-timeline.mjs +2 -2
- package/dist/components/ui/support-agent/index.js +1131 -0
- package/dist/components/ui/support-agent/index.mjs +27 -0
- package/dist/index.js +5609 -4100
- package/dist/index.mjs +77 -41
- package/dist/styles.css +1 -1
- package/package.json +16 -1
- package/src/components/index.tsx +54 -0
- package/src/components/ui/ai-assistant-drawer.tsx +24 -51
- package/src/components/ui/ai-conversations/index.tsx +16 -8
- package/src/components/ui/ai-conversations/thread.tsx +38 -27
- package/src/components/ui/chat-input-area.tsx +244 -0
- package/src/components/ui/page-top-bar.tsx +31 -5
- package/src/components/ui/policy-ai/index.tsx +41 -0
- package/src/components/ui/policy-ai/policy-ai-panel.tsx +526 -0
- package/src/components/ui/policy-ai/policy-ai-primitives.tsx +332 -0
- package/src/components/ui/policy-ai/policy-ai-responses.tsx +543 -0
- package/src/components/ui/progress.tsx +15 -12
- package/src/components/ui/support-agent/index.tsx +25 -0
- package/src/components/ui/support-agent/support-agent-fab.tsx +116 -0
- package/src/components/ui/support-agent/support-agent-panel.tsx +498 -0
- package/src/components/ui/support-agent/support-agent-primitives.tsx +354 -0
- package/src/styles/globals.css +1 -0
- package/src/styles/styles-css.ts +1 -1
- package/tsup.config.ts +3 -0
|
@@ -1,10 +1,19 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Button
|
|
3
|
+
} from "./chunk-NOOEKOWY.mjs";
|
|
1
4
|
import {
|
|
2
5
|
cn
|
|
3
6
|
} from "./chunk-AFML43VJ.mjs";
|
|
4
7
|
|
|
5
8
|
// src/components/ui/page-top-bar.tsx
|
|
9
|
+
import { Bot } from "lucide-react";
|
|
6
10
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
|
-
function PageTopBar({
|
|
11
|
+
function PageTopBar({
|
|
12
|
+
title,
|
|
13
|
+
actions,
|
|
14
|
+
onAskSupport,
|
|
15
|
+
className
|
|
16
|
+
}) {
|
|
8
17
|
return /* @__PURE__ */ jsxs(
|
|
9
18
|
"div",
|
|
10
19
|
{
|
|
@@ -16,7 +25,13 @@ function PageTopBar({ title, actions, className }) {
|
|
|
16
25
|
),
|
|
17
26
|
children: [
|
|
18
27
|
/* @__PURE__ */ jsx("h1", { className: "text-lg font-semibold leading-tight", children: title }),
|
|
19
|
-
|
|
28
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
29
|
+
actions,
|
|
30
|
+
onAskSupport && /* @__PURE__ */ jsxs(Button, { variant: "outline", size: "sm", onClick: onAskSupport, children: [
|
|
31
|
+
/* @__PURE__ */ jsx(Bot, { className: "size-3.5", "aria-hidden": "true" }),
|
|
32
|
+
"Ask Support"
|
|
33
|
+
] })
|
|
34
|
+
] })
|
|
20
35
|
]
|
|
21
36
|
}
|
|
22
37
|
);
|
|
@@ -0,0 +1,587 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Skeleton
|
|
3
|
+
} from "./chunk-GTAVSBDO.mjs";
|
|
4
|
+
import {
|
|
5
|
+
ChatInputArea
|
|
6
|
+
} from "./chunk-EFHPSKVF.mjs";
|
|
7
|
+
import {
|
|
8
|
+
Sheet,
|
|
9
|
+
SheetContent
|
|
10
|
+
} from "./chunk-H3PTREG6.mjs";
|
|
11
|
+
import {
|
|
12
|
+
Spinner
|
|
13
|
+
} from "./chunk-JVMXMFBB.mjs";
|
|
14
|
+
import {
|
|
15
|
+
Button
|
|
16
|
+
} from "./chunk-NOOEKOWY.mjs";
|
|
17
|
+
import {
|
|
18
|
+
cn
|
|
19
|
+
} from "./chunk-AFML43VJ.mjs";
|
|
20
|
+
|
|
21
|
+
// src/components/ui/support-agent/support-agent-primitives.tsx
|
|
22
|
+
import * as React from "react";
|
|
23
|
+
import {
|
|
24
|
+
Check,
|
|
25
|
+
ChevronDown,
|
|
26
|
+
ChevronUp,
|
|
27
|
+
ExternalLink,
|
|
28
|
+
MapPin,
|
|
29
|
+
MousePointerClick
|
|
30
|
+
} from "lucide-react";
|
|
31
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
32
|
+
function SupportContextChip({
|
|
33
|
+
context,
|
|
34
|
+
isLoading = false,
|
|
35
|
+
className
|
|
36
|
+
}) {
|
|
37
|
+
if (isLoading) {
|
|
38
|
+
return /* @__PURE__ */ jsx(
|
|
39
|
+
Skeleton,
|
|
40
|
+
{
|
|
41
|
+
className: cn("h-6 w-48", className),
|
|
42
|
+
"data-slot": "support-context-chip"
|
|
43
|
+
}
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
if (!context) return null;
|
|
47
|
+
return /* @__PURE__ */ jsxs(
|
|
48
|
+
"div",
|
|
49
|
+
{
|
|
50
|
+
className: cn(
|
|
51
|
+
"flex w-fit items-center gap-1.5 bg-muted px-2.5 py-1 text-xs text-muted-foreground",
|
|
52
|
+
className
|
|
53
|
+
),
|
|
54
|
+
"data-slot": "support-context-chip",
|
|
55
|
+
children: [
|
|
56
|
+
/* @__PURE__ */ jsx(MapPin, { className: "size-3 shrink-0", "aria-hidden": "true" }),
|
|
57
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium text-foreground", children: context.pageLabel }),
|
|
58
|
+
context.entityLabel && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
59
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\u203A" }),
|
|
60
|
+
/* @__PURE__ */ jsx("span", { className: "truncate max-w-[160px]", children: context.entityLabel })
|
|
61
|
+
] })
|
|
62
|
+
]
|
|
63
|
+
}
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
function SupportSuggestedQuestion({
|
|
67
|
+
question,
|
|
68
|
+
onSelect,
|
|
69
|
+
className
|
|
70
|
+
}) {
|
|
71
|
+
return /* @__PURE__ */ jsx(
|
|
72
|
+
Button,
|
|
73
|
+
{
|
|
74
|
+
type: "button",
|
|
75
|
+
variant: "ghost",
|
|
76
|
+
onClick: () => onSelect(question),
|
|
77
|
+
className: cn(
|
|
78
|
+
"h-auto w-full justify-start border border-border bg-background px-3 py-2.5 text-left text-sm font-normal text-foreground hover:bg-muted/50",
|
|
79
|
+
className
|
|
80
|
+
),
|
|
81
|
+
"data-slot": "support-suggested-question",
|
|
82
|
+
children: question
|
|
83
|
+
}
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
function SupportStepGuideCard({
|
|
87
|
+
title,
|
|
88
|
+
steps,
|
|
89
|
+
onHighlight,
|
|
90
|
+
onStepComplete,
|
|
91
|
+
defaultExpanded,
|
|
92
|
+
className
|
|
93
|
+
}) {
|
|
94
|
+
const isLong = steps.length > 5;
|
|
95
|
+
const [expanded, setExpanded] = React.useState(defaultExpanded != null ? defaultExpanded : !isLong);
|
|
96
|
+
const completedCount = steps.filter((s) => s.completed).length;
|
|
97
|
+
const allDone = completedCount === steps.length;
|
|
98
|
+
return /* @__PURE__ */ jsxs(
|
|
99
|
+
"div",
|
|
100
|
+
{
|
|
101
|
+
className: cn("mt-2 border border-border bg-background", className),
|
|
102
|
+
"data-slot": "support-step-guide-card",
|
|
103
|
+
children: [
|
|
104
|
+
/* @__PURE__ */ jsxs(
|
|
105
|
+
"button",
|
|
106
|
+
{
|
|
107
|
+
type: "button",
|
|
108
|
+
onClick: () => setExpanded((v) => !v),
|
|
109
|
+
className: "flex w-full items-center justify-between gap-2 px-3 py-2.5 text-left hover:bg-muted/30",
|
|
110
|
+
"aria-expanded": expanded,
|
|
111
|
+
children: [
|
|
112
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-0.5", children: [
|
|
113
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-semibold text-foreground", children: title }),
|
|
114
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: allDone ? "All steps complete" : `${completedCount} of ${steps.length} complete` })
|
|
115
|
+
] }),
|
|
116
|
+
expanded ? /* @__PURE__ */ jsx(
|
|
117
|
+
ChevronUp,
|
|
118
|
+
{
|
|
119
|
+
className: "size-4 shrink-0 text-muted-foreground",
|
|
120
|
+
"aria-hidden": "true"
|
|
121
|
+
}
|
|
122
|
+
) : /* @__PURE__ */ jsx(
|
|
123
|
+
ChevronDown,
|
|
124
|
+
{
|
|
125
|
+
className: "size-4 shrink-0 text-muted-foreground",
|
|
126
|
+
"aria-hidden": "true"
|
|
127
|
+
}
|
|
128
|
+
)
|
|
129
|
+
]
|
|
130
|
+
}
|
|
131
|
+
),
|
|
132
|
+
expanded && /* @__PURE__ */ jsx("ol", { className: "flex flex-col divide-y divide-border border-t border-border", children: steps.map((step, index) => /* @__PURE__ */ jsxs(
|
|
133
|
+
"li",
|
|
134
|
+
{
|
|
135
|
+
className: cn(
|
|
136
|
+
"flex items-start gap-3 px-3 py-2.5",
|
|
137
|
+
step.completed && "opacity-60"
|
|
138
|
+
),
|
|
139
|
+
children: [
|
|
140
|
+
/* @__PURE__ */ jsx(
|
|
141
|
+
"button",
|
|
142
|
+
{
|
|
143
|
+
type: "button",
|
|
144
|
+
onClick: () => !step.completed && (onStepComplete == null ? void 0 : onStepComplete(step.id)),
|
|
145
|
+
disabled: step.completed,
|
|
146
|
+
title: step.completed ? "Step complete" : "Mark as done",
|
|
147
|
+
className: cn(
|
|
148
|
+
"mt-0.5 flex size-5 shrink-0 items-center justify-center border text-xs font-semibold",
|
|
149
|
+
step.completed ? "border-primary bg-primary text-primary-foreground" : "border-border text-muted-foreground hover:bg-muted"
|
|
150
|
+
),
|
|
151
|
+
"aria-label": step.completed ? `Step ${index + 1} complete` : `Mark step ${index + 1} as done`,
|
|
152
|
+
children: step.completed ? /* @__PURE__ */ jsx(Check, { className: "size-3", "aria-hidden": "true" }) : index + 1
|
|
153
|
+
}
|
|
154
|
+
),
|
|
155
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col gap-1", children: [
|
|
156
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm text-foreground leading-snug", children: step.label }),
|
|
157
|
+
step.elementId && onHighlight && !step.completed && /* @__PURE__ */ jsxs(
|
|
158
|
+
Button,
|
|
159
|
+
{
|
|
160
|
+
type: "button",
|
|
161
|
+
variant: "ghost",
|
|
162
|
+
size: "sm",
|
|
163
|
+
onClick: () => onHighlight(step.elementId),
|
|
164
|
+
className: "h-auto w-fit gap-1 px-0 py-0 text-xs text-primary hover:bg-transparent hover:underline",
|
|
165
|
+
children: [
|
|
166
|
+
/* @__PURE__ */ jsx(MousePointerClick, { className: "size-3", "aria-hidden": "true" }),
|
|
167
|
+
"Show me"
|
|
168
|
+
]
|
|
169
|
+
}
|
|
170
|
+
)
|
|
171
|
+
] })
|
|
172
|
+
]
|
|
173
|
+
},
|
|
174
|
+
step.id
|
|
175
|
+
)) })
|
|
176
|
+
]
|
|
177
|
+
}
|
|
178
|
+
);
|
|
179
|
+
}
|
|
180
|
+
function SupportArticleCard({
|
|
181
|
+
title,
|
|
182
|
+
excerpt,
|
|
183
|
+
href,
|
|
184
|
+
isExternal = false,
|
|
185
|
+
className
|
|
186
|
+
}) {
|
|
187
|
+
return /* @__PURE__ */ jsxs(
|
|
188
|
+
"a",
|
|
189
|
+
{
|
|
190
|
+
href,
|
|
191
|
+
target: isExternal ? "_blank" : void 0,
|
|
192
|
+
rel: isExternal ? "noopener noreferrer" : void 0,
|
|
193
|
+
className: cn(
|
|
194
|
+
"mt-2 flex flex-col gap-1.5 border border-border bg-background px-3 py-2.5 text-left no-underline hover:bg-muted/30 text-foreground",
|
|
195
|
+
className
|
|
196
|
+
),
|
|
197
|
+
"data-slot": "support-article-card",
|
|
198
|
+
children: [
|
|
199
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
|
|
200
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate text-sm font-semibold text-foreground", children: title }),
|
|
201
|
+
isExternal && /* @__PURE__ */ jsx(
|
|
202
|
+
ExternalLink,
|
|
203
|
+
{
|
|
204
|
+
className: "size-3.5 shrink-0 text-muted-foreground",
|
|
205
|
+
"aria-hidden": "true"
|
|
206
|
+
}
|
|
207
|
+
)
|
|
208
|
+
] }),
|
|
209
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground line-clamp-2 leading-relaxed", children: excerpt }),
|
|
210
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-primary", children: isExternal ? "Open article \u2192" : "Read more \u2192" })
|
|
211
|
+
]
|
|
212
|
+
}
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// src/components/ui/support-agent/support-agent-fab.tsx
|
|
217
|
+
import { HelpCircle, X } from "lucide-react";
|
|
218
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
219
|
+
function SupportAgentFAB({
|
|
220
|
+
isOpen = false,
|
|
221
|
+
onClick,
|
|
222
|
+
hasNudge = false,
|
|
223
|
+
nudgeMessage,
|
|
224
|
+
onDismissNudge,
|
|
225
|
+
position = "bottom-right",
|
|
226
|
+
className
|
|
227
|
+
}) {
|
|
228
|
+
const showBubble = hasNudge && !!nudgeMessage && !isOpen;
|
|
229
|
+
return /* @__PURE__ */ jsxs2(
|
|
230
|
+
"div",
|
|
231
|
+
{
|
|
232
|
+
className: cn(
|
|
233
|
+
"fixed bottom-6 z-50 flex flex-col items-end gap-2",
|
|
234
|
+
position === "bottom-right" ? "right-6" : "left-6",
|
|
235
|
+
className
|
|
236
|
+
),
|
|
237
|
+
"data-slot": "support-agent-fab",
|
|
238
|
+
children: [
|
|
239
|
+
showBubble && /* @__PURE__ */ jsxs2("div", { className: "relative flex max-w-[220px] items-start gap-2 border border-border bg-background px-3 py-2 shadow-md", children: [
|
|
240
|
+
/* @__PURE__ */ jsx2("p", { className: "flex-1 text-xs text-foreground leading-relaxed", children: nudgeMessage }),
|
|
241
|
+
onDismissNudge && /* @__PURE__ */ jsx2(
|
|
242
|
+
"button",
|
|
243
|
+
{
|
|
244
|
+
type: "button",
|
|
245
|
+
onClick: onDismissNudge,
|
|
246
|
+
className: "mt-0.5 shrink-0 text-muted-foreground hover:text-foreground",
|
|
247
|
+
"aria-label": "Dismiss",
|
|
248
|
+
children: /* @__PURE__ */ jsx2(X, { className: "size-3" })
|
|
249
|
+
}
|
|
250
|
+
),
|
|
251
|
+
/* @__PURE__ */ jsx2(
|
|
252
|
+
"span",
|
|
253
|
+
{
|
|
254
|
+
className: "absolute -bottom-[5px] right-4 size-2.5 rotate-45 border-b border-r border-border bg-background",
|
|
255
|
+
"aria-hidden": "true"
|
|
256
|
+
}
|
|
257
|
+
)
|
|
258
|
+
] }),
|
|
259
|
+
/* @__PURE__ */ jsxs2("div", { className: "relative", children: [
|
|
260
|
+
/* @__PURE__ */ jsx2(
|
|
261
|
+
Button,
|
|
262
|
+
{
|
|
263
|
+
type: "button",
|
|
264
|
+
size: "icon",
|
|
265
|
+
onClick,
|
|
266
|
+
className: "size-12 rounded-full shadow-lg",
|
|
267
|
+
"aria-label": isOpen ? "Close support assistant" : "Open support assistant",
|
|
268
|
+
"data-state": isOpen ? "open" : "closed",
|
|
269
|
+
children: isOpen ? /* @__PURE__ */ jsx2(X, { className: "size-5", "aria-hidden": "true" }) : /* @__PURE__ */ jsx2(HelpCircle, { className: "size-5", "aria-hidden": "true" })
|
|
270
|
+
}
|
|
271
|
+
),
|
|
272
|
+
hasNudge && !isOpen && /* @__PURE__ */ jsx2(
|
|
273
|
+
"span",
|
|
274
|
+
{
|
|
275
|
+
className: "absolute -right-0.5 -top-0.5 size-3 rounded-full border-2 border-background bg-destructive",
|
|
276
|
+
"aria-label": "New suggestion",
|
|
277
|
+
role: "status"
|
|
278
|
+
}
|
|
279
|
+
)
|
|
280
|
+
] })
|
|
281
|
+
]
|
|
282
|
+
}
|
|
283
|
+
);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// src/components/ui/support-agent/support-agent-panel.tsx
|
|
287
|
+
import * as React2 from "react";
|
|
288
|
+
import { Bot, ChevronLeft, ChevronRight, SquarePen, X as X2 } from "lucide-react";
|
|
289
|
+
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
290
|
+
function SupportTypingIndicator() {
|
|
291
|
+
return /* @__PURE__ */ jsx3(
|
|
292
|
+
"span",
|
|
293
|
+
{
|
|
294
|
+
className: "flex items-center gap-1 py-1",
|
|
295
|
+
"aria-label": "Assistant is thinking",
|
|
296
|
+
role: "status",
|
|
297
|
+
children: [0, 150, 300].map((delay) => /* @__PURE__ */ jsx3(
|
|
298
|
+
"span",
|
|
299
|
+
{
|
|
300
|
+
className: "size-1.5 rounded-full bg-current animate-bounce",
|
|
301
|
+
style: { animationDelay: `${delay}ms` },
|
|
302
|
+
"aria-hidden": "true"
|
|
303
|
+
},
|
|
304
|
+
delay
|
|
305
|
+
))
|
|
306
|
+
}
|
|
307
|
+
);
|
|
308
|
+
}
|
|
309
|
+
function MessageBubble({ message }) {
|
|
310
|
+
const isUser = message.role === "user";
|
|
311
|
+
const isEmpty = !message.content.trim();
|
|
312
|
+
return /* @__PURE__ */ jsxs3(
|
|
313
|
+
"div",
|
|
314
|
+
{
|
|
315
|
+
className: cn(
|
|
316
|
+
"flex w-full flex-col",
|
|
317
|
+
isUser ? "items-end" : "items-start"
|
|
318
|
+
),
|
|
319
|
+
children: [
|
|
320
|
+
/* @__PURE__ */ jsxs3(
|
|
321
|
+
"div",
|
|
322
|
+
{
|
|
323
|
+
className: cn(
|
|
324
|
+
"max-w-[88%] px-3 py-2 text-sm",
|
|
325
|
+
isUser ? "bg-primary text-primary-foreground" : "bg-muted text-foreground",
|
|
326
|
+
message.isErrored && "bg-destructive/10 text-destructive"
|
|
327
|
+
),
|
|
328
|
+
"data-slot": "support-message-bubble",
|
|
329
|
+
"data-role": message.role,
|
|
330
|
+
children: [
|
|
331
|
+
isEmpty && message.isStreaming ? /* @__PURE__ */ jsx3(SupportTypingIndicator, {}) : /* @__PURE__ */ jsx3("span", { className: "whitespace-pre-wrap break-words leading-relaxed", children: message.content }),
|
|
332
|
+
message.isErrored && /* @__PURE__ */ jsx3("p", { className: "mt-1 text-xs opacity-70", children: "Failed to send. Please try again." })
|
|
333
|
+
]
|
|
334
|
+
}
|
|
335
|
+
),
|
|
336
|
+
!isUser && message.richContent && /* @__PURE__ */ jsx3("div", { className: "w-full max-w-[88%]", children: /* @__PURE__ */ jsx3(RichContentRenderer, { richContent: message.richContent }) })
|
|
337
|
+
]
|
|
338
|
+
}
|
|
339
|
+
);
|
|
340
|
+
}
|
|
341
|
+
function RichContentRenderer({ richContent }) {
|
|
342
|
+
if (richContent.type === "step-guide") {
|
|
343
|
+
return /* @__PURE__ */ jsx3(
|
|
344
|
+
SupportStepGuideCard,
|
|
345
|
+
{
|
|
346
|
+
title: richContent.title,
|
|
347
|
+
steps: richContent.steps
|
|
348
|
+
}
|
|
349
|
+
);
|
|
350
|
+
}
|
|
351
|
+
if (richContent.type === "article") {
|
|
352
|
+
return /* @__PURE__ */ jsx3(
|
|
353
|
+
SupportArticleCard,
|
|
354
|
+
{
|
|
355
|
+
title: richContent.title,
|
|
356
|
+
excerpt: richContent.excerpt,
|
|
357
|
+
href: richContent.href,
|
|
358
|
+
isExternal: richContent.isExternal
|
|
359
|
+
}
|
|
360
|
+
);
|
|
361
|
+
}
|
|
362
|
+
return null;
|
|
363
|
+
}
|
|
364
|
+
function SupportAgentPanel({
|
|
365
|
+
open,
|
|
366
|
+
onClose,
|
|
367
|
+
messages = [],
|
|
368
|
+
recentConversations,
|
|
369
|
+
suggestedQuestions = [],
|
|
370
|
+
conversationTitle,
|
|
371
|
+
context,
|
|
372
|
+
isStreaming = false,
|
|
373
|
+
isLoading = false,
|
|
374
|
+
onSendMessage,
|
|
375
|
+
onAttachFile,
|
|
376
|
+
onAttachImage,
|
|
377
|
+
onNewChat,
|
|
378
|
+
onBack,
|
|
379
|
+
onOpenConversation,
|
|
380
|
+
onViewAllConversations,
|
|
381
|
+
className
|
|
382
|
+
}) {
|
|
383
|
+
var _a;
|
|
384
|
+
const [inputValue, setInputValue] = React2.useState("");
|
|
385
|
+
const messagesEndRef = React2.useRef(null);
|
|
386
|
+
const hasMessages = messages.length > 0;
|
|
387
|
+
const isChatMode = hasMessages && !!conversationTitle;
|
|
388
|
+
React2.useEffect(() => {
|
|
389
|
+
if (!messagesEndRef.current) return;
|
|
390
|
+
messagesEndRef.current.scrollIntoView({
|
|
391
|
+
behavior: "smooth",
|
|
392
|
+
block: "nearest"
|
|
393
|
+
});
|
|
394
|
+
}, [messages.length]);
|
|
395
|
+
const handleSend = React2.useCallback(
|
|
396
|
+
(text) => {
|
|
397
|
+
onSendMessage == null ? void 0 : onSendMessage(text);
|
|
398
|
+
setInputValue("");
|
|
399
|
+
},
|
|
400
|
+
[onSendMessage]
|
|
401
|
+
);
|
|
402
|
+
const handleQuestionSelect = React2.useCallback(
|
|
403
|
+
(question) => {
|
|
404
|
+
onSendMessage == null ? void 0 : onSendMessage(question);
|
|
405
|
+
},
|
|
406
|
+
[onSendMessage]
|
|
407
|
+
);
|
|
408
|
+
const hasRecents = !!(recentConversations == null ? void 0 : recentConversations.length);
|
|
409
|
+
return /* @__PURE__ */ jsx3(Sheet, { open, onOpenChange: (o) => !o && onClose(), children: /* @__PURE__ */ jsxs3(
|
|
410
|
+
SheetContent,
|
|
411
|
+
{
|
|
412
|
+
side: "right",
|
|
413
|
+
showCloseButton: false,
|
|
414
|
+
className: cn(
|
|
415
|
+
"flex w-[400px] max-w-full flex-col gap-0 p-0",
|
|
416
|
+
className
|
|
417
|
+
),
|
|
418
|
+
"data-slot": "support-agent-panel",
|
|
419
|
+
children: [
|
|
420
|
+
/* @__PURE__ */ jsxs3("div", { className: "shrink-0 border-b border-border px-3 py-2.5", children: [
|
|
421
|
+
isChatMode ? (
|
|
422
|
+
/* Chat mode: [←] Conversation title [✕] */
|
|
423
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-1", children: [
|
|
424
|
+
onBack && /* @__PURE__ */ jsxs3(
|
|
425
|
+
Button,
|
|
426
|
+
{
|
|
427
|
+
variant: "ghost",
|
|
428
|
+
size: "icon",
|
|
429
|
+
className: "size-7 shrink-0",
|
|
430
|
+
onClick: onBack,
|
|
431
|
+
title: "Back to conversations",
|
|
432
|
+
children: [
|
|
433
|
+
/* @__PURE__ */ jsx3(ChevronLeft, { className: "size-3.5" }),
|
|
434
|
+
/* @__PURE__ */ jsx3("span", { className: "sr-only", children: "Back" })
|
|
435
|
+
]
|
|
436
|
+
}
|
|
437
|
+
),
|
|
438
|
+
/* @__PURE__ */ jsx3("span", { className: "flex-1 truncate px-1 text-sm font-medium text-foreground", children: conversationTitle }),
|
|
439
|
+
/* @__PURE__ */ jsxs3(
|
|
440
|
+
Button,
|
|
441
|
+
{
|
|
442
|
+
variant: "ghost",
|
|
443
|
+
size: "icon",
|
|
444
|
+
className: "size-7 shrink-0",
|
|
445
|
+
onClick: onClose,
|
|
446
|
+
title: "Close",
|
|
447
|
+
children: [
|
|
448
|
+
/* @__PURE__ */ jsx3(X2, { className: "size-3.5" }),
|
|
449
|
+
/* @__PURE__ */ jsx3("span", { className: "sr-only", children: "Close" })
|
|
450
|
+
]
|
|
451
|
+
}
|
|
452
|
+
)
|
|
453
|
+
] })
|
|
454
|
+
) : (
|
|
455
|
+
/* Home mode: [Bot icon] Support Assistant [✕] */
|
|
456
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex items-center justify-between", children: [
|
|
457
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2.5", children: [
|
|
458
|
+
/* @__PURE__ */ jsx3("span", { className: "flex size-7 shrink-0 items-center justify-center rounded-full border border-primary/40 bg-primary/10", children: /* @__PURE__ */ jsx3(
|
|
459
|
+
Bot,
|
|
460
|
+
{
|
|
461
|
+
className: "size-3.5 text-foreground",
|
|
462
|
+
"aria-hidden": "true"
|
|
463
|
+
}
|
|
464
|
+
) }),
|
|
465
|
+
/* @__PURE__ */ jsx3("span", { className: "text-sm font-semibold text-foreground", children: "Support Assistant" })
|
|
466
|
+
] }),
|
|
467
|
+
/* @__PURE__ */ jsxs3(
|
|
468
|
+
Button,
|
|
469
|
+
{
|
|
470
|
+
variant: "ghost",
|
|
471
|
+
size: "icon",
|
|
472
|
+
className: "size-7",
|
|
473
|
+
onClick: onClose,
|
|
474
|
+
title: "Close",
|
|
475
|
+
children: [
|
|
476
|
+
/* @__PURE__ */ jsx3(X2, { className: "size-3.5" }),
|
|
477
|
+
/* @__PURE__ */ jsx3("span", { className: "sr-only", children: "Close" })
|
|
478
|
+
]
|
|
479
|
+
}
|
|
480
|
+
)
|
|
481
|
+
] })
|
|
482
|
+
),
|
|
483
|
+
context && /* @__PURE__ */ jsx3("div", { className: "mt-2", children: /* @__PURE__ */ jsx3(SupportContextChip, { context }) })
|
|
484
|
+
] }),
|
|
485
|
+
/* @__PURE__ */ jsx3("div", { className: "flex flex-1 flex-col overflow-y-auto", children: isLoading ? (
|
|
486
|
+
/* Loading state */
|
|
487
|
+
/* @__PURE__ */ jsx3("div", { className: "flex flex-1 items-center justify-center py-20", children: /* @__PURE__ */ jsxs3("div", { className: "flex flex-col items-center gap-3", children: [
|
|
488
|
+
/* @__PURE__ */ jsx3(Spinner, { size: "lg", className: "text-muted-foreground" }),
|
|
489
|
+
/* @__PURE__ */ jsx3("p", { className: "text-sm text-muted-foreground", children: "Loading\u2026" })
|
|
490
|
+
] }) })
|
|
491
|
+
) : !hasMessages ? (
|
|
492
|
+
/* Home state — Rovo pattern: New Chat CTA + Recents + Suggested */
|
|
493
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex flex-col gap-5 p-4", children: [
|
|
494
|
+
onNewChat && /* @__PURE__ */ jsxs3(
|
|
495
|
+
Button,
|
|
496
|
+
{
|
|
497
|
+
variant: "outline",
|
|
498
|
+
className: "w-full justify-start gap-2 text-sm font-medium",
|
|
499
|
+
onClick: onNewChat,
|
|
500
|
+
disabled: isLoading,
|
|
501
|
+
children: [
|
|
502
|
+
/* @__PURE__ */ jsx3(SquarePen, { className: "size-3.5", "aria-hidden": "true" }),
|
|
503
|
+
"New chat"
|
|
504
|
+
]
|
|
505
|
+
}
|
|
506
|
+
),
|
|
507
|
+
hasRecents && /* @__PURE__ */ jsxs3("div", { className: "flex flex-col gap-1", children: [
|
|
508
|
+
/* @__PURE__ */ jsx3("p", { className: "px-1 text-xs font-medium uppercase tracking-wide text-muted-foreground", children: "Recents" }),
|
|
509
|
+
/* @__PURE__ */ jsx3("div", { className: "flex flex-col", children: recentConversations.map((conv) => /* @__PURE__ */ jsxs3(
|
|
510
|
+
"button",
|
|
511
|
+
{
|
|
512
|
+
type: "button",
|
|
513
|
+
onClick: () => onOpenConversation == null ? void 0 : onOpenConversation(conv.id),
|
|
514
|
+
className: "flex w-full items-center justify-between gap-2 px-1 py-2.5 text-left text-sm text-foreground hover:bg-muted/50",
|
|
515
|
+
children: [
|
|
516
|
+
/* @__PURE__ */ jsx3("span", { className: "flex-1 truncate", children: conv.title }),
|
|
517
|
+
/* @__PURE__ */ jsx3(
|
|
518
|
+
ChevronRight,
|
|
519
|
+
{
|
|
520
|
+
className: "size-3.5 shrink-0 text-muted-foreground",
|
|
521
|
+
"aria-hidden": "true"
|
|
522
|
+
}
|
|
523
|
+
)
|
|
524
|
+
]
|
|
525
|
+
},
|
|
526
|
+
conv.id
|
|
527
|
+
)) }),
|
|
528
|
+
onViewAllConversations && /* @__PURE__ */ jsxs3(
|
|
529
|
+
Button,
|
|
530
|
+
{
|
|
531
|
+
variant: "ghost",
|
|
532
|
+
size: "sm",
|
|
533
|
+
onClick: onViewAllConversations,
|
|
534
|
+
className: "h-auto w-fit gap-0.5 px-1 py-1 text-xs text-muted-foreground hover:bg-transparent hover:text-foreground",
|
|
535
|
+
children: [
|
|
536
|
+
"View all conversations",
|
|
537
|
+
/* @__PURE__ */ jsx3(ChevronRight, { className: "size-3.5", "aria-hidden": "true" })
|
|
538
|
+
]
|
|
539
|
+
}
|
|
540
|
+
)
|
|
541
|
+
] }),
|
|
542
|
+
suggestedQuestions.length > 0 && /* @__PURE__ */ jsxs3("div", { className: "flex flex-col gap-1.5", children: [
|
|
543
|
+
/* @__PURE__ */ jsx3("p", { className: "text-xs font-medium uppercase tracking-wide text-muted-foreground", children: "Suggested" }),
|
|
544
|
+
/* @__PURE__ */ jsx3("div", { className: "flex flex-col gap-1.5", children: suggestedQuestions.map((q) => /* @__PURE__ */ jsx3(
|
|
545
|
+
SupportSuggestedQuestion,
|
|
546
|
+
{
|
|
547
|
+
question: q,
|
|
548
|
+
onSelect: handleQuestionSelect
|
|
549
|
+
},
|
|
550
|
+
q
|
|
551
|
+
)) })
|
|
552
|
+
] }),
|
|
553
|
+
!onNewChat && !hasRecents && !suggestedQuestions.length && /* @__PURE__ */ jsx3("p", { className: "text-sm text-muted-foreground", children: "How can I help you today?" })
|
|
554
|
+
] })
|
|
555
|
+
) : (
|
|
556
|
+
/* Chat thread */
|
|
557
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex flex-col gap-3 p-4", children: [
|
|
558
|
+
messages.map((msg) => /* @__PURE__ */ jsx3(MessageBubble, { message: msg }, msg.id)),
|
|
559
|
+
isStreaming && ((_a = messages[messages.length - 1]) == null ? void 0 : _a.role) === "user" && /* @__PURE__ */ jsx3("div", { className: "flex justify-start", children: /* @__PURE__ */ jsx3("div", { className: "bg-muted px-3 py-2 text-muted-foreground", children: /* @__PURE__ */ jsx3(SupportTypingIndicator, {}) }) }),
|
|
560
|
+
/* @__PURE__ */ jsx3("div", { ref: messagesEndRef, "aria-hidden": "true" })
|
|
561
|
+
] })
|
|
562
|
+
) }),
|
|
563
|
+
/* @__PURE__ */ jsx3("div", { className: "shrink-0 border-t border-border p-3", children: /* @__PURE__ */ jsx3(
|
|
564
|
+
ChatInputArea,
|
|
565
|
+
{
|
|
566
|
+
value: inputValue,
|
|
567
|
+
onChange: setInputValue,
|
|
568
|
+
onSend: handleSend,
|
|
569
|
+
onAttachFile,
|
|
570
|
+
onAttachImage,
|
|
571
|
+
disabled: isLoading || isStreaming,
|
|
572
|
+
placeholder: "Ask anything\u2026"
|
|
573
|
+
}
|
|
574
|
+
) })
|
|
575
|
+
]
|
|
576
|
+
}
|
|
577
|
+
) });
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
export {
|
|
581
|
+
SupportContextChip,
|
|
582
|
+
SupportSuggestedQuestion,
|
|
583
|
+
SupportStepGuideCard,
|
|
584
|
+
SupportArticleCard,
|
|
585
|
+
SupportAgentFAB,
|
|
586
|
+
SupportAgentPanel
|
|
587
|
+
};
|