@retrivora-ai/rag-engine 1.1.4 → 1.1.6
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/index.js +242 -95
- package/dist/index.mjs +218 -71
- package/package.json +1 -1
- package/src/app/globals.css +9 -0
- package/src/components/MessageBubble.tsx +87 -2
- package/src/components/ProductCard.tsx +90 -0
- package/src/components/ProductCarousel.tsx +69 -0
package/dist/index.js
CHANGED
|
@@ -59,16 +59,16 @@ __export(index_exports, {
|
|
|
59
59
|
module.exports = __toCommonJS(index_exports);
|
|
60
60
|
|
|
61
61
|
// src/components/ChatWidget.tsx
|
|
62
|
-
var
|
|
63
|
-
var
|
|
62
|
+
var import_react8 = __toESM(require("react"));
|
|
63
|
+
var import_lucide_react6 = require("lucide-react");
|
|
64
64
|
|
|
65
65
|
// src/components/ChatWindow.tsx
|
|
66
|
-
var
|
|
67
|
-
var
|
|
66
|
+
var import_react7 = __toESM(require("react"));
|
|
67
|
+
var import_lucide_react5 = require("lucide-react");
|
|
68
68
|
|
|
69
69
|
// src/components/MessageBubble.tsx
|
|
70
|
-
var
|
|
71
|
-
var
|
|
70
|
+
var import_react4 = __toESM(require("react"));
|
|
71
|
+
var import_lucide_react4 = require("lucide-react");
|
|
72
72
|
var import_react_markdown = __toESM(require("react-markdown"));
|
|
73
73
|
var import_remark_gfm = __toESM(require("remark-gfm"));
|
|
74
74
|
|
|
@@ -95,6 +95,98 @@ function SourceCard({ source, index }) {
|
|
|
95
95
|
);
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
+
// src/components/ProductCarousel.tsx
|
|
99
|
+
var import_react3 = __toESM(require("react"));
|
|
100
|
+
var import_lucide_react3 = require("lucide-react");
|
|
101
|
+
|
|
102
|
+
// src/components/ProductCard.tsx
|
|
103
|
+
var import_react2 = __toESM(require("react"));
|
|
104
|
+
var import_image = __toESM(require("next/image"));
|
|
105
|
+
var import_lucide_react2 = require("lucide-react");
|
|
106
|
+
function ProductCard({ product, primaryColor = "#6366f1" }) {
|
|
107
|
+
return /* @__PURE__ */ import_react2.default.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__ */ import_react2.default.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__ */ import_react2.default.createElement(
|
|
108
|
+
import_image.default,
|
|
109
|
+
{
|
|
110
|
+
src: product.image,
|
|
111
|
+
alt: product.name,
|
|
112
|
+
fill: true,
|
|
113
|
+
unoptimized: true,
|
|
114
|
+
className: "object-cover group-hover:scale-105 transition-transform duration-500"
|
|
115
|
+
}
|
|
116
|
+
) : /* @__PURE__ */ import_react2.default.createElement("div", { className: "text-slate-400 dark:text-white/20" }, /* @__PURE__ */ import_react2.default.createElement(import_lucide_react2.ShoppingCart, { className: "w-12 h-12" })), product.brand && /* @__PURE__ */ import_react2.default.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__ */ import_react2.default.createElement("div", { className: "p-4 flex flex-col gap-2" }, /* @__PURE__ */ import_react2.default.createElement("div", { className: "flex justify-between items-start gap-2" }, /* @__PURE__ */ import_react2.default.createElement("h3", { className: "text-sm font-semibold text-slate-800 dark:text-white/90 line-clamp-1" }, product.name), product.price && /* @__PURE__ */ import_react2.default.createElement("span", { className: "text-sm font-bold", style: { color: primaryColor } }, typeof product.price === "number" ? `$${product.price}` : product.price)), product.description && /* @__PURE__ */ import_react2.default.createElement("p", { className: "text-[11px] text-slate-500 dark:text-white/50 line-clamp-2 leading-relaxed" }, product.description), /* @__PURE__ */ import_react2.default.createElement("div", { className: "mt-2 flex gap-2" }, /* @__PURE__ */ import_react2.default.createElement(
|
|
117
|
+
"button",
|
|
118
|
+
{
|
|
119
|
+
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",
|
|
120
|
+
style: { background: primaryColor }
|
|
121
|
+
},
|
|
122
|
+
/* @__PURE__ */ import_react2.default.createElement(import_lucide_react2.ShoppingCart, { className: "w-3 h-3" }),
|
|
123
|
+
"Add to Cart"
|
|
124
|
+
), product.link && /* @__PURE__ */ import_react2.default.createElement(
|
|
125
|
+
"a",
|
|
126
|
+
{
|
|
127
|
+
href: product.link,
|
|
128
|
+
target: "_blank",
|
|
129
|
+
rel: "noopener noreferrer",
|
|
130
|
+
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"
|
|
131
|
+
},
|
|
132
|
+
/* @__PURE__ */ import_react2.default.createElement(import_lucide_react2.ExternalLink, { className: "w-3.5 h-3.5" })
|
|
133
|
+
))));
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// src/components/ProductCarousel.tsx
|
|
137
|
+
function ProductCarousel({ products, primaryColor = "#6366f1" }) {
|
|
138
|
+
const scrollRef = (0, import_react3.useRef)(null);
|
|
139
|
+
const scroll = (direction) => {
|
|
140
|
+
if (scrollRef.current) {
|
|
141
|
+
const firstCard = scrollRef.current.firstElementChild;
|
|
142
|
+
if (firstCard) {
|
|
143
|
+
const cardWidth = firstCard.offsetWidth + 16;
|
|
144
|
+
const scrollAmount = direction === "left" ? -cardWidth : cardWidth;
|
|
145
|
+
scrollRef.current.scrollBy({ left: scrollAmount, behavior: "smooth" });
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
if (!products || products.length === 0) return null;
|
|
150
|
+
return /* @__PURE__ */ import_react3.default.createElement("div", { className: "relative w-full my-4 group/carousel" }, /* @__PURE__ */ import_react3.default.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__ */ import_react3.default.createElement(
|
|
151
|
+
"button",
|
|
152
|
+
{
|
|
153
|
+
onClick: (e) => {
|
|
154
|
+
e.stopPropagation();
|
|
155
|
+
scroll("left");
|
|
156
|
+
},
|
|
157
|
+
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",
|
|
158
|
+
"aria-label": "Scroll left"
|
|
159
|
+
},
|
|
160
|
+
/* @__PURE__ */ import_react3.default.createElement(import_lucide_react3.ChevronLeft, { className: "w-5 h-5" })
|
|
161
|
+
)), /* @__PURE__ */ import_react3.default.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__ */ import_react3.default.createElement(
|
|
162
|
+
"button",
|
|
163
|
+
{
|
|
164
|
+
onClick: (e) => {
|
|
165
|
+
e.stopPropagation();
|
|
166
|
+
scroll("right");
|
|
167
|
+
},
|
|
168
|
+
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",
|
|
169
|
+
"aria-label": "Scroll right"
|
|
170
|
+
},
|
|
171
|
+
/* @__PURE__ */ import_react3.default.createElement(import_lucide_react3.ChevronRight, { className: "w-5 h-5" })
|
|
172
|
+
)), /* @__PURE__ */ import_react3.default.createElement(
|
|
173
|
+
"div",
|
|
174
|
+
{
|
|
175
|
+
ref: scrollRef,
|
|
176
|
+
className: "flex gap-4 overflow-x-auto pb-4 px-1 scrollbar-hide snap-x snap-mandatory",
|
|
177
|
+
style: { scrollbarWidth: "none", msOverflowStyle: "none" }
|
|
178
|
+
},
|
|
179
|
+
products.map((product) => /* @__PURE__ */ import_react3.default.createElement(
|
|
180
|
+
"div",
|
|
181
|
+
{
|
|
182
|
+
key: product.id,
|
|
183
|
+
className: "snap-start flex-shrink-0 w-[85%] sm:w-[48%] md:w-[31%] min-w-[200px] max-w-[300px]"
|
|
184
|
+
},
|
|
185
|
+
/* @__PURE__ */ import_react3.default.createElement(ProductCard, { product, primaryColor })
|
|
186
|
+
))
|
|
187
|
+
));
|
|
188
|
+
}
|
|
189
|
+
|
|
98
190
|
// src/components/MessageBubble.tsx
|
|
99
191
|
function MessageBubble({
|
|
100
192
|
message,
|
|
@@ -104,37 +196,92 @@ function MessageBubble({
|
|
|
104
196
|
accentColor = "#8b5cf6"
|
|
105
197
|
}) {
|
|
106
198
|
const isUser = message.role === "user";
|
|
107
|
-
const [showSources, setShowSources] =
|
|
108
|
-
|
|
199
|
+
const [showSources, setShowSources] = import_react4.default.useState(false);
|
|
200
|
+
const resolveImage = (data) => {
|
|
201
|
+
if (!data) return void 0;
|
|
202
|
+
const singleFields = ["image", "img", "thumbnail"];
|
|
203
|
+
for (const field of singleFields) {
|
|
204
|
+
const val = data[field];
|
|
205
|
+
if (typeof val === "string" && val) return val;
|
|
206
|
+
}
|
|
207
|
+
if (Array.isArray(data.images) && data.images.length > 0) {
|
|
208
|
+
if (typeof data.images[0] === "string") return data.images[0];
|
|
209
|
+
}
|
|
210
|
+
return void 0;
|
|
211
|
+
};
|
|
212
|
+
const productsFromSources = import_react4.default.useMemo(() => {
|
|
213
|
+
if (isUser || !sources) return [];
|
|
214
|
+
return sources.filter((s) => {
|
|
215
|
+
const m = s.metadata || {};
|
|
216
|
+
return m.price || m.image || m.img || m.thumbnail || m.images || m.brand || m.type === "product";
|
|
217
|
+
}).map((s) => {
|
|
218
|
+
const m = s.metadata || {};
|
|
219
|
+
return {
|
|
220
|
+
id: s.id,
|
|
221
|
+
name: m.name || m.title || s.content.split("\n")[0] || "Unknown Product",
|
|
222
|
+
brand: m.brand,
|
|
223
|
+
price: m.price,
|
|
224
|
+
image: resolveImage(m),
|
|
225
|
+
link: m.link,
|
|
226
|
+
description: s.content
|
|
227
|
+
};
|
|
228
|
+
});
|
|
229
|
+
}, [sources, isUser]);
|
|
230
|
+
const { productsFromContent, cleanContent } = import_react4.default.useMemo(() => {
|
|
231
|
+
if (isUser) return { productsFromContent: [], cleanContent: message.content };
|
|
232
|
+
const jsonRegex = /```json\s*([\s\S]*?)\s*```/g;
|
|
233
|
+
const products = [];
|
|
234
|
+
let content = message.content;
|
|
235
|
+
if (content.includes('"type": "products"') || content.includes('"type":"products"')) {
|
|
236
|
+
const matches = Array.from(content.matchAll(jsonRegex));
|
|
237
|
+
for (const m of matches) {
|
|
238
|
+
try {
|
|
239
|
+
const data = JSON.parse(m[1]);
|
|
240
|
+
if (data.type === "products" && Array.isArray(data.items)) {
|
|
241
|
+
const formattedItems = data.items.map((item) => __spreadProps(__spreadValues({}, item), {
|
|
242
|
+
image: item.image || resolveImage(item)
|
|
243
|
+
}));
|
|
244
|
+
products.push(...formattedItems);
|
|
245
|
+
content = content.replace(m[0], "");
|
|
246
|
+
}
|
|
247
|
+
} catch (e) {
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
return { productsFromContent: products, cleanContent: content.trim() };
|
|
252
|
+
}, [message.content, isUser]);
|
|
253
|
+
const allProducts = [...productsFromSources, ...productsFromContent];
|
|
254
|
+
const hasProducts = allProducts.length > 0;
|
|
255
|
+
return /* @__PURE__ */ import_react4.default.createElement("div", { className: `flex gap-3 ${isUser ? "flex-row-reverse" : "flex-row"} items-start` }, /* @__PURE__ */ import_react4.default.createElement(
|
|
109
256
|
"div",
|
|
110
257
|
{
|
|
111
258
|
className: `flex-shrink-0 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"}`,
|
|
112
259
|
style: isUser ? { background: `linear-gradient(135deg, ${primaryColor}, ${accentColor})` } : {}
|
|
113
260
|
},
|
|
114
|
-
isUser ? /* @__PURE__ */
|
|
115
|
-
), /* @__PURE__ */
|
|
261
|
+
isUser ? /* @__PURE__ */ import_react4.default.createElement(import_lucide_react4.User, { className: "w-4 h-4 text-white" }) : /* @__PURE__ */ import_react4.default.createElement(import_lucide_react4.Bot, { className: "w-4 h-4" })
|
|
262
|
+
), /* @__PURE__ */ import_react4.default.createElement("div", { className: `flex flex-col gap-1 max-w-[90%] ${isUser ? "items-end" : "items-start"}` }, /* @__PURE__ */ import_react4.default.createElement(
|
|
116
263
|
"div",
|
|
117
264
|
{
|
|
118
265
|
className: `relative px-4 py-3 rounded-2xl text-sm 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"}`,
|
|
119
266
|
style: isUser ? { background: `linear-gradient(135deg, ${primaryColor}, ${accentColor})` } : {}
|
|
120
267
|
},
|
|
121
|
-
isStreaming && !message.content ? /* @__PURE__ */
|
|
122
|
-
), !isUser && sources && sources.length > 0 && /* @__PURE__ */
|
|
268
|
+
isStreaming && !message.content ? /* @__PURE__ */ import_react4.default.createElement("span", { className: "flex items-center gap-1 py-1" }, /* @__PURE__ */ import_react4.default.createElement("span", { className: "w-1.5 h-1.5 rounded-full bg-slate-400 dark:bg-white/60 animate-bounce [animation-delay:0ms]" }), /* @__PURE__ */ import_react4.default.createElement("span", { className: "w-1.5 h-1.5 rounded-full bg-slate-400 dark:bg-white/60 animate-bounce [animation-delay:150ms]" }), /* @__PURE__ */ import_react4.default.createElement("span", { className: "w-1.5 h-1.5 rounded-full bg-slate-400 dark:bg-white/60 animate-bounce [animation-delay:300ms]" })) : /* @__PURE__ */ import_react4.default.createElement("div", { className: `prose prose-sm max-w-none ${isUser ? "prose-invert" : "dark:prose-invert"}` }, /* @__PURE__ */ import_react4.default.createElement(import_react_markdown.default, { remarkPlugins: [import_remark_gfm.default] }, cleanContent || message.content), isStreaming && message.content && /* @__PURE__ */ import_react4.default.createElement("span", { className: "inline-block w-1.5 h-3.5 ml-1 bg-emerald-500 animate-pulse align-middle" }))
|
|
269
|
+
), !isUser && hasProducts && /* @__PURE__ */ import_react4.default.createElement("div", { className: "w-full mt-1" }, /* @__PURE__ */ import_react4.default.createElement(ProductCarousel, { products: allProducts, primaryColor })), !isUser && sources && sources.length > 0 && /* @__PURE__ */ import_react4.default.createElement("div", { className: "w-full" }, /* @__PURE__ */ import_react4.default.createElement(
|
|
123
270
|
"button",
|
|
124
271
|
{
|
|
125
272
|
onClick: () => setShowSources((s) => !s),
|
|
126
273
|
className: "text-[11px] text-indigo-400 hover:text-indigo-300 transition-colors flex items-center gap-1 mt-1"
|
|
127
274
|
},
|
|
128
|
-
showSources ? /* @__PURE__ */
|
|
275
|
+
showSources ? /* @__PURE__ */ import_react4.default.createElement(import_lucide_react4.ChevronDown, { className: "w-3 h-3" }) : /* @__PURE__ */ import_react4.default.createElement(import_lucide_react4.ChevronRight, { className: "w-3 h-3" }),
|
|
129
276
|
sources.length,
|
|
130
277
|
" source",
|
|
131
278
|
sources.length !== 1 ? "s" : "",
|
|
132
279
|
" used"
|
|
133
|
-
), showSources && /* @__PURE__ */
|
|
280
|
+
), showSources && /* @__PURE__ */ import_react4.default.createElement("div", { className: "mt-2 flex flex-col gap-2" }, sources.map((src, i) => /* @__PURE__ */ import_react4.default.createElement(SourceCard, { key: src.id, source: src, index: i }))))));
|
|
134
281
|
}
|
|
135
282
|
|
|
136
283
|
// src/components/ConfigProvider.tsx
|
|
137
|
-
var
|
|
284
|
+
var import_react5 = __toESM(require("react"));
|
|
138
285
|
|
|
139
286
|
// src/utils/templateUtils.ts
|
|
140
287
|
function mergeDefined(base, override) {
|
|
@@ -170,7 +317,7 @@ var defaultConfig = {
|
|
|
170
317
|
allowResize: true
|
|
171
318
|
}
|
|
172
319
|
};
|
|
173
|
-
var ConfigContext = (0,
|
|
320
|
+
var ConfigContext = (0, import_react5.createContext)(defaultConfig);
|
|
174
321
|
function ConfigProvider({
|
|
175
322
|
config,
|
|
176
323
|
children
|
|
@@ -179,17 +326,17 @@ function ConfigProvider({
|
|
|
179
326
|
projectId: (config == null ? void 0 : config.projectId) || defaultConfig.projectId,
|
|
180
327
|
ui: mergeDefined(defaultConfig.ui, config == null ? void 0 : config.ui)
|
|
181
328
|
};
|
|
182
|
-
return /* @__PURE__ */
|
|
329
|
+
return /* @__PURE__ */ import_react5.default.createElement(ConfigContext.Provider, { value: merged }, children);
|
|
183
330
|
}
|
|
184
331
|
function useConfig() {
|
|
185
|
-
return (0,
|
|
332
|
+
return (0, import_react5.useContext)(ConfigContext);
|
|
186
333
|
}
|
|
187
334
|
|
|
188
335
|
// src/hooks/useRagChat.ts
|
|
189
|
-
var
|
|
336
|
+
var import_react6 = require("react");
|
|
190
337
|
|
|
191
338
|
// src/hooks/useStoredMessages.ts
|
|
192
|
-
var
|
|
339
|
+
var React6 = __toESM(require("react"));
|
|
193
340
|
function readStoredMessages(storageKey) {
|
|
194
341
|
if (typeof window === "undefined") {
|
|
195
342
|
return [];
|
|
@@ -206,8 +353,8 @@ function readStoredMessages(storageKey) {
|
|
|
206
353
|
}
|
|
207
354
|
}
|
|
208
355
|
function useStoredMessages(storageKey, persist) {
|
|
209
|
-
const [messages, setMessages] =
|
|
210
|
-
|
|
356
|
+
const [messages, setMessages] = React6.useState(() => persist ? readStoredMessages(storageKey) : []);
|
|
357
|
+
React6.useEffect(() => {
|
|
211
358
|
if (!persist || typeof window === "undefined") {
|
|
212
359
|
return;
|
|
213
360
|
}
|
|
@@ -247,14 +394,14 @@ function useRagChat(projectId, options = {}) {
|
|
|
247
394
|
} = options;
|
|
248
395
|
const storageKey = `rag_chat_${projectId}`;
|
|
249
396
|
const [messages, setMessages] = useStoredMessages(storageKey, persist);
|
|
250
|
-
const [isLoading, setIsLoading] = (0,
|
|
251
|
-
const [error, setError] = (0,
|
|
252
|
-
const lastInputRef = (0,
|
|
253
|
-
const messagesRef = (0,
|
|
254
|
-
(0,
|
|
397
|
+
const [isLoading, setIsLoading] = (0, import_react6.useState)(false);
|
|
398
|
+
const [error, setError] = (0, import_react6.useState)(null);
|
|
399
|
+
const lastInputRef = (0, import_react6.useRef)("");
|
|
400
|
+
const messagesRef = (0, import_react6.useRef)(messages);
|
|
401
|
+
(0, import_react6.useEffect)(() => {
|
|
255
402
|
messagesRef.current = messages;
|
|
256
403
|
}, [messages]);
|
|
257
|
-
const sendMessage = (0,
|
|
404
|
+
const sendMessage = (0, import_react6.useCallback)(
|
|
258
405
|
async (text, opts) => {
|
|
259
406
|
var _a, _b;
|
|
260
407
|
const trimmed = text.trim();
|
|
@@ -351,12 +498,12 @@ function useRagChat(projectId, options = {}) {
|
|
|
351
498
|
},
|
|
352
499
|
[apiUrl, isLoading, namespace, onError, onReply, projectId, setMessages]
|
|
353
500
|
);
|
|
354
|
-
const clear = (0,
|
|
501
|
+
const clear = (0, import_react6.useCallback)(() => {
|
|
355
502
|
setMessages([]);
|
|
356
503
|
setError(null);
|
|
357
504
|
if (persist) localStorage.removeItem(storageKey);
|
|
358
505
|
}, [persist, setMessages, storageKey]);
|
|
359
|
-
const retry = (0,
|
|
506
|
+
const retry = (0, import_react6.useCallback)(async () => {
|
|
360
507
|
if (lastInputRef.current) {
|
|
361
508
|
const latestMessage = messagesRef.current[messagesRef.current.length - 1];
|
|
362
509
|
await sendMessage(lastInputRef.current, {
|
|
@@ -404,23 +551,23 @@ function ChatWindow({
|
|
|
404
551
|
}) {
|
|
405
552
|
var _a;
|
|
406
553
|
const { ui, projectId } = useConfig();
|
|
407
|
-
const [input, setInput] = (0,
|
|
408
|
-
const [mounted, setMounted] = (0,
|
|
409
|
-
const bottomRef = (0,
|
|
410
|
-
const inputRef = (0,
|
|
554
|
+
const [input, setInput] = (0, import_react7.useState)("");
|
|
555
|
+
const [mounted, setMounted] = (0, import_react7.useState)(false);
|
|
556
|
+
const bottomRef = (0, import_react7.useRef)(null);
|
|
557
|
+
const inputRef = (0, import_react7.useRef)(null);
|
|
411
558
|
const { messages, send, clear, isLoading, error } = useRagChat(projectId, {
|
|
412
559
|
namespace: projectId
|
|
413
560
|
});
|
|
414
|
-
(0,
|
|
561
|
+
(0, import_react7.useEffect)(() => {
|
|
415
562
|
setMounted(true);
|
|
416
563
|
}, []);
|
|
417
|
-
(0,
|
|
564
|
+
(0, import_react7.useEffect)(() => {
|
|
418
565
|
var _a2;
|
|
419
566
|
if (messages.length > 0 || isLoading) {
|
|
420
567
|
(_a2 = bottomRef.current) == null ? void 0 : _a2.scrollIntoView({ behavior: "smooth" });
|
|
421
568
|
}
|
|
422
569
|
}, [messages, isLoading]);
|
|
423
|
-
const sendMessage = (0,
|
|
570
|
+
const sendMessage = (0, import_react7.useCallback)(async () => {
|
|
424
571
|
const text = input.trim();
|
|
425
572
|
if (!text || isLoading) return;
|
|
426
573
|
setInput("");
|
|
@@ -442,83 +589,83 @@ function ChatWindow({
|
|
|
442
589
|
const isEmpty = messages.length === 0;
|
|
443
590
|
const currentRadius = BORDER_RADIUS_MAP[ui.borderRadius || "xl"];
|
|
444
591
|
const isGlass = ui.visualStyle !== "solid";
|
|
445
|
-
return /* @__PURE__ */
|
|
592
|
+
return /* @__PURE__ */ import_react7.default.createElement(
|
|
446
593
|
"div",
|
|
447
594
|
{
|
|
448
595
|
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}`,
|
|
449
596
|
style: __spreadValues({ "--primary": ui.primaryColor, "--accent": ui.accentColor }, style)
|
|
450
597
|
},
|
|
451
|
-
onResizeStart && /* @__PURE__ */
|
|
598
|
+
onResizeStart && /* @__PURE__ */ import_react7.default.createElement(
|
|
452
599
|
"div",
|
|
453
600
|
{
|
|
454
601
|
onMouseDown: onResizeStart,
|
|
455
602
|
className: "absolute top-0 left-0 w-6 h-6 cursor-nw-resize z-[100] group flex items-start justify-start p-1",
|
|
456
603
|
title: "Drag to resize"
|
|
457
604
|
},
|
|
458
|
-
/* @__PURE__ */
|
|
605
|
+
/* @__PURE__ */ import_react7.default.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]" })
|
|
459
606
|
),
|
|
460
|
-
/* @__PURE__ */
|
|
607
|
+
/* @__PURE__ */ import_react7.default.createElement(
|
|
461
608
|
"div",
|
|
462
609
|
{
|
|
463
610
|
className: "flex items-center justify-between px-5 py-4 border-b border-slate-200 dark:border-white/10",
|
|
464
611
|
style: { background: `linear-gradient(135deg, ${ui.primaryColor}15, ${ui.accentColor}10)` }
|
|
465
612
|
},
|
|
466
|
-
/* @__PURE__ */
|
|
613
|
+
/* @__PURE__ */ import_react7.default.createElement("div", { className: "flex items-center gap-3" }, ui.logoUrl ? (
|
|
467
614
|
// eslint-disable-next-line @next/next/no-img-element
|
|
468
|
-
/* @__PURE__ */
|
|
469
|
-
) : /* @__PURE__ */
|
|
615
|
+
/* @__PURE__ */ import_react7.default.createElement("img", { src: ui.logoUrl, alt: "logo", className: "w-8 h-8 rounded-lg object-cover" })
|
|
616
|
+
) : /* @__PURE__ */ import_react7.default.createElement(
|
|
470
617
|
"div",
|
|
471
618
|
{
|
|
472
619
|
className: `w-9 h-9 flex items-center justify-center shadow-md ${ui.borderRadius === "full" ? "rounded-full" : "rounded-xl"}`,
|
|
473
620
|
style: { background: `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` }
|
|
474
621
|
},
|
|
475
|
-
/* @__PURE__ */
|
|
476
|
-
), /* @__PURE__ */
|
|
477
|
-
/* @__PURE__ */
|
|
622
|
+
/* @__PURE__ */ import_react7.default.createElement(import_lucide_react5.Bot, { className: "w-5 h-5 text-white" })
|
|
623
|
+
), /* @__PURE__ */ import_react7.default.createElement("div", null, /* @__PURE__ */ import_react7.default.createElement("h2", { className: "text-slate-900 dark:text-white font-semibold text-sm leading-tight" }, ui.title), ui.poweredBy && /* @__PURE__ */ import_react7.default.createElement("p", { className: "text-slate-500 dark:text-white/40 text-[11px] leading-tight" }, `Powered by ${ui.poweredBy}`))),
|
|
624
|
+
/* @__PURE__ */ import_react7.default.createElement("div", { className: "flex items-center gap-1.5" }, /* @__PURE__ */ import_react7.default.createElement("span", { className: "flex items-center gap-1 text-[10px] text-emerald-500 dark:text-emerald-400 mr-2" }, /* @__PURE__ */ import_react7.default.createElement("span", { className: "w-1.5 h-1.5 rounded-full bg-emerald-500 dark:bg-emerald-400 animate-pulse" }), "Online"), /* @__PURE__ */ import_react7.default.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__ */ import_react7.default.createElement(
|
|
478
625
|
"button",
|
|
479
626
|
{
|
|
480
627
|
onClick: clearHistory,
|
|
481
628
|
title: "Clear conversation",
|
|
482
629
|
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"
|
|
483
630
|
},
|
|
484
|
-
/* @__PURE__ */
|
|
485
|
-
), isResized && onResetResize && /* @__PURE__ */
|
|
631
|
+
/* @__PURE__ */ import_react7.default.createElement(import_lucide_react5.Trash2, { className: "w-3.5 h-3.5" })
|
|
632
|
+
), isResized && onResetResize && /* @__PURE__ */ import_react7.default.createElement(
|
|
486
633
|
"button",
|
|
487
634
|
{
|
|
488
635
|
onClick: onResetResize,
|
|
489
636
|
title: "Reset to default size",
|
|
490
637
|
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"
|
|
491
638
|
},
|
|
492
|
-
/* @__PURE__ */
|
|
493
|
-
), onMaximize && /* @__PURE__ */
|
|
639
|
+
/* @__PURE__ */ import_react7.default.createElement(import_lucide_react5.RotateCcw, { className: "w-3.5 h-3.5" })
|
|
640
|
+
), onMaximize && /* @__PURE__ */ import_react7.default.createElement(
|
|
494
641
|
"button",
|
|
495
642
|
{
|
|
496
643
|
onClick: onMaximize,
|
|
497
644
|
title: isMaximized ? "Minimize" : "Maximize",
|
|
498
645
|
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"
|
|
499
646
|
},
|
|
500
|
-
isMaximized ? /* @__PURE__ */
|
|
501
|
-
), showClose && onClose && /* @__PURE__ */
|
|
647
|
+
isMaximized ? /* @__PURE__ */ import_react7.default.createElement(import_lucide_react5.Minimize2, { className: "w-3.5 h-3.5" }) : /* @__PURE__ */ import_react7.default.createElement(import_lucide_react5.Maximize2, { className: "w-3.5 h-3.5" })
|
|
648
|
+
), showClose && onClose && /* @__PURE__ */ import_react7.default.createElement(
|
|
502
649
|
"button",
|
|
503
650
|
{
|
|
504
651
|
onClick: onClose,
|
|
505
652
|
title: "Close chat",
|
|
506
653
|
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"
|
|
507
654
|
},
|
|
508
|
-
/* @__PURE__ */
|
|
655
|
+
/* @__PURE__ */ import_react7.default.createElement(import_lucide_react5.X, { className: "w-4 h-4" })
|
|
509
656
|
)))
|
|
510
657
|
),
|
|
511
|
-
/* @__PURE__ */
|
|
658
|
+
/* @__PURE__ */ import_react7.default.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 ? (
|
|
512
659
|
/* Welcome state */
|
|
513
|
-
/* @__PURE__ */
|
|
660
|
+
/* @__PURE__ */ import_react7.default.createElement("div", { className: "h-full flex flex-col items-center justify-center text-center gap-4 px-6 py-12" }, /* @__PURE__ */ import_react7.default.createElement(
|
|
514
661
|
"div",
|
|
515
662
|
{
|
|
516
663
|
className: `w-16 h-16 flex items-center justify-center shadow-lg ${ui.borderRadius === "full" ? "rounded-full" : "rounded-2xl"}`,
|
|
517
664
|
style: { background: `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` }
|
|
518
665
|
},
|
|
519
|
-
/* @__PURE__ */
|
|
520
|
-
), /* @__PURE__ */
|
|
521
|
-
(suggestion) => /* @__PURE__ */
|
|
666
|
+
/* @__PURE__ */ import_react7.default.createElement(import_lucide_react5.Sparkles, { className: "w-8 h-8 text-white" })
|
|
667
|
+
), /* @__PURE__ */ import_react7.default.createElement("div", null, /* @__PURE__ */ import_react7.default.createElement("p", { className: "text-slate-800 dark:text-white/80 font-medium leading-relaxed" }, ui.welcomeMessage), /* @__PURE__ */ import_react7.default.createElement("p", { className: "text-slate-500 dark:text-white/30 text-sm mt-2" }, "Ask a question to get started")), /* @__PURE__ */ import_react7.default.createElement("div", { className: "flex flex-wrap gap-2 justify-center mt-2" }, CHAT_SUGGESTIONS.map(
|
|
668
|
+
(suggestion) => /* @__PURE__ */ import_react7.default.createElement(
|
|
522
669
|
"button",
|
|
523
670
|
{
|
|
524
671
|
key: suggestion,
|
|
@@ -532,7 +679,7 @@ function ChatWindow({
|
|
|
532
679
|
suggestion
|
|
533
680
|
)
|
|
534
681
|
)))
|
|
535
|
-
) : messages.map((msg, index) => /* @__PURE__ */
|
|
682
|
+
) : messages.map((msg, index) => /* @__PURE__ */ import_react7.default.createElement(
|
|
536
683
|
MessageBubble,
|
|
537
684
|
{
|
|
538
685
|
key: msg.id,
|
|
@@ -542,7 +689,7 @@ function ChatWindow({
|
|
|
542
689
|
primaryColor: ui.primaryColor,
|
|
543
690
|
accentColor: ui.accentColor
|
|
544
691
|
}
|
|
545
|
-
)), isLoading && ((_a = messages[messages.length - 1]) == null ? void 0 : _a.role) !== "assistant" && /* @__PURE__ */
|
|
692
|
+
)), isLoading && ((_a = messages[messages.length - 1]) == null ? void 0 : _a.role) !== "assistant" && /* @__PURE__ */ import_react7.default.createElement(
|
|
546
693
|
MessageBubble,
|
|
547
694
|
{
|
|
548
695
|
message: { role: "assistant", content: "" },
|
|
@@ -550,8 +697,8 @@ function ChatWindow({
|
|
|
550
697
|
primaryColor: ui.primaryColor,
|
|
551
698
|
accentColor: ui.accentColor
|
|
552
699
|
}
|
|
553
|
-
), error && /* @__PURE__ */
|
|
554
|
-
/* @__PURE__ */
|
|
700
|
+
), error && /* @__PURE__ */ import_react7.default.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__ */ import_react7.default.createElement(import_lucide_react5.TriangleAlert, { className: "w-4 h-4 flex-shrink-0" }), /* @__PURE__ */ import_react7.default.createElement("span", null, error)), /* @__PURE__ */ import_react7.default.createElement("div", { ref: bottomRef })),
|
|
701
|
+
/* @__PURE__ */ import_react7.default.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]"}` }, /* @__PURE__ */ import_react7.default.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__ */ import_react7.default.createElement(
|
|
555
702
|
"textarea",
|
|
556
703
|
{
|
|
557
704
|
ref: inputRef,
|
|
@@ -564,7 +711,7 @@ function ChatWindow({
|
|
|
564
711
|
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",
|
|
565
712
|
style: { scrollbarWidth: "none" }
|
|
566
713
|
}
|
|
567
|
-
), /* @__PURE__ */
|
|
714
|
+
), /* @__PURE__ */ import_react7.default.createElement(
|
|
568
715
|
"button",
|
|
569
716
|
{
|
|
570
717
|
onClick: sendMessage,
|
|
@@ -575,8 +722,8 @@ function ChatWindow({
|
|
|
575
722
|
// slate-400/20 for light mode disabled
|
|
576
723
|
}
|
|
577
724
|
},
|
|
578
|
-
/* @__PURE__ */
|
|
579
|
-
)), /* @__PURE__ */
|
|
725
|
+
/* @__PURE__ */ import_react7.default.createElement(import_lucide_react5.ArrowUp, { className: "w-4 h-4 text-white" })
|
|
726
|
+
)), /* @__PURE__ */ import_react7.default.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"))
|
|
580
727
|
);
|
|
581
728
|
}
|
|
582
729
|
|
|
@@ -584,12 +731,12 @@ function ChatWindow({
|
|
|
584
731
|
var DEFAULT_DIMENSIONS = { width: 380, height: 600 };
|
|
585
732
|
function ChatWidget({ position = "bottom-right" }) {
|
|
586
733
|
const { ui } = useConfig();
|
|
587
|
-
const [isOpen, setIsOpen] = (0,
|
|
588
|
-
const [hasUnread, setHasUnread] = (0,
|
|
589
|
-
const [dimensions, setDimensions] = (0,
|
|
590
|
-
const [isResizing, setIsResizing] = (0,
|
|
591
|
-
const [isMaximized, setIsMaximized] = (0,
|
|
592
|
-
const [prevDimensions, setPrevDimensions] = (0,
|
|
734
|
+
const [isOpen, setIsOpen] = (0, import_react8.useState)(false);
|
|
735
|
+
const [hasUnread, setHasUnread] = (0, import_react8.useState)(false);
|
|
736
|
+
const [dimensions, setDimensions] = (0, import_react8.useState)(DEFAULT_DIMENSIONS);
|
|
737
|
+
const [isResizing, setIsResizing] = (0, import_react8.useState)(false);
|
|
738
|
+
const [isMaximized, setIsMaximized] = (0, import_react8.useState)(false);
|
|
739
|
+
const [prevDimensions, setPrevDimensions] = (0, import_react8.useState)(DEFAULT_DIMENSIONS);
|
|
593
740
|
if (ui.showWidget === false) return null;
|
|
594
741
|
const positionClass = position === "bottom-left" ? "bottom-6 left-6" : "bottom-6 right-6";
|
|
595
742
|
const windowPositionClass = position === "bottom-left" ? "bottom-20 left-6" : "bottom-20 right-6";
|
|
@@ -639,7 +786,7 @@ function ChatWidget({ position = "bottom-right" }) {
|
|
|
639
786
|
}
|
|
640
787
|
};
|
|
641
788
|
const isResized = dimensions.width !== DEFAULT_DIMENSIONS.width || dimensions.height !== DEFAULT_DIMENSIONS.height;
|
|
642
|
-
return /* @__PURE__ */
|
|
789
|
+
return /* @__PURE__ */ import_react8.default.createElement(import_react8.default.Fragment, null, /* @__PURE__ */ import_react8.default.createElement(
|
|
643
790
|
"div",
|
|
644
791
|
{
|
|
645
792
|
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"}`,
|
|
@@ -649,7 +796,7 @@ function ChatWidget({ position = "bottom-right" }) {
|
|
|
649
796
|
maxHeight: "calc(100vh - 6rem)"
|
|
650
797
|
}
|
|
651
798
|
},
|
|
652
|
-
/* @__PURE__ */
|
|
799
|
+
/* @__PURE__ */ import_react8.default.createElement(
|
|
653
800
|
ChatWindow,
|
|
654
801
|
{
|
|
655
802
|
className: "h-full relative z-10",
|
|
@@ -662,13 +809,13 @@ function ChatWidget({ position = "bottom-right" }) {
|
|
|
662
809
|
isMaximized
|
|
663
810
|
}
|
|
664
811
|
),
|
|
665
|
-
/* @__PURE__ */
|
|
812
|
+
/* @__PURE__ */ import_react8.default.createElement(
|
|
666
813
|
"div",
|
|
667
814
|
{
|
|
668
815
|
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"}`
|
|
669
816
|
}
|
|
670
817
|
)
|
|
671
|
-
), /* @__PURE__ */
|
|
818
|
+
), /* @__PURE__ */ import_react8.default.createElement(
|
|
672
819
|
"button",
|
|
673
820
|
{
|
|
674
821
|
onClick: isOpen ? () => setIsOpen(false) : handleOpen,
|
|
@@ -676,32 +823,32 @@ function ChatWidget({ position = "bottom-right" }) {
|
|
|
676
823
|
style: { background: `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` },
|
|
677
824
|
"aria-label": "Open chat"
|
|
678
825
|
},
|
|
679
|
-
/* @__PURE__ */
|
|
826
|
+
/* @__PURE__ */ import_react8.default.createElement(
|
|
680
827
|
"span",
|
|
681
828
|
{
|
|
682
829
|
className: "absolute inset-0 rounded-full animate-ping opacity-20",
|
|
683
830
|
style: { background: ui.primaryColor }
|
|
684
831
|
}
|
|
685
832
|
),
|
|
686
|
-
/* @__PURE__ */
|
|
833
|
+
/* @__PURE__ */ import_react8.default.createElement(
|
|
687
834
|
"span",
|
|
688
835
|
{
|
|
689
836
|
className: `transition-transform duration-300 ${isOpen ? "rotate-90 scale-90" : "rotate-0 scale-100"}`
|
|
690
837
|
},
|
|
691
|
-
isOpen ? /* @__PURE__ */
|
|
838
|
+
isOpen ? /* @__PURE__ */ import_react8.default.createElement(import_lucide_react6.X, { className: "w-6 h-6 text-white" }) : /* @__PURE__ */ import_react8.default.createElement(import_lucide_react6.MessageSquare, { className: "w-6 h-6 text-white" })
|
|
692
839
|
),
|
|
693
|
-
hasUnread && !isOpen && /* @__PURE__ */
|
|
840
|
+
hasUnread && !isOpen && /* @__PURE__ */ import_react8.default.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")
|
|
694
841
|
));
|
|
695
842
|
}
|
|
696
843
|
|
|
697
844
|
// src/components/DocumentUpload.tsx
|
|
698
|
-
var
|
|
699
|
-
var
|
|
845
|
+
var import_react9 = __toESM(require("react"));
|
|
846
|
+
var import_lucide_react7 = require("lucide-react");
|
|
700
847
|
function DocumentUpload({ namespace, onUploadComplete, className = "" }) {
|
|
701
848
|
const { ui } = useConfig();
|
|
702
|
-
const [fileStates, setFileStates] = (0,
|
|
703
|
-
const [isDragging, setIsDragging] = (0,
|
|
704
|
-
const fileInputRef = (0,
|
|
849
|
+
const [fileStates, setFileStates] = (0, import_react9.useState)([]);
|
|
850
|
+
const [isDragging, setIsDragging] = (0, import_react9.useState)(false);
|
|
851
|
+
const fileInputRef = (0, import_react9.useRef)(null);
|
|
705
852
|
const addFiles = (files) => {
|
|
706
853
|
const newStates = files.map((file) => ({ file, status: "idle" }));
|
|
707
854
|
setFileStates((prev) => [...prev, ...newStates]);
|
|
@@ -751,7 +898,7 @@ function DocumentUpload({ namespace, onUploadComplete, className = "" }) {
|
|
|
751
898
|
};
|
|
752
899
|
const isUploading = fileStates.some((s) => s.status === "uploading");
|
|
753
900
|
const hasIdle = fileStates.some((s) => s.status === "idle");
|
|
754
|
-
return /* @__PURE__ */
|
|
901
|
+
return /* @__PURE__ */ import_react9.default.createElement(
|
|
755
902
|
"div",
|
|
756
903
|
{
|
|
757
904
|
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}`,
|
|
@@ -759,14 +906,14 @@ function DocumentUpload({ namespace, onUploadComplete, className = "" }) {
|
|
|
759
906
|
onDragLeave,
|
|
760
907
|
onDrop
|
|
761
908
|
},
|
|
762
|
-
/* @__PURE__ */
|
|
909
|
+
/* @__PURE__ */ import_react9.default.createElement("div", { className: "flex flex-col items-center justify-center text-center" }, /* @__PURE__ */ import_react9.default.createElement(
|
|
763
910
|
"div",
|
|
764
911
|
{
|
|
765
912
|
className: "w-12 h-12 rounded-full flex items-center justify-center mb-4 shadow-sm",
|
|
766
913
|
style: { background: `linear-gradient(135deg, ${ui.primaryColor}20, ${ui.accentColor}20)` }
|
|
767
914
|
},
|
|
768
|
-
/* @__PURE__ */
|
|
769
|
-
), /* @__PURE__ */
|
|
915
|
+
/* @__PURE__ */ import_react9.default.createElement(import_lucide_react7.Upload, { className: "w-6 h-6", style: { color: ui.primaryColor } })
|
|
916
|
+
), /* @__PURE__ */ import_react9.default.createElement("h3", { className: "text-slate-900 dark:text-white font-semibold mb-1" }, "Upload Documents"), /* @__PURE__ */ import_react9.default.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__ */ import_react9.default.createElement(
|
|
770
917
|
"button",
|
|
771
918
|
{
|
|
772
919
|
onClick: () => {
|
|
@@ -782,7 +929,7 @@ function DocumentUpload({ namespace, onUploadComplete, className = "" }) {
|
|
|
782
929
|
}
|
|
783
930
|
},
|
|
784
931
|
"Select Files"
|
|
785
|
-
), /* @__PURE__ */
|
|
932
|
+
), /* @__PURE__ */ import_react9.default.createElement(
|
|
786
933
|
"input",
|
|
787
934
|
{
|
|
788
935
|
ref: fileInputRef,
|
|
@@ -793,22 +940,22 @@ function DocumentUpload({ namespace, onUploadComplete, className = "" }) {
|
|
|
793
940
|
accept: ".pdf,.docx,.txt,.md,.json,.csv"
|
|
794
941
|
}
|
|
795
942
|
)),
|
|
796
|
-
fileStates.length > 0 && /* @__PURE__ */
|
|
943
|
+
fileStates.length > 0 && /* @__PURE__ */ import_react9.default.createElement("div", { className: "mt-8 space-y-3" }, fileStates.map((state, i) => /* @__PURE__ */ import_react9.default.createElement(
|
|
797
944
|
"div",
|
|
798
945
|
{
|
|
799
946
|
key: i,
|
|
800
947
|
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"
|
|
801
948
|
},
|
|
802
|
-
/* @__PURE__ */
|
|
803
|
-
/* @__PURE__ */
|
|
949
|
+
/* @__PURE__ */ import_react9.default.createElement("div", { className: "flex items-center gap-3 overflow-hidden" }, /* @__PURE__ */ import_react9.default.createElement("div", { className: "w-8 h-8 rounded-lg bg-white dark:bg-white/10 flex items-center justify-center shadow-sm" }, /* @__PURE__ */ import_react9.default.createElement(import_lucide_react7.File, { className: "w-4 h-4 text-slate-400" })), /* @__PURE__ */ import_react9.default.createElement("div", { className: "truncate" }, /* @__PURE__ */ import_react9.default.createElement("p", { className: "text-xs font-medium text-slate-700 dark:text-white/80 truncate" }, state.file.name), /* @__PURE__ */ import_react9.default.createElement("p", { className: "text-[10px] text-slate-400" }, (state.file.size / 1024).toFixed(1), " KB"))),
|
|
950
|
+
/* @__PURE__ */ import_react9.default.createElement("div", { className: "flex items-center gap-2" }, state.status === "uploading" && /* @__PURE__ */ import_react9.default.createElement(import_lucide_react7.Loader2, { className: "w-4 h-4 text-slate-400 animate-spin" }), state.status === "success" && /* @__PURE__ */ import_react9.default.createElement(import_lucide_react7.CheckCircle, { className: "w-4 h-4 text-emerald-500" }), state.status === "error" && /* @__PURE__ */ import_react9.default.createElement("div", { title: state.error }, /* @__PURE__ */ import_react9.default.createElement(import_lucide_react7.AlertCircle, { className: "w-4 h-4 text-rose-500" })), state.status !== "uploading" && /* @__PURE__ */ import_react9.default.createElement(
|
|
804
951
|
"button",
|
|
805
952
|
{
|
|
806
953
|
onClick: () => removeFile(i),
|
|
807
954
|
className: "p-1 rounded-md hover:bg-slate-200 dark:hover:bg-white/10 transition-colors"
|
|
808
955
|
},
|
|
809
|
-
/* @__PURE__ */
|
|
956
|
+
/* @__PURE__ */ import_react9.default.createElement(import_lucide_react7.X, { className: "w-3.5 h-3.5 text-slate-400" })
|
|
810
957
|
))
|
|
811
|
-
)), hasIdle && !isUploading && /* @__PURE__ */
|
|
958
|
+
)), hasIdle && !isUploading && /* @__PURE__ */ import_react9.default.createElement(
|
|
812
959
|
"button",
|
|
813
960
|
{
|
|
814
961
|
onClick: uploadFiles,
|