mehdi-akbari-ai-assistant-free 0.9.0 → 0.9.2
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/react.d.mts +3 -1
- package/dist/react.d.ts +3 -1
- package/dist/react.js +30 -15
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +31 -16
- package/dist/react.mjs.map +1 -1
- package/dist/styles.css +122 -93
- package/package.json +1 -1
package/dist/react.d.mts
CHANGED
|
@@ -5,11 +5,13 @@ interface ChatWindowProps {
|
|
|
5
5
|
apiEndpoint: string;
|
|
6
6
|
title?: string;
|
|
7
7
|
welcomeMessage?: string;
|
|
8
|
+
isFullScreen?: boolean;
|
|
9
|
+
onToggleFullScreen?: () => void;
|
|
8
10
|
}
|
|
9
11
|
declare const ChatWindow: React.FC<ChatWindowProps>;
|
|
10
12
|
|
|
11
13
|
interface AiAssistantProps extends ChatWindowProps {
|
|
12
|
-
|
|
14
|
+
lottieAnimationData?: any;
|
|
13
15
|
}
|
|
14
16
|
declare const AiAssistant: React.FC<AiAssistantProps>;
|
|
15
17
|
|
package/dist/react.d.ts
CHANGED
|
@@ -5,11 +5,13 @@ interface ChatWindowProps {
|
|
|
5
5
|
apiEndpoint: string;
|
|
6
6
|
title?: string;
|
|
7
7
|
welcomeMessage?: string;
|
|
8
|
+
isFullScreen?: boolean;
|
|
9
|
+
onToggleFullScreen?: () => void;
|
|
8
10
|
}
|
|
9
11
|
declare const ChatWindow: React.FC<ChatWindowProps>;
|
|
10
12
|
|
|
11
13
|
interface AiAssistantProps extends ChatWindowProps {
|
|
12
|
-
|
|
14
|
+
lottieAnimationData?: any;
|
|
13
15
|
}
|
|
14
16
|
declare const AiAssistant: React.FC<AiAssistantProps>;
|
|
15
17
|
|
package/dist/react.js
CHANGED
|
@@ -138,11 +138,13 @@ var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
|
138
138
|
var ChatWindow = ({
|
|
139
139
|
apiEndpoint,
|
|
140
140
|
title = "AI Assistant",
|
|
141
|
-
welcomeMessage = "\u0633\u0644\u0627\u0645! \u0686\u0637\u0648\u0631 \u0645\u06CC\u200C\u062A\u0648\u0627\u0646\u0645 \u06A9\u0645\u06A9\u062A\u0627\u0646 \u06A9\u0646\u0645\u061F"
|
|
141
|
+
welcomeMessage = "\u0633\u0644\u0627\u0645! \u0686\u0637\u0648\u0631 \u0645\u06CC\u200C\u062A\u0648\u0627\u0646\u0645 \u06A9\u0645\u06A9\u062A\u0627\u0646 \u06A9\u0646\u0645\u061F",
|
|
142
|
+
isFullScreen = false,
|
|
143
|
+
onToggleFullScreen
|
|
142
144
|
}) => {
|
|
143
145
|
const [messages, setMessages] = (0, import_react3.useState)([]);
|
|
144
146
|
const [isLoading, setIsLoading] = (0, import_react3.useState)(false);
|
|
145
|
-
const version = "0.9.
|
|
147
|
+
const version = "0.9.2";
|
|
146
148
|
(0, import_react3.useEffect)(() => {
|
|
147
149
|
if (welcomeMessage && messages.length === 0) {
|
|
148
150
|
setMessages([{ role: "assistant", content: welcomeMessage }]);
|
|
@@ -173,8 +175,11 @@ var ChatWindow = ({
|
|
|
173
175
|
};
|
|
174
176
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mra-chat-window", children: [
|
|
175
177
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mra-header", children: [
|
|
176
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.
|
|
177
|
-
|
|
178
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mra-header-title-group", children: [
|
|
179
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_lucide_react2.Bot, { size: 20 }),
|
|
180
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mra-title", children: title })
|
|
181
|
+
] }),
|
|
182
|
+
onToggleFullScreen && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { onClick: onToggleFullScreen, className: "mra-header-icon-button", children: isFullScreen ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_lucide_react2.Minimize, { size: 16 }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_lucide_react2.Maximize, { size: 16 }) })
|
|
178
183
|
] }),
|
|
179
184
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MessageList, { messages, isLoading }),
|
|
180
185
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ChatInput, { onSendMessage: handleSendMessage, isLoading }),
|
|
@@ -195,26 +200,36 @@ var ChatWindow = ({
|
|
|
195
200
|
// src/components/ChatbotFAB/ChatbotFAB.tsx
|
|
196
201
|
var import_lottie_react = __toESM(require("lottie-react"));
|
|
197
202
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
198
|
-
var ChatbotFAB = ({ onClick,
|
|
199
|
-
|
|
203
|
+
var ChatbotFAB = ({ onClick, animationData }) => {
|
|
204
|
+
const lottieProps = typeof animationData === "string" ? { animationData: null, path: animationData } : { animationData };
|
|
205
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { className: "mra-fab", onClick, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lottie_react.default, { ...lottieProps, loop: true }) });
|
|
200
206
|
};
|
|
201
207
|
|
|
202
208
|
// src/components/AiAssistant/AiAssistant.tsx
|
|
203
209
|
var import_clsx2 = __toESM(require("clsx"));
|
|
204
|
-
var import_jsx_runtime6 =
|
|
210
|
+
var import_jsx_runtime6 = (
|
|
211
|
+
// اگر تمامصفحه باشد، کلاس جدید اضافه میشود
|
|
212
|
+
require("react/jsx-runtime")
|
|
213
|
+
);
|
|
205
214
|
var DEFAULT_LOTTIE_URL = "https://lottie.host/a822cf1a-1e96-4187-a220-42adb2a61d19/B5bQnC2p9K.json";
|
|
206
215
|
var AiAssistant = ({
|
|
207
|
-
|
|
216
|
+
lottieAnimationData = DEFAULT_LOTTIE_URL,
|
|
208
217
|
...chatWindowProps
|
|
209
|
-
// بقیه پراپها برای ChatWindow هستند
|
|
210
218
|
}) => {
|
|
211
219
|
const [isOpen, setIsOpen] = (0, import_react4.useState)(false);
|
|
212
|
-
const
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mra-container", children: [
|
|
216
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: (0, import_clsx2.default)("mra-chat-window-container", isOpen && "mra-chat-window-container--open"), children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
217
|
-
|
|
220
|
+
const [isFullScreen, setIsFullScreen] = (0, import_react4.useState)(false);
|
|
221
|
+
const toggleChat = () => setIsOpen((prev) => !prev);
|
|
222
|
+
const toggleFullScreen = () => setIsFullScreen((prev) => !prev);
|
|
223
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: (0, import_clsx2.default)("mra-container", isFullScreen && "mra-container--fullscreen"), children: [
|
|
224
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: (0, import_clsx2.default)("mra-chat-window-container", isOpen && "mra-chat-window-container--open"), children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
225
|
+
ChatWindow,
|
|
226
|
+
{
|
|
227
|
+
...chatWindowProps,
|
|
228
|
+
isFullScreen,
|
|
229
|
+
onToggleFullScreen: toggleFullScreen
|
|
230
|
+
}
|
|
231
|
+
) }),
|
|
232
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ChatbotFAB, { onClick: toggleChat, animationData: lottieAnimationData })
|
|
218
233
|
] });
|
|
219
234
|
};
|
|
220
235
|
// Annotate the CommonJS export names for ESM import in node:
|
package/dist/react.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/react.ts","../src/components/AiAssistant/AiAssistant.tsx","../src/components/ChatWindow/ChatWindow.tsx","../src/components/MessageList/MessageList.tsx","../src/components/MessageBubble/MessageBubble.tsx","../src/components/ChatInput/ChatInput.tsx","../src/components/ChatbotFAB/ChatbotFAB.tsx"],"sourcesContent":["\r\n\"use client\";\r\n\r\n\r\nexport { AiAssistant } from \"./components/AiAssistant/AiAssistant\";\r\n\r\n\r\nexport { ChatWindow, type ChatWindowProps } from \"./components/ChatWindow/ChatWindow\";\r\nexport * from \"./types\";","// src/components/AiAssistant/AiAssistant.tsx\r\n\"use client\";\r\nimport React, { useState } from 'react';\r\nimport { ChatWindow, ChatWindowProps } from '../ChatWindow/ChatWindow';\r\nimport { ChatbotFAB } from '../ChatbotFAB/ChatbotFAB';\r\nimport clsx from 'clsx';\r\n\r\n// این کامپوننت تمام پراپهای ChatWindow را به علاوهی پراپ lottieUrl میپذیرد\r\ninterface AiAssistantProps extends ChatWindowProps {\r\n lottieUrl?: string;\r\n}\r\n\r\n// یک انیمیشن پیشفرض جذاب\r\nconst DEFAULT_LOTTIE_URL = \"https://lottie.host/a822cf1a-1e96-4187-a220-42adb2a61d19/B5bQnC2p9K.json\";\r\n\r\nexport const AiAssistant: React.FC<AiAssistantProps> = ({ \r\n lottieUrl = DEFAULT_LOTTIE_URL,\r\n ...chatWindowProps // بقیه پراپها برای ChatWindow هستند\r\n}) => {\r\n const [isOpen, setIsOpen] = useState(false);\r\n\r\n const toggleChat = () => {\r\n setIsOpen(prev => !prev);\r\n };\r\n\r\n return (\r\n <div className=\"mra-container\">\r\n \r\n <div className={clsx(\"mra-chat-window-container\", isOpen && \"mra-chat-window-container--open\")}>\r\n <ChatWindow {...chatWindowProps} />\r\n </div>\r\n\r\n \r\n <ChatbotFAB onClick={toggleChat} lottieUrl={lottieUrl} />\r\n </div>\r\n );\r\n};","// src/components/ChatWindow/ChatWindow.tsx\r\n\"use client\";\r\n\r\nimport React, { useState, useEffect } from 'react';\r\nimport { MessageList } from '../MessageList/MessageList';\r\nimport { ChatInput } from '../ChatInput/ChatInput';\r\nimport { Message } from '../../types';\r\nimport { Bot } from 'lucide-react';\r\n\r\nexport interface ChatWindowProps {\r\n apiEndpoint: string;\r\n title?: string;\r\n welcomeMessage?: string;\r\n}\r\n\r\nexport const ChatWindow: React.FC<ChatWindowProps> = ({\r\n apiEndpoint,\r\n title = \"AI Assistant\",\r\n welcomeMessage = \"سلام! چطور میتوانم کمکتان کنم؟\"\r\n}) => {\r\n const [messages, setMessages] = useState<Message[]>([]);\r\n const [isLoading, setIsLoading] = useState(false);\r\n const version = process.env.PACKAGE_VERSION; \r\n\r\n useEffect(() => {\r\n if (welcomeMessage && messages.length === 0) {\r\n setMessages([{ role: 'assistant', content: welcomeMessage }]);\r\n }\r\n }, [welcomeMessage, messages.length]);\r\n\r\n const handleSendMessage = async (userMessage: string) => {\r\n const newUserMsg: Message = { role: 'user', content: userMessage };\r\n const currentMessages = [...messages, newUserMsg];\r\n setMessages(currentMessages);\r\n setIsLoading(true);\r\n\r\n try {\r\n const response = await fetch(apiEndpoint, {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({ messages: currentMessages }),\r\n });\r\n\r\n if (!response.ok) throw new Error(\"Network response was not ok\");\r\n \r\n const data = await response.json();\r\n const botMsg: Message = { role: 'assistant', content: data.content };\r\n setMessages(prev => [...prev, botMsg]);\r\n\r\n } catch (error) {\r\n console.error(\"Chat Error:\", error);\r\n const errorMsg: Message = { role: 'assistant', content: \"خطایی رخ داده است.\" };\r\n setMessages(prev => [...prev, errorMsg]);\r\n } finally {\r\n setIsLoading(false);\r\n }\r\n };\r\n\r\n return (\r\n <div className=\"mra-chat-window\">\r\n <div className=\"mra-header\">\r\n <Bot size={20} />\r\n <span className=\"mra-title\">{title}</span>\r\n </div>\r\n\r\n <MessageList messages={messages} isLoading={isLoading} />\r\n <ChatInput onSendMessage={handleSendMessage} isLoading={isLoading} />\r\n\r\n {/* === فوتر جدید اضافه شده === */}\r\n <footer className=\"mra-footer\">\r\n <span>v{version}</span>\r\n <div className=\"mra-footer-links\">\r\n <span>Powered By Mehdi Akbari |</span>\r\n <a href=\"mailto:mehdiakbarideveloper@gmail.com\" className=\"mra-footer-link\" target=\"_blank\" rel=\"noopener noreferrer\">Gmail</a>\r\n <a href=\"https://t.me/MehdiAkbariDev\" className=\"mra-footer-link\" target=\"_blank\" rel=\"noopener noreferrer\">Telegram</a>\r\n </div>\r\n </footer>\r\n </div>\r\n );\r\n};","// src/components/MessageList/MessageList.tsx\r\n\"use client\";\r\n\r\nimport React, { useRef, useEffect } from 'react';\r\nimport { MessageBubble } from '../MessageBubble/MessageBubble';\r\nimport { Message } from '../../types';\r\n\r\ninterface MessageListProps {\r\n messages: Message[];\r\n isLoading: boolean;\r\n}\r\n\r\nexport const MessageList: React.FC<MessageListProps> = ({ messages, isLoading }) => {\r\n const messagesEndRef = useRef<HTMLDivElement>(null);\r\n\r\n useEffect(() => {\r\n messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });\r\n }, [messages, isLoading]);\r\n\r\n return (\r\n <div className=\"mra-message-list\">\r\n {messages.map((msg, index) => (\r\n <MessageBubble key={index} message={msg} />\r\n ))}\r\n\r\n {isLoading && (\r\n <div className=\"mra-loading-wrapper\">\r\n <div className=\"mra-loading-bubble\">\r\n <div className=\"mra-loading-dot\" style={{ animationDelay: '-0.32s' }}></div>\r\n <div className=\"mra-loading-dot\" style={{ animationDelay: '-0.16s' }}></div>\r\n <div className=\"mra-loading-dot\"></div>\r\n </div>\r\n </div>\r\n )}\r\n\r\n <div ref={messagesEndRef} />\r\n </div>\r\n );\r\n};","// src/components/MessageBubble/MessageBubble.tsx\r\n\"use client\";\r\n\r\nimport React from 'react';\r\nimport clsx from 'clsx';\r\nimport { Message } from '../../types';\r\n\r\ninterface MessageBubbleProps {\r\n message: Message;\r\n}\r\n\r\nexport const MessageBubble: React.FC<MessageBubbleProps> = ({ message }) => {\r\n const isUser = message.role === 'user';\r\n\r\n return (\r\n <div className={clsx(\"mra-bubble-wrapper\", isUser ? \"mra-wrapper-user\" : \"mra-wrapper-bot\")}>\r\n <div\r\n className={clsx(\r\n \"mra-bubble\",\r\n isUser ? \"mra-bubble-user\" : \"mra-bubble-bot\"\r\n )}\r\n >\r\n {message.content}\r\n </div>\r\n </div>\r\n );\r\n};","// src/components/ChatInput/ChatInput.tsx\r\n\"use client\";\r\n\r\nimport React, { useState, useRef, useEffect } from 'react';\r\nimport { Send } from 'lucide-react';\r\n\r\ninterface ChatInputProps {\r\n onSendMessage: (message: string) => void;\r\n isLoading: boolean;\r\n}\r\n\r\nexport const ChatInput: React.FC<ChatInputProps> = ({ onSendMessage, isLoading }) => {\r\n const [inputValue, setInputValue] = useState('');\r\n const textareaRef = useRef<HTMLTextAreaElement>(null); // Ref برای دسترسی به textarea\r\n\r\n // این افکت با هر بار تغییر متن، ارتفاع textarea را تنظیم میکند\r\n useEffect(() => {\r\n const textarea = textareaRef.current;\r\n if (textarea) {\r\n // ارتفاع را ریست میکنیم تا در صورت پاک کردن متن، کوچک شود\r\n textarea.style.height = 'auto';\r\n // ارتفاع جدید را بر اساس محتوای داخلی تنظیم میکنیم\r\n textarea.style.height = `${textarea.scrollHeight}px`;\r\n }\r\n }, [inputValue]);\r\n\r\n const handleSend = () => {\r\n if (inputValue.trim()) {\r\n onSendMessage(inputValue);\r\n setInputValue('');\r\n }\r\n };\r\n\r\n // این منطق به درستی Shift+Enter را برای ایجاد خط جدید مدیریت میکند\r\n const handleKeyDown = (e: React.KeyboardEvent) => {\r\n if (e.key === 'Enter' && !e.shiftKey) {\r\n e.preventDefault();\r\n handleSend();\r\n }\r\n };\r\n\r\n return (\r\n <div className=\"mra-input-wrapper\">\r\n <textarea\r\n ref={textareaRef}\r\n className=\"mra-input-field\"\r\n value={inputValue}\r\n onChange={(e) => setInputValue(e.target.value)}\r\n onKeyDown={handleKeyDown}\r\n placeholder=\"پیام خود را بنویسید...\"\r\n disabled={isLoading}\r\n rows={1} // با یک ردیف شروع میشود\r\n />\r\n <button\r\n className=\"mra-send-button\"\r\n onClick={handleSend}\r\n disabled={isLoading || !inputValue.trim()}\r\n >\r\n <Send size={18} />\r\n </button>\r\n </div>\r\n );\r\n};","\r\n\"use client\";\r\nimport React from 'react';\r\nimport Lottie from 'lottie-react';\r\n\r\ninterface ChatbotFABProps {\r\n onClick: () => void;\r\n lottieUrl: string; \r\n}\r\n\r\nexport const ChatbotFAB: React.FC<ChatbotFABProps> = ({ onClick, lottieUrl }) => {\r\n return (\r\n <button className=\"mra-fab\" onClick={onClick}>\r\n <Lottie animationData={lottieUrl} loop={true} />\r\n </button>\r\n );\r\n};"],"mappings":"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","names":["import_react","import_react","clsx","import_jsx_runtime","import_react","import_jsx_runtime","import_lucide_react","import_jsx_runtime","import_jsx_runtime","Lottie","import_clsx","import_jsx_runtime","clsx"]}
|
|
1
|
+
{"version":3,"sources":["../src/react.ts","../src/components/AiAssistant/AiAssistant.tsx","../src/components/ChatWindow/ChatWindow.tsx","../src/components/MessageList/MessageList.tsx","../src/components/MessageBubble/MessageBubble.tsx","../src/components/ChatInput/ChatInput.tsx","../src/components/ChatbotFAB/ChatbotFAB.tsx"],"sourcesContent":["\r\n\"use client\";\r\n\r\n\r\nexport { AiAssistant } from \"./components/AiAssistant/AiAssistant\";\r\n\r\n\r\n\r\nexport { ChatWindow, type ChatWindowProps } from \"./components/ChatWindow/ChatWindow\";\r\nexport * from \"./types\";","// src/components/AiAssistant/AiAssistant.tsx\r\n\"use client\";\r\nimport React, { useState } from 'react';\r\nimport { ChatWindow, ChatWindowProps } from '../ChatWindow/ChatWindow';\r\nimport { ChatbotFAB } from '../ChatbotFAB/ChatbotFAB';\r\nimport clsx from 'clsx';\r\n\r\ninterface AiAssistantProps extends ChatWindowProps {\r\n lottieAnimationData?: any;\r\n}\r\n\r\nconst DEFAULT_LOTTIE_URL = \"https://lottie.host/a822cf1a-1e96-4187-a220-42adb2a61d19/B5bQnC2p9K.json\";\r\n\r\nexport const AiAssistant: React.FC<AiAssistantProps> = ({\r\n lottieAnimationData = DEFAULT_LOTTIE_URL,\r\n ...chatWindowProps\r\n}) => {\r\n const [isOpen, setIsOpen] = useState(false);\r\n const [isFullScreen, setIsFullScreen] = useState(false); // استیت جدید برای حالت تمامصفحه\r\n\r\n const toggleChat = () => setIsOpen(prev => !prev);\r\n const toggleFullScreen = () => setIsFullScreen(prev => !prev);\r\n\r\n return (\r\n // اگر تمامصفحه باشد، کلاس جدید اضافه میشود\r\n <div className={clsx(\"mra-container\", isFullScreen && \"mra-container--fullscreen\")}>\r\n <div className={clsx(\"mra-chat-window-container\", isOpen && \"mra-chat-window-container--open\")}>\r\n <ChatWindow\r\n {...chatWindowProps}\r\n // دو پراپ جدید به ChatWindow پاس میدهیم\r\n isFullScreen={isFullScreen}\r\n onToggleFullScreen={toggleFullScreen}\r\n />\r\n </div>\r\n <ChatbotFAB onClick={toggleChat} animationData={lottieAnimationData} />\r\n </div>\r\n );\r\n};","// src/components/ChatWindow/ChatWindow.tsx\r\n\"use client\";\r\n\r\nimport React, { useState, useEffect } from 'react';\r\nimport { MessageList } from '../MessageList/MessageList';\r\nimport { ChatInput } from '../ChatInput/ChatInput';\r\nimport { Message } from '../../types';\r\nimport { Bot, Maximize, Minimize } from 'lucide-react'; // آیکونهای تمامصفحه اضافه شدند\r\n\r\n// پراپهای کامپوننت با گزینههای جدید آپدیت شدند\r\nexport interface ChatWindowProps {\r\n apiEndpoint: string;\r\n title?: string;\r\n welcomeMessage?: string;\r\n isFullScreen?: boolean;\r\n onToggleFullScreen?: () => void;\r\n}\r\n\r\nexport const ChatWindow: React.FC<ChatWindowProps> = ({\r\n apiEndpoint,\r\n title = \"AI Assistant\",\r\n welcomeMessage = \"سلام! چطور میتوانم کمکتان کنم؟\",\r\n isFullScreen = false,\r\n onToggleFullScreen,\r\n}) => {\r\n const [messages, setMessages] = useState<Message[]>([]);\r\n const [isLoading, setIsLoading] = useState(false);\r\n const version = process.env.PACKAGE_VERSION; \r\n\r\n useEffect(() => {\r\n if (welcomeMessage && messages.length === 0) {\r\n setMessages([{ role: 'assistant', content: welcomeMessage }]);\r\n }\r\n }, [welcomeMessage, messages.length]);\r\n\r\n const handleSendMessage = async (userMessage: string) => {\r\n const newUserMsg: Message = { role: 'user', content: userMessage };\r\n const currentMessages = [...messages, newUserMsg];\r\n setMessages(currentMessages);\r\n setIsLoading(true);\r\n\r\n try {\r\n const response = await fetch(apiEndpoint, {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({ messages: currentMessages }),\r\n });\r\n\r\n if (!response.ok) throw new Error(\"Network response was not ok\");\r\n \r\n const data = await response.json();\r\n const botMsg: Message = { role: 'assistant', content: data.content };\r\n setMessages(prev => [...prev, botMsg]);\r\n\r\n } catch (error) {\r\n console.error(\"Chat Error:\", error);\r\n const errorMsg: Message = { role: 'assistant', content: \"خطایی رخ داده است.\" };\r\n setMessages(prev => [...prev, errorMsg]);\r\n } finally {\r\n setIsLoading(false);\r\n }\r\n };\r\n\r\n return (\r\n <div className=\"mra-chat-window\">\r\n {/* هدر با دکمه تمامصفحه آپدیت شده است */}\r\n <div className=\"mra-header\">\r\n <div className=\"mra-header-title-group\">\r\n <Bot size={20} />\r\n <span className=\"mra-title\">{title}</span>\r\n </div>\r\n {onToggleFullScreen && (\r\n <button onClick={onToggleFullScreen} className=\"mra-header-icon-button\">\r\n {isFullScreen ? <Minimize size={16} /> : <Maximize size={16} />}\r\n </button>\r\n )}\r\n </div>\r\n\r\n <MessageList messages={messages} isLoading={isLoading} />\r\n <ChatInput onSendMessage={handleSendMessage} isLoading={isLoading} />\r\n\r\n <footer className=\"mra-footer\">\r\n <span>v{version}</span>\r\n <div className=\"mra-footer-links\">\r\n <span>Powered By Mehdi Akbari |</span>\r\n <a href=\"mailto:mehdiakbarideveloper@gmail.com\" className=\"mra-footer-link\" target=\"_blank\" rel=\"noopener noreferrer\">Gmail</a>\r\n <a href=\"https://t.me/MehdiAkbariDev\" className=\"mra-footer-link\" target=\"_blank\" rel=\"noopener noreferrer\">Telegram</a>\r\n </div>\r\n </footer>\r\n </div>\r\n );\r\n};","// src/components/MessageList/MessageList.tsx\r\n\"use client\";\r\n\r\nimport React, { useRef, useEffect } from 'react';\r\nimport { MessageBubble } from '../MessageBubble/MessageBubble';\r\nimport { Message } from '../../types';\r\n\r\ninterface MessageListProps {\r\n messages: Message[];\r\n isLoading: boolean;\r\n}\r\n\r\nexport const MessageList: React.FC<MessageListProps> = ({ messages, isLoading }) => {\r\n const messagesEndRef = useRef<HTMLDivElement>(null);\r\n\r\n useEffect(() => {\r\n messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });\r\n }, [messages, isLoading]);\r\n\r\n return (\r\n <div className=\"mra-message-list\">\r\n {messages.map((msg, index) => (\r\n <MessageBubble key={index} message={msg} />\r\n ))}\r\n\r\n {isLoading && (\r\n <div className=\"mra-loading-wrapper\">\r\n <div className=\"mra-loading-bubble\">\r\n <div className=\"mra-loading-dot\" style={{ animationDelay: '-0.32s' }}></div>\r\n <div className=\"mra-loading-dot\" style={{ animationDelay: '-0.16s' }}></div>\r\n <div className=\"mra-loading-dot\"></div>\r\n </div>\r\n </div>\r\n )}\r\n\r\n <div ref={messagesEndRef} />\r\n </div>\r\n );\r\n};","// src/components/MessageBubble/MessageBubble.tsx\r\n\"use client\";\r\n\r\nimport React from 'react';\r\nimport clsx from 'clsx';\r\nimport { Message } from '../../types';\r\n\r\ninterface MessageBubbleProps {\r\n message: Message;\r\n}\r\n\r\nexport const MessageBubble: React.FC<MessageBubbleProps> = ({ message }) => {\r\n const isUser = message.role === 'user';\r\n\r\n return (\r\n <div className={clsx(\"mra-bubble-wrapper\", isUser ? \"mra-wrapper-user\" : \"mra-wrapper-bot\")}>\r\n <div\r\n className={clsx(\r\n \"mra-bubble\",\r\n isUser ? \"mra-bubble-user\" : \"mra-bubble-bot\"\r\n )}\r\n >\r\n {message.content}\r\n </div>\r\n </div>\r\n );\r\n};","// src/components/ChatInput/ChatInput.tsx\r\n\"use client\";\r\n\r\nimport React, { useState, useRef, useEffect } from 'react';\r\nimport { Send } from 'lucide-react';\r\n\r\ninterface ChatInputProps {\r\n onSendMessage: (message: string) => void;\r\n isLoading: boolean;\r\n}\r\n\r\nexport const ChatInput: React.FC<ChatInputProps> = ({ onSendMessage, isLoading }) => {\r\n const [inputValue, setInputValue] = useState('');\r\n const textareaRef = useRef<HTMLTextAreaElement>(null); // Ref برای دسترسی به textarea\r\n\r\n // این افکت با هر بار تغییر متن، ارتفاع textarea را تنظیم میکند\r\n useEffect(() => {\r\n const textarea = textareaRef.current;\r\n if (textarea) {\r\n // ارتفاع را ریست میکنیم تا در صورت پاک کردن متن، کوچک شود\r\n textarea.style.height = 'auto';\r\n // ارتفاع جدید را بر اساس محتوای داخلی تنظیم میکنیم\r\n textarea.style.height = `${textarea.scrollHeight}px`;\r\n }\r\n }, [inputValue]);\r\n\r\n const handleSend = () => {\r\n if (inputValue.trim()) {\r\n onSendMessage(inputValue);\r\n setInputValue('');\r\n }\r\n };\r\n\r\n // این منطق به درستی Shift+Enter را برای ایجاد خط جدید مدیریت میکند\r\n const handleKeyDown = (e: React.KeyboardEvent) => {\r\n if (e.key === 'Enter' && !e.shiftKey) {\r\n e.preventDefault();\r\n handleSend();\r\n }\r\n };\r\n\r\n return (\r\n <div className=\"mra-input-wrapper\">\r\n <textarea\r\n ref={textareaRef}\r\n className=\"mra-input-field\"\r\n value={inputValue}\r\n onChange={(e) => setInputValue(e.target.value)}\r\n onKeyDown={handleKeyDown}\r\n placeholder=\"پیام خود را بنویسید...\"\r\n disabled={isLoading}\r\n rows={1} // با یک ردیف شروع میشود\r\n />\r\n <button\r\n className=\"mra-send-button\"\r\n onClick={handleSend}\r\n disabled={isLoading || !inputValue.trim()}\r\n >\r\n <Send size={18} />\r\n </button>\r\n </div>\r\n );\r\n};","\r\n\"use client\";\r\nimport React from 'react';\r\nimport Lottie from 'lottie-react';\r\n\r\ninterface ChatbotFABProps {\r\n onClick: () => void;\r\n \r\n \r\n animationData: any; \r\n}\r\n\r\nexport const ChatbotFAB: React.FC<ChatbotFABProps> = ({ onClick, animationData }) => {\r\n \r\n \r\n const lottieProps = typeof animationData === 'string' \r\n ? { animationData: null, path: animationData } \r\n : { animationData: animationData };\r\n\r\n return (\r\n <button className=\"mra-fab\" onClick={onClick}>\r\n <Lottie {...lottieProps} loop={true} />\r\n </button>\r\n );\r\n};"],"mappings":"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","names":["import_react","import_react","clsx","import_jsx_runtime","import_react","import_jsx_runtime","import_lucide_react","import_jsx_runtime","import_jsx_runtime","Lottie","import_clsx","import_jsx_runtime","clsx"]}
|
package/dist/react.mjs
CHANGED
|
@@ -97,16 +97,18 @@ var ChatInput = ({ onSendMessage, isLoading }) => {
|
|
|
97
97
|
};
|
|
98
98
|
|
|
99
99
|
// src/components/ChatWindow/ChatWindow.tsx
|
|
100
|
-
import { Bot } from "lucide-react";
|
|
100
|
+
import { Bot, Maximize, Minimize } from "lucide-react";
|
|
101
101
|
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
102
102
|
var ChatWindow = ({
|
|
103
103
|
apiEndpoint,
|
|
104
104
|
title = "AI Assistant",
|
|
105
|
-
welcomeMessage = "\u0633\u0644\u0627\u0645! \u0686\u0637\u0648\u0631 \u0645\u06CC\u200C\u062A\u0648\u0627\u0646\u0645 \u06A9\u0645\u06A9\u062A\u0627\u0646 \u06A9\u0646\u0645\u061F"
|
|
105
|
+
welcomeMessage = "\u0633\u0644\u0627\u0645! \u0686\u0637\u0648\u0631 \u0645\u06CC\u200C\u062A\u0648\u0627\u0646\u0645 \u06A9\u0645\u06A9\u062A\u0627\u0646 \u06A9\u0646\u0645\u061F",
|
|
106
|
+
isFullScreen = false,
|
|
107
|
+
onToggleFullScreen
|
|
106
108
|
}) => {
|
|
107
109
|
const [messages, setMessages] = useState2([]);
|
|
108
110
|
const [isLoading, setIsLoading] = useState2(false);
|
|
109
|
-
const version = "0.9.
|
|
111
|
+
const version = "0.9.2";
|
|
110
112
|
useEffect3(() => {
|
|
111
113
|
if (welcomeMessage && messages.length === 0) {
|
|
112
114
|
setMessages([{ role: "assistant", content: welcomeMessage }]);
|
|
@@ -137,8 +139,11 @@ var ChatWindow = ({
|
|
|
137
139
|
};
|
|
138
140
|
return /* @__PURE__ */ jsxs3("div", { className: "mra-chat-window", children: [
|
|
139
141
|
/* @__PURE__ */ jsxs3("div", { className: "mra-header", children: [
|
|
140
|
-
/* @__PURE__ */
|
|
141
|
-
|
|
142
|
+
/* @__PURE__ */ jsxs3("div", { className: "mra-header-title-group", children: [
|
|
143
|
+
/* @__PURE__ */ jsx4(Bot, { size: 20 }),
|
|
144
|
+
/* @__PURE__ */ jsx4("span", { className: "mra-title", children: title })
|
|
145
|
+
] }),
|
|
146
|
+
onToggleFullScreen && /* @__PURE__ */ jsx4("button", { onClick: onToggleFullScreen, className: "mra-header-icon-button", children: isFullScreen ? /* @__PURE__ */ jsx4(Minimize, { size: 16 }) : /* @__PURE__ */ jsx4(Maximize, { size: 16 }) })
|
|
142
147
|
] }),
|
|
143
148
|
/* @__PURE__ */ jsx4(MessageList, { messages, isLoading }),
|
|
144
149
|
/* @__PURE__ */ jsx4(ChatInput, { onSendMessage: handleSendMessage, isLoading }),
|
|
@@ -159,8 +164,9 @@ var ChatWindow = ({
|
|
|
159
164
|
// src/components/ChatbotFAB/ChatbotFAB.tsx
|
|
160
165
|
import Lottie from "lottie-react";
|
|
161
166
|
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
162
|
-
var ChatbotFAB = ({ onClick,
|
|
163
|
-
|
|
167
|
+
var ChatbotFAB = ({ onClick, animationData }) => {
|
|
168
|
+
const lottieProps = typeof animationData === "string" ? { animationData: null, path: animationData } : { animationData };
|
|
169
|
+
return /* @__PURE__ */ jsx5("button", { className: "mra-fab", onClick, children: /* @__PURE__ */ jsx5(Lottie, { ...lottieProps, loop: true }) });
|
|
164
170
|
};
|
|
165
171
|
|
|
166
172
|
// src/components/AiAssistant/AiAssistant.tsx
|
|
@@ -168,18 +174,27 @@ import clsx2 from "clsx";
|
|
|
168
174
|
import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
169
175
|
var DEFAULT_LOTTIE_URL = "https://lottie.host/a822cf1a-1e96-4187-a220-42adb2a61d19/B5bQnC2p9K.json";
|
|
170
176
|
var AiAssistant = ({
|
|
171
|
-
|
|
177
|
+
lottieAnimationData = DEFAULT_LOTTIE_URL,
|
|
172
178
|
...chatWindowProps
|
|
173
|
-
// بقیه پراپها برای ChatWindow هستند
|
|
174
179
|
}) => {
|
|
175
180
|
const [isOpen, setIsOpen] = useState3(false);
|
|
176
|
-
const
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
return
|
|
180
|
-
|
|
181
|
-
/* @__PURE__ */
|
|
182
|
-
|
|
181
|
+
const [isFullScreen, setIsFullScreen] = useState3(false);
|
|
182
|
+
const toggleChat = () => setIsOpen((prev) => !prev);
|
|
183
|
+
const toggleFullScreen = () => setIsFullScreen((prev) => !prev);
|
|
184
|
+
return (
|
|
185
|
+
// اگر تمامصفحه باشد، کلاس جدید اضافه میشود
|
|
186
|
+
/* @__PURE__ */ jsxs4("div", { className: clsx2("mra-container", isFullScreen && "mra-container--fullscreen"), children: [
|
|
187
|
+
/* @__PURE__ */ jsx6("div", { className: clsx2("mra-chat-window-container", isOpen && "mra-chat-window-container--open"), children: /* @__PURE__ */ jsx6(
|
|
188
|
+
ChatWindow,
|
|
189
|
+
{
|
|
190
|
+
...chatWindowProps,
|
|
191
|
+
isFullScreen,
|
|
192
|
+
onToggleFullScreen: toggleFullScreen
|
|
193
|
+
}
|
|
194
|
+
) }),
|
|
195
|
+
/* @__PURE__ */ jsx6(ChatbotFAB, { onClick: toggleChat, animationData: lottieAnimationData })
|
|
196
|
+
] })
|
|
197
|
+
);
|
|
183
198
|
};
|
|
184
199
|
export {
|
|
185
200
|
AiAssistant,
|
package/dist/react.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/AiAssistant/AiAssistant.tsx","../src/components/ChatWindow/ChatWindow.tsx","../src/components/MessageList/MessageList.tsx","../src/components/MessageBubble/MessageBubble.tsx","../src/components/ChatInput/ChatInput.tsx","../src/components/ChatbotFAB/ChatbotFAB.tsx"],"sourcesContent":["// src/components/AiAssistant/AiAssistant.tsx\r\n\"use client\";\r\nimport React, { useState } from 'react';\r\nimport { ChatWindow, ChatWindowProps } from '../ChatWindow/ChatWindow';\r\nimport { ChatbotFAB } from '../ChatbotFAB/ChatbotFAB';\r\nimport clsx from 'clsx';\r\n\r\n// این کامپوننت تمام پراپهای ChatWindow را به علاوهی پراپ lottieUrl میپذیرد\r\ninterface AiAssistantProps extends ChatWindowProps {\r\n lottieUrl?: string;\r\n}\r\n\r\n// یک انیمیشن پیشفرض جذاب\r\nconst DEFAULT_LOTTIE_URL = \"https://lottie.host/a822cf1a-1e96-4187-a220-42adb2a61d19/B5bQnC2p9K.json\";\r\n\r\nexport const AiAssistant: React.FC<AiAssistantProps> = ({ \r\n lottieUrl = DEFAULT_LOTTIE_URL,\r\n ...chatWindowProps // بقیه پراپها برای ChatWindow هستند\r\n}) => {\r\n const [isOpen, setIsOpen] = useState(false);\r\n\r\n const toggleChat = () => {\r\n setIsOpen(prev => !prev);\r\n };\r\n\r\n return (\r\n <div className=\"mra-container\">\r\n \r\n <div className={clsx(\"mra-chat-window-container\", isOpen && \"mra-chat-window-container--open\")}>\r\n <ChatWindow {...chatWindowProps} />\r\n </div>\r\n\r\n \r\n <ChatbotFAB onClick={toggleChat} lottieUrl={lottieUrl} />\r\n </div>\r\n );\r\n};","// src/components/ChatWindow/ChatWindow.tsx\r\n\"use client\";\r\n\r\nimport React, { useState, useEffect } from 'react';\r\nimport { MessageList } from '../MessageList/MessageList';\r\nimport { ChatInput } from '../ChatInput/ChatInput';\r\nimport { Message } from '../../types';\r\nimport { Bot } from 'lucide-react';\r\n\r\nexport interface ChatWindowProps {\r\n apiEndpoint: string;\r\n title?: string;\r\n welcomeMessage?: string;\r\n}\r\n\r\nexport const ChatWindow: React.FC<ChatWindowProps> = ({\r\n apiEndpoint,\r\n title = \"AI Assistant\",\r\n welcomeMessage = \"سلام! چطور میتوانم کمکتان کنم؟\"\r\n}) => {\r\n const [messages, setMessages] = useState<Message[]>([]);\r\n const [isLoading, setIsLoading] = useState(false);\r\n const version = process.env.PACKAGE_VERSION; \r\n\r\n useEffect(() => {\r\n if (welcomeMessage && messages.length === 0) {\r\n setMessages([{ role: 'assistant', content: welcomeMessage }]);\r\n }\r\n }, [welcomeMessage, messages.length]);\r\n\r\n const handleSendMessage = async (userMessage: string) => {\r\n const newUserMsg: Message = { role: 'user', content: userMessage };\r\n const currentMessages = [...messages, newUserMsg];\r\n setMessages(currentMessages);\r\n setIsLoading(true);\r\n\r\n try {\r\n const response = await fetch(apiEndpoint, {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({ messages: currentMessages }),\r\n });\r\n\r\n if (!response.ok) throw new Error(\"Network response was not ok\");\r\n \r\n const data = await response.json();\r\n const botMsg: Message = { role: 'assistant', content: data.content };\r\n setMessages(prev => [...prev, botMsg]);\r\n\r\n } catch (error) {\r\n console.error(\"Chat Error:\", error);\r\n const errorMsg: Message = { role: 'assistant', content: \"خطایی رخ داده است.\" };\r\n setMessages(prev => [...prev, errorMsg]);\r\n } finally {\r\n setIsLoading(false);\r\n }\r\n };\r\n\r\n return (\r\n <div className=\"mra-chat-window\">\r\n <div className=\"mra-header\">\r\n <Bot size={20} />\r\n <span className=\"mra-title\">{title}</span>\r\n </div>\r\n\r\n <MessageList messages={messages} isLoading={isLoading} />\r\n <ChatInput onSendMessage={handleSendMessage} isLoading={isLoading} />\r\n\r\n {/* === فوتر جدید اضافه شده === */}\r\n <footer className=\"mra-footer\">\r\n <span>v{version}</span>\r\n <div className=\"mra-footer-links\">\r\n <span>Powered By Mehdi Akbari |</span>\r\n <a href=\"mailto:mehdiakbarideveloper@gmail.com\" className=\"mra-footer-link\" target=\"_blank\" rel=\"noopener noreferrer\">Gmail</a>\r\n <a href=\"https://t.me/MehdiAkbariDev\" className=\"mra-footer-link\" target=\"_blank\" rel=\"noopener noreferrer\">Telegram</a>\r\n </div>\r\n </footer>\r\n </div>\r\n );\r\n};","// src/components/MessageList/MessageList.tsx\r\n\"use client\";\r\n\r\nimport React, { useRef, useEffect } from 'react';\r\nimport { MessageBubble } from '../MessageBubble/MessageBubble';\r\nimport { Message } from '../../types';\r\n\r\ninterface MessageListProps {\r\n messages: Message[];\r\n isLoading: boolean;\r\n}\r\n\r\nexport const MessageList: React.FC<MessageListProps> = ({ messages, isLoading }) => {\r\n const messagesEndRef = useRef<HTMLDivElement>(null);\r\n\r\n useEffect(() => {\r\n messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });\r\n }, [messages, isLoading]);\r\n\r\n return (\r\n <div className=\"mra-message-list\">\r\n {messages.map((msg, index) => (\r\n <MessageBubble key={index} message={msg} />\r\n ))}\r\n\r\n {isLoading && (\r\n <div className=\"mra-loading-wrapper\">\r\n <div className=\"mra-loading-bubble\">\r\n <div className=\"mra-loading-dot\" style={{ animationDelay: '-0.32s' }}></div>\r\n <div className=\"mra-loading-dot\" style={{ animationDelay: '-0.16s' }}></div>\r\n <div className=\"mra-loading-dot\"></div>\r\n </div>\r\n </div>\r\n )}\r\n\r\n <div ref={messagesEndRef} />\r\n </div>\r\n );\r\n};","// src/components/MessageBubble/MessageBubble.tsx\r\n\"use client\";\r\n\r\nimport React from 'react';\r\nimport clsx from 'clsx';\r\nimport { Message } from '../../types';\r\n\r\ninterface MessageBubbleProps {\r\n message: Message;\r\n}\r\n\r\nexport const MessageBubble: React.FC<MessageBubbleProps> = ({ message }) => {\r\n const isUser = message.role === 'user';\r\n\r\n return (\r\n <div className={clsx(\"mra-bubble-wrapper\", isUser ? \"mra-wrapper-user\" : \"mra-wrapper-bot\")}>\r\n <div\r\n className={clsx(\r\n \"mra-bubble\",\r\n isUser ? \"mra-bubble-user\" : \"mra-bubble-bot\"\r\n )}\r\n >\r\n {message.content}\r\n </div>\r\n </div>\r\n );\r\n};","// src/components/ChatInput/ChatInput.tsx\r\n\"use client\";\r\n\r\nimport React, { useState, useRef, useEffect } from 'react';\r\nimport { Send } from 'lucide-react';\r\n\r\ninterface ChatInputProps {\r\n onSendMessage: (message: string) => void;\r\n isLoading: boolean;\r\n}\r\n\r\nexport const ChatInput: React.FC<ChatInputProps> = ({ onSendMessage, isLoading }) => {\r\n const [inputValue, setInputValue] = useState('');\r\n const textareaRef = useRef<HTMLTextAreaElement>(null); // Ref برای دسترسی به textarea\r\n\r\n // این افکت با هر بار تغییر متن، ارتفاع textarea را تنظیم میکند\r\n useEffect(() => {\r\n const textarea = textareaRef.current;\r\n if (textarea) {\r\n // ارتفاع را ریست میکنیم تا در صورت پاک کردن متن، کوچک شود\r\n textarea.style.height = 'auto';\r\n // ارتفاع جدید را بر اساس محتوای داخلی تنظیم میکنیم\r\n textarea.style.height = `${textarea.scrollHeight}px`;\r\n }\r\n }, [inputValue]);\r\n\r\n const handleSend = () => {\r\n if (inputValue.trim()) {\r\n onSendMessage(inputValue);\r\n setInputValue('');\r\n }\r\n };\r\n\r\n // این منطق به درستی Shift+Enter را برای ایجاد خط جدید مدیریت میکند\r\n const handleKeyDown = (e: React.KeyboardEvent) => {\r\n if (e.key === 'Enter' && !e.shiftKey) {\r\n e.preventDefault();\r\n handleSend();\r\n }\r\n };\r\n\r\n return (\r\n <div className=\"mra-input-wrapper\">\r\n <textarea\r\n ref={textareaRef}\r\n className=\"mra-input-field\"\r\n value={inputValue}\r\n onChange={(e) => setInputValue(e.target.value)}\r\n onKeyDown={handleKeyDown}\r\n placeholder=\"پیام خود را بنویسید...\"\r\n disabled={isLoading}\r\n rows={1} // با یک ردیف شروع میشود\r\n />\r\n <button\r\n className=\"mra-send-button\"\r\n onClick={handleSend}\r\n disabled={isLoading || !inputValue.trim()}\r\n >\r\n <Send size={18} />\r\n </button>\r\n </div>\r\n );\r\n};","\r\n\"use client\";\r\nimport React from 'react';\r\nimport Lottie from 'lottie-react';\r\n\r\ninterface ChatbotFABProps {\r\n onClick: () => void;\r\n lottieUrl: string; \r\n}\r\n\r\nexport const ChatbotFAB: React.FC<ChatbotFABProps> = ({ onClick, lottieUrl }) => {\r\n return (\r\n <button className=\"mra-fab\" onClick={onClick}>\r\n <Lottie animationData={lottieUrl} loop={true} />\r\n </button>\r\n );\r\n};"],"mappings":";;;AAEA,SAAgB,YAAAA,iBAAgB;;;ACChC,SAAgB,YAAAC,WAAU,aAAAC,kBAAiB;;;ACA3C,SAAgB,QAAQ,iBAAiB;;;ACCzC,OAAO,UAAU;AAYX;AALC,IAAM,gBAA8C,CAAC,EAAE,QAAQ,MAAM;AAC1E,QAAM,SAAS,QAAQ,SAAS;AAEhC,SACE,oBAAC,SAAI,WAAW,KAAK,sBAAsB,SAAS,qBAAqB,iBAAiB,GACxF;AAAA,IAAC;AAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACA,SAAS,oBAAoB;AAAA,MAC/B;AAAA,MAEC,kBAAQ;AAAA;AAAA,EACX,GACF;AAEJ;;;ADJQ,gBAAAC,MAKE,YALF;AAVD,IAAM,cAA0C,CAAC,EAAE,UAAU,UAAU,MAAM;AAClF,QAAM,iBAAiB,OAAuB,IAAI;AAElD,YAAU,MAAM;AACd,mBAAe,SAAS,eAAe,EAAE,UAAU,SAAS,CAAC;AAAA,EAC/D,GAAG,CAAC,UAAU,SAAS,CAAC;AAExB,SACE,qBAAC,SAAI,WAAU,oBACZ;AAAA,aAAS,IAAI,CAAC,KAAK,UAClB,gBAAAA,KAAC,iBAA0B,SAAS,OAAhB,KAAqB,CAC1C;AAAA,IAEA,aACC,gBAAAA,KAAC,SAAI,WAAU,uBACb,+BAAC,SAAI,WAAU,sBACb;AAAA,sBAAAA,KAAC,SAAI,WAAU,mBAAkB,OAAO,EAAE,gBAAgB,SAAS,GAAG;AAAA,MACtE,gBAAAA,KAAC,SAAI,WAAU,mBAAkB,OAAO,EAAE,gBAAgB,SAAS,GAAG;AAAA,MACtE,gBAAAA,KAAC,SAAI,WAAU,mBAAkB;AAAA,OACnC,GACF;AAAA,IAGF,gBAAAA,KAAC,SAAI,KAAK,gBAAgB;AAAA,KAC5B;AAEJ;;;AEnCA,SAAgB,UAAU,UAAAC,SAAQ,aAAAC,kBAAiB;AACnD,SAAS,YAAY;AAsCjB,SACE,OAAAC,MADF,QAAAC,aAAA;AA/BG,IAAM,YAAsC,CAAC,EAAE,eAAe,UAAU,MAAM;AACnF,QAAM,CAAC,YAAY,aAAa,IAAI,SAAS,EAAE;AAC/C,QAAM,cAAcH,QAA4B,IAAI;AAGpD,EAAAC,WAAU,MAAM;AACd,UAAM,WAAW,YAAY;AAC7B,QAAI,UAAU;AAEZ,eAAS,MAAM,SAAS;AAExB,eAAS,MAAM,SAAS,GAAG,SAAS,YAAY;AAAA,IAClD;AAAA,EACF,GAAG,CAAC,UAAU,CAAC;AAEf,QAAM,aAAa,MAAM;AACvB,QAAI,WAAW,KAAK,GAAG;AACrB,oBAAc,UAAU;AACxB,oBAAc,EAAE;AAAA,IAClB;AAAA,EACF;AAGA,QAAM,gBAAgB,CAAC,MAA2B;AAChD,QAAI,EAAE,QAAQ,WAAW,CAAC,EAAE,UAAU;AACpC,QAAE,eAAe;AACjB,iBAAW;AAAA,IACb;AAAA,EACF;AAEA,SACE,gBAAAE,MAAC,SAAI,WAAU,qBACb;AAAA,oBAAAD;AAAA,MAAC;AAAA;AAAA,QACC,KAAK;AAAA,QACL,WAAU;AAAA,QACV,OAAO;AAAA,QACP,UAAU,CAAC,MAAM,cAAc,EAAE,OAAO,KAAK;AAAA,QAC7C,WAAW;AAAA,QACX,aAAY;AAAA,QACZ,UAAU;AAAA,QACV,MAAM;AAAA;AAAA,IACR;AAAA,IACA,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,WAAU;AAAA,QACV,SAAS;AAAA,QACT,UAAU,aAAa,CAAC,WAAW,KAAK;AAAA,QAExC,0BAAAA,KAAC,QAAK,MAAM,IAAI;AAAA;AAAA,IAClB;AAAA,KACF;AAEJ;;;AHvDA,SAAS,WAAW;AAqDd,SACE,OAAAE,MADF,QAAAC,aAAA;AA7CC,IAAM,aAAwC,CAAC;AAAA,EACpD;AAAA,EACA,QAAQ;AAAA,EACR,iBAAiB;AACnB,MAAM;AACJ,QAAM,CAAC,UAAU,WAAW,IAAIC,UAAoB,CAAC,CAAC;AACtD,QAAM,CAAC,WAAW,YAAY,IAAIA,UAAS,KAAK;AAChD,QAAM,UAAU;AAEhB,EAAAC,WAAU,MAAM;AACd,QAAI,kBAAkB,SAAS,WAAW,GAAG;AAC3C,kBAAY,CAAC,EAAE,MAAM,aAAa,SAAS,eAAe,CAAC,CAAC;AAAA,IAC9D;AAAA,EACF,GAAG,CAAC,gBAAgB,SAAS,MAAM,CAAC;AAEpC,QAAM,oBAAoB,OAAO,gBAAwB;AACvD,UAAM,aAAsB,EAAE,MAAM,QAAQ,SAAS,YAAY;AACjE,UAAM,kBAAkB,CAAC,GAAG,UAAU,UAAU;AAChD,gBAAY,eAAe;AAC3B,iBAAa,IAAI;AAEjB,QAAI;AACF,YAAM,WAAW,MAAM,MAAM,aAAa;AAAA,QACxC,QAAQ;AAAA,QACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,QAC9C,MAAM,KAAK,UAAU,EAAE,UAAU,gBAAgB,CAAC;AAAA,MACpD,CAAC;AAED,UAAI,CAAC,SAAS,GAAI,OAAM,IAAI,MAAM,6BAA6B;AAE/D,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,SAAkB,EAAE,MAAM,aAAa,SAAS,KAAK,QAAQ;AACnE,kBAAY,UAAQ,CAAC,GAAG,MAAM,MAAM,CAAC;AAAA,IAEvC,SAAS,OAAO;AACd,cAAQ,MAAM,eAAe,KAAK;AAClC,YAAM,WAAoB,EAAE,MAAM,aAAa,SAAS,2FAAqB;AAC7E,kBAAY,UAAQ,CAAC,GAAG,MAAM,QAAQ,CAAC;AAAA,IACzC,UAAE;AACA,mBAAa,KAAK;AAAA,IACpB;AAAA,EACF;AAEA,SACE,gBAAAF,MAAC,SAAI,WAAU,mBACb;AAAA,oBAAAA,MAAC,SAAI,WAAU,cACb;AAAA,sBAAAD,KAAC,OAAI,MAAM,IAAI;AAAA,MACf,gBAAAA,KAAC,UAAK,WAAU,aAAa,iBAAM;AAAA,OACrC;AAAA,IAEA,gBAAAA,KAAC,eAAY,UAAoB,WAAsB;AAAA,IACvD,gBAAAA,KAAC,aAAU,eAAe,mBAAmB,WAAsB;AAAA,IAGnE,gBAAAC,MAAC,YAAO,WAAU,cAChB;AAAA,sBAAAA,MAAC,UAAK;AAAA;AAAA,QAAE;AAAA,SAAQ;AAAA,MAChB,gBAAAA,MAAC,SAAI,WAAU,oBACb;AAAA,wBAAAD,KAAC,UAAK,uCAAyB;AAAA,QAC/B,gBAAAA,KAAC,OAAE,MAAK,yCAAwC,WAAU,mBAAkB,QAAO,UAAS,KAAI,uBAAsB,mBAAK;AAAA,QAC3H,gBAAAA,KAAC,OAAE,MAAK,+BAA8B,WAAU,mBAAkB,QAAO,UAAS,KAAI,uBAAsB,sBAAQ;AAAA,SACtH;AAAA,OACF;AAAA,KACF;AAEJ;;;AI5EA,OAAO,YAAY;AAUb,gBAAAI,YAAA;AAHC,IAAM,aAAwC,CAAC,EAAE,SAAS,UAAU,MAAM;AAC/E,SACE,gBAAAA,KAAC,YAAO,WAAU,WAAU,SAC1B,0BAAAA,KAAC,UAAO,eAAe,WAAW,MAAM,MAAM,GAChD;AAEJ;;;ALXA,OAAOC,WAAU;AAqBb,SAGI,OAAAC,MAHJ,QAAAC,aAAA;AAbJ,IAAM,qBAAqB;AAEpB,IAAM,cAA0C,CAAC;AAAA,EACtD,YAAY;AAAA,EACZ,GAAG;AAAA;AACL,MAAM;AACJ,QAAM,CAAC,QAAQ,SAAS,IAAIC,UAAS,KAAK;AAE1C,QAAM,aAAa,MAAM;AACvB,cAAU,UAAQ,CAAC,IAAI;AAAA,EACzB;AAEA,SACE,gBAAAD,MAAC,SAAI,WAAU,iBAEb;AAAA,oBAAAD,KAAC,SAAI,WAAWD,MAAK,6BAA6B,UAAU,iCAAiC,GAC3F,0BAAAC,KAAC,cAAY,GAAG,iBAAiB,GACnC;AAAA,IAGA,gBAAAA,KAAC,cAAW,SAAS,YAAY,WAAsB;AAAA,KACzD;AAEJ;","names":["useState","useState","useEffect","jsx","useRef","useEffect","jsx","jsxs","jsx","jsxs","useState","useEffect","jsx","clsx","jsx","jsxs","useState"]}
|
|
1
|
+
{"version":3,"sources":["../src/components/AiAssistant/AiAssistant.tsx","../src/components/ChatWindow/ChatWindow.tsx","../src/components/MessageList/MessageList.tsx","../src/components/MessageBubble/MessageBubble.tsx","../src/components/ChatInput/ChatInput.tsx","../src/components/ChatbotFAB/ChatbotFAB.tsx"],"sourcesContent":["// src/components/AiAssistant/AiAssistant.tsx\r\n\"use client\";\r\nimport React, { useState } from 'react';\r\nimport { ChatWindow, ChatWindowProps } from '../ChatWindow/ChatWindow';\r\nimport { ChatbotFAB } from '../ChatbotFAB/ChatbotFAB';\r\nimport clsx from 'clsx';\r\n\r\ninterface AiAssistantProps extends ChatWindowProps {\r\n lottieAnimationData?: any;\r\n}\r\n\r\nconst DEFAULT_LOTTIE_URL = \"https://lottie.host/a822cf1a-1e96-4187-a220-42adb2a61d19/B5bQnC2p9K.json\";\r\n\r\nexport const AiAssistant: React.FC<AiAssistantProps> = ({\r\n lottieAnimationData = DEFAULT_LOTTIE_URL,\r\n ...chatWindowProps\r\n}) => {\r\n const [isOpen, setIsOpen] = useState(false);\r\n const [isFullScreen, setIsFullScreen] = useState(false); // استیت جدید برای حالت تمامصفحه\r\n\r\n const toggleChat = () => setIsOpen(prev => !prev);\r\n const toggleFullScreen = () => setIsFullScreen(prev => !prev);\r\n\r\n return (\r\n // اگر تمامصفحه باشد، کلاس جدید اضافه میشود\r\n <div className={clsx(\"mra-container\", isFullScreen && \"mra-container--fullscreen\")}>\r\n <div className={clsx(\"mra-chat-window-container\", isOpen && \"mra-chat-window-container--open\")}>\r\n <ChatWindow\r\n {...chatWindowProps}\r\n // دو پراپ جدید به ChatWindow پاس میدهیم\r\n isFullScreen={isFullScreen}\r\n onToggleFullScreen={toggleFullScreen}\r\n />\r\n </div>\r\n <ChatbotFAB onClick={toggleChat} animationData={lottieAnimationData} />\r\n </div>\r\n );\r\n};","// src/components/ChatWindow/ChatWindow.tsx\r\n\"use client\";\r\n\r\nimport React, { useState, useEffect } from 'react';\r\nimport { MessageList } from '../MessageList/MessageList';\r\nimport { ChatInput } from '../ChatInput/ChatInput';\r\nimport { Message } from '../../types';\r\nimport { Bot, Maximize, Minimize } from 'lucide-react'; // آیکونهای تمامصفحه اضافه شدند\r\n\r\n// پراپهای کامپوننت با گزینههای جدید آپدیت شدند\r\nexport interface ChatWindowProps {\r\n apiEndpoint: string;\r\n title?: string;\r\n welcomeMessage?: string;\r\n isFullScreen?: boolean;\r\n onToggleFullScreen?: () => void;\r\n}\r\n\r\nexport const ChatWindow: React.FC<ChatWindowProps> = ({\r\n apiEndpoint,\r\n title = \"AI Assistant\",\r\n welcomeMessage = \"سلام! چطور میتوانم کمکتان کنم؟\",\r\n isFullScreen = false,\r\n onToggleFullScreen,\r\n}) => {\r\n const [messages, setMessages] = useState<Message[]>([]);\r\n const [isLoading, setIsLoading] = useState(false);\r\n const version = process.env.PACKAGE_VERSION; \r\n\r\n useEffect(() => {\r\n if (welcomeMessage && messages.length === 0) {\r\n setMessages([{ role: 'assistant', content: welcomeMessage }]);\r\n }\r\n }, [welcomeMessage, messages.length]);\r\n\r\n const handleSendMessage = async (userMessage: string) => {\r\n const newUserMsg: Message = { role: 'user', content: userMessage };\r\n const currentMessages = [...messages, newUserMsg];\r\n setMessages(currentMessages);\r\n setIsLoading(true);\r\n\r\n try {\r\n const response = await fetch(apiEndpoint, {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({ messages: currentMessages }),\r\n });\r\n\r\n if (!response.ok) throw new Error(\"Network response was not ok\");\r\n \r\n const data = await response.json();\r\n const botMsg: Message = { role: 'assistant', content: data.content };\r\n setMessages(prev => [...prev, botMsg]);\r\n\r\n } catch (error) {\r\n console.error(\"Chat Error:\", error);\r\n const errorMsg: Message = { role: 'assistant', content: \"خطایی رخ داده است.\" };\r\n setMessages(prev => [...prev, errorMsg]);\r\n } finally {\r\n setIsLoading(false);\r\n }\r\n };\r\n\r\n return (\r\n <div className=\"mra-chat-window\">\r\n {/* هدر با دکمه تمامصفحه آپدیت شده است */}\r\n <div className=\"mra-header\">\r\n <div className=\"mra-header-title-group\">\r\n <Bot size={20} />\r\n <span className=\"mra-title\">{title}</span>\r\n </div>\r\n {onToggleFullScreen && (\r\n <button onClick={onToggleFullScreen} className=\"mra-header-icon-button\">\r\n {isFullScreen ? <Minimize size={16} /> : <Maximize size={16} />}\r\n </button>\r\n )}\r\n </div>\r\n\r\n <MessageList messages={messages} isLoading={isLoading} />\r\n <ChatInput onSendMessage={handleSendMessage} isLoading={isLoading} />\r\n\r\n <footer className=\"mra-footer\">\r\n <span>v{version}</span>\r\n <div className=\"mra-footer-links\">\r\n <span>Powered By Mehdi Akbari |</span>\r\n <a href=\"mailto:mehdiakbarideveloper@gmail.com\" className=\"mra-footer-link\" target=\"_blank\" rel=\"noopener noreferrer\">Gmail</a>\r\n <a href=\"https://t.me/MehdiAkbariDev\" className=\"mra-footer-link\" target=\"_blank\" rel=\"noopener noreferrer\">Telegram</a>\r\n </div>\r\n </footer>\r\n </div>\r\n );\r\n};","// src/components/MessageList/MessageList.tsx\r\n\"use client\";\r\n\r\nimport React, { useRef, useEffect } from 'react';\r\nimport { MessageBubble } from '../MessageBubble/MessageBubble';\r\nimport { Message } from '../../types';\r\n\r\ninterface MessageListProps {\r\n messages: Message[];\r\n isLoading: boolean;\r\n}\r\n\r\nexport const MessageList: React.FC<MessageListProps> = ({ messages, isLoading }) => {\r\n const messagesEndRef = useRef<HTMLDivElement>(null);\r\n\r\n useEffect(() => {\r\n messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });\r\n }, [messages, isLoading]);\r\n\r\n return (\r\n <div className=\"mra-message-list\">\r\n {messages.map((msg, index) => (\r\n <MessageBubble key={index} message={msg} />\r\n ))}\r\n\r\n {isLoading && (\r\n <div className=\"mra-loading-wrapper\">\r\n <div className=\"mra-loading-bubble\">\r\n <div className=\"mra-loading-dot\" style={{ animationDelay: '-0.32s' }}></div>\r\n <div className=\"mra-loading-dot\" style={{ animationDelay: '-0.16s' }}></div>\r\n <div className=\"mra-loading-dot\"></div>\r\n </div>\r\n </div>\r\n )}\r\n\r\n <div ref={messagesEndRef} />\r\n </div>\r\n );\r\n};","// src/components/MessageBubble/MessageBubble.tsx\r\n\"use client\";\r\n\r\nimport React from 'react';\r\nimport clsx from 'clsx';\r\nimport { Message } from '../../types';\r\n\r\ninterface MessageBubbleProps {\r\n message: Message;\r\n}\r\n\r\nexport const MessageBubble: React.FC<MessageBubbleProps> = ({ message }) => {\r\n const isUser = message.role === 'user';\r\n\r\n return (\r\n <div className={clsx(\"mra-bubble-wrapper\", isUser ? \"mra-wrapper-user\" : \"mra-wrapper-bot\")}>\r\n <div\r\n className={clsx(\r\n \"mra-bubble\",\r\n isUser ? \"mra-bubble-user\" : \"mra-bubble-bot\"\r\n )}\r\n >\r\n {message.content}\r\n </div>\r\n </div>\r\n );\r\n};","// src/components/ChatInput/ChatInput.tsx\r\n\"use client\";\r\n\r\nimport React, { useState, useRef, useEffect } from 'react';\r\nimport { Send } from 'lucide-react';\r\n\r\ninterface ChatInputProps {\r\n onSendMessage: (message: string) => void;\r\n isLoading: boolean;\r\n}\r\n\r\nexport const ChatInput: React.FC<ChatInputProps> = ({ onSendMessage, isLoading }) => {\r\n const [inputValue, setInputValue] = useState('');\r\n const textareaRef = useRef<HTMLTextAreaElement>(null); // Ref برای دسترسی به textarea\r\n\r\n // این افکت با هر بار تغییر متن، ارتفاع textarea را تنظیم میکند\r\n useEffect(() => {\r\n const textarea = textareaRef.current;\r\n if (textarea) {\r\n // ارتفاع را ریست میکنیم تا در صورت پاک کردن متن، کوچک شود\r\n textarea.style.height = 'auto';\r\n // ارتفاع جدید را بر اساس محتوای داخلی تنظیم میکنیم\r\n textarea.style.height = `${textarea.scrollHeight}px`;\r\n }\r\n }, [inputValue]);\r\n\r\n const handleSend = () => {\r\n if (inputValue.trim()) {\r\n onSendMessage(inputValue);\r\n setInputValue('');\r\n }\r\n };\r\n\r\n // این منطق به درستی Shift+Enter را برای ایجاد خط جدید مدیریت میکند\r\n const handleKeyDown = (e: React.KeyboardEvent) => {\r\n if (e.key === 'Enter' && !e.shiftKey) {\r\n e.preventDefault();\r\n handleSend();\r\n }\r\n };\r\n\r\n return (\r\n <div className=\"mra-input-wrapper\">\r\n <textarea\r\n ref={textareaRef}\r\n className=\"mra-input-field\"\r\n value={inputValue}\r\n onChange={(e) => setInputValue(e.target.value)}\r\n onKeyDown={handleKeyDown}\r\n placeholder=\"پیام خود را بنویسید...\"\r\n disabled={isLoading}\r\n rows={1} // با یک ردیف شروع میشود\r\n />\r\n <button\r\n className=\"mra-send-button\"\r\n onClick={handleSend}\r\n disabled={isLoading || !inputValue.trim()}\r\n >\r\n <Send size={18} />\r\n </button>\r\n </div>\r\n );\r\n};","\r\n\"use client\";\r\nimport React from 'react';\r\nimport Lottie from 'lottie-react';\r\n\r\ninterface ChatbotFABProps {\r\n onClick: () => void;\r\n \r\n \r\n animationData: any; \r\n}\r\n\r\nexport const ChatbotFAB: React.FC<ChatbotFABProps> = ({ onClick, animationData }) => {\r\n \r\n \r\n const lottieProps = typeof animationData === 'string' \r\n ? { animationData: null, path: animationData } \r\n : { animationData: animationData };\r\n\r\n return (\r\n <button className=\"mra-fab\" onClick={onClick}>\r\n <Lottie {...lottieProps} loop={true} />\r\n </button>\r\n );\r\n};"],"mappings":"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","names":["useState","useState","useEffect","jsx","useRef","useEffect","jsx","jsxs","jsx","jsxs","useState","useEffect","jsx","clsx","jsx","jsxs","useState"]}
|
package/dist/styles.css
CHANGED
|
@@ -1,46 +1,139 @@
|
|
|
1
1
|
/* src/styles.css */
|
|
2
2
|
|
|
3
|
+
/* === Container & FAB Styles === */
|
|
4
|
+
.mra-container {
|
|
5
|
+
position: fixed;
|
|
6
|
+
bottom: 2rem;
|
|
7
|
+
right: 2rem;
|
|
8
|
+
z-index: 1000;
|
|
9
|
+
transition: all 0.3s ease-in-out;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/* Styles for Fullscreen Mode */
|
|
13
|
+
.mra-container--fullscreen {
|
|
14
|
+
bottom: 0;
|
|
15
|
+
right: 0;
|
|
16
|
+
width: 100%;
|
|
17
|
+
height: 100%;
|
|
18
|
+
max-width: 100%;
|
|
19
|
+
max-height: 100%;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.mra-container--fullscreen .mra-chat-window-container {
|
|
23
|
+
position: static;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.mra-container--fullscreen .mra-chat-window {
|
|
27
|
+
height: 100%;
|
|
28
|
+
width: 100%;
|
|
29
|
+
max-width: 100%;
|
|
30
|
+
border-radius: 0;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.mra-container--fullscreen .mra-fab {
|
|
34
|
+
display: none;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/* Floating Action Button */
|
|
38
|
+
.mra-fab {
|
|
39
|
+
width: 64px;
|
|
40
|
+
height: 64px;
|
|
41
|
+
border-radius: 9999px;
|
|
42
|
+
background-color: var(--ai-primary, #2563eb);
|
|
43
|
+
border: none;
|
|
44
|
+
cursor: pointer;
|
|
45
|
+
box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.2), 0 4px 6px -4px rgb(0 0 0 / 0.2);
|
|
46
|
+
display: flex;
|
|
47
|
+
align-items: center;
|
|
48
|
+
justify-content: center;
|
|
49
|
+
transition: transform 0.2s ease-in-out;
|
|
50
|
+
}
|
|
51
|
+
.mra-fab:hover {
|
|
52
|
+
transform: scale(1.1);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/* Chat Window Container (when not fullscreen) */
|
|
56
|
+
.mra-chat-window-container {
|
|
57
|
+
position: absolute;
|
|
58
|
+
bottom: calc(100% + 1rem);
|
|
59
|
+
right: 0;
|
|
60
|
+
opacity: 0;
|
|
61
|
+
transform: translateY(20px);
|
|
62
|
+
transition: opacity 0.3s ease, transform 0.3s ease;
|
|
63
|
+
pointer-events: none;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.mra-chat-window-container--open {
|
|
67
|
+
opacity: 1;
|
|
68
|
+
transform: translateY(0);
|
|
69
|
+
pointer-events: auto;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
|
|
3
73
|
/* === ChatWindow Styles === */
|
|
4
74
|
.mra-chat-window {
|
|
5
75
|
display: flex;
|
|
6
76
|
flex-direction: column;
|
|
7
77
|
height: 500px;
|
|
8
78
|
width: 100%;
|
|
9
|
-
max-width:
|
|
10
|
-
border-radius: 0.75rem;
|
|
79
|
+
max-width: 32rem; /* Increased default width to max-w-lg */
|
|
80
|
+
border-radius: 0.75rem;
|
|
11
81
|
border: 1px solid var(--ai-border, #e5e7eb);
|
|
12
82
|
background-color: var(--ai-bg, #ffffff);
|
|
13
83
|
overflow: hidden;
|
|
14
|
-
box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
|
|
84
|
+
box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
|
|
15
85
|
position: relative;
|
|
16
86
|
font-family: inherit;
|
|
17
87
|
font-size: 1rem;
|
|
18
88
|
line-height: 1.5rem;
|
|
19
89
|
box-sizing: border-box;
|
|
90
|
+
transition: all 0.3s ease-in-out;
|
|
20
91
|
}
|
|
21
92
|
|
|
22
93
|
.mra-header {
|
|
23
94
|
display: flex;
|
|
24
95
|
align-items: center;
|
|
25
|
-
|
|
26
|
-
|
|
96
|
+
justify-content: space-between; /* Important for alignment */
|
|
97
|
+
gap: 0.5rem;
|
|
98
|
+
padding: 1rem;
|
|
27
99
|
border-bottom: 1px solid var(--ai-border, #e5e7eb);
|
|
28
|
-
background-color: #f9fafb;
|
|
100
|
+
background-color: #f9fafb;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.mra-header-title-group {
|
|
104
|
+
display: flex;
|
|
105
|
+
align-items: center;
|
|
106
|
+
gap: 0.5rem;
|
|
29
107
|
}
|
|
30
108
|
|
|
31
109
|
.mra-title {
|
|
32
|
-
font-weight: 600;
|
|
33
|
-
color: #1f2937;
|
|
110
|
+
font-weight: 600;
|
|
111
|
+
color: #1f2937;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.mra-header-icon-button {
|
|
115
|
+
padding: 0.25rem;
|
|
116
|
+
border-radius: 0.25rem;
|
|
117
|
+
background: transparent;
|
|
118
|
+
border: none;
|
|
119
|
+
cursor: pointer;
|
|
120
|
+
color: #6b7280;
|
|
121
|
+
transition: background-color 0.2s, color 0.2s;
|
|
34
122
|
}
|
|
35
123
|
|
|
124
|
+
.mra-header-icon-button:hover {
|
|
125
|
+
background-color: #e5e7eb;
|
|
126
|
+
color: #1f2937;
|
|
127
|
+
}
|
|
36
128
|
|
|
129
|
+
/* === MessageList Styles === */
|
|
37
130
|
.mra-message-list {
|
|
38
131
|
flex: 1 1 0%;
|
|
39
132
|
overflow-y: auto;
|
|
40
133
|
padding: 1rem;
|
|
41
134
|
display: flex;
|
|
42
135
|
flex-direction: column;
|
|
43
|
-
gap: 0.75rem;
|
|
136
|
+
gap: 0.75rem;
|
|
44
137
|
scroll-behavior: smooth;
|
|
45
138
|
}
|
|
46
139
|
|
|
@@ -51,21 +144,21 @@
|
|
|
51
144
|
|
|
52
145
|
.mra-loading-bubble {
|
|
53
146
|
max-width: 80%;
|
|
54
|
-
padding: 0.5rem 0.75rem;
|
|
147
|
+
padding: 0.5rem 0.75rem;
|
|
55
148
|
border-radius: 0.75rem;
|
|
56
149
|
background-color: var(--ai-bot-bg, #f3f4f6);
|
|
57
150
|
color: var(--ai-text, #1f2937);
|
|
58
|
-
border-bottom-left-radius: 0.125rem;
|
|
151
|
+
border-bottom-left-radius: 0.125rem;
|
|
59
152
|
display: flex;
|
|
60
|
-
gap: 0.25rem;
|
|
153
|
+
gap: 0.25rem;
|
|
61
154
|
align-items: center;
|
|
62
155
|
}
|
|
63
156
|
|
|
64
157
|
.mra-loading-dot {
|
|
65
|
-
width: 0.375rem;
|
|
66
|
-
height: 0.375rem;
|
|
67
|
-
background-color: #9ca3af;
|
|
68
|
-
border-radius: 9999px;
|
|
158
|
+
width: 0.375rem;
|
|
159
|
+
height: 0.375rem;
|
|
160
|
+
background-color: #9ca3af;
|
|
161
|
+
border-radius: 9999px;
|
|
69
162
|
animation: bounce 1s infinite;
|
|
70
163
|
}
|
|
71
164
|
|
|
@@ -96,18 +189,18 @@
|
|
|
96
189
|
max-width: 80%;
|
|
97
190
|
padding: 0.5rem 0.75rem;
|
|
98
191
|
border-radius: 0.75rem;
|
|
99
|
-
font-size: 0.875rem;
|
|
192
|
+
font-size: 0.875rem;
|
|
100
193
|
word-wrap: break-word;
|
|
101
194
|
}
|
|
102
195
|
.mra-bubble-user {
|
|
103
196
|
background-color: var(--ai-user-bg, #dbeafe);
|
|
104
197
|
color: var(--ai-user-text, #1e40af);
|
|
105
|
-
border-bottom-right-radius: 0.125rem;
|
|
198
|
+
border-bottom-right-radius: 0.125rem;
|
|
106
199
|
}
|
|
107
200
|
.mra-bubble-bot {
|
|
108
201
|
background-color: var(--ai-bot-bg, #f3f4f6);
|
|
109
202
|
color: var(--ai-text, #1f2937);
|
|
110
|
-
border-bottom-left-radius: 0.125rem;
|
|
203
|
+
border-bottom-left-radius: 0.125rem;
|
|
111
204
|
}
|
|
112
205
|
|
|
113
206
|
/* === ChatInput Styles === */
|
|
@@ -117,7 +210,6 @@
|
|
|
117
210
|
padding: 0.75rem;
|
|
118
211
|
border-top: 1px solid var(--ai-border, #e5e7eb);
|
|
119
212
|
background-color: var(--ai-bg, #ffffff);
|
|
120
|
-
/* این خط جدید برای تراز کردن دکمه با textarea است */
|
|
121
213
|
align-items: flex-end;
|
|
122
214
|
}
|
|
123
215
|
|
|
@@ -129,13 +221,11 @@
|
|
|
129
221
|
outline: none;
|
|
130
222
|
font-family: inherit;
|
|
131
223
|
color: var(--ai-text, #1f2937);
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
line-height: 1.5; /* بهبود خوانایی متن چندخطی */
|
|
224
|
+
resize: none;
|
|
225
|
+
max-height: 120px;
|
|
226
|
+
overflow-y: auto;
|
|
227
|
+
line-height: 1.5;
|
|
137
228
|
}
|
|
138
|
-
|
|
139
229
|
.mra-input-field::placeholder {
|
|
140
230
|
color: var(--ai-text-secondary, #6b7280);
|
|
141
231
|
}
|
|
@@ -157,11 +247,9 @@
|
|
|
157
247
|
color: var(--ai-primary-fg, #ffffff);
|
|
158
248
|
border: none;
|
|
159
249
|
cursor: pointer;
|
|
160
|
-
/* این خط جدید برای تراز کردن دکمه است */
|
|
161
250
|
align-self: flex-end;
|
|
162
|
-
height: 38px;
|
|
251
|
+
height: 38px;
|
|
163
252
|
}
|
|
164
|
-
|
|
165
253
|
.mra-send-button:hover {
|
|
166
254
|
opacity: 0.9;
|
|
167
255
|
}
|
|
@@ -170,15 +258,16 @@
|
|
|
170
258
|
cursor: not-allowed;
|
|
171
259
|
}
|
|
172
260
|
|
|
261
|
+
/* === Footer Styles === */
|
|
173
262
|
.mra-footer {
|
|
174
|
-
padding: 0.5rem 0.75rem;
|
|
263
|
+
padding: 0.5rem 0.75rem;
|
|
175
264
|
border-top: 1px solid var(--ai-border, #e5e7eb);
|
|
176
|
-
background-color: #f9fafb;
|
|
265
|
+
background-color: #f9fafb;
|
|
177
266
|
display: flex;
|
|
178
267
|
justify-content: space-between;
|
|
179
268
|
align-items: center;
|
|
180
269
|
font-size: 0.75rem;
|
|
181
|
-
color: #6b7280;
|
|
270
|
+
color: #6b7280;
|
|
182
271
|
}
|
|
183
272
|
|
|
184
273
|
.mra-footer-links {
|
|
@@ -188,71 +277,11 @@
|
|
|
188
277
|
}
|
|
189
278
|
|
|
190
279
|
.mra-footer-link {
|
|
191
|
-
color: #4b5563;
|
|
280
|
+
color: #4b5563;
|
|
192
281
|
text-decoration: none;
|
|
193
282
|
transition: color 0.2s;
|
|
194
283
|
}
|
|
195
284
|
|
|
196
285
|
.mra-footer-link:hover {
|
|
197
286
|
color: var(--ai-primary, #2563eb);
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
.mra-container {
|
|
201
|
-
position: fixed;
|
|
202
|
-
bottom: 2rem; /* 32px */
|
|
203
|
-
right: 2rem; /* 32px */
|
|
204
|
-
z-index: 1000;
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
.mra-fab {
|
|
208
|
-
width: 64px;
|
|
209
|
-
height: 64px;
|
|
210
|
-
border-radius: 9999px; /* rounded-full */
|
|
211
|
-
background-color: var(--ai-primary, #2563eb);
|
|
212
|
-
border: none;
|
|
213
|
-
cursor: pointer;
|
|
214
|
-
box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.2), 0 4px 6px -4px rgb(0 0 0 / 0.2);
|
|
215
|
-
display: flex;
|
|
216
|
-
align-items: center;
|
|
217
|
-
justify-content: center;
|
|
218
|
-
transition: transform 0.2s ease-in-out;
|
|
219
|
-
}
|
|
220
|
-
.mra-fab:hover {
|
|
221
|
-
transform: scale(1.1);
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
.mra-chat-window-container {
|
|
225
|
-
position: absolute;
|
|
226
|
-
bottom: calc(100% + 1rem); /* 16px فاصله بالای دکمه */
|
|
227
|
-
right: 0;
|
|
228
|
-
opacity: 0;
|
|
229
|
-
transform: translateY(20px);
|
|
230
|
-
transition: opacity 0.3s ease, transform 0.3s ease;
|
|
231
|
-
pointer-events: none; /* در حالت بسته قابل کلیک نیست */
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
.mra-chat-window-container--open {
|
|
235
|
-
opacity: 1;
|
|
236
|
-
transform: translateY(0);
|
|
237
|
-
pointer-events: auto; /* در حالت باز قابل کلیک است */
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
/* === ChatWindow Styles === */
|
|
242
|
-
.mra-chat-window {
|
|
243
|
-
display: flex;
|
|
244
|
-
flex-direction: column;
|
|
245
|
-
height: 500px;
|
|
246
|
-
width: 100%;
|
|
247
|
-
max-width: 28rem; /* max-w-md */
|
|
248
|
-
border-radius: 0.75rem; /* rounded-xl */
|
|
249
|
-
border: 1px solid var(--ai-border, #e5e7eb);
|
|
250
|
-
background-color: var(--ai-bg, #ffffff);
|
|
251
|
-
overflow: hidden;
|
|
252
|
-
box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); /* shadow-lg */
|
|
253
|
-
position: relative;
|
|
254
|
-
font-family: inherit;
|
|
255
|
-
font-size: 1rem;
|
|
256
|
-
line-height: 1.5rem;
|
|
257
|
-
box-sizing: border-box;
|
|
258
287
|
}
|