tigerbase-chatbot 1.0.2 → 1.0.4

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.
Files changed (2) hide show
  1. package/dist/ChatbotPopup.js +101 -50
  2. package/package.json +55 -55
@@ -14,31 +14,18 @@ const ChatbotPopup = () => {
14
14
  const cfg = getConfig();
15
15
  const MCP_URL = cfg.secretKey || "";
16
16
  const genAIKey = cfg.aiKey;
17
- const defaultLang = cfg.defaultLang || "ar";
18
- if (!genAIKey) {
19
- toast.error(defaultLang === "ar"
20
- ? "مفتاح Google GenAI غير موجود"
21
- : "Google GenAI key not set");
22
- throw new Error("Google GenAI key not set");
23
- }
24
- const genAI = new GoogleGenerativeAI(genAIKey);
25
- const systemInstruction = `You are a helpful assistant for product management. Always respond in ${defaultLang === "ar" ? "Arabic" : "English"}. ${cfg.customPrompt || ""}
26
- When user asks for product information with an ID, use the get-product-info tool and pass the ID in the arguments.
27
- When user asks to list products, use the list-products tool.
28
- When user asks to add a product, use the add-product tool with name, price, and description.`;
29
- const model = genAI.getGenerativeModel({
30
- model: "gemini-2.5-flash",
31
- systemInstruction,
32
- });
33
17
  const [isOpen, setIsOpen] = useState(false);
34
18
  const [isExpanded, setIsExpanded] = useState(false);
19
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
20
+ const [remoteConfig, setRemoteConfig] = useState(null);
21
+ const effectiveLang = remoteConfig?.language || cfg.defaultLang || "ar";
35
22
  const [messages, setMessages] = useState([
36
23
  {
37
24
  role: "model",
38
- content: defaultLang === "ar"
25
+ content: effectiveLang === "ar"
39
26
  ? "أهلاً وسهلاً! أنا هنا لمساعدتك في إدارة المنتجات. كيف يمكنني مساعدتك؟"
40
27
  : "Hello! I'm here to help with product management. How can I assist you?",
41
- timestamp: new Date().toLocaleTimeString(defaultLang === "ar" ? "ar-EG" : "en-US", {
28
+ timestamp: new Date().toLocaleTimeString(effectiveLang === "ar" ? "ar-EG" : "en-US", {
42
29
  hour: "2-digit",
43
30
  minute: "2-digit",
44
31
  hour12: true,
@@ -48,6 +35,66 @@ const ChatbotPopup = () => {
48
35
  const [input, setInput] = useState("");
49
36
  const [loading, setLoading] = useState(false);
50
37
  const messagesEndRef = useRef(null);
38
+ if (!genAIKey) {
39
+ toast.error(effectiveLang === "ar"
40
+ ? "مفتاح Google GenAI غير موجود"
41
+ : "Google GenAI key not set");
42
+ throw new Error("Google GenAI key not set");
43
+ }
44
+ const genAI = new GoogleGenerativeAI(genAIKey);
45
+ const baseSystemInstruction = `You are a helpful assistant. Always respond in ${effectiveLang === "ar" ? "Arabic" : "English"}.
46
+ When user asks for product information with an ID, use the get-product-info tool and pass the ID in the arguments.
47
+ When user asks to list products, use the list-products tool.
48
+ When user asks to add a product, use the add-product tool with name, price, and description.
49
+
50
+ IMPORTANT: If specific information (regulations, data, etc.) is provided in the context below, prioritize it over your general knowledge.`;
51
+ const systemInstruction = remoteConfig?.systemInstruction
52
+ ? `${remoteConfig.systemInstruction}\n\n${baseSystemInstruction}`
53
+ : baseSystemInstruction;
54
+ const model = genAI.getGenerativeModel({
55
+ model: "gemini-2.5-flash",
56
+ systemInstruction,
57
+ });
58
+ // Fetch remote config
59
+ useEffect(() => {
60
+ const fetchConfig = async () => {
61
+ if (!MCP_URL || !cfg.apiKey)
62
+ return;
63
+ try {
64
+ // Derive API URL from MCP URL (remove /mcp suffix if present)
65
+ const baseUrl = MCP_URL.replace(/\/mcp\/?$/, "");
66
+ const response = await fetch(`${baseUrl}/chatbots/public/config`, {
67
+ headers: {
68
+ "x-api-key": cfg.apiKey,
69
+ },
70
+ });
71
+ if (response.ok) {
72
+ const data = await response.json();
73
+ setRemoteConfig(data);
74
+ // Update initial message if no user interaction yet
75
+ if (messages.length === 1 && messages[0].role === "model") {
76
+ const initialMsg = data.initialMessage ||
77
+ (data.language === "ar"
78
+ ? "أهلاً وسهلاً! كيف يمكنني مساعدتك؟"
79
+ : "Hello! How can I help you?");
80
+ setMessages([
81
+ {
82
+ role: "model",
83
+ content: initialMsg,
84
+ timestamp: new Date().toLocaleTimeString(data.language === "ar" ? "ar-EG" : "en-US", { hour: "2-digit", minute: "2-digit", hour12: true }),
85
+ },
86
+ ]);
87
+ }
88
+ }
89
+ }
90
+ catch (error) {
91
+ console.error("Failed to fetch chatbot config:", error);
92
+ }
93
+ };
94
+ if (isOpen) {
95
+ fetchConfig();
96
+ }
97
+ }, [MCP_URL, cfg.apiKey, isOpen]);
51
98
  // Auto delete chats
52
99
  useEffect(() => {
53
100
  if (cfg.autoDeleteChats) {
@@ -55,23 +102,23 @@ const ChatbotPopup = () => {
55
102
  setMessages([
56
103
  {
57
104
  role: "model",
58
- content: defaultLang === "ar"
105
+ content: effectiveLang === "ar"
59
106
  ? "أهلاً وسهلاً! أنا هنا لمساعدتك في إدارة المنتجات. كيف يمكنني مساعدتك؟"
60
107
  : "Hello! I'm here to help with product management. How can I assist you?",
61
- timestamp: new Date().toLocaleTimeString(defaultLang === "ar" ? "ar-EG" : "en-US", {
108
+ timestamp: new Date().toLocaleTimeString(effectiveLang === "ar" ? "ar-EG" : "en-US", {
62
109
  hour: "2-digit",
63
110
  minute: "2-digit",
64
111
  hour12: true,
65
112
  }),
66
113
  },
67
114
  ]);
68
- toast.info(defaultLang === "ar"
115
+ toast.info(effectiveLang === "ar"
69
116
  ? "تم مسح المحادثة تلقائيًا"
70
117
  : "Chat cleared automatically");
71
118
  }, cfg.autoDeleteChats * 60 * 1000);
72
119
  return () => clearTimeout(timer);
73
120
  }
74
- }, [messages, cfg.autoDeleteChats, defaultLang]);
121
+ }, [messages, cfg.autoDeleteChats, effectiveLang]);
75
122
  const scrollToBottom = () => {
76
123
  messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
77
124
  };
@@ -79,7 +126,7 @@ const ChatbotPopup = () => {
79
126
  scrollToBottom();
80
127
  }, [messages]);
81
128
  const formatTimestamp = () => {
82
- return new Date().toLocaleTimeString(defaultLang === "ar" ? "ar-EG" : "en-US", {
129
+ return new Date().toLocaleTimeString(effectiveLang === "ar" ? "ar-EG" : "en-US", {
83
130
  hour: "2-digit",
84
131
  minute: "2-digit",
85
132
  hour12: true,
@@ -87,7 +134,7 @@ const ChatbotPopup = () => {
87
134
  };
88
135
  const handleMcpToolCall = async (toolName, args, retries = 2) => {
89
136
  if (!cfg.validatedTools.includes(toolName)) {
90
- throw new Error(defaultLang === "ar"
137
+ throw new Error(effectiveLang === "ar"
91
138
  ? `الأداة ${toolName} غير متاحة لهذا السيريال`
92
139
  : `Tool ${toolName} not available for this serial`);
93
140
  }
@@ -124,7 +171,7 @@ const ChatbotPopup = () => {
124
171
  return JSON.parse(data.result.content[0].text);
125
172
  }
126
173
  return (data.result ||
127
- (defaultLang === "ar"
174
+ (effectiveLang === "ar"
128
175
  ? "تم تنفيذ الأمر بنجاح"
129
176
  : "Command executed successfully"));
130
177
  }
@@ -133,7 +180,7 @@ const ChatbotPopup = () => {
133
180
  await new Promise((resolve) => setTimeout(resolve, 1000 * (i + 1)));
134
181
  continue;
135
182
  }
136
- throw new Error(defaultLang === "ar"
183
+ throw new Error(effectiveLang === "ar"
137
184
  ? `فشل استدعاء ${toolName} بعد ${retries + 1} محاولة: ${e.message}`
138
185
  : `Failed to call ${toolName} after ${retries + 1} attempts: ${e.message}`);
139
186
  }
@@ -221,7 +268,7 @@ const ChatbotPopup = () => {
221
268
  },
222
269
  tools: toolsConfig,
223
270
  });
224
- let assistantReply = defaultLang === "ar"
271
+ let assistantReply = effectiveLang === "ar"
225
272
  ? "عذرًا، لم أفهم الطلب."
226
273
  : "Sorry, I didn't understand the request.";
227
274
  const response = await result.response;
@@ -238,13 +285,13 @@ const ChatbotPopup = () => {
238
285
  assistantReply = {
239
286
  products: Array.isArray(toolResult) ? toolResult : [toolResult],
240
287
  };
241
- toast.success(defaultLang === "ar"
288
+ toast.success(effectiveLang === "ar"
242
289
  ? "تم جلب البيانات بنجاح!"
243
290
  : "Data fetched successfully!");
244
291
  }
245
292
  catch (e) {
246
293
  assistantReply =
247
- defaultLang === "ar"
294
+ effectiveLang === "ar"
248
295
  ? `عذرًا، حدث خطأ أثناء تنفيذ الأمر: ${e.message}`
249
296
  : `Sorry, an error occurred while executing the command: ${e.message}`;
250
297
  toast.error(e.message);
@@ -258,7 +305,9 @@ const ChatbotPopup = () => {
258
305
  .join("\n");
259
306
  assistantReply =
260
307
  textParts ||
261
- (defaultLang === "ar" ? "لم أتمكن من الرد." : "Couldn't respond.");
308
+ (effectiveLang === "ar"
309
+ ? "لم أتمكن من الرد."
310
+ : "Couldn't respond.");
262
311
  }
263
312
  }
264
313
  setMessages((prev) => [
@@ -275,20 +324,22 @@ const ChatbotPopup = () => {
275
324
  const isOverloaded = errorMessage.includes("overloaded") || errorMessage.includes("503");
276
325
  const waitTime = isOverloaded ? 5000 : 1000;
277
326
  if (retryCount > 0) {
278
- toast.warn(defaultLang === "ar"
327
+ toast.warn(effectiveLang === "ar"
279
328
  ? `فشل الطلب، جاري إعادة المحاولة... (${retryCount} محاولة متبقية)`
280
329
  : `Request failed, retrying... (${retryCount} attempts left)`);
281
330
  setTimeout(() => handleSend(retryCount - 1), waitTime);
282
331
  return;
283
332
  }
284
333
  const errorMsg = errorMessage ||
285
- (defaultLang === "ar" ? "حدث خطأ غير متوقع" : "Unexpected error");
286
- toast.error(`${defaultLang === "ar" ? "خطأ" : "Error"}: ${errorMsg}`);
334
+ (effectiveLang === "ar" ? "حدث خطأ غير متوقع" : "Unexpected error");
335
+ toast.error(`${effectiveLang === "ar" ? "خطأ" : "Error"}: ${errorMsg}`);
287
336
  setMessages((prev) => [
288
337
  ...prev,
289
338
  {
290
339
  role: "model",
291
- content: `${defaultLang === "ar" ? "عذرًا، حدث خطأ" : "Sorry, an error occurred"}: ${errorMsg}`,
340
+ content: `${effectiveLang === "ar"
341
+ ? "عذرًا، حدث خطأ"
342
+ : "Sorry, an error occurred"}: ${errorMsg}`,
292
343
  timestamp: formatTimestamp(),
293
344
  },
294
345
  ]);
@@ -317,12 +368,12 @@ const ChatbotPopup = () => {
317
368
  timestamp: formatTimestamp(),
318
369
  },
319
370
  ]);
320
- toast.success(defaultLang === "ar"
371
+ toast.success(effectiveLang === "ar"
321
372
  ? "تم تحديث قائمة المنتجات!"
322
373
  : "Product list updated!");
323
374
  }
324
375
  catch (e) {
325
- toast.error(defaultLang === "ar"
376
+ toast.error(effectiveLang === "ar"
326
377
  ? `فشل تحديث المنتجات: ${e.message}`
327
378
  : `Failed to update products: ${e.message}`);
328
379
  }
@@ -334,24 +385,24 @@ const ChatbotPopup = () => {
334
385
  setMessages([
335
386
  {
336
387
  role: "model",
337
- content: defaultLang === "ar"
388
+ content: effectiveLang === "ar"
338
389
  ? "أهلاً وسهلاً! أنا هنا لمساعدتك في إدارة المنتجات. كيف يمكنني مساعدتك؟"
339
390
  : "Hello! I'm here to help with product management. How can I assist you?",
340
391
  timestamp: formatTimestamp(),
341
392
  },
342
393
  ]);
343
394
  setInput("");
344
- toast.info(defaultLang === "ar" ? "تم مسح المحادثة" : "Chat cleared");
395
+ toast.info(effectiveLang === "ar" ? "تم مسح المحادثة" : "Chat cleared");
345
396
  };
346
397
  const showCart = () => {
347
398
  const cart = JSON.parse(localStorage.getItem("cart") || "[]");
348
399
  if (cart.length === 0) {
349
- toast.warn(defaultLang === "ar" ? "السلة فاضية!" : "Cart is empty!");
400
+ toast.warn(effectiveLang === "ar" ? "السلة فاضية!" : "Cart is empty!");
350
401
  setMessages((prev) => [
351
402
  ...prev,
352
403
  {
353
404
  role: "model",
354
- content: defaultLang === "ar"
405
+ content: effectiveLang === "ar"
355
406
  ? "السلة فاضية حالياً! يمكنك إضافة المنتجات من قائمة المنتجات."
356
407
  : "The cart is empty! You can add products from the product list.",
357
408
  timestamp: formatTimestamp(),
@@ -367,38 +418,38 @@ const ChatbotPopup = () => {
367
418
  timestamp: formatTimestamp(),
368
419
  },
369
420
  ]);
370
- toast.info(defaultLang === "ar"
421
+ toast.info(effectiveLang === "ar"
371
422
  ? `عرض السلة (${cart.length} منتج)`
372
423
  : `Showing cart (${cart.length} items)`);
373
424
  };
374
- const ProductCard = ({ product }) => (_jsx(Card, { className: "mb-3 border border-gray-200 shadow-sm hover:shadow-md transition-shadow", children: _jsx(CardContent, { className: "p-4", children: _jsxs("div", { className: "flex justify-between items-start", children: [_jsxs("div", { className: "flex-1", children: [_jsx("h4", { className: "font-semibold text-gray-800 text-sm", children: product.name }), _jsx("p", { className: "text-xs text-gray-600 mt-1 line-clamp-2", children: product.description }), _jsxs("div", { className: "flex items-center gap-2 mt-2", children: [_jsxs(Badge, { variant: "secondary", className: "text-xs", children: [product.price, " ", defaultLang === "ar" ? "جنيه" : "EGP"] }), _jsxs(Badge, { variant: "outline", className: "text-xs", children: ["ID: ", product.id] })] })] }), _jsx(Button, { size: "sm", variant: "outline", className: "text-xs h-8 px-3", onClick: () => {
425
+ const ProductCard = ({ product }) => (_jsx(Card, { className: "mb-3 border border-gray-200 shadow-sm hover:shadow-md transition-shadow", children: _jsx(CardContent, { className: "p-4", children: _jsxs("div", { className: "flex justify-between items-start", children: [_jsxs("div", { className: "flex-1", children: [_jsx("h4", { className: "font-semibold text-gray-800 text-sm", children: product.name }), _jsx("p", { className: "text-xs text-gray-600 mt-1 line-clamp-2", children: product.description }), _jsxs("div", { className: "flex items-center gap-2 mt-2", children: [_jsxs(Badge, { variant: "secondary", className: "text-xs", children: [product.price, " ", effectiveLang === "ar" ? "جنيه" : "EGP"] }), _jsxs(Badge, { variant: "outline", className: "text-xs", children: ["ID: ", product.id] })] })] }), _jsx(Button, { size: "sm", variant: "outline", className: "text-xs h-8 px-3", onClick: () => {
375
426
  const cart = JSON.parse(localStorage.getItem("cart") || "[]");
376
427
  cart.push(product);
377
428
  localStorage.setItem("cart", JSON.stringify(cart));
378
- toast.success(defaultLang === "ar"
429
+ toast.success(effectiveLang === "ar"
379
430
  ? "تم إضافة المنتج للسلة!"
380
431
  : "Product added to cart!");
381
- }, children: defaultLang === "ar" ? "إضافة للسلة" : "Add to Cart" })] }) }) }));
432
+ }, children: effectiveLang === "ar" ? "إضافة للسلة" : "Add to Cart" })] }) }) }));
382
433
  const MessageBubble = ({ message }) => {
383
434
  const isUser = message.role === "user";
384
435
  return (_jsx("div", { className: `flex mb-4 ${isUser ? "justify-end" : "justify-start"}`, children: _jsxs("div", { className: `flex max-w-[85%] ${isUser ? "flex-row-reverse" : "flex-row"}`, children: [_jsx("div", { className: `w-8 h-8 rounded-full flex items-center justify-center shrink-0 ${isUser ? "bg-blue-500 ml-3" : "bg-gray-200 mr-3"}`, children: isUser ? (_jsx(User, { className: "w-4 h-4 text-white" })) : (_jsx(Bot, { className: "w-4 h-4 text-gray-600" })) }), _jsxs("div", { className: `p-3 rounded-2xl ${isUser
385
436
  ? "bg-blue-500 text-white rounded-br-md"
386
- : "bg-gray-100 text-gray-800 rounded-bl-md"}`, children: [typeof message.content === "string" ? (_jsx("p", { className: "text-sm leading-relaxed", children: message.content })) : message.content.products ? (_jsxs("div", { children: [_jsx("p", { className: "text-sm mb-3 font-medium", children: defaultLang === "ar"
437
+ : "bg-gray-100 text-gray-800 rounded-bl-md"}`, children: [typeof message.content === "string" ? (_jsx("p", { className: "text-sm leading-relaxed", children: message.content })) : message.content.products ? (_jsxs("div", { children: [_jsx("p", { className: "text-sm mb-3 font-medium", children: effectiveLang === "ar"
387
438
  ? "المنتجات المتاحة:"
388
439
  : "Available products:" }), _jsx("div", { className: "space-y-2", children: message.content.products.map((product, index) => (_jsx(ProductCard, { product: product }, product.id || index))) })] })) : null, _jsx("p", { className: `text-xs mt-2 ${isUser ? "text-blue-100" : "text-gray-500"}`, children: message.timestamp })] })] }) }));
389
440
  };
390
441
  if (!isOpen) {
391
- return (_jsx("div", { className: "fixed bottom-6 right-6 z-50", children: _jsx(Button, { onClick: () => setIsOpen(true), className: "w-16 h-16 rounded-full shadow-xl bg-black hover:bg-gray-800 transition-all duration-300 hover:scale-105 flex items-center justify-center group cursor-pointer", children: _jsxs("div", { className: "flex items-center", children: [_jsx(Sparkles, { className: "text-white" }), _jsx("span", { className: "text-white font-medium text-sm opacity-0 group-hover:opacity-100 transition-opacity absolute -left-20 bg-black px-3 py-1 rounded-full whitespace-nowrap", children: defaultLang === "ar" ? "اسأل الذكاء الاصطناعي" : "Ask AI" })] }) }) }));
442
+ return (_jsx("div", { className: "fixed bottom-6 right-6 z-50", children: _jsx(Button, { onClick: () => setIsOpen(true), className: "w-16 h-16 rounded-full shadow-xl bg-black hover:bg-gray-800 transition-all duration-300 hover:scale-105 flex items-center justify-center group cursor-pointer", children: _jsxs("div", { className: "flex items-center", children: [_jsx(Sparkles, { className: "text-white" }), _jsx("span", { className: "text-white font-medium text-sm opacity-0 group-hover:opacity-100 transition-opacity absolute -left-20 bg-black px-3 py-1 rounded-full whitespace-nowrap", children: effectiveLang === "ar" ? "اسأل الذكاء الاصطناعي" : "Ask AI" })] }) }) }));
392
443
  }
393
444
  const chatClasses = isExpanded
394
445
  ? "fixed inset-0 z-50 animate-in slide-in-from-right-4 duration-300"
395
446
  : "fixed bottom-0 right-0 w-96 h-screen z-50 animate-in slide-in-right-bottom-4 slide-in-from-right-4 duration-300";
396
- return (_jsx("div", { className: chatClasses, children: _jsxs(Card, { className: "h-full shadow-2xl border-0 overflow-hidden bg-white flex flex-col", children: [_jsx(CardHeader, { className: "bg-white border-b p-4 flex-shrink-0", children: _jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center space-x-3 rtl:space-x-reverse", children: [_jsx("div", { className: "w-8 h-8 rounded-full bg-red-500 flex items-center justify-center text-white font-bold text-sm", children: "tb" }), _jsxs("div", { children: [_jsx("h3", { className: "font-semibold text-gray-800 text-sm", children: defaultLang === "ar" ? "اسأل Tigerbase" : "Ask Tigerbase" }), _jsx("p", { className: "text-xs text-gray-500", children: defaultLang === "ar"
447
+ return (_jsx("div", { className: chatClasses, children: _jsxs(Card, { className: "h-full shadow-2xl border-0 overflow-hidden bg-white flex flex-col", children: [_jsx(CardHeader, { className: "bg-white border-b p-4 flex-shrink-0", children: _jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center space-x-3 rtl:space-x-reverse", children: [_jsx("div", { className: "w-8 h-8 rounded-full bg-red-500 flex items-center justify-center text-white font-bold text-sm", children: "tb" }), _jsxs("div", { children: [_jsx("h3", { className: "font-semibold text-gray-800 text-sm", children: effectiveLang === "ar" ? "اسأل Tigerbase" : "Ask Tigerbase" }), _jsx("p", { className: "text-xs text-gray-500", children: effectiveLang === "ar"
397
448
  ? "متاح الآن للمساعدة"
398
- : "Available now to assist" })] })] }), _jsxs("div", { className: "flex items-center space-x-2 rtl:space-x-reverse", children: [_jsx(Button, { variant: "ghost", size: "icon", onClick: () => setIsExpanded(!isExpanded), className: "text-gray-500 hover:bg-gray-100 w-8 h-8", children: isExpanded ? (_jsx(Minimize2, { className: "w-4 h-4" })) : (_jsx(Maximize2, { className: "w-4 h-4" })) }), _jsx(Button, { variant: "ghost", size: "icon", onClick: () => setIsOpen(false), className: "text-gray-500 hover:bg-gray-100 w-8 h-8", children: _jsx(X, { className: "w-4 h-4" }) })] })] }) }), _jsxs(CardContent, { className: "flex-1 p-0 flex flex-col overflow-hidden", children: [_jsx("div", { className: "flex-1 overflow-hidden", children: _jsx(ScrollArea, { className: "h-full", children: _jsxs("div", { className: "p-4", children: [messages.length === 1 && (_jsxs("div", { className: "text-center py-12", children: [_jsx("div", { className: "w-16 h-16 mx-auto mb-4 bg-gradient-to-br from-purple-500 to-blue-600 rounded-full flex items-center justify-center", children: _jsx(Sparkles, { className: "w-8 h-8 text-white" }) }), _jsx("h3", { className: "text-lg font-semibold text-gray-800 mb-2", children: defaultLang === "ar"
449
+ : "Available now to assist" })] })] }), _jsxs("div", { className: "flex items-center space-x-2 rtl:space-x-reverse", children: [_jsx(Button, { variant: "ghost", size: "icon", onClick: () => setIsExpanded(!isExpanded), className: "text-gray-500 hover:bg-gray-100 w-8 h-8", children: isExpanded ? (_jsx(Minimize2, { className: "w-4 h-4" })) : (_jsx(Maximize2, { className: "w-4 h-4" })) }), _jsx(Button, { variant: "ghost", size: "icon", onClick: () => setIsOpen(false), className: "text-gray-500 hover:bg-gray-100 w-8 h-8", children: _jsx(X, { className: "w-4 h-4" }) })] })] }) }), _jsxs(CardContent, { className: "flex-1 p-0 flex flex-col overflow-hidden", children: [_jsx("div", { className: "flex-1 overflow-hidden", children: _jsx(ScrollArea, { className: "h-full", children: _jsxs("div", { className: "p-4", children: [messages.length === 1 && (_jsxs("div", { className: "text-center py-12", children: [_jsx("div", { className: "w-16 h-16 mx-auto mb-4 bg-gradient-to-br from-purple-500 to-blue-600 rounded-full flex items-center justify-center", children: _jsx(Sparkles, { className: "w-8 h-8 text-white" }) }), _jsx("h3", { className: "text-lg font-semibold text-gray-800 mb-2", children: effectiveLang === "ar"
399
450
  ? "اسأل أي شيء عن Tigerbase"
400
- : "Ask anything about Tigerbase" }), _jsx("p", { className: "text-sm text-gray-500 max-w-xs mx-auto", children: defaultLang === "ar"
451
+ : "Ask anything about Tigerbase" }), _jsx("p", { className: "text-sm text-gray-500 max-w-xs mx-auto", children: effectiveLang === "ar"
401
452
  ? "يستخدم Tigerbase أحدث البيانات في التوثيق للإجابة على أسئلتك."
402
- : "Tigerbase uses the latest data in the documentation to answer your questions." })] })), messages.map((message, index) => (_jsx(MessageBubble, { message: message }, index))), loading && (_jsx("div", { className: "flex justify-start mb-4", children: _jsxs("div", { className: "flex", children: [_jsx("div", { className: "w-8 h-8 rounded-full bg-gray-200 mr-3 flex items-center justify-center", children: _jsx(Bot, { className: "w-4 h-4 text-gray-600" }) }), _jsx("div", { className: "bg-gray-100 p-3 rounded-2xl rounded-bl-md", children: _jsxs("div", { className: "flex space-x-1", children: [_jsx("div", { className: "w-2 h-2 bg-gray-400 rounded-full animate-bounce" }), _jsx("div", { className: "w-2 h-2 bg-gray-400 rounded-full animate-bounce", style: { animationDelay: "0.1s" } }), _jsx("div", { className: "w-2 h-2 bg-gray-400 rounded-full animate-bounce", style: { animationDelay: "0.2s" } })] }) })] }) })), _jsx("div", { ref: messagesEndRef })] }) }) }), messages.length > 1 && (_jsx("div", { className: "border-t bg-gray-50 p-3 flex-shrink-0", children: _jsxs("div", { className: "flex space-x-2 rtl:space-x-reverse mb-0 flex-wrap gap-2", children: [_jsxs(Button, { variant: "outline", size: "sm", onClick: refreshProducts, className: "text-xs h-8 px-3 flex items-center gap-1", disabled: loading, children: [_jsx(RefreshCw, { className: "w-3 h-3" }), defaultLang === "ar" ? "المنتجات" : "Products"] }), _jsxs(Button, { variant: "outline", size: "sm", onClick: showCart, className: "text-xs h-8 px-3 flex items-center gap-1", children: [_jsx(ShoppingCart, { className: "w-3 h-3" }), defaultLang === "ar" ? "السلة" : "Cart"] }), _jsxs(Button, { variant: "outline", size: "sm", onClick: clearChat, className: "text-xs h-8 px-3 flex items-center gap-1", children: [_jsx(Trash2, { className: "w-3 h-3" }), defaultLang === "ar" ? "مسح" : "Clear"] })] }) })), _jsxs("div", { className: "border-t bg-white p-4 flex-shrink-0", children: [_jsxs("div", { className: "flex space-x-2 rtl:space-x-reverse items-center", children: [_jsx(Input, { value: input, onChange: (e) => setInput(e.target.value), onKeyPress: handleKeyPress, placeholder: defaultLang === "ar" ? "اسأل أي شيء" : "Ask anything", className: "flex-1 border-0 bg-gray-100 focus:bg-white transition-colors text-right placeholder:text-gray-500 text-sm", disabled: loading }), _jsx(Button, { onClick: () => handleSend(1), disabled: loading || !input.trim(), size: "icon", className: "bg-gray-300 hover:bg-gray-400 text-gray-600 w-8 h-8 rounded-full shrink-0", children: _jsx(Send, { className: "w-4 h-4" }) })] }), _jsx("div", { className: "mt-3 text-center", children: _jsxs("p", { className: "text-xs text-gray-500", children: [defaultLang === "ar" ? "مدعوم بواسطة" : "Powered by", " ", _jsx("span", { className: "text-red-500 font-semibold", children: "Tigerbase" })] }) })] })] })] }) }));
453
+ : "Tigerbase uses the latest data in the documentation to answer your questions." })] })), messages.map((message, index) => (_jsx(MessageBubble, { message: message }, index))), loading && (_jsx("div", { className: "flex justify-start mb-4", children: _jsxs("div", { className: "flex", children: [_jsx("div", { className: "w-8 h-8 rounded-full bg-gray-200 mr-3 flex items-center justify-center", children: _jsx(Bot, { className: "w-4 h-4 text-gray-600" }) }), _jsx("div", { className: "bg-gray-100 p-3 rounded-2xl rounded-bl-md", children: _jsxs("div", { className: "flex space-x-1", children: [_jsx("div", { className: "w-2 h-2 bg-gray-400 rounded-full animate-bounce" }), _jsx("div", { className: "w-2 h-2 bg-gray-400 rounded-full animate-bounce", style: { animationDelay: "0.1s" } }), _jsx("div", { className: "w-2 h-2 bg-gray-400 rounded-full animate-bounce", style: { animationDelay: "0.2s" } })] }) })] }) })), _jsx("div", { ref: messagesEndRef })] }) }) }), messages.length > 1 && (_jsx("div", { className: "border-t bg-gray-50 p-3 flex-shrink-0", children: _jsxs("div", { className: "flex space-x-2 rtl:space-x-reverse mb-0 flex-wrap gap-2", children: [_jsxs(Button, { variant: "outline", size: "sm", onClick: refreshProducts, className: "text-xs h-8 px-3 flex items-center gap-1", disabled: loading, children: [_jsx(RefreshCw, { className: "w-3 h-3" }), effectiveLang === "ar" ? "المنتجات" : "Products"] }), _jsxs(Button, { variant: "outline", size: "sm", onClick: showCart, className: "text-xs h-8 px-3 flex items-center gap-1", children: [_jsx(ShoppingCart, { className: "w-3 h-3" }), effectiveLang === "ar" ? "السلة" : "Cart"] }), _jsxs(Button, { variant: "outline", size: "sm", onClick: clearChat, className: "text-xs h-8 px-3 flex items-center gap-1", children: [_jsx(Trash2, { className: "w-3 h-3" }), effectiveLang === "ar" ? "مسح" : "Clear"] })] }) })), _jsxs("div", { className: "border-t bg-white p-4 flex-shrink-0", children: [_jsxs("div", { className: "flex space-x-2 rtl:space-x-reverse items-center", children: [_jsx(Input, { value: input, onChange: (e) => setInput(e.target.value), onKeyPress: handleKeyPress, placeholder: effectiveLang === "ar" ? "اسأل أي شيء" : "Ask anything", className: "flex-1 border-0 bg-gray-100 focus:bg-white transition-colors text-right placeholder:text-gray-500 text-sm", disabled: loading }), _jsx(Button, { onClick: () => handleSend(1), disabled: loading || !input.trim(), size: "icon", className: "bg-gray-300 hover:bg-gray-400 text-gray-600 w-8 h-8 rounded-full shrink-0", children: _jsx(Send, { className: "w-4 h-4" }) })] }), _jsx("div", { className: "mt-3 text-center", children: _jsxs("p", { className: "text-xs text-gray-500", children: [effectiveLang === "ar" ? "مدعوم بواسطة" : "Powered by", " ", _jsx("span", { className: "text-red-500 font-semibold", children: "Tigerbase" })] }) })] })] })] }) }));
403
454
  };
404
455
  export default ChatbotPopup;
package/package.json CHANGED
@@ -1,55 +1,55 @@
1
- {
2
- "name": "tigerbase-chatbot",
3
- "version": "1.0.2",
4
- "description": "TigerBase Chatbot Client - AI-powered chatbot for product management",
5
- "main": "dist/index.js",
6
- "module": "dist/index.js",
7
- "types": "dist/index.d.ts",
8
- "scripts": {
9
- "build": "tsc",
10
- "prepublishOnly": "npm run build"
11
- },
12
- "dependencies": {
13
- "@google/generative-ai": "^0.21.0",
14
- "@radix-ui/react-dialog": "^1.1.15",
15
- "@radix-ui/react-scroll-area": "^1.0.5",
16
- "@radix-ui/react-slot": "^1.2.3",
17
- "class-variance-authority": "^0.7.1",
18
- "clsx": "^2.0.0",
19
- "lucide-react": "^0.441.0",
20
- "react-toastify": "^10.0.6",
21
- "tailwind-merge": "^2.3.0"
22
- },
23
- "devDependencies": {
24
- "@types/node": "^20.14.2",
25
- "@types/react": "^18.3.3",
26
- "@types/react-dom": "^18.3.0",
27
- "typescript": "^5.5.4"
28
- },
29
- "peerDependencies": {
30
- "react": "^18.2.0 || ^19.0.0",
31
- "react-dom": "^18.2.0 || ^19.0.0"
32
- },
33
- "author": "SolomDev00",
34
- "license": "MIT",
35
- "repository": {
36
- "type": "git",
37
- "url": "git+https://github.com/SolomDev00/Tigerbase.git"
38
- },
39
- "homepage": "https://tigerbase.cloud",
40
- "files": [
41
- "dist"
42
- ],
43
- "keywords": [
44
- "tigerbase",
45
- "chatbot",
46
- "react",
47
- "ai",
48
- "gemini",
49
- "product-management",
50
- "mcp"
51
- ],
52
- "publishConfig": {
53
- "access": "public"
54
- }
55
- }
1
+ {
2
+ "name": "tigerbase-chatbot",
3
+ "version": "1.0.4",
4
+ "description": "TigerBase Chatbot Client - AI-powered chatbot for product management",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "scripts": {
9
+ "build": "tsc",
10
+ "prepublishOnly": "npm run build"
11
+ },
12
+ "dependencies": {
13
+ "@google/generative-ai": "^0.21.0",
14
+ "@radix-ui/react-dialog": "^1.1.15",
15
+ "@radix-ui/react-scroll-area": "^1.0.5",
16
+ "@radix-ui/react-slot": "^1.2.3",
17
+ "class-variance-authority": "^0.7.1",
18
+ "clsx": "^2.0.0",
19
+ "lucide-react": "^0.441.0",
20
+ "react-toastify": "^10.0.6",
21
+ "tailwind-merge": "^2.3.0"
22
+ },
23
+ "devDependencies": {
24
+ "@types/node": "^20.14.2",
25
+ "@types/react": "^18.3.3",
26
+ "@types/react-dom": "^18.3.0",
27
+ "typescript": "^5.5.4"
28
+ },
29
+ "peerDependencies": {
30
+ "react": "^18.2.0 || ^19.0.0",
31
+ "react-dom": "^18.2.0 || ^19.0.0"
32
+ },
33
+ "author": "SolomDev00",
34
+ "license": "MIT",
35
+ "repository": {
36
+ "type": "git",
37
+ "url": "git+https://github.com/SolomDev00/Tigerbase.git"
38
+ },
39
+ "homepage": "https://tigerbase.cloud",
40
+ "files": [
41
+ "dist"
42
+ ],
43
+ "keywords": [
44
+ "tigerbase",
45
+ "chatbot",
46
+ "react",
47
+ "ai",
48
+ "gemini",
49
+ "product-management",
50
+ "mcp"
51
+ ],
52
+ "publishConfig": {
53
+ "access": "public"
54
+ }
55
+ }