tigerbase-chatbot 1.0.2 → 1.0.3

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.
@@ -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,60 @@ 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 for product management. Always respond in ${effectiveLang === "ar" ? "Arabic" : "English"}. ${cfg.customPrompt || ""}
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
+ const systemInstruction = remoteConfig?.systemInstruction || baseSystemInstruction;
50
+ const model = genAI.getGenerativeModel({
51
+ model: "gemini-2.5-flash",
52
+ systemInstruction,
53
+ });
54
+ // Fetch remote config
55
+ useEffect(() => {
56
+ const fetchConfig = async () => {
57
+ if (!MCP_URL || !cfg.apiKey)
58
+ return;
59
+ try {
60
+ // Derive API URL from MCP URL (remove /mcp suffix if present)
61
+ const baseUrl = MCP_URL.replace(/\/mcp\/?$/, "");
62
+ const response = await fetch(`${baseUrl}/chatbots/public/config`, {
63
+ headers: {
64
+ "x-api-key": cfg.apiKey,
65
+ },
66
+ });
67
+ if (response.ok) {
68
+ const data = await response.json();
69
+ setRemoteConfig(data);
70
+ // Update initial message if no user interaction yet
71
+ if (messages.length === 1 && messages[0].role === "model") {
72
+ const initialMsg = data.initialMessage ||
73
+ (data.language === "ar"
74
+ ? "أهلاً وسهلاً! كيف يمكنني مساعدتك؟"
75
+ : "Hello! How can I help you?");
76
+ setMessages([
77
+ {
78
+ role: "model",
79
+ content: initialMsg,
80
+ timestamp: new Date().toLocaleTimeString(data.language === "ar" ? "ar-EG" : "en-US", { hour: "2-digit", minute: "2-digit", hour12: true }),
81
+ },
82
+ ]);
83
+ }
84
+ }
85
+ }
86
+ catch (error) {
87
+ console.error("Failed to fetch chatbot config:", error);
88
+ }
89
+ };
90
+ fetchConfig();
91
+ }, [MCP_URL, cfg.apiKey]);
51
92
  // Auto delete chats
52
93
  useEffect(() => {
53
94
  if (cfg.autoDeleteChats) {
@@ -55,23 +96,23 @@ const ChatbotPopup = () => {
55
96
  setMessages([
56
97
  {
57
98
  role: "model",
58
- content: defaultLang === "ar"
99
+ content: effectiveLang === "ar"
59
100
  ? "أهلاً وسهلاً! أنا هنا لمساعدتك في إدارة المنتجات. كيف يمكنني مساعدتك؟"
60
101
  : "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", {
102
+ timestamp: new Date().toLocaleTimeString(effectiveLang === "ar" ? "ar-EG" : "en-US", {
62
103
  hour: "2-digit",
63
104
  minute: "2-digit",
64
105
  hour12: true,
65
106
  }),
66
107
  },
67
108
  ]);
68
- toast.info(defaultLang === "ar"
109
+ toast.info(effectiveLang === "ar"
69
110
  ? "تم مسح المحادثة تلقائيًا"
70
111
  : "Chat cleared automatically");
71
112
  }, cfg.autoDeleteChats * 60 * 1000);
72
113
  return () => clearTimeout(timer);
73
114
  }
74
- }, [messages, cfg.autoDeleteChats, defaultLang]);
115
+ }, [messages, cfg.autoDeleteChats, effectiveLang]);
75
116
  const scrollToBottom = () => {
76
117
  messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
77
118
  };
@@ -79,7 +120,7 @@ const ChatbotPopup = () => {
79
120
  scrollToBottom();
80
121
  }, [messages]);
