@retrivora-ai/rag-engine 1.7.6 → 1.7.8
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/{DocumentChunker-BXOUMKoP.d.ts → DocumentChunker-DMZVv6hi.d.ts} +1 -1
- package/dist/{DocumentChunker-D1dg5iCi.d.mts → DocumentChunker-wKE98F_G.d.mts} +1 -1
- package/dist/{chunk-XGVKIPNY.mjs → chunk-UHGYLTTY.mjs} +890 -882
- package/dist/handlers/index.d.mts +2 -2
- package/dist/handlers/index.d.ts +2 -2
- package/dist/handlers/index.js +890 -882
- package/dist/handlers/index.mjs +1 -1
- package/dist/{index-BejNscWZ.d.mts → index-B1u4loP6.d.mts} +1 -1
- package/dist/{index-CbkMJvu5.d.ts → index-D9w9fLjh.d.ts} +1 -1
- package/dist/{index-Cti1u0y1.d.mts → index-DfsVx0a4.d.mts} +1 -0
- package/dist/{index-Cti1u0y1.d.ts → index-DfsVx0a4.d.ts} +1 -0
- package/dist/index.d.mts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +185 -5
- package/dist/index.mjs +318 -138
- package/dist/server.d.mts +5 -5
- package/dist/server.d.ts +5 -5
- package/dist/server.js +1241 -1235
- package/dist/server.mjs +1 -1
- package/package.json +1 -1
- package/src/components/MessageBubble.tsx +8 -0
- package/src/core/Pipeline.ts +15 -2
- package/src/hooks/useRagChat.ts +12 -2
- package/src/types/chat.ts +1 -0
package/dist/index.mjs
CHANGED
|
@@ -8,11 +8,11 @@ import {
|
|
|
8
8
|
} from "./chunk-X4TOT24V.mjs";
|
|
9
9
|
|
|
10
10
|
// src/components/ChatWidget.tsx
|
|
11
|
-
import
|
|
11
|
+
import React10, { useState as useState5 } from "react";
|
|
12
12
|
import { MessageSquare, X as X2 } from "lucide-react";
|
|
13
13
|
|
|
14
14
|
// src/components/ChatWindow.tsx
|
|
15
|
-
import
|
|
15
|
+
import React9, { useState as useState4, useRef as useRef3, useEffect as useEffect4, useCallback as useCallback2 } from "react";
|
|
16
16
|
import {
|
|
17
17
|
Bot as Bot2,
|
|
18
18
|
Trash2,
|
|
@@ -28,44 +28,44 @@ import {
|
|
|
28
28
|
} from "lucide-react";
|
|
29
29
|
|
|
30
30
|
// src/components/MessageBubble.tsx
|
|
31
|
-
import
|
|
31
|
+
import React6 from "react";
|
|
32
32
|
import { Bot, User, ChevronDown as ChevronDown2, ChevronRight as ChevronRight2 } from "lucide-react";
|
|
33
33
|
import ReactMarkdown from "react-markdown";
|
|
34
34
|
import remarkGfm from "remark-gfm";
|
|
35
35
|
|
|
36
36
|
// src/components/SourceCard.tsx
|
|
37
|
-
import
|
|
37
|
+
import React2 from "react";
|
|
38
38
|
import { ChevronDown, ChevronUp } from "lucide-react";
|
|
39
39
|
function SourceCard({ source, index }) {
|
|
40
40
|
var _a, _b;
|
|
41
|
-
const [expanded, setExpanded] =
|
|
41
|
+
const [expanded, setExpanded] = React2.useState(false);
|
|
42
42
|
const scorePercent = Math.round(source.score * 100);
|
|
43
43
|
const scoreColor = source.score >= 0.8 ? "text-emerald-400" : source.score >= 0.6 ? "text-amber-400" : "text-rose-400";
|
|
44
44
|
const scoreBg = source.score >= 0.8 ? "bg-emerald-50 border-emerald-100 dark:bg-emerald-400/10 dark:border-emerald-400/20" : source.score >= 0.6 ? "bg-amber-50 border-amber-100 dark:bg-amber-400/10 dark:border-amber-400/20" : "bg-rose-50 border-rose-100 dark:bg-rose-400/10 dark:border-rose-400/20";
|
|
45
45
|
const preview = source.content.slice(0, 120);
|
|
46
46
|
const hasMore = source.content.length > 120;
|
|
47
|
-
return /* @__PURE__ */
|
|
47
|
+
return /* @__PURE__ */ React2.createElement(
|
|
48
48
|
"div",
|
|
49
49
|
{
|
|
50
50
|
className: `rounded-xl border backdrop-blur-sm p-3 transition-all duration-200 hover:scale-[1.01] cursor-pointer ${scoreBg}`,
|
|
51
51
|
onClick: () => setExpanded((e) => !e)
|
|
52
52
|
},
|
|
53
|
-
/* @__PURE__ */
|
|
54
|
-
/* @__PURE__ */
|
|
55
|
-
hasMore && /* @__PURE__ */
|
|
53
|
+
/* @__PURE__ */ React2.createElement("div", { className: "flex items-start justify-between gap-2" }, /* @__PURE__ */ React2.createElement("div", { className: "flex items-center gap-2 min-w-0" }, /* @__PURE__ */ React2.createElement("span", { className: "flex-shrink-0 w-5 h-5 rounded-full bg-slate-200 dark:bg-white/10 flex items-center justify-center text-[10px] font-bold text-slate-500 dark:text-white/60" }, index + 1), /* @__PURE__ */ React2.createElement("span", { className: "text-xs text-slate-500 dark:text-white/50 truncate font-mono" }, (_b = (_a = source.metadata) == null ? void 0 : _a.docId) != null ? _b : source.id)), /* @__PURE__ */ React2.createElement("span", { className: `flex-shrink-0 text-xs font-semibold ${scoreColor} tabular-nums` }, scorePercent, "%")),
|
|
54
|
+
/* @__PURE__ */ React2.createElement("p", { className: "mt-2 text-xs text-slate-600 dark:text-white/70 leading-relaxed" }, expanded ? source.content : `${preview}${hasMore && !expanded ? "\u2026" : ""}`),
|
|
55
|
+
hasMore && /* @__PURE__ */ React2.createElement("button", { className: "mt-1 text-[10px] text-indigo-400 hover:text-indigo-300 transition-colors flex items-center gap-0.5" }, expanded ? /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(ChevronUp, { className: "w-3 h-3" }), " Show less") : /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(ChevronDown, { className: "w-3 h-3" }), " Show more"))
|
|
56
56
|
);
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
// src/components/ProductCarousel.tsx
|
|
60
|
-
import
|
|
60
|
+
import React4, { useRef, useState, useEffect } from "react";
|
|
61
61
|
import { ChevronLeft, ChevronRight } from "lucide-react";
|
|
62
62
|
|
|
63
63
|
// src/components/ProductCard.tsx
|
|
64
|
-
import
|
|
64
|
+
import React3 from "react";
|
|
65
65
|
import Image from "next/image";
|
|
66
66
|
import { ShoppingCart, ExternalLink } from "lucide-react";
|
|
67
67
|
function ProductCard({ product, primaryColor = "#6366f1", onAddToCart }) {
|
|
68
|
-
return /* @__PURE__ */
|
|
68
|
+
return /* @__PURE__ */ React3.createElement("div", { className: "flex-shrink-0 w-full bg-white dark:bg-white/5 border border-slate-200 dark:border-white/10 rounded-xl overflow-hidden shadow-sm hover:shadow-md transition-all duration-300 group" }, /* @__PURE__ */ React3.createElement("div", { className: "relative h-40 w-full bg-slate-100 dark:bg-white/5 flex items-center justify-center overflow-hidden" }, product.image ? /* @__PURE__ */ React3.createElement(
|
|
69
69
|
Image,
|
|
70
70
|
{
|
|
71
71
|
src: product.image,
|
|
@@ -74,16 +74,16 @@ function ProductCard({ product, primaryColor = "#6366f1", onAddToCart }) {
|
|
|
74
74
|
unoptimized: true,
|
|
75
75
|
className: "object-cover group-hover:scale-105 transition-transform duration-500"
|
|
76
76
|
}
|
|
77
|
-
) : /* @__PURE__ */
|
|
77
|
+
) : /* @__PURE__ */ React3.createElement("div", { className: "text-slate-400 dark:text-white/20" }, /* @__PURE__ */ React3.createElement(ShoppingCart, { className: "w-12 h-12" })), product.brand && /* @__PURE__ */ React3.createElement("div", { className: "absolute top-2 left-2 px-2 py-1 bg-white/90 dark:bg-black/60 backdrop-blur-md rounded-md text-[10px] font-bold uppercase tracking-wider text-slate-700 dark:text-white/90 shadow-sm" }, product.brand)), /* @__PURE__ */ React3.createElement("div", { className: "p-4 flex flex-col gap-2" }, /* @__PURE__ */ React3.createElement("div", { className: "flex justify-between items-start gap-2" }, /* @__PURE__ */ React3.createElement("h3", { className: "text-sm font-semibold text-slate-800 dark:text-white/90 line-clamp-1" }, product.name), product.price && /* @__PURE__ */ React3.createElement("span", { className: "text-sm font-bold", style: { color: primaryColor } }, typeof product.price === "number" ? `$${product.price}` : product.price)), product.description && /* @__PURE__ */ React3.createElement("p", { className: "text-[11px] text-slate-500 dark:text-white/50 line-clamp-2 leading-relaxed" }, product.description), /* @__PURE__ */ React3.createElement("div", { className: "mt-2 flex gap-2" }, /* @__PURE__ */ React3.createElement(
|
|
78
78
|
"button",
|
|
79
79
|
{
|
|
80
80
|
onClick: () => onAddToCart == null ? void 0 : onAddToCart(product),
|
|
81
81
|
className: "flex-1 py-2 px-3 rounded-lg text-[11px] font-medium text-white shadow-sm hover:opacity-90 transition-opacity flex items-center justify-center gap-1.5",
|
|
82
82
|
style: { background: primaryColor }
|
|
83
83
|
},
|
|
84
|
-
/* @__PURE__ */
|
|
84
|
+
/* @__PURE__ */ React3.createElement(ShoppingCart, { className: "w-3 h-3" }),
|
|
85
85
|
"Add to Cart"
|
|
86
|
-
), product.link && /* @__PURE__ */
|
|
86
|
+
), product.link && /* @__PURE__ */ React3.createElement(
|
|
87
87
|
"a",
|
|
88
88
|
{
|
|
89
89
|
href: product.link,
|
|
@@ -91,7 +91,7 @@ function ProductCard({ product, primaryColor = "#6366f1", onAddToCart }) {
|
|
|
91
91
|
rel: "noopener noreferrer",
|
|
92
92
|
className: "p-2 rounded-lg bg-slate-100 dark:bg-white/10 text-slate-600 dark:text-white/70 hover:bg-slate-200 dark:hover:bg-white/20 transition-colors"
|
|
93
93
|
},
|
|
94
|
-
/* @__PURE__ */
|
|
94
|
+
/* @__PURE__ */ React3.createElement(ExternalLink, { className: "w-3.5 h-3.5" })
|
|
95
95
|
))));
|
|
96
96
|
}
|
|
97
97
|
|
|
@@ -123,9 +123,9 @@ function ProductCarousel({ products, primaryColor = "#6366f1", onAddToCart }) {
|
|
|
123
123
|
};
|
|
124
124
|
if (!products || products.length === 0) return null;
|
|
125
125
|
if (products.length === 1) {
|
|
126
|
-
return /* @__PURE__ */
|
|
126
|
+
return /* @__PURE__ */ React4.createElement("div", { className: "my-4 w-[min(88%,18rem)] min-w-0 max-w-full animate-fade-in-up" }, /* @__PURE__ */ React4.createElement(ProductCard, { product: products[0], primaryColor, onAddToCart }));
|
|
127
127
|
}
|
|
128
|
-
return /* @__PURE__ */
|
|
128
|
+
return /* @__PURE__ */ React4.createElement("div", { className: "relative w-full my-4 group/carousel animate-fade-in-up" }, canScroll && /* @__PURE__ */ React4.createElement(React4.Fragment, null, /* @__PURE__ */ React4.createElement("div", { className: "absolute -left-4 top-1/2 -translate-y-1/2 z-20 opacity-100 md:opacity-0 md:group-hover/carousel:opacity-100 transition-opacity" }, /* @__PURE__ */ React4.createElement(
|
|
129
129
|
"button",
|
|
130
130
|
{
|
|
131
131
|
onClick: (e) => {
|
|
@@ -135,8 +135,8 @@ function ProductCarousel({ products, primaryColor = "#6366f1", onAddToCart }) {
|
|
|
135
135
|
className: "p-2 rounded-full bg-white dark:bg-slate-800 shadow-xl border border-slate-200 dark:border-white/10 text-slate-600 dark:text-white/80 hover:text-indigo-500 dark:hover:text-indigo-400 transition-all hover:scale-110 active:scale-95",
|
|
136
136
|
"aria-label": "Scroll left"
|
|
137
137
|
},
|
|
138
|
-
/* @__PURE__ */
|
|
139
|
-
)), /* @__PURE__ */
|
|
138
|
+
/* @__PURE__ */ React4.createElement(ChevronLeft, { className: "w-5 h-5" })
|
|
139
|
+
)), /* @__PURE__ */ React4.createElement("div", { className: "absolute -right-4 top-1/2 -translate-y-1/2 z-20 opacity-100 md:opacity-0 md:group-hover/carousel:opacity-100 transition-opacity" }, /* @__PURE__ */ React4.createElement(
|
|
140
140
|
"button",
|
|
141
141
|
{
|
|
142
142
|
onClick: (e) => {
|
|
@@ -146,27 +146,27 @@ function ProductCarousel({ products, primaryColor = "#6366f1", onAddToCart }) {
|
|
|
146
146
|
className: "p-2 rounded-full bg-white dark:bg-slate-800 shadow-xl border border-slate-200 dark:border-white/10 text-slate-600 dark:text-white/80 hover:text-indigo-500 dark:hover:text-indigo-400 transition-all hover:scale-110 active:scale-95",
|
|
147
147
|
"aria-label": "Scroll right"
|
|
148
148
|
},
|
|
149
|
-
/* @__PURE__ */
|
|
150
|
-
))), /* @__PURE__ */
|
|
149
|
+
/* @__PURE__ */ React4.createElement(ChevronRight, { className: "w-5 h-5" })
|
|
150
|
+
))), /* @__PURE__ */ React4.createElement(
|
|
151
151
|
"div",
|
|
152
152
|
{
|
|
153
153
|
ref: scrollRef,
|
|
154
154
|
className: "flex gap-4 overflow-x-auto pb-4 px-1 scrollbar-hide snap-x snap-mandatory",
|
|
155
155
|
style: { scrollbarWidth: "none", msOverflowStyle: "none" }
|
|
156
156
|
},
|
|
157
|
-
products.map((product) => /* @__PURE__ */
|
|
157
|
+
products.map((product) => /* @__PURE__ */ React4.createElement(
|
|
158
158
|
"div",
|
|
159
159
|
{
|
|
160
160
|
key: product.id,
|
|
161
161
|
className: "snap-start flex-shrink-0 w-[min(88%,18rem)] min-w-[11rem] max-w-full"
|
|
162
162
|
},
|
|
163
|
-
/* @__PURE__ */
|
|
163
|
+
/* @__PURE__ */ React4.createElement(ProductCard, { product, primaryColor, onAddToCart })
|
|
164
164
|
))
|
|
165
165
|
));
|
|
166
166
|
}
|
|
167
167
|
|
|
168
168
|
// src/components/DynamicChart.tsx
|
|
169
|
-
import
|
|
169
|
+
import React5 from "react";
|
|
170
170
|
import {
|
|
171
171
|
BarChart,
|
|
172
172
|
Bar,
|
|
@@ -191,9 +191,9 @@ function DynamicChart({
|
|
|
191
191
|
}) {
|
|
192
192
|
const { type, data } = config;
|
|
193
193
|
const colors = config.colors || [primaryColor, accentColor, ...DEFAULT_COLORS];
|
|
194
|
-
const containerRef =
|
|
195
|
-
const [containerWidth, setContainerWidth] =
|
|
196
|
-
|
|
194
|
+
const containerRef = React5.useRef(null);
|
|
195
|
+
const [containerWidth, setContainerWidth] = React5.useState(0);
|
|
196
|
+
React5.useEffect(() => {
|
|
197
197
|
const element = containerRef.current;
|
|
198
198
|
if (!element || typeof ResizeObserver === "undefined") return;
|
|
199
199
|
const updateWidth = (width) => {
|
|
@@ -219,7 +219,7 @@ function DynamicChart({
|
|
|
219
219
|
return text.length > maxLength ? `${text.slice(0, maxLength)}\u2026` : text;
|
|
220
220
|
};
|
|
221
221
|
const chartMargin = isTiny ? { top: 8, right: 4, left: -28, bottom: 0 } : isCompact ? { top: 10, right: 6, left: -24, bottom: 0 } : { top: 10, right: 10, left: -20, bottom: 0 };
|
|
222
|
-
const sanitizedData =
|
|
222
|
+
const sanitizedData = React5.useMemo(() => {
|
|
223
223
|
if (!data) return [];
|
|
224
224
|
return data.map((item) => {
|
|
225
225
|
const newItem = {};
|
|
@@ -252,7 +252,7 @@ function DynamicChart({
|
|
|
252
252
|
});
|
|
253
253
|
}, [data]);
|
|
254
254
|
if (!data || data.length === 0) {
|
|
255
|
-
return /* @__PURE__ */
|
|
255
|
+
return /* @__PURE__ */ React5.createElement("div", { className: "p-4 text-sm text-slate-500" }, "No data available for chart.");
|
|
256
256
|
}
|
|
257
257
|
const firstItem = sanitizedData[0];
|
|
258
258
|
const allKeys = Object.keys(firstItem);
|
|
@@ -302,11 +302,11 @@ function DynamicChart({
|
|
|
302
302
|
const renderTooltip = (row, label) => {
|
|
303
303
|
var _a, _b;
|
|
304
304
|
if (!row) return null;
|
|
305
|
-
return /* @__PURE__ */
|
|
305
|
+
return /* @__PURE__ */ React5.createElement("div", { className: "rounded-xl border border-slate-200 bg-white px-3 py-2 text-xs shadow-xl dark:border-white/10 dark:bg-slate-950" }, /* @__PURE__ */ React5.createElement("p", { className: "mb-2 font-semibold text-slate-800 dark:text-white/90" }, String((_b = (_a = row[finalXKey]) != null ? _a : label) != null ? _b : "Details")), Object.entries(row).map(([key, value]) => {
|
|
306
306
|
var _a2;
|
|
307
307
|
if (value === null || value === void 0 || key === finalXKey) return null;
|
|
308
308
|
if (typeof value === "object") return null;
|
|
309
|
-
return /* @__PURE__ */
|
|
309
|
+
return /* @__PURE__ */ React5.createElement("div", { key, className: "flex items-center justify-between gap-3 text-slate-600 dark:text-white/70" }, /* @__PURE__ */ React5.createElement("span", null, (_a2 = tooltipLabelMap[key]) != null ? _a2 : key), /* @__PURE__ */ React5.createElement("span", { className: "font-medium text-slate-900 dark:text-white/90" }, String(value)));
|
|
310
310
|
}));
|
|
311
311
|
};
|
|
312
312
|
const getTooltipRow = (payload) => {
|
|
@@ -318,7 +318,7 @@ function DynamicChart({
|
|
|
318
318
|
return row;
|
|
319
319
|
};
|
|
320
320
|
if (type === "pie") {
|
|
321
|
-
return /* @__PURE__ */
|
|
321
|
+
return /* @__PURE__ */ React5.createElement("div", { ref: containerRef, className: "w-full min-w-0 mt-4 mb-2 select-none overflow-hidden" }, /* @__PURE__ */ React5.createElement("div", { className: "mx-auto w-full max-w-full aspect-square" }, /* @__PURE__ */ React5.createElement(ResponsiveContainer, { width: "100%", height: "100%" }, /* @__PURE__ */ React5.createElement(PieChart, null, /* @__PURE__ */ React5.createElement(
|
|
322
322
|
Pie,
|
|
323
323
|
{
|
|
324
324
|
data: sanitizedData,
|
|
@@ -330,10 +330,10 @@ function DynamicChart({
|
|
|
330
330
|
label: false,
|
|
331
331
|
labelLine: false
|
|
332
332
|
},
|
|
333
|
-
sanitizedData.map((entry, index) => /* @__PURE__ */
|
|
334
|
-
), /* @__PURE__ */
|
|
333
|
+
sanitizedData.map((entry, index) => /* @__PURE__ */ React5.createElement(Cell, { key: `cell-${index}`, fill: stockAwareColor(entry, index) }))
|
|
334
|
+
), /* @__PURE__ */ React5.createElement(Tooltip, { content: (props) => renderTooltip(getTooltipRow(props.payload), typeof props.label === "string" ? props.label : void 0) }), showLegend && !isCompact && /* @__PURE__ */ React5.createElement(Legend, { wrapperStyle: { fontSize: 12 }, verticalAlign: "bottom" })))));
|
|
335
335
|
}
|
|
336
|
-
return /* @__PURE__ */
|
|
336
|
+
return /* @__PURE__ */ React5.createElement("div", { ref: containerRef, className: "w-full min-w-0 mt-4 mb-2 select-none overflow-hidden" }, /* @__PURE__ */ React5.createElement("div", { className: "w-full aspect-[4/3]" }, /* @__PURE__ */ React5.createElement(ResponsiveContainer, { width: "100%", height: "100%" }, type === "bar" ? /* @__PURE__ */ React5.createElement(BarChart, { data: sanitizedData, margin: chartMargin }, /* @__PURE__ */ React5.createElement(CartesianGrid, { strokeDasharray: "3 3", vertical: false, stroke: "#e2e8f0" }), /* @__PURE__ */ React5.createElement(XAxis, { dataKey: finalXKey, tick: axisTick, tickFormatter: truncateAxisLabel, tickLine: false, axisLine: { stroke: "#cbd5e1" }, interval: 0, minTickGap: isTiny ? 2 : isCompact ? 6 : 12 }), /* @__PURE__ */ React5.createElement(YAxis, { tick: axisTick, tickLine: false, axisLine: false }), /* @__PURE__ */ React5.createElement(Tooltip, { content: (props) => renderTooltip(getTooltipRow(props.payload), typeof props.label === "string" ? props.label : void 0), cursor: { fill: "#f1f5f9" } }), showLegend && /* @__PURE__ */ React5.createElement(Legend, { wrapperStyle: { fontSize: isCompact ? 10 : 12 } }), finalDataKeys.map((key, index) => /* @__PURE__ */ React5.createElement(
|
|
337
337
|
Bar,
|
|
338
338
|
{
|
|
339
339
|
key,
|
|
@@ -342,7 +342,7 @@ function DynamicChart({
|
|
|
342
342
|
radius: [4, 4, 0, 0],
|
|
343
343
|
barSize: isTiny ? Math.max(10, 28 / data.length) : isCompact ? Math.max(14, 42 / data.length) : Math.max(20, 60 / data.length)
|
|
344
344
|
}
|
|
345
|
-
))) : /* @__PURE__ */
|
|
345
|
+
))) : /* @__PURE__ */ React5.createElement(LineChart, { data: sanitizedData, margin: chartMargin }, /* @__PURE__ */ React5.createElement(CartesianGrid, { strokeDasharray: "3 3", vertical: false, stroke: "#e2e8f0" }), /* @__PURE__ */ React5.createElement(XAxis, { dataKey: finalXKey, tick: axisTick, tickFormatter: truncateAxisLabel, tickLine: false, axisLine: { stroke: "#cbd5e1" }, interval: 0, minTickGap: isTiny ? 2 : isCompact ? 6 : 12 }), /* @__PURE__ */ React5.createElement(YAxis, { tick: axisTick, tickLine: false, axisLine: false }), /* @__PURE__ */ React5.createElement(Tooltip, { content: (props) => renderTooltip(getTooltipRow(props.payload), typeof props.label === "string" ? props.label : void 0) }), showLegend && /* @__PURE__ */ React5.createElement(Legend, { wrapperStyle: { fontSize: isCompact ? 10 : 12 } }), finalDataKeys.map((key, index) => /* @__PURE__ */ React5.createElement(
|
|
346
346
|
Line,
|
|
347
347
|
{
|
|
348
348
|
key,
|
|
@@ -356,6 +356,178 @@ function DynamicChart({
|
|
|
356
356
|
))))));
|
|
357
357
|
}
|
|
358
358
|
|
|
359
|
+
// src/components/VisualizationRenderer.tsx
|
|
360
|
+
import Image2 from "next/image";
|
|
361
|
+
function VisualizationRenderer({
|
|
362
|
+
data,
|
|
363
|
+
className = ""
|
|
364
|
+
}) {
|
|
365
|
+
if (!data) {
|
|
366
|
+
return /* @__PURE__ */ React.createElement("div", { className: `p-4 text-gray-500 ${className}` }, "No data available for visualization");
|
|
367
|
+
}
|
|
368
|
+
return /* @__PURE__ */ React.createElement("div", { className: `space-y-4 ${className}` }, /* @__PURE__ */ React.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React.createElement("h3", { className: "text-lg font-semibold text-gray-900 dark:text-white" }, data.title), data.description && /* @__PURE__ */ React.createElement("p", { className: "text-sm text-gray-600 dark:text-gray-400" }, data.description)), renderVisualization(data.type, data.data));
|
|
369
|
+
}
|
|
370
|
+
function renderVisualization(type, data) {
|
|
371
|
+
switch (type) {
|
|
372
|
+
case "pie_chart":
|
|
373
|
+
return renderPieChart(data);
|
|
374
|
+
case "bar_chart":
|
|
375
|
+
return renderBarChart(data);
|
|
376
|
+
case "line_chart":
|
|
377
|
+
return renderLineChart(data);
|
|
378
|
+
case "table":
|
|
379
|
+
return renderTable(data);
|
|
380
|
+
case "product_carousel":
|
|
381
|
+
return renderProductCarousel(data);
|
|
382
|
+
case "text":
|
|
383
|
+
default:
|
|
384
|
+
return renderText(data);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
function renderPieChart(data) {
|
|
388
|
+
if (!Array.isArray(data)) {
|
|
389
|
+
return /* @__PURE__ */ React.createElement("div", { className: "text-red-500" }, "Invalid pie chart data");
|
|
390
|
+
}
|
|
391
|
+
return /* @__PURE__ */ React.createElement("div", { className: "bg-white dark:bg-gray-800 p-4 rounded-lg shadow" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap gap-2" }, data.map((item, idx) => /* @__PURE__ */ React.createElement(
|
|
392
|
+
"div",
|
|
393
|
+
{
|
|
394
|
+
key: idx,
|
|
395
|
+
className: "flex items-center gap-2 p-2 bg-gray-50 dark:bg-gray-700 rounded"
|
|
396
|
+
},
|
|
397
|
+
/* @__PURE__ */ React.createElement(
|
|
398
|
+
"div",
|
|
399
|
+
{
|
|
400
|
+
className: "w-3 h-3 rounded-full",
|
|
401
|
+
style: { backgroundColor: generateColor(idx) }
|
|
402
|
+
}
|
|
403
|
+
),
|
|
404
|
+
/* @__PURE__ */ React.createElement("span", { className: "text-sm font-medium text-gray-700 dark:text-gray-300" }, item.label, ": ", item.value),
|
|
405
|
+
item.inStock !== void 0 && /* @__PURE__ */ React.createElement(
|
|
406
|
+
"span",
|
|
407
|
+
{
|
|
408
|
+
className: `text-xs px-2 py-1 rounded ${item.inStock ? "bg-green-100 text-green-800" : "bg-red-100 text-red-800"}`
|
|
409
|
+
},
|
|
410
|
+
item.inStock ? "In Stock" : "Out of Stock"
|
|
411
|
+
)
|
|
412
|
+
))));
|
|
413
|
+
}
|
|
414
|
+
function renderBarChart(data) {
|
|
415
|
+
if (!Array.isArray(data)) {
|
|
416
|
+
return /* @__PURE__ */ React.createElement("div", { className: "text-red-500" }, "Invalid bar chart data");
|
|
417
|
+
}
|
|
418
|
+
return /* @__PURE__ */ React.createElement("div", { className: "bg-white dark:bg-gray-800 p-4 rounded-lg shadow overflow-x-auto" }, /* @__PURE__ */ React.createElement("div", { className: "space-y-3" }, data.map((item, idx) => /* @__PURE__ */ React.createElement("div", { key: idx, className: "space-y-1" }, /* @__PURE__ */ React.createElement("div", { className: "flex justify-between items-center" }, /* @__PURE__ */ React.createElement("span", { className: "text-sm font-medium text-gray-700 dark:text-gray-300" }, item.category), /* @__PURE__ */ React.createElement("span", { className: "text-sm text-gray-600 dark:text-gray-400" }, item.value)), /* @__PURE__ */ React.createElement("div", { className: "w-full bg-gray-200 dark:bg-gray-700 rounded-full h-2" }, /* @__PURE__ */ React.createElement(
|
|
419
|
+
"div",
|
|
420
|
+
{
|
|
421
|
+
className: "h-full rounded-full transition-all",
|
|
422
|
+
style: {
|
|
423
|
+
width: `${item.value / Math.max(...data.map((d) => d.value)) * 100}%`,
|
|
424
|
+
backgroundColor: generateColor(idx)
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
)), item.inStock !== void 0 && /* @__PURE__ */ React.createElement(
|
|
428
|
+
"span",
|
|
429
|
+
{
|
|
430
|
+
className: `text-xs px-2 py-1 rounded inline-block ${item.inStock ? "bg-green-100 text-green-800" : "bg-red-100 text-red-800"}`
|
|
431
|
+
},
|
|
432
|
+
item.inStock ? "In Stock" : "Out of Stock"
|
|
433
|
+
)))));
|
|
434
|
+
}
|
|
435
|
+
function renderLineChart(data) {
|
|
436
|
+
if (!Array.isArray(data)) {
|
|
437
|
+
return /* @__PURE__ */ React.createElement("div", { className: "text-red-500" }, "Invalid line chart data");
|
|
438
|
+
}
|
|
439
|
+
return /* @__PURE__ */ React.createElement("div", { className: "bg-white dark:bg-gray-800 p-4 rounded-lg shadow overflow-x-auto" }, /* @__PURE__ */ React.createElement("div", { className: "space-y-2" }, data.map((point, idx) => /* @__PURE__ */ React.createElement(
|
|
440
|
+
"div",
|
|
441
|
+
{
|
|
442
|
+
key: idx,
|
|
443
|
+
className: "flex justify-between items-center p-2 bg-gray-50 dark:bg-gray-700 rounded"
|
|
444
|
+
},
|
|
445
|
+
/* @__PURE__ */ React.createElement("span", { className: "text-sm text-gray-600 dark:text-gray-400" }, point.label || point.timestamp),
|
|
446
|
+
/* @__PURE__ */ React.createElement("span", { className: "text-sm font-semibold text-gray-900 dark:text-white" }, typeof point.value === "number" ? point.value.toFixed(2) : point.value)
|
|
447
|
+
))));
|
|
448
|
+
}
|
|
449
|
+
function renderTable(data) {
|
|
450
|
+
if (!data.columns || !data.rows) {
|
|
451
|
+
return /* @__PURE__ */ React.createElement("div", { className: "text-red-500" }, "Invalid table data");
|
|
452
|
+
}
|
|
453
|
+
return /* @__PURE__ */ React.createElement("div", { className: "bg-white dark:bg-gray-800 rounded-lg shadow overflow-x-auto" }, /* @__PURE__ */ React.createElement("table", { className: "w-full text-sm" }, /* @__PURE__ */ React.createElement("thead", { className: "bg-gray-100 dark:bg-gray-700 border-b border-gray-200 dark:border-gray-600" }, /* @__PURE__ */ React.createElement("tr", null, data.columns.map((col, idx) => /* @__PURE__ */ React.createElement(
|
|
454
|
+
"th",
|
|
455
|
+
{
|
|
456
|
+
key: idx,
|
|
457
|
+
className: "px-4 py-2 text-left font-semibold text-gray-900 dark:text-white"
|
|
458
|
+
},
|
|
459
|
+
col
|
|
460
|
+
)))), /* @__PURE__ */ React.createElement("tbody", { className: "divide-y divide-gray-200 dark:divide-gray-600" }, data.rows.map((row, rowIdx) => /* @__PURE__ */ React.createElement(
|
|
461
|
+
"tr",
|
|
462
|
+
{
|
|
463
|
+
key: rowIdx,
|
|
464
|
+
className: "hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors"
|
|
465
|
+
},
|
|
466
|
+
row.map((cell, cellIdx) => /* @__PURE__ */ React.createElement(
|
|
467
|
+
"td",
|
|
468
|
+
{
|
|
469
|
+
key: cellIdx,
|
|
470
|
+
className: "px-4 py-2 text-gray-700 dark:text-gray-300"
|
|
471
|
+
},
|
|
472
|
+
String(cell)
|
|
473
|
+
))
|
|
474
|
+
)))));
|
|
475
|
+
}
|
|
476
|
+
function renderProductCarousel(data) {
|
|
477
|
+
if (!Array.isArray(data)) {
|
|
478
|
+
return /* @__PURE__ */ React.createElement("div", { className: "text-red-500" }, "Invalid carousel data");
|
|
479
|
+
}
|
|
480
|
+
return /* @__PURE__ */ React.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React.createElement("div", { className: "flex gap-4 pb-4" }, data.map((product) => /* @__PURE__ */ React.createElement(
|
|
481
|
+
"div",
|
|
482
|
+
{
|
|
483
|
+
key: product.id,
|
|
484
|
+
className: "flex-shrink-0 w-64 bg-white dark:bg-gray-800 rounded-lg shadow-md overflow-hidden hover:shadow-lg transition-shadow"
|
|
485
|
+
},
|
|
486
|
+
product.image && /* @__PURE__ */ React.createElement("div", { className: "relative w-full h-40 bg-gray-200" }, /* @__PURE__ */ React.createElement(
|
|
487
|
+
Image2,
|
|
488
|
+
{
|
|
489
|
+
src: product.image,
|
|
490
|
+
alt: product.name,
|
|
491
|
+
fill: true,
|
|
492
|
+
className: "object-cover",
|
|
493
|
+
sizes: "(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
|
|
494
|
+
}
|
|
495
|
+
)),
|
|
496
|
+
/* @__PURE__ */ React.createElement("div", { className: "p-4 space-y-2" }, /* @__PURE__ */ React.createElement("h4", { className: "font-semibold text-gray-900 dark:text-white line-clamp-2" }, product.name), product.brand && /* @__PURE__ */ React.createElement("p", { className: "text-xs text-gray-500 dark:text-gray-400" }, "Brand: ", product.brand), product.price && /* @__PURE__ */ React.createElement("p", { className: "text-lg font-bold text-gray-900 dark:text-white" }, "$", typeof product.price === "number" ? product.price.toFixed(2) : product.price), product.description && /* @__PURE__ */ React.createElement("p", { className: "text-sm text-gray-600 dark:text-gray-400 line-clamp-2" }, product.description), /* @__PURE__ */ React.createElement("div", { className: "flex gap-2 pt-2" }, /* @__PURE__ */ React.createElement(
|
|
497
|
+
"span",
|
|
498
|
+
{
|
|
499
|
+
className: `text-xs px-2 py-1 rounded flex-1 text-center ${product.inStock ? "bg-green-100 text-green-800" : "bg-red-100 text-red-800"}`
|
|
500
|
+
},
|
|
501
|
+
product.inStock ? "In Stock" : "Out of Stock"
|
|
502
|
+
)))
|
|
503
|
+
))));
|
|
504
|
+
}
|
|
505
|
+
function renderText(data) {
|
|
506
|
+
const content = (data == null ? void 0 : data.content) || String(data);
|
|
507
|
+
return /* @__PURE__ */ React.createElement("div", { className: "bg-white dark:bg-gray-800 p-4 rounded-lg shadow prose dark:prose-invert max-w-none" }, /* @__PURE__ */ React.createElement("p", { className: "text-gray-700 dark:text-gray-300 whitespace-pre-wrap" }, content));
|
|
508
|
+
}
|
|
509
|
+
function generateColor(index) {
|
|
510
|
+
const colors = [
|
|
511
|
+
"#3B82F6",
|
|
512
|
+
// blue
|
|
513
|
+
"#10B981",
|
|
514
|
+
// green
|
|
515
|
+
"#F59E0B",
|
|
516
|
+
// amber
|
|
517
|
+
"#EF4444",
|
|
518
|
+
// red
|
|
519
|
+
"#8B5CF6",
|
|
520
|
+
// purple
|
|
521
|
+
"#EC4899",
|
|
522
|
+
// pink
|
|
523
|
+
"#06B6D4",
|
|
524
|
+
// cyan
|
|
525
|
+
"#F97316"
|
|
526
|
+
// orange
|
|
527
|
+
];
|
|
528
|
+
return colors[index % colors.length];
|
|
529
|
+
}
|
|
530
|
+
|
|
359
531
|
// src/components/MessageBubble.tsx
|
|
360
532
|
function sanitizeJson(raw) {
|
|
361
533
|
let s = raw.trim();
|
|
@@ -509,7 +681,7 @@ function resolveImage(data) {
|
|
|
509
681
|
return void 0;
|
|
510
682
|
}
|
|
511
683
|
function normaliseChild(children) {
|
|
512
|
-
if (typeof children === "object" && children !== null && !Array.isArray(children) && !
|
|
684
|
+
if (typeof children === "object" && children !== null && !Array.isArray(children) && !React6.isValidElement(children)) {
|
|
513
685
|
return JSON.stringify(children);
|
|
514
686
|
}
|
|
515
687
|
return children;
|
|
@@ -523,7 +695,7 @@ function formatColumnLabel(value) {
|
|
|
523
695
|
function DataTable({ config, viewportSize = "large" }) {
|
|
524
696
|
const isCompact = viewportSize === "compact";
|
|
525
697
|
const isMedium = viewportSize === "medium";
|
|
526
|
-
const columns =
|
|
698
|
+
const columns = React6.useMemo(() => {
|
|
527
699
|
const rowKeys = Array.from(
|
|
528
700
|
new Set(
|
|
529
701
|
config.data.flatMap((row) => Object.keys(row))
|
|
@@ -553,27 +725,27 @@ function DataTable({ config, viewportSize = "large" }) {
|
|
|
553
725
|
return rowKeys.map((key) => ({ label: formatColumnLabel(key), accessor: key }));
|
|
554
726
|
}, [config]);
|
|
555
727
|
if (!config.data.length || !columns.length) {
|
|
556
|
-
return /* @__PURE__ */
|
|
728
|
+
return /* @__PURE__ */ React6.createElement("p", { className: "text-xs text-slate-400 italic my-2" }, "No data to display.");
|
|
557
729
|
}
|
|
558
730
|
const formatCell = (val) => {
|
|
559
731
|
if (val === null || val === void 0) return "\u2014";
|
|
560
732
|
if (typeof val === "boolean") return val ? "\u2713" : "\u2717";
|
|
561
733
|
return String(val);
|
|
562
734
|
};
|
|
563
|
-
return /* @__PURE__ */
|
|
735
|
+
return /* @__PURE__ */ React6.createElement("div", { className: "my-4 rounded-xl border border-slate-200 dark:border-white/10 shadow-sm overflow-hidden" }, config.title && /* @__PURE__ */ React6.createElement("div", { className: "px-4 py-2.5 bg-slate-50 dark:bg-white/5 border-b border-slate-200 dark:border-white/10" }, /* @__PURE__ */ React6.createElement("p", { className: "text-xs font-semibold text-slate-600 dark:text-white/70 uppercase tracking-wide" }, config.title)), /* @__PURE__ */ React6.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React6.createElement("table", { className: `w-full text-left border-collapse ${isCompact ? "min-w-[240px] text-xs" : isMedium ? "min-w-[280px] text-[13px]" : "min-w-[320px] text-sm"}` }, /* @__PURE__ */ React6.createElement("thead", { className: "bg-slate-50 dark:bg-white/5 border-b border-slate-200 dark:border-white/10" }, /* @__PURE__ */ React6.createElement("tr", null, columns.map((column) => /* @__PURE__ */ React6.createElement(
|
|
564
736
|
"th",
|
|
565
737
|
{
|
|
566
738
|
key: column.label,
|
|
567
739
|
className: `${isCompact ? "px-2.5 py-2" : "px-4 py-3"} font-semibold text-slate-700 dark:text-white/90 whitespace-nowrap`
|
|
568
740
|
},
|
|
569
741
|
column.label
|
|
570
|
-
)))), /* @__PURE__ */
|
|
742
|
+
)))), /* @__PURE__ */ React6.createElement("tbody", null, config.data.map((row, ri) => /* @__PURE__ */ React6.createElement(
|
|
571
743
|
"tr",
|
|
572
744
|
{
|
|
573
745
|
key: ri,
|
|
574
746
|
className: "border-b border-slate-100 dark:border-white/5 last:border-0 hover:bg-slate-50/60 dark:hover:bg-white/5 transition-colors"
|
|
575
747
|
},
|
|
576
|
-
columns.map((column) => /* @__PURE__ */
|
|
748
|
+
columns.map((column) => /* @__PURE__ */ React6.createElement(
|
|
577
749
|
"td",
|
|
578
750
|
{
|
|
579
751
|
key: column.label,
|
|
@@ -581,7 +753,7 @@ function DataTable({ config, viewportSize = "large" }) {
|
|
|
581
753
|
},
|
|
582
754
|
formatCell(row[column.accessor])
|
|
583
755
|
))
|
|
584
|
-
))))), /* @__PURE__ */
|
|
756
|
+
))))), /* @__PURE__ */ React6.createElement("div", { className: "px-4 py-2 bg-slate-50 dark:bg-white/5 border-t border-slate-100 dark:border-white/5" }, /* @__PURE__ */ React6.createElement("p", { className: "text-[11px] text-slate-400 dark:text-white/30" }, config.data.length, " row", config.data.length !== 1 ? "s" : "")));
|
|
585
757
|
}
|
|
586
758
|
function normalizeTabularRows(rows, columns) {
|
|
587
759
|
if (!Array.isArray(rows)) return [];
|
|
@@ -614,7 +786,7 @@ function resolveStructuredRows(config) {
|
|
|
614
786
|
}
|
|
615
787
|
function UIDispatcher({ rawContent, primaryColor, accentColor, isStreaming, onAddToCart, viewportSize = "large" }) {
|
|
616
788
|
var _a;
|
|
617
|
-
const result =
|
|
789
|
+
const result = React6.useMemo(() => {
|
|
618
790
|
if (isStreaming) return { loading: true };
|
|
619
791
|
try {
|
|
620
792
|
const clean = rawContent.replace(/^```[a-z]*\s*/i, "").replace(/```\s*$/, "").trim();
|
|
@@ -656,10 +828,10 @@ function UIDispatcher({ rawContent, primaryColor, accentColor, isStreaming, onAd
|
|
|
656
828
|
}
|
|
657
829
|
}, [rawContent, isStreaming]);
|
|
658
830
|
if ("loading" in result) {
|
|
659
|
-
return /* @__PURE__ */
|
|
831
|
+
return /* @__PURE__ */ React6.createElement("div", { className: "my-4 p-8 bg-slate-50 dark:bg-white/5 rounded-xl border border-dashed border-slate-300 dark:border-white/10 flex flex-col items-center justify-center gap-3 animate-pulse" }, /* @__PURE__ */ React6.createElement("div", { className: "w-5 h-5 border-2 border-indigo-500 border-t-transparent rounded-full animate-spin" }), /* @__PURE__ */ React6.createElement("p", { className: "text-xs text-slate-500 font-medium italic" }, "Preparing view..."));
|
|
660
832
|
}
|
|
661
833
|
if ("error" in result) {
|
|
662
|
-
return /* @__PURE__ */
|
|
834
|
+
return /* @__PURE__ */ React6.createElement("pre", { className: "p-4 my-2 bg-slate-900 text-slate-100 rounded-lg text-[10px] overflow-auto max-h-40" }, /* @__PURE__ */ React6.createElement("code", null, rawContent));
|
|
663
835
|
}
|
|
664
836
|
const { config } = result;
|
|
665
837
|
const isCompact = viewportSize === "compact";
|
|
@@ -667,7 +839,7 @@ function UIDispatcher({ rawContent, primaryColor, accentColor, isStreaming, onAd
|
|
|
667
839
|
const hasDescription = typeof config.description === "string" && config.description.trim().length > 0;
|
|
668
840
|
switch (config.view) {
|
|
669
841
|
case "chart":
|
|
670
|
-
return /* @__PURE__ */
|
|
842
|
+
return /* @__PURE__ */ React6.createElement("div", { className: `${isCompact ? "my-4 p-3" : "my-6 p-4"} bg-white dark:bg-slate-900 rounded-2xl border border-slate-200 dark:border-white/10 shadow-sm overflow-hidden` }, config.title && /* @__PURE__ */ React6.createElement("h4", { className: `${isCompact ? "text-[11px] mb-3" : "text-xs mb-4"} font-semibold text-slate-500 px-2` }, config.title), hasDescription && /* @__PURE__ */ React6.createElement("p", { className: `px-2 ${isCompact ? "text-xs" : "text-sm"} text-slate-500 dark:text-white/60` }, config.description), /* @__PURE__ */ React6.createElement(
|
|
671
843
|
DynamicChart,
|
|
672
844
|
{
|
|
673
845
|
config: {
|
|
@@ -681,7 +853,7 @@ function UIDispatcher({ rawContent, primaryColor, accentColor, isStreaming, onAd
|
|
|
681
853
|
accentColor,
|
|
682
854
|
viewportSize
|
|
683
855
|
}
|
|
684
|
-
), hasInsights && /* @__PURE__ */
|
|
856
|
+
), hasInsights && /* @__PURE__ */ React6.createElement("div", { className: "mt-4 flex flex-wrap gap-2 px-2" }, (_a = config.insights) == null ? void 0 : _a.map((insight) => /* @__PURE__ */ React6.createElement(
|
|
685
857
|
"span",
|
|
686
858
|
{
|
|
687
859
|
key: insight,
|
|
@@ -690,14 +862,14 @@ function UIDispatcher({ rawContent, primaryColor, accentColor, isStreaming, onAd
|
|
|
690
862
|
insight
|
|
691
863
|
))));
|
|
692
864
|
case "carousel":
|
|
693
|
-
return /* @__PURE__ */
|
|
865
|
+
return /* @__PURE__ */ React6.createElement("div", { className: "my-4" }, config.title && /* @__PURE__ */ React6.createElement("h4", { className: `${isCompact ? "mb-1.5 text-[11px]" : "mb-2 text-xs"} font-semibold text-slate-500` }, config.title), hasDescription && /* @__PURE__ */ React6.createElement("p", { className: `mb-3 ${isCompact ? "text-xs" : "text-sm"} text-slate-500 dark:text-white/60` }, config.description), /* @__PURE__ */ React6.createElement(ProductCarousel, { products: config.data.map((item) => {
|
|
694
866
|
var _a2;
|
|
695
867
|
return __spreadProps(__spreadValues({}, item), {
|
|
696
868
|
image: (_a2 = item.image) != null ? _a2 : typeof resolveImage === "function" ? resolveImage(item) : void 0
|
|
697
869
|
});
|
|
698
870
|
}), primaryColor, onAddToCart }));
|
|
699
871
|
case "table":
|
|
700
|
-
return /* @__PURE__ */
|
|
872
|
+
return /* @__PURE__ */ React6.createElement("div", { className: `${isCompact ? "my-3 p-3 max-h-[320px]" : "my-4 p-4 max-h-[400px]"} bg-white dark:bg-slate-900 rounded-xl border border-slate-200 dark:border-white/10 shadow-sm overflow-auto` }, config.title && /* @__PURE__ */ React6.createElement("h4", { className: `${isCompact ? "text-[11px]" : "text-xs"} font-semibold text-slate-500 mb-2` }, config.title), hasDescription && /* @__PURE__ */ React6.createElement("p", { className: `mb-3 ${isCompact ? "text-xs" : "text-sm"} text-slate-500 dark:text-white/60` }, config.description), /* @__PURE__ */ React6.createElement(DataTable, { config: {
|
|
701
873
|
type: "table",
|
|
702
874
|
title: config.title,
|
|
703
875
|
description: config.description,
|
|
@@ -722,17 +894,17 @@ function MessageBubble({
|
|
|
722
894
|
const isUser = message.role === "user";
|
|
723
895
|
const isCompact = viewportSize === "compact";
|
|
724
896
|
const isMedium = viewportSize === "medium";
|
|
725
|
-
const [showSources, setShowSources] =
|
|
726
|
-
const hasStructuredProductBlock =
|
|
897
|
+
const [showSources, setShowSources] = React6.useState(false);
|
|
898
|
+
const hasStructuredProductBlock = React6.useMemo(
|
|
727
899
|
() => /```(?:ui|json|chart)\s*[\s\S]*?"?(?:view|type|data|products)"?\s*:\s*"?(?:carousel|products|table)"?/i.test(message.content) || /\{[\s\S]*?"?(?:view|type|data|products)"?\s*:\s*"?(?:carousel|products)"?[\s\S]*\}/i.test(message.content) && looksLikeStructuredPayload(message.content),
|
|
728
900
|
[message.content]
|
|
729
901
|
);
|
|
730
|
-
const structuredContent =
|
|
902
|
+
const structuredContent = React6.useMemo(
|
|
731
903
|
() => isUser ? { payload: null, text: message.content } : extractStructuredPayload(message.content),
|
|
732
904
|
[isUser, message.content]
|
|
733
905
|
);
|
|
734
906
|
const shouldRenderStructuredOnly = !isUser && Boolean(structuredContent.payload) && isLikelyUiOnlyMessage(structuredContent.text);
|
|
735
|
-
const productsFromSources =
|
|
907
|
+
const productsFromSources = React6.useMemo(() => {
|
|
736
908
|
if (isUser || !sources) return [];
|
|
737
909
|
return sources.filter((s) => {
|
|
738
910
|
var _a;
|
|
@@ -752,7 +924,7 @@ function MessageBubble({
|
|
|
752
924
|
};
|
|
753
925
|
});
|
|
754
926
|
}, [sources, isUser]);
|
|
755
|
-
const { productsFromContent, cleanContent } =
|
|
927
|
+
const { productsFromContent, cleanContent } = React6.useMemo(() => {
|
|
756
928
|
if (isUser) {
|
|
757
929
|
return { productsFromContent: [], cleanContent: message.content };
|
|
758
930
|
}
|
|
@@ -798,7 +970,7 @@ function MessageBubble({
|
|
|
798
970
|
}
|
|
799
971
|
return { productsFromContent: products, cleanContent: content.trim() };
|
|
800
972
|
}, [message.content, isUser, structuredContent]);
|
|
801
|
-
const allProducts =
|
|
973
|
+
const allProducts = React6.useMemo(() => {
|
|
802
974
|
if (productsFromContent.length > 0) return productsFromContent;
|
|
803
975
|
const seen = /* @__PURE__ */ new Set();
|
|
804
976
|
const contentLower = message.content.toLowerCase();
|
|
@@ -814,7 +986,7 @@ function MessageBubble({
|
|
|
814
986
|
return false;
|
|
815
987
|
});
|
|
816
988
|
}, [productsFromSources, productsFromContent, message.content]);
|
|
817
|
-
const processedMarkdown =
|
|
989
|
+
const processedMarkdown = React6.useMemo(() => {
|
|
818
990
|
let raw = structuredContent.payload ? structuredContent.text : cleanContent || message.content;
|
|
819
991
|
const hasStructuredUiBlock = Boolean(structuredContent.payload) || /```(?:ui|json|chart)\s*[\s\S]*?"(?:view|chartType|type|data|items|rows|products|results)"\s*:/i.test(raw);
|
|
820
992
|
raw = raw.replace(/([^\n])\n\|/g, "$1\n\n|").replace(/(\|[^\n]*\|)\n\n+(?=\|)/g, "$1\n");
|
|
@@ -848,16 +1020,16 @@ ${match.trim()}
|
|
|
848
1020
|
}
|
|
849
1021
|
return raw;
|
|
850
1022
|
}, [cleanContent, message.content, isStreaming, structuredContent]);
|
|
851
|
-
const markdownComponents =
|
|
1023
|
+
const markdownComponents = React6.useMemo(
|
|
852
1024
|
() => ({
|
|
853
1025
|
// Wrap in not-prose so Tailwind Typography resets don't clobber our styles.
|
|
854
1026
|
// prose applies display:block and padding:0 to table/th/td — not-prose opts out.
|
|
855
1027
|
table: (_a) => {
|
|
856
1028
|
var props = __objRest(_a, []);
|
|
857
1029
|
if (isStreaming) {
|
|
858
|
-
return /* @__PURE__ */
|
|
1030
|
+
return /* @__PURE__ */ React6.createElement("div", { className: "my-5 p-6 bg-slate-50 dark:bg-white/5 rounded-xl border border-dashed border-slate-300 dark:border-white/10 flex items-center justify-center gap-3 select-none" }, /* @__PURE__ */ React6.createElement("div", { className: "w-4 h-4 border-2 border-indigo-500 border-t-transparent rounded-full animate-spin" }), /* @__PURE__ */ React6.createElement("p", { className: "text-xs text-slate-500 font-medium italic animate-pulse" }, "Generating data table..."));
|
|
859
1031
|
}
|
|
860
|
-
return /* @__PURE__ */
|
|
1032
|
+
return /* @__PURE__ */ React6.createElement("div", { className: "not-prose overflow-hidden my-5 rounded-xl border border-slate-200 dark:border-white/10 shadow-sm bg-white dark:bg-slate-900/50" }, /* @__PURE__ */ React6.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React6.createElement(
|
|
861
1033
|
"table",
|
|
862
1034
|
__spreadValues({
|
|
863
1035
|
className: "!table w-full text-left border-collapse min-w-[400px] text-sm"
|
|
@@ -866,7 +1038,7 @@ ${match.trim()}
|
|
|
866
1038
|
},
|
|
867
1039
|
thead: (_b) => {
|
|
868
1040
|
var props = __objRest(_b, []);
|
|
869
|
-
return /* @__PURE__ */
|
|
1041
|
+
return /* @__PURE__ */ React6.createElement(
|
|
870
1042
|
"thead",
|
|
871
1043
|
__spreadValues({
|
|
872
1044
|
className: "!table-header-group bg-slate-50 dark:bg-white/5 border-b border-slate-200 dark:border-white/10"
|
|
@@ -875,11 +1047,11 @@ ${match.trim()}
|
|
|
875
1047
|
},
|
|
876
1048
|
tbody: (_c) => {
|
|
877
1049
|
var props = __objRest(_c, []);
|
|
878
|
-
return /* @__PURE__ */
|
|
1050
|
+
return /* @__PURE__ */ React6.createElement("tbody", __spreadValues({ className: "!table-row-group divide-y divide-slate-100 dark:divide-white/5" }, props));
|
|
879
1051
|
},
|
|
880
1052
|
tr: (_d) => {
|
|
881
1053
|
var props = __objRest(_d, []);
|
|
882
|
-
return /* @__PURE__ */
|
|
1054
|
+
return /* @__PURE__ */ React6.createElement(
|
|
883
1055
|
"tr",
|
|
884
1056
|
__spreadValues({
|
|
885
1057
|
className: "!table-row hover:bg-slate-50/70 dark:hover:bg-white/5 transition-colors"
|
|
@@ -888,7 +1060,7 @@ ${match.trim()}
|
|
|
888
1060
|
},
|
|
889
1061
|
th: (_e) => {
|
|
890
1062
|
var _f = _e, { children } = _f, props = __objRest(_f, ["children"]);
|
|
891
|
-
return /* @__PURE__ */
|
|
1063
|
+
return /* @__PURE__ */ React6.createElement(
|
|
892
1064
|
"th",
|
|
893
1065
|
__spreadValues({
|
|
894
1066
|
className: "!table-cell px-4 py-3 font-bold text-slate-700 dark:text-white/90 whitespace-nowrap text-[11px] uppercase tracking-wider text-left"
|
|
@@ -898,7 +1070,7 @@ ${match.trim()}
|
|
|
898
1070
|
},
|
|
899
1071
|
td: (_g) => {
|
|
900
1072
|
var _h = _g, { children } = _h, props = __objRest(_h, ["children"]);
|
|
901
|
-
return /* @__PURE__ */
|
|
1073
|
+
return /* @__PURE__ */ React6.createElement(
|
|
902
1074
|
"td",
|
|
903
1075
|
__spreadValues({
|
|
904
1076
|
className: "!table-cell px-4 py-3 text-slate-600 dark:text-white/70 whitespace-nowrap text-sm"
|
|
@@ -919,7 +1091,7 @@ ${match.trim()}
|
|
|
919
1091
|
var _a;
|
|
920
1092
|
const lang = (_a = /language-(\w+)/.exec(className != null ? className : "")) == null ? void 0 : _a[1];
|
|
921
1093
|
if (!inline && (lang === "ui" || lang === "chart")) {
|
|
922
|
-
return /* @__PURE__ */
|
|
1094
|
+
return /* @__PURE__ */ React6.createElement(
|
|
923
1095
|
UIDispatcher,
|
|
924
1096
|
{
|
|
925
1097
|
rawContent: String(children != null ? children : "").trim(),
|
|
@@ -934,7 +1106,7 @@ ${match.trim()}
|
|
|
934
1106
|
if (!inline && lang === "json") {
|
|
935
1107
|
const content = String(children != null ? children : "").trim();
|
|
936
1108
|
if (looksLikeStructuredPayload(content)) {
|
|
937
|
-
return /* @__PURE__ */
|
|
1109
|
+
return /* @__PURE__ */ React6.createElement(
|
|
938
1110
|
UIDispatcher,
|
|
939
1111
|
{
|
|
940
1112
|
rawContent: content,
|
|
@@ -950,7 +1122,7 @@ ${match.trim()}
|
|
|
950
1122
|
if (!inline) {
|
|
951
1123
|
const content = String(children != null ? children : "").trim();
|
|
952
1124
|
if (looksLikeStructuredPayload(content)) {
|
|
953
|
-
return /* @__PURE__ */
|
|
1125
|
+
return /* @__PURE__ */ React6.createElement(
|
|
954
1126
|
UIDispatcher,
|
|
955
1127
|
{
|
|
956
1128
|
rawContent: content,
|
|
@@ -964,27 +1136,27 @@ ${match.trim()}
|
|
|
964
1136
|
}
|
|
965
1137
|
}
|
|
966
1138
|
if (!inline && lang === "table-loading") {
|
|
967
|
-
return /* @__PURE__ */
|
|
1139
|
+
return /* @__PURE__ */ React6.createElement("div", { className: "my-5 p-6 bg-slate-50 dark:bg-white/5 rounded-xl border border-dashed border-slate-300 dark:border-white/10 flex items-center justify-center gap-3 select-none" }, /* @__PURE__ */ React6.createElement("div", { className: "w-4 h-4 border-2 border-indigo-500 border-t-transparent rounded-full animate-spin" }), /* @__PURE__ */ React6.createElement("p", { className: "text-xs text-slate-500 font-medium italic animate-pulse" }, "Generating data table..."));
|
|
968
1140
|
}
|
|
969
|
-
return /* @__PURE__ */
|
|
1141
|
+
return /* @__PURE__ */ React6.createElement("code", __spreadValues({ className }, props), typeof children === "string" || typeof children === "number" ? children : JSON.stringify(children));
|
|
970
1142
|
}
|
|
971
1143
|
}),
|
|
972
1144
|
[primaryColor, accentColor, isStreaming, onAddToCart, viewportSize]
|
|
973
1145
|
);
|
|
974
|
-
return /* @__PURE__ */
|
|
1146
|
+
return /* @__PURE__ */ React6.createElement("div", { className: `flex ${isCompact ? "gap-2" : "gap-3"} ${isUser ? "flex-row-reverse" : "flex-row"} items-start` }, /* @__PURE__ */ React6.createElement(
|
|
975
1147
|
"div",
|
|
976
1148
|
{
|
|
977
1149
|
className: `flex-shrink-0 ${isCompact ? "w-7 h-7" : "w-8 h-8"} rounded-full flex items-center justify-center shadow-lg ${isUser ? "text-white" : "bg-slate-100 dark:bg-white/10 text-slate-700 dark:text-white/80"}`,
|
|
978
1150
|
style: isUser ? { background: `linear-gradient(135deg, ${primaryColor}, ${accentColor})` } : {}
|
|
979
1151
|
},
|
|
980
|
-
isUser ? /* @__PURE__ */
|
|
981
|
-
), /* @__PURE__ */
|
|
1152
|
+
isUser ? /* @__PURE__ */ React6.createElement(User, { className: `${isCompact ? "w-3.5 h-3.5" : "w-4 h-4"} text-white` }) : /* @__PURE__ */ React6.createElement(Bot, { className: `${isCompact ? "w-3.5 h-3.5" : "w-4 h-4"}` })
|
|
1153
|
+
), /* @__PURE__ */ React6.createElement("div", { className: `flex flex-col gap-1 ${isCompact ? "max-w-[94%]" : isMedium ? "max-w-[92%]" : "max-w-[90%]"} ${isUser ? "items-end" : "items-start"}` }, /* @__PURE__ */ React6.createElement(
|
|
982
1154
|
"div",
|
|
983
1155
|
{
|
|
984
1156
|
className: `relative ${isCompact ? "px-3 py-2.5 text-[13px]" : "px-4 py-3 text-sm"} rounded-2xl leading-relaxed shadow-sm dark:shadow-lg ${isUser ? "text-white rounded-tr-sm" : "bg-white dark:bg-white/5 border border-slate-200 dark:border-white/10 text-slate-800 dark:text-white/90 rounded-tl-sm"}`,
|
|
985
1157
|
style: isUser ? { background: `linear-gradient(135deg, ${primaryColor}, ${accentColor})` } : {}
|
|
986
1158
|
},
|
|
987
|
-
isStreaming && !message.content ? /* @__PURE__ */
|
|
1159
|
+
isStreaming && !message.content ? /* @__PURE__ */ React6.createElement("span", { className: "flex items-center gap-1 py-1" }, /* @__PURE__ */ React6.createElement("span", { className: "w-1.5 h-1.5 rounded-full bg-slate-400 dark:bg-white/60 animate-bounce [animation-delay:0ms]" }), /* @__PURE__ */ React6.createElement("span", { className: "w-1.5 h-1.5 rounded-full bg-slate-400 dark:bg-white/60 animate-bounce [animation-delay:150ms]" }), /* @__PURE__ */ React6.createElement("span", { className: "w-1.5 h-1.5 rounded-full bg-slate-400 dark:bg-white/60 animate-bounce [animation-delay:300ms]" })) : /* @__PURE__ */ React6.createElement("div", { className: `prose ${isCompact ? "prose-xs" : "prose-sm"} max-w-none break-words ${isUser ? "prose-invert" : "dark:prose-invert"}` }, !isUser && structuredContent.payload && /* @__PURE__ */ React6.createElement(
|
|
988
1160
|
UIDispatcher,
|
|
989
1161
|
{
|
|
990
1162
|
rawContent: structuredContent.payload,
|
|
@@ -994,30 +1166,30 @@ ${match.trim()}
|
|
|
994
1166
|
onAddToCart,
|
|
995
1167
|
viewportSize
|
|
996
1168
|
}
|
|
997
|
-
), !shouldRenderStructuredOnly && /* @__PURE__ */
|
|
998
|
-
), !isUser && !hasStructuredProductBlock && allProducts.length > 0 && /* @__PURE__ */
|
|
1169
|
+
), !shouldRenderStructuredOnly && /* @__PURE__ */ React6.createElement(ReactMarkdown, { remarkPlugins: [remarkGfm], components: markdownComponents }, processedMarkdown), !isUser && !structuredContent.payload && message.uiTransformation && /* @__PURE__ */ React6.createElement("div", { className: "mt-4 border-t border-slate-100 dark:border-white/5 pt-4" }, /* @__PURE__ */ React6.createElement(VisualizationRenderer, { data: message.uiTransformation })), isStreaming && message.content && /* @__PURE__ */ React6.createElement("span", { className: "inline-block w-1.5 h-3.5 ml-1 bg-emerald-500 animate-pulse align-middle" }))
|
|
1170
|
+
), !isUser && !hasStructuredProductBlock && allProducts.length > 0 && /* @__PURE__ */ React6.createElement("div", { className: "w-full mt-1" }, /* @__PURE__ */ React6.createElement(
|
|
999
1171
|
ProductCarousel,
|
|
1000
1172
|
{
|
|
1001
1173
|
products: allProducts,
|
|
1002
1174
|
primaryColor,
|
|
1003
1175
|
onAddToCart
|
|
1004
1176
|
}
|
|
1005
|
-
)), !isUser && sources && sources.length > 0 && /* @__PURE__ */
|
|
1177
|
+
)), !isUser && sources && sources.length > 0 && /* @__PURE__ */ React6.createElement("div", { className: "w-full" }, /* @__PURE__ */ React6.createElement(
|
|
1006
1178
|
"button",
|
|
1007
1179
|
{
|
|
1008
1180
|
onClick: () => setShowSources((s) => !s),
|
|
1009
1181
|
className: "text-[11px] text-indigo-400 hover:text-indigo-300 transition-colors flex items-center gap-1 mt-1"
|
|
1010
1182
|
},
|
|
1011
|
-
showSources ? /* @__PURE__ */
|
|
1183
|
+
showSources ? /* @__PURE__ */ React6.createElement(ChevronDown2, { className: "w-3 h-3" }) : /* @__PURE__ */ React6.createElement(ChevronRight2, { className: "w-3 h-3" }),
|
|
1012
1184
|
sources.length,
|
|
1013
1185
|
" source",
|
|
1014
1186
|
sources.length !== 1 ? "s" : "",
|
|
1015
1187
|
" used"
|
|
1016
|
-
), showSources && /* @__PURE__ */
|
|
1188
|
+
), showSources && /* @__PURE__ */ React6.createElement("div", { className: "mt-2 flex flex-col gap-2" }, sources.map((src, i) => /* @__PURE__ */ React6.createElement(SourceCard, { key: src.id, source: src, index: i }))))));
|
|
1017
1189
|
}
|
|
1018
1190
|
|
|
1019
1191
|
// src/components/ConfigProvider.tsx
|
|
1020
|
-
import
|
|
1192
|
+
import React7, { createContext, useContext } from "react";
|
|
1021
1193
|
|
|
1022
1194
|
// src/config/uiConstants.ts
|
|
1023
1195
|
var DEFAULT_CONFIG = {
|
|
@@ -1064,7 +1236,7 @@ function ConfigProvider({
|
|
|
1064
1236
|
projectId: (config == null ? void 0 : config.projectId) || DEFAULT_CONFIG.projectId,
|
|
1065
1237
|
ui: mergeDefined(DEFAULT_CONFIG.ui, config == null ? void 0 : config.ui)
|
|
1066
1238
|
};
|
|
1067
|
-
return /* @__PURE__ */
|
|
1239
|
+
return /* @__PURE__ */ React7.createElement(ConfigContext.Provider, { value: merged }, children);
|
|
1068
1240
|
}
|
|
1069
1241
|
function useConfig() {
|
|
1070
1242
|
return useContext(ConfigContext);
|
|
@@ -1074,7 +1246,7 @@ function useConfig() {
|
|
|
1074
1246
|
import { useState as useState3, useCallback, useRef as useRef2, useEffect as useEffect3 } from "react";
|
|
1075
1247
|
|
|
1076
1248
|
// src/hooks/useStoredMessages.ts
|
|
1077
|
-
import * as
|
|
1249
|
+
import * as React8 from "react";
|
|
1078
1250
|
function readStoredMessages(storageKey) {
|
|
1079
1251
|
if (typeof window === "undefined") {
|
|
1080
1252
|
return [];
|
|
@@ -1091,8 +1263,8 @@ function readStoredMessages(storageKey) {
|
|
|
1091
1263
|
}
|
|
1092
1264
|
}
|
|
1093
1265
|
function useStoredMessages(storageKey, persist) {
|
|
1094
|
-
const [messages, setMessages] =
|
|
1095
|
-
|
|
1266
|
+
const [messages, setMessages] = React8.useState(() => persist ? readStoredMessages(storageKey) : []);
|
|
1267
|
+
React8.useEffect(() => {
|
|
1096
1268
|
if (!persist || typeof window === "undefined") {
|
|
1097
1269
|
return;
|
|
1098
1270
|
}
|
|
@@ -1178,6 +1350,7 @@ function useRagChat(projectId, options = {}) {
|
|
|
1178
1350
|
const decoder = new TextDecoder();
|
|
1179
1351
|
let assistantContent = "";
|
|
1180
1352
|
let sources = [];
|
|
1353
|
+
let uiTransformation = null;
|
|
1181
1354
|
let buffer = "";
|
|
1182
1355
|
const assistantMessageId = `assistant_${Date.now()}`;
|
|
1183
1356
|
setMessages((prev) => [
|
|
@@ -1202,13 +1375,19 @@ function useRagChat(projectId, options = {}) {
|
|
|
1202
1375
|
assistantContent += frame.text;
|
|
1203
1376
|
} else if (frame.type === "metadata") {
|
|
1204
1377
|
sources = (_a = frame.sources) != null ? _a : [];
|
|
1378
|
+
} else if (frame.type === "ui_transformation") {
|
|
1379
|
+
uiTransformation = frame.data;
|
|
1205
1380
|
} else if (frame.type === "error") {
|
|
1206
1381
|
setError(frame.error || "Stream error");
|
|
1207
1382
|
}
|
|
1208
1383
|
}
|
|
1209
1384
|
setMessages(
|
|
1210
1385
|
(prev) => prev.map(
|
|
1211
|
-
(msg) => msg.id === assistantMessageId ? __spreadProps(__spreadValues({}, msg), {
|
|
1386
|
+
(msg) => msg.id === assistantMessageId ? __spreadProps(__spreadValues({}, msg), {
|
|
1387
|
+
content: assistantContent,
|
|
1388
|
+
sources: sources.length > 0 ? sources : msg.sources,
|
|
1389
|
+
uiTransformation: uiTransformation || msg.uiTransformation
|
|
1390
|
+
}) : msg
|
|
1212
1391
|
)
|
|
1213
1392
|
);
|
|
1214
1393
|
}
|
|
@@ -1223,6 +1402,7 @@ function useRagChat(projectId, options = {}) {
|
|
|
1223
1402
|
role: "assistant",
|
|
1224
1403
|
content: assistantContent,
|
|
1225
1404
|
sources: sources.length > 0 ? sources : void 0,
|
|
1405
|
+
uiTransformation: uiTransformation || void 0,
|
|
1226
1406
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1227
1407
|
};
|
|
1228
1408
|
onReply == null ? void 0 : onReply(finalAssistantMessage);
|
|
@@ -1413,84 +1593,84 @@ function ChatWindow({
|
|
|
1413
1593
|
}, 800);
|
|
1414
1594
|
return () => clearTimeout(timer);
|
|
1415
1595
|
}, [input, projectId]);
|
|
1416
|
-
return /* @__PURE__ */
|
|
1596
|
+
return /* @__PURE__ */ React9.createElement(
|
|
1417
1597
|
"div",
|
|
1418
1598
|
{
|
|
1419
1599
|
ref: windowRef,
|
|
1420
1600
|
className: `relative flex flex-col border border-slate-200 dark:border-white/10 shadow-2xl transition-all duration-300 ${currentRadius} ${isGlass ? "bg-white/90 dark:bg-[#0f0f1a]/90 backdrop-blur-xl" : "bg-white dark:bg-[#0f0f1a]"} ${className}`,
|
|
1421
1601
|
style: __spreadValues({ "--primary": ui.primaryColor, "--accent": ui.accentColor }, style)
|
|
1422
1602
|
},
|
|
1423
|
-
onResizeStart && /* @__PURE__ */
|
|
1603
|
+
onResizeStart && /* @__PURE__ */ React9.createElement(
|
|
1424
1604
|
"div",
|
|
1425
1605
|
{
|
|
1426
1606
|
onMouseDown: onResizeStart,
|
|
1427
1607
|
className: "absolute top-0 left-0 w-6 h-6 cursor-nw-resize z-[100] group flex items-start justify-start p-1",
|
|
1428
1608
|
title: "Drag to resize"
|
|
1429
1609
|
},
|
|
1430
|
-
/* @__PURE__ */
|
|
1610
|
+
/* @__PURE__ */ React9.createElement("div", { className: "w-2.5 h-2.5 border-t-2 border-l-2 border-slate-300 dark:border-white/20 group-hover:border-slate-500 dark:group-hover:border-white/50 transition-colors rounded-tl-[2px]" })
|
|
1431
1611
|
),
|
|
1432
|
-
/* @__PURE__ */
|
|
1612
|
+
/* @__PURE__ */ React9.createElement(
|
|
1433
1613
|
"div",
|
|
1434
1614
|
{
|
|
1435
1615
|
className: "flex items-center justify-between px-5 py-4 border-b border-slate-200 dark:border-white/10",
|
|
1436
1616
|
style: { background: `linear-gradient(135deg, ${ui.primaryColor}15, ${ui.accentColor}10)` }
|
|
1437
1617
|
},
|
|
1438
|
-
/* @__PURE__ */
|
|
1618
|
+
/* @__PURE__ */ React9.createElement("div", { className: "flex items-center gap-3" }, ui.logoUrl ? (
|
|
1439
1619
|
// eslint-disable-next-line @next/next/no-img-element
|
|
1440
|
-
/* @__PURE__ */
|
|
1441
|
-
) : /* @__PURE__ */
|
|
1620
|
+
/* @__PURE__ */ React9.createElement("img", { src: ui.logoUrl, alt: "logo", className: "w-8 h-8 rounded-lg object-cover" })
|
|
1621
|
+
) : /* @__PURE__ */ React9.createElement(
|
|
1442
1622
|
"div",
|
|
1443
1623
|
{
|
|
1444
1624
|
className: `w-9 h-9 flex items-center justify-center shadow-md ${ui.borderRadius === "full" ? "rounded-full" : "rounded-xl"}`,
|
|
1445
1625
|
style: { background: `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` }
|
|
1446
1626
|
},
|
|
1447
|
-
/* @__PURE__ */
|
|
1448
|
-
), /* @__PURE__ */
|
|
1449
|
-
/* @__PURE__ */
|
|
1627
|
+
/* @__PURE__ */ React9.createElement(Bot2, { className: "w-5 h-5 text-white" })
|
|
1628
|
+
), /* @__PURE__ */ React9.createElement("div", null, /* @__PURE__ */ React9.createElement("h2", { className: "text-slate-900 dark:text-white font-semibold text-sm leading-tight" }, ui.title), ui.poweredBy && /* @__PURE__ */ React9.createElement("p", { className: "text-slate-500 dark:text-white/40 text-[11px] leading-tight" }, `Powered by ${ui.poweredBy}`))),
|
|
1629
|
+
/* @__PURE__ */ React9.createElement("div", { className: "flex items-center gap-1.5" }, /* @__PURE__ */ React9.createElement("span", { className: "flex items-center gap-1 text-[10px] text-emerald-500 dark:text-emerald-400 mr-2" }, /* @__PURE__ */ React9.createElement("span", { className: "w-1.5 h-1.5 rounded-full bg-emerald-500 dark:bg-emerald-400 animate-pulse" }), "Online"), /* @__PURE__ */ React9.createElement("div", { className: "flex items-center bg-slate-100/50 dark:bg-white/5 rounded-lg p-0.5 border border-slate-200/50 dark:border-white/5" }, mounted && messages.length > 0 && /* @__PURE__ */ React9.createElement(
|
|
1450
1630
|
"button",
|
|
1451
1631
|
{
|
|
1452
1632
|
onClick: clearHistory,
|
|
1453
1633
|
title: "Clear conversation",
|
|
1454
1634
|
className: "w-7 h-7 rounded-md flex items-center justify-center text-slate-400 hover:text-rose-500 dark:text-white/40 dark:hover:text-rose-400 hover:bg-white dark:hover:bg-white/10 transition-all cursor-pointer"
|
|
1455
1635
|
},
|
|
1456
|
-
/* @__PURE__ */
|
|
1457
|
-
), isResized && onResetResize && /* @__PURE__ */
|
|
1636
|
+
/* @__PURE__ */ React9.createElement(Trash2, { className: "w-3.5 h-3.5" })
|
|
1637
|
+
), isResized && onResetResize && /* @__PURE__ */ React9.createElement(
|
|
1458
1638
|
"button",
|
|
1459
1639
|
{
|
|
1460
1640
|
onClick: onResetResize,
|
|
1461
1641
|
title: "Reset to default size",
|
|
1462
1642
|
className: "w-7 h-7 rounded-md flex items-center justify-center text-slate-400 hover:text-blue-500 dark:text-white/40 dark:hover:text-blue-400 hover:bg-white dark:hover:bg-white/10 transition-all cursor-pointer"
|
|
1463
1643
|
},
|
|
1464
|
-
/* @__PURE__ */
|
|
1465
|
-
), onMaximize && /* @__PURE__ */
|
|
1644
|
+
/* @__PURE__ */ React9.createElement(RotateCcw, { className: "w-3.5 h-3.5" })
|
|
1645
|
+
), onMaximize && /* @__PURE__ */ React9.createElement(
|
|
1466
1646
|
"button",
|
|
1467
1647
|
{
|
|
1468
1648
|
onClick: onMaximize,
|
|
1469
1649
|
title: isMaximized ? "Minimize" : "Maximize",
|
|
1470
1650
|
className: "w-7 h-7 rounded-md flex items-center justify-center text-slate-400 hover:text-blue-500 dark:text-white/40 dark:hover:text-blue-400 hover:bg-white dark:hover:bg-white/10 transition-all cursor-pointer"
|
|
1471
1651
|
},
|
|
1472
|
-
isMaximized ? /* @__PURE__ */
|
|
1473
|
-
), showClose && onClose && /* @__PURE__ */
|
|
1652
|
+
isMaximized ? /* @__PURE__ */ React9.createElement(Minimize2, { className: "w-3.5 h-3.5" }) : /* @__PURE__ */ React9.createElement(Maximize2, { className: "w-3.5 h-3.5" })
|
|
1653
|
+
), showClose && onClose && /* @__PURE__ */ React9.createElement(
|
|
1474
1654
|
"button",
|
|
1475
1655
|
{
|
|
1476
1656
|
onClick: onClose,
|
|
1477
1657
|
title: "Close chat",
|
|
1478
1658
|
className: "w-7 h-7 rounded-md flex items-center justify-center text-slate-400 hover:text-slate-600 dark:text-white/40 dark:hover:text-white/70 hover:bg-white dark:hover:bg-white/10 transition-all cursor-pointer"
|
|
1479
1659
|
},
|
|
1480
|
-
/* @__PURE__ */
|
|
1660
|
+
/* @__PURE__ */ React9.createElement(X, { className: "w-4 h-4" })
|
|
1481
1661
|
)))
|
|
1482
1662
|
),
|
|
1483
|
-
/* @__PURE__ */
|
|
1663
|
+
/* @__PURE__ */ React9.createElement("div", { className: "flex-1 overflow-y-auto px-4 py-4 space-y-5 scrollbar-thin scrollbar-thumb-slate-200 dark:scrollbar-thumb-white/10 scrollbar-track-transparent min-h-0 bg-slate-50 dark:bg-transparent" }, !mounted || isEmpty ? (
|
|
1484
1664
|
/* Welcome state */
|
|
1485
|
-
/* @__PURE__ */
|
|
1665
|
+
/* @__PURE__ */ React9.createElement("div", { className: "h-full flex flex-col items-center justify-center text-center gap-4 px-6 py-12" }, /* @__PURE__ */ React9.createElement(
|
|
1486
1666
|
"div",
|
|
1487
1667
|
{
|
|
1488
1668
|
className: `w-16 h-16 flex items-center justify-center shadow-lg ${ui.borderRadius === "full" ? "rounded-full" : "rounded-2xl"}`,
|
|
1489
1669
|
style: { background: `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` }
|
|
1490
1670
|
},
|
|
1491
|
-
/* @__PURE__ */
|
|
1492
|
-
), /* @__PURE__ */
|
|
1493
|
-
(suggestion) => /* @__PURE__ */
|
|
1671
|
+
/* @__PURE__ */ React9.createElement(Sparkles, { className: "w-8 h-8 text-white" })
|
|
1672
|
+
), /* @__PURE__ */ React9.createElement("div", null, /* @__PURE__ */ React9.createElement("p", { className: "text-slate-800 dark:text-white/80 font-medium leading-relaxed" }, ui.welcomeMessage), /* @__PURE__ */ React9.createElement("p", { className: "text-slate-500 dark:text-white/30 text-sm mt-2" }, "Ask a question to get started")), /* @__PURE__ */ React9.createElement("div", { className: "flex flex-wrap gap-2 justify-center mt-2" }, CHAT_SUGGESTIONS.map(
|
|
1673
|
+
(suggestion) => /* @__PURE__ */ React9.createElement(
|
|
1494
1674
|
"button",
|
|
1495
1675
|
{
|
|
1496
1676
|
key: suggestion,
|
|
@@ -1504,7 +1684,7 @@ function ChatWindow({
|
|
|
1504
1684
|
suggestion
|
|
1505
1685
|
)
|
|
1506
1686
|
)))
|
|
1507
|
-
) : messages.map((msg, index) => /* @__PURE__ */
|
|
1687
|
+
) : messages.map((msg, index) => /* @__PURE__ */ React9.createElement(
|
|
1508
1688
|
MessageBubble,
|
|
1509
1689
|
{
|
|
1510
1690
|
key: msg.id,
|
|
@@ -1516,7 +1696,7 @@ function ChatWindow({
|
|
|
1516
1696
|
onAddToCart,
|
|
1517
1697
|
viewportSize
|
|
1518
1698
|
}
|
|
1519
|
-
)), isLoading && ((_a = messages[messages.length - 1]) == null ? void 0 : _a.role) !== "assistant" && /* @__PURE__ */
|
|
1699
|
+
)), isLoading && ((_a = messages[messages.length - 1]) == null ? void 0 : _a.role) !== "assistant" && /* @__PURE__ */ React9.createElement(
|
|
1520
1700
|
MessageBubble,
|
|
1521
1701
|
{
|
|
1522
1702
|
message: { id: "loading", role: "assistant", content: "", createdAt: (/* @__PURE__ */ new Date()).toISOString() },
|
|
@@ -1526,8 +1706,8 @@ function ChatWindow({
|
|
|
1526
1706
|
onAddToCart,
|
|
1527
1707
|
viewportSize
|
|
1528
1708
|
}
|
|
1529
|
-
), error && /* @__PURE__ */
|
|
1530
|
-
/* @__PURE__ */
|
|
1709
|
+
), error && /* @__PURE__ */ React9.createElement("div", { className: "flex items-center gap-2 text-rose-500 dark:text-rose-400 text-sm bg-rose-50 dark:bg-rose-400/10 border border-rose-200 dark:border-rose-400/20 rounded-xl px-4 py-3" }, /* @__PURE__ */ React9.createElement(TriangleAlert, { className: "w-4 h-4 flex-shrink-0" }), /* @__PURE__ */ React9.createElement("span", null, error)), /* @__PURE__ */ React9.createElement("div", { ref: bottomRef })),
|
|
1710
|
+
/* @__PURE__ */ React9.createElement("div", { className: `px-4 pb-4 pt-2 border-t border-slate-200 dark:border-white/10 ${isGlass ? "bg-transparent" : "bg-white dark:bg-[#0f0f1a]"}` }, (suggestions.length > 0 || isSuggesting) && !isLoading && /* @__PURE__ */ React9.createElement("div", { className: "mb-3 flex flex-wrap gap-2 animate-in fade-in slide-in-from-bottom-2 duration-300" }, suggestions.map((suggestion) => /* @__PURE__ */ React9.createElement(
|
|
1531
1711
|
"button",
|
|
1532
1712
|
{
|
|
1533
1713
|
key: suggestion,
|
|
@@ -1539,9 +1719,9 @@ function ChatWindow({
|
|
|
1539
1719
|
},
|
|
1540
1720
|
className: "flex items-center gap-1.5 px-3 py-1.5 rounded-xl text-[11px] font-medium bg-white dark:bg-white/5 border border-slate-200 dark:border-white/10 text-slate-600 dark:text-white/60 hover:text-slate-900 dark:hover:text-white/90 hover:border-slate-300 dark:hover:border-white/20 transition-all shadow-sm cursor-pointer group"
|
|
1541
1721
|
},
|
|
1542
|
-
/* @__PURE__ */
|
|
1722
|
+
/* @__PURE__ */ React9.createElement(Sparkles, { className: "w-3 h-3 text-amber-400" }),
|
|
1543
1723
|
suggestion
|
|
1544
|
-
)), isSuggesting && suggestions.length === 0 && /* @__PURE__ */
|
|
1724
|
+
)), isSuggesting && suggestions.length === 0 && /* @__PURE__ */ React9.createElement("div", { className: "flex items-center gap-1.5 px-3 py-1.5 rounded-xl text-[11px] font-medium text-slate-400 dark:text-white/30 animate-pulse" }, /* @__PURE__ */ React9.createElement(Sparkles, { className: "w-3 h-3" }), "Thinking...")), /* @__PURE__ */ React9.createElement("div", { className: `flex items-end gap-2 bg-slate-50 dark:bg-white/5 border border-slate-200 dark:border-white/10 p-2 focus-within:border-slate-300 dark:focus-within:border-white/20 transition-all ${ui.borderRadius === "full" ? "rounded-3xl" : "rounded-2xl"}` }, /* @__PURE__ */ React9.createElement(
|
|
1545
1725
|
"textarea",
|
|
1546
1726
|
{
|
|
1547
1727
|
ref: inputRef,
|
|
@@ -1560,7 +1740,7 @@ function ChatWindow({
|
|
|
1560
1740
|
className: "flex-1 bg-transparent text-slate-900 dark:text-white/90 placeholder-slate-400 dark:placeholder-white/30 text-sm resize-none outline-none py-1.5 px-2 max-h-32 leading-relaxed disabled:opacity-50",
|
|
1561
1741
|
style: { scrollbarWidth: "none" }
|
|
1562
1742
|
}
|
|
1563
|
-
), ui.enableVoiceInput !== false && /* @__PURE__ */
|
|
1743
|
+
), ui.enableVoiceInput !== false && /* @__PURE__ */ React9.createElement(
|
|
1564
1744
|
"button",
|
|
1565
1745
|
{
|
|
1566
1746
|
type: "button",
|
|
@@ -1569,8 +1749,8 @@ function ChatWindow({
|
|
|
1569
1749
|
className: `flex-shrink-0 w-9 h-9 rounded-xl flex items-center justify-center transition-all hover:scale-105 active:scale-95 disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:scale-100 disabled:active:scale-100 ${isListening ? "bg-rose-500 text-white animate-pulse shadow-md shadow-rose-500/20" : "text-slate-400 dark:text-white/40 hover:bg-slate-200 dark:hover:bg-white/10"}`,
|
|
1570
1750
|
title: isListening ? "Stop listening" : "Start voice input"
|
|
1571
1751
|
},
|
|
1572
|
-
isListening ? /* @__PURE__ */
|
|
1573
|
-
), /* @__PURE__ */
|
|
1752
|
+
isListening ? /* @__PURE__ */ React9.createElement(MicOff, { className: "w-4 h-4" }) : /* @__PURE__ */ React9.createElement(Mic, { className: "w-4 h-4" })
|
|
1753
|
+
), /* @__PURE__ */ React9.createElement(
|
|
1574
1754
|
"button",
|
|
1575
1755
|
{
|
|
1576
1756
|
onClick: sendMessage,
|
|
@@ -1581,8 +1761,8 @@ function ChatWindow({
|
|
|
1581
1761
|
// slate-400/20 for light mode disabled
|
|
1582
1762
|
}
|
|
1583
1763
|
},
|
|
1584
|
-
/* @__PURE__ */
|
|
1585
|
-
)), /* @__PURE__ */
|
|
1764
|
+
/* @__PURE__ */ React9.createElement(ArrowUp, { className: "w-4 h-4 text-white" })
|
|
1765
|
+
)), /* @__PURE__ */ React9.createElement("p", { className: "text-center text-[10px] text-slate-400 dark:text-white/20 mt-2" }, "Press Enter to send \xB7 Shift+Enter for new line"))
|
|
1586
1766
|
);
|
|
1587
1767
|
}
|
|
1588
1768
|
|
|
@@ -1645,7 +1825,7 @@ function ChatWidget({ position = "bottom-right", onAddToCart }) {
|
|
|
1645
1825
|
}
|
|
1646
1826
|
};
|
|
1647
1827
|
const isResized = dimensions.width !== DEFAULT_DIMENSIONS.width || dimensions.height !== DEFAULT_DIMENSIONS.height;
|
|
1648
|
-
return /* @__PURE__ */
|
|
1828
|
+
return /* @__PURE__ */ React10.createElement(React10.Fragment, null, /* @__PURE__ */ React10.createElement(
|
|
1649
1829
|
"div",
|
|
1650
1830
|
{
|
|
1651
1831
|
className: `fixed z-[9998] max-w-[calc(100vw-3rem)] ease-in-out ${windowPositionClass} ${isOpen ? "opacity-100 translate-y-0 pointer-events-auto" : "opacity-0 translate-y-4 pointer-events-none"} ${isResizing ? "" : "transition-all duration-300"}`,
|
|
@@ -1655,7 +1835,7 @@ function ChatWidget({ position = "bottom-right", onAddToCart }) {
|
|
|
1655
1835
|
maxHeight: "calc(100vh - 6rem)"
|
|
1656
1836
|
}
|
|
1657
1837
|
},
|
|
1658
|
-
/* @__PURE__ */
|
|
1838
|
+
/* @__PURE__ */ React10.createElement(
|
|
1659
1839
|
ChatWindow,
|
|
1660
1840
|
{
|
|
1661
1841
|
className: "h-full relative z-10",
|
|
@@ -1669,13 +1849,13 @@ function ChatWidget({ position = "bottom-right", onAddToCart }) {
|
|
|
1669
1849
|
onAddToCart
|
|
1670
1850
|
}
|
|
1671
1851
|
),
|
|
1672
|
-
/* @__PURE__ */
|
|
1852
|
+
/* @__PURE__ */ React10.createElement(
|
|
1673
1853
|
"div",
|
|
1674
1854
|
{
|
|
1675
1855
|
className: `absolute -bottom-1.5 w-4 h-4 rotate-45 border-r border-b border-slate-200 dark:border-white/10 z-0 ${ui.visualStyle === "solid" ? "bg-white dark:bg-[#0f0f1a]" : "bg-white/90 dark:bg-[#0f0f1a]/90 backdrop-blur-xl"} ${position === "bottom-left" ? "left-5" : "right-5"}`
|
|
1676
1856
|
}
|
|
1677
1857
|
)
|
|
1678
|
-
), /* @__PURE__ */
|
|
1858
|
+
), /* @__PURE__ */ React10.createElement(
|
|
1679
1859
|
"button",
|
|
1680
1860
|
{
|
|
1681
1861
|
onClick: isOpen ? () => setIsOpen(false) : handleOpen,
|
|
@@ -1683,26 +1863,26 @@ function ChatWidget({ position = "bottom-right", onAddToCart }) {
|
|
|
1683
1863
|
style: { background: `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` },
|
|
1684
1864
|
"aria-label": "Open chat"
|
|
1685
1865
|
},
|
|
1686
|
-
/* @__PURE__ */
|
|
1866
|
+
/* @__PURE__ */ React10.createElement(
|
|
1687
1867
|
"span",
|
|
1688
1868
|
{
|
|
1689
1869
|
className: "absolute inset-0 rounded-full animate-ping opacity-20",
|
|
1690
1870
|
style: { background: ui.primaryColor }
|
|
1691
1871
|
}
|
|
1692
1872
|
),
|
|
1693
|
-
/* @__PURE__ */
|
|
1873
|
+
/* @__PURE__ */ React10.createElement(
|
|
1694
1874
|
"span",
|
|
1695
1875
|
{
|
|
1696
1876
|
className: `transition-transform duration-300 ${isOpen ? "rotate-90 scale-90" : "rotate-0 scale-100"}`
|
|
1697
1877
|
},
|
|
1698
|
-
isOpen ? /* @__PURE__ */
|
|
1878
|
+
isOpen ? /* @__PURE__ */ React10.createElement(X2, { className: "w-6 h-6 text-white" }) : /* @__PURE__ */ React10.createElement(MessageSquare, { className: "w-6 h-6 text-white" })
|
|
1699
1879
|
),
|
|
1700
|
-
hasUnread && !isOpen && /* @__PURE__ */
|
|
1880
|
+
hasUnread && !isOpen && /* @__PURE__ */ React10.createElement("span", { className: "absolute top-0 right-0 w-4 h-4 bg-rose-500 rounded-full border-2 border-white flex items-center justify-center text-[9px] font-bold text-white" }, "1")
|
|
1701
1881
|
));
|
|
1702
1882
|
}
|
|
1703
1883
|
|
|
1704
1884
|
// src/components/DocumentUpload.tsx
|
|
1705
|
-
import
|
|
1885
|
+
import React11, { useState as useState6, useRef as useRef4 } from "react";
|
|
1706
1886
|
import { Upload, File, X as X3, CheckCircle, AlertCircle, Loader2 } from "lucide-react";
|
|
1707
1887
|
function DocumentUpload({ namespace, onUploadComplete, className = "" }) {
|
|
1708
1888
|
const { ui } = useConfig();
|
|
@@ -1758,7 +1938,7 @@ function DocumentUpload({ namespace, onUploadComplete, className = "" }) {
|
|
|
1758
1938
|
};
|
|
1759
1939
|
const isUploading = fileStates.some((s) => s.status === "uploading");
|
|
1760
1940
|
const hasIdle = fileStates.some((s) => s.status === "idle");
|
|
1761
|
-
return /* @__PURE__ */
|
|
1941
|
+
return /* @__PURE__ */ React11.createElement(
|
|
1762
1942
|
"div",
|
|
1763
1943
|
{
|
|
1764
1944
|
className: `p-6 border-2 border-dashed transition-all duration-300 rounded-2xl ${isDragging ? "border-emerald-500 bg-emerald-50/50 dark:bg-emerald-500/5" : "border-slate-200 dark:border-white/10 bg-white dark:bg-white/5"} ${className}`,
|
|
@@ -1766,14 +1946,14 @@ function DocumentUpload({ namespace, onUploadComplete, className = "" }) {
|
|
|
1766
1946
|
onDragLeave,
|
|
1767
1947
|
onDrop
|
|
1768
1948
|
},
|
|
1769
|
-
/* @__PURE__ */
|
|
1949
|
+
/* @__PURE__ */ React11.createElement("div", { className: "flex flex-col items-center justify-center text-center" }, /* @__PURE__ */ React11.createElement(
|
|
1770
1950
|
"div",
|
|
1771
1951
|
{
|
|
1772
1952
|
className: "w-12 h-12 rounded-full flex items-center justify-center mb-4 shadow-sm",
|
|
1773
1953
|
style: { background: `linear-gradient(135deg, ${ui.primaryColor}20, ${ui.accentColor}20)` }
|
|
1774
1954
|
},
|
|
1775
|
-
/* @__PURE__ */
|
|
1776
|
-
), /* @__PURE__ */
|
|
1955
|
+
/* @__PURE__ */ React11.createElement(Upload, { className: "w-6 h-6", style: { color: ui.primaryColor } })
|
|
1956
|
+
), /* @__PURE__ */ React11.createElement("h3", { className: "text-slate-900 dark:text-white font-semibold mb-1" }, "Upload Documents"), /* @__PURE__ */ React11.createElement("p", { className: "text-slate-500 dark:text-white/40 text-sm mb-6 max-w-xs" }, "Drag and drop PDF, DOCX, TXT, or JSON files to train your AI on your own data."), /* @__PURE__ */ React11.createElement(
|
|
1777
1957
|
"button",
|
|
1778
1958
|
{
|
|
1779
1959
|
onClick: () => {
|
|
@@ -1789,7 +1969,7 @@ function DocumentUpload({ namespace, onUploadComplete, className = "" }) {
|
|
|
1789
1969
|
}
|
|
1790
1970
|
},
|
|
1791
1971
|
"Select Files"
|
|
1792
|
-
), /* @__PURE__ */
|
|
1972
|
+
), /* @__PURE__ */ React11.createElement(
|
|
1793
1973
|
"input",
|
|
1794
1974
|
{
|
|
1795
1975
|
ref: fileInputRef,
|
|
@@ -1800,22 +1980,22 @@ function DocumentUpload({ namespace, onUploadComplete, className = "" }) {
|
|
|
1800
1980
|
accept: ".pdf,.docx,.txt,.md,.json,.csv"
|
|
1801
1981
|
}
|
|
1802
1982
|
)),
|
|
1803
|
-
fileStates.length > 0 && /* @__PURE__ */
|
|
1983
|
+
fileStates.length > 0 && /* @__PURE__ */ React11.createElement("div", { className: "mt-8 space-y-3" }, fileStates.map((state, i) => /* @__PURE__ */ React11.createElement(
|
|
1804
1984
|
"div",
|
|
1805
1985
|
{
|
|
1806
1986
|
key: i,
|
|
1807
1987
|
className: "flex items-center justify-between p-3 rounded-xl bg-slate-50 dark:bg-white/5 border border-slate-100 dark:border-white/10"
|
|
1808
1988
|
},
|
|
1809
|
-
/* @__PURE__ */
|
|
1810
|
-
/* @__PURE__ */
|
|
1989
|
+
/* @__PURE__ */ React11.createElement("div", { className: "flex items-center gap-3 overflow-hidden" }, /* @__PURE__ */ React11.createElement("div", { className: "w-8 h-8 rounded-lg bg-white dark:bg-white/10 flex items-center justify-center shadow-sm" }, /* @__PURE__ */ React11.createElement(File, { className: "w-4 h-4 text-slate-400" })), /* @__PURE__ */ React11.createElement("div", { className: "truncate" }, /* @__PURE__ */ React11.createElement("p", { className: "text-xs font-medium text-slate-700 dark:text-white/80 truncate" }, state.file.name), /* @__PURE__ */ React11.createElement("p", { className: "text-[10px] text-slate-400" }, (state.file.size / 1024).toFixed(1), " KB"))),
|
|
1990
|
+
/* @__PURE__ */ React11.createElement("div", { className: "flex items-center gap-2" }, state.status === "uploading" && /* @__PURE__ */ React11.createElement(Loader2, { className: "w-4 h-4 text-slate-400 animate-spin" }), state.status === "success" && /* @__PURE__ */ React11.createElement(CheckCircle, { className: "w-4 h-4 text-emerald-500" }), state.status === "error" && /* @__PURE__ */ React11.createElement("div", { title: state.error }, /* @__PURE__ */ React11.createElement(AlertCircle, { className: "w-4 h-4 text-rose-500" })), state.status !== "uploading" && /* @__PURE__ */ React11.createElement(
|
|
1811
1991
|
"button",
|
|
1812
1992
|
{
|
|
1813
1993
|
onClick: () => removeFile(i),
|
|
1814
1994
|
className: "p-1 rounded-md hover:bg-slate-200 dark:hover:bg-white/10 transition-colors"
|
|
1815
1995
|
},
|
|
1816
|
-
/* @__PURE__ */
|
|
1996
|
+
/* @__PURE__ */ React11.createElement(X3, { className: "w-3.5 h-3.5 text-slate-400" })
|
|
1817
1997
|
))
|
|
1818
|
-
)), hasIdle && !isUploading && /* @__PURE__ */
|
|
1998
|
+
)), hasIdle && !isUploading && /* @__PURE__ */ React11.createElement(
|
|
1819
1999
|
"button",
|
|
1820
2000
|
{
|
|
1821
2001
|
onClick: uploadFiles,
|