81
122
  const formatTimestamp = () => {
82
- return new Date().toLocaleTimeString(defaultLang === "ar" ? "ar-EG" : "en-US", {
123
+ return new Date().toLocaleTimeString(effectiveLang === "ar" ? "ar-EG" : "en-US", {
83
124
  hour: "2-digit",
84
125
  minute: "2-digit",
85
126
  hour12: true,
@@ -87,7 +128,7 @@ const ChatbotPopup = () => {
87
128
  };
88
129
  const handleMcpToolCall = async (toolName, args, retries = 2) => {
89
130
  if (!cfg.validatedTools.includes(toolName)) {
90
- throw new Error(defaultLang === "ar"
131
+ throw new Error(effectiveLang === "ar"
91
132
  ? `الأداة ${toolName} غير متاحة لهذا السيريال`
92
133
  : `Tool ${toolName} not available for this serial`);
93
134
  }
@@ -124,7 +165,7 @@ const ChatbotPopup = () => {
124
165
  return JSON.parse(data.result.content[0].text);
125
166
  }
126
167
  return (data.result ||
127
- (defaultLang === "ar"
168
+ (effectiveLang === "ar"
128
169
  ? "تم تنفيذ الأمر بنجاح"
129
170
  : "Command executed successfully"));
130
171
  }
@@ -133,7 +174,7 @@ const ChatbotPopup = () => {
133
174
  await new Promise((resolve) => setTimeout(resolve, 1000 * (i + 1)));
134
175
  continue;
135
176
  }
136
- throw new Error(defaultLang === "ar"
177
+ throw new Error(effectiveLang === "ar"
137
178
  ? `فشل استدعاء ${toolName} بعد ${retries + 1} محاولة: ${e.message}`
138
179
  : `Failed to call ${toolName} after ${retries + 1} attempts: ${e.message}`);
139
180
  }
@@ -221,7 +262,7 @@ const ChatbotPopup = () => {
221
262
  },
222
263
  tools: toolsConfig,
223
264
  });
224
- let assistantReply = defaultLang === "ar"
265
+ let assistantReply = effectiveLang === "ar"
225
266
  ? "عذرًا، لم أفهم الطلب."
226
267
  : "Sorry, I didn't understand the request.";
227
268
  const response = await result.response;
@@ -238,13 +279,13 @@ const ChatbotPopup = () => {
238
279
  assistantReply = {
239
280
  products: Array.isArray(toolResult) ? toolResult : [toolResult],
240
281
  };
241
- toast.success(defaultLang === "ar"
282
+ toast.success(effectiveLang === "ar"
242
283
  ? "تم جلب البيانات بنجاح!"
243
284
  : "Data fetched successfully!");
244
285
  }
245
286
  catch (e) {
246
287
  assistantReply =
247
- defaultLang === "ar"
288
+ effectiveLang === "ar"
248
289
  ? `عذرًا، حدث خطأ أثناء تنفيذ الأمر: ${e.message}`
249
290
  : `Sorry, an error occurred while executing the command: ${e.message}`;
250
291
  toast.error(e.message);
@@ -258,7 +299,9 @@ const ChatbotPopup = () => {
258
299
  .join("\n");
259
300
  assistantReply =
260
301
  textParts ||
261
- (defaultLang === "ar" ? "لم أتمكن من الرد." : "Couldn't respond.");
302
+ (effectiveLang === "ar"
303
+ ? "لم أتمكن من الرد."
304
+ : "Couldn't respond.");
262
305
  }
263
306
  }
264
307
  setMessages((prev) => [
@@ -275,20 +318,22 @@ const ChatbotPopup = () => {
275
318
  const isOverloaded = errorMessage.includes("overloaded") || errorMessage.includes("503");
276
319
  const waitTime = isOverloaded ? 5000 : 1000;
277
320
  if (retryCount > 0) {
278
- toast.warn(defaultLang === "ar"
321
+ toast.warn(effectiveLang === "ar"
279
322
  ? `فشل الطلب، جاري إعادة المحاولة... (${retryCount} محاولة متبقية)`
280
323
  : `Request failed, retrying... (${retryCount} attempts left)`);
281
324
  setTimeout(() => handleSend(retryCount - 1), waitTime);
282
325
  return;
283
326
  }
284
327
  const errorMsg = errorMessage ||
285
- (defaultLang === "ar" ? "حدث خطأ غير متوقع" : "Unexpected error");
286
- toast.error(`${defaultLang === "ar" ? "خطأ" : "Error"}: ${errorMsg}`);
328
+ (effectiveLang === "ar" ? "حدث خطأ غير متوقع" : "Unexpected error");
329
+ toast.error(`${effectiveLang === "ar" ? "خطأ" : "Error"}: ${errorMsg}`);
287
330
  setMessages((prev) => [
288
331
  ...prev,
289
332
  {
290
333
  role: "model",
291
- content: `${defaultLang === "ar" ? "عذرًا، حدث خطأ" : "Sorry, an error occurred"}: ${errorMsg}`,
334
+ content: `${effectiveLang === "ar"
335
+ ? "عذرًا، حدث خطأ"
336
+ : "Sorry, an error occurred"}: ${errorMsg}`,
292
337
  timestamp: formatTimestamp(),
293
338
  },
294
339
  ]);
@@ -317,12 +362,12 @@ const ChatbotPopup = () => {
317
362
  timestamp: formatTimestamp(),
318
363
  },
319
364
  ]);
320
- toast.success(defaultLang === "ar"
365
+ toast.success(effectiveLang === "ar"
321
366
  ? "تم تحديث قائمة المنتجات!"
322
367
  : "Product list updated!");
323
368
  }
324
369
  catch (e) {
325
- toast.error(defaultLang === "ar"
370
+ toast.error(effectiveLang === "ar"
326
371
  ? `فشل تحديث المنتجات: ${e.message}`
327
372
  : `Failed to update products: ${e.message}`);
328
373
  }
@@ -334,24 +379,24 @@ const ChatbotPopup = () => {
334
379
  setMessages([
335
380
  {
336
381
  role: "model",
337
- content: defaultLang === "ar"
382
+ content: effectiveLang === "ar"
338
383
  ? "أهلاً وسهلاً! أنا هنا لمساعدتك في إدارة المنتجات. كيف يمكنني مساعدتك؟"
339
384
  : "Hello! I'm here to help with product management. How can I assist you?",
340
385
  timestamp: formatTimestamp(),
341
386
  },
342
387
  ]);
343
388
  setInput("");
344
- toast.info(defaultLang === "ar" ? "تم مسح المحادثة" : "Chat cleared");
389
+ toast.info(effectiveLang === "ar" ? "تم مسح المحادثة" : "Chat cleared");
345
390
  };
346
391
  const showCart = () => {
347
392
  const cart = JSON.parse(localStorage.getItem("cart") || "[]");
348
393
  if (cart.length === 0) {
349
- toast.warn(defaultLang === "ar" ? "السلة فاضية!" : "Cart is empty!");
394
+ toast.warn(effectiveLang === "ar" ? "السلة فاضية!" : "Cart is empty!");
350
395
  setMessages((prev) => [
351
396
  ...prev,
352
397
  {
353
398
  role: "model",
354
- content: defaultLang === "ar"
399
+ content: effectiveLang === "ar"
355
400
  ? "السلة فاضية حالياً! يمكنك إضافة المنتجات من قائمة المنتجات."
356
401
  : "The cart is empty! You can add products from the product list.",
357
402
  timestamp: formatTimestamp(),
@@ -367,38 +412,38 @@ const ChatbotPopup = () => {
367
412
  timestamp: formatTimestamp(),
368
413
  },
369
414
  ]);
370
- toast.info(defaultLang === "ar"
415
+ toast.info(effectiveLang === "ar"
371
416
  ? `عرض السلة (${cart.length} منتج)`
372
417
  : `Showing cart (${cart.length} items)`);
373
418
  };
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: () => {
419
+ 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
420
  const cart = JSON.parse(localStorage.getItem("cart") || "[]");
376
421
  cart.push(product);
377
422
  localStorage.setItem("cart", JSON.stringify(cart));
378
- toast.success(defaultLang === "ar"
423
+ toast.success(effectiveLang === "ar"
379
424
  ? "تم إضافة المنتج للسلة!"
380
425
  : "Product added to cart!");
381
- }, children: defaultLang === "ar" ? "إضافة للسلة" : "Add to Cart" })] }) }) }));
426
+ }, children: effectiveLang === "ar" ? "إضافة للسلة" : "Add to Cart" })] }) }) }));
382
427
  const MessageBubble = ({ message }) => {
383
428
  const isUser = message.role === "user";
384
429
  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
430
  ? "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"
431
+ : "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
432
  ? "المنتجات المتاحة:"
388
433
  : "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
434
  };
390
435
  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" })] }) }) }));
436
+ 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
437
  }
393
438
  const chatClasses = isExpanded
394
439
  ? "fixed inset-0 z-50 animate-in slide-in-from-right-4 duration-300"
395
440
  : "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"
441
+ 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
442
  ? "متاح الآن للمساعدة"
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"
443
+ : "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
444
  ? "اسأل أي شيء عن Tigerbase"
400
- : "Ask anything about Tigerbase" }), _jsx("p", { className: "text-sm text-gray-500 max-w-xs mx-auto", children: defaultLang === "ar"
445
+ : "Ask anything about Tigerbase" }), _jsx("p", { className: "text-sm text-gray-500 max-w-xs mx-auto", children: effectiveLang === "ar"
401
446
  ? "يستخدم 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" })] }) })] })] })] }) }));
447
+ : "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
448
  };
404
449
  export default ChatbotPopup;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tigerbase-chatbot",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "TigerBase Chatbot Client - AI-powered chatbot for product management",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",