fix build
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
VITE_TOKEN_NAME = 'dzone_token'
|
VITE_TOKEN_NAME = 'dzone_token'
|
||||||
VITE_REFRESH_TOKEN_NAME = 'dzone_refresh_token'
|
VITE_REFRESH_TOKEN_NAME = 'dzone_refresh_token'
|
||||||
# VITE_BASE_URL = 'https://api-dzone.danakcorp.com'
|
VITE_BASE_URL = 'https://api-dzone.danakcorp.com'
|
||||||
VITE_BASE_URL = 'http://localhost:4000'
|
# VITE_BASE_URL = 'http://localhost:4000'
|
||||||
|
|
||||||
VITE_SLUG_ID = 'slug_id'
|
VITE_SLUG_ID = 'slug_id'
|
||||||
+60
-71
@@ -55,8 +55,8 @@ const Chatbot: FC<ChatbotProps> = ({ isOpen, onClose }) => {
|
|||||||
const [currentSessionId, setCurrentSessionId] = useState<string | null>(null);
|
const [currentSessionId, setCurrentSessionId] = useState<string | null>(null);
|
||||||
const [socket, setSocket] = useState<Socket | null>(null);
|
const [socket, setSocket] = useState<Socket | null>(null);
|
||||||
const [showChatbot, setShowChatbot] = useState<boolean>(false);
|
const [showChatbot, setShowChatbot] = useState<boolean>(false);
|
||||||
const [showConnectionMessage, setShowConnectionMessage] =
|
// const [showConnectionMessage, setShowConnectionMessage] =
|
||||||
useState<boolean>(false);
|
// useState<boolean>(false);
|
||||||
const [reconnectAttempts, setReconnectAttempts] = useState<number>(0);
|
const [reconnectAttempts, setReconnectAttempts] = useState<number>(0);
|
||||||
const maxReconnectAttempts = 5;
|
const maxReconnectAttempts = 5;
|
||||||
|
|
||||||
@@ -73,7 +73,6 @@ const Chatbot: FC<ChatbotProps> = ({ isOpen, onClose }) => {
|
|||||||
addMessage,
|
addMessage,
|
||||||
addSystemMessage,
|
addSystemMessage,
|
||||||
updateMessage,
|
updateMessage,
|
||||||
clearMessages,
|
|
||||||
} = useMessages();
|
} = useMessages();
|
||||||
const { setupSocketHandlers } = useSocketHandlers({
|
const { setupSocketHandlers } = useSocketHandlers({
|
||||||
socket,
|
socket,
|
||||||
@@ -202,7 +201,7 @@ const Chatbot: FC<ChatbotProps> = ({ isOpen, onClose }) => {
|
|||||||
// Show connection message only briefly when status changes
|
// Show connection message only briefly when status changes
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Always show connection status, don't hide it
|
// Always show connection status, don't hide it
|
||||||
setShowConnectionMessage(true);
|
// setShowConnectionMessage(true);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
if (connectionTimeoutRef.current) {
|
if (connectionTimeoutRef.current) {
|
||||||
@@ -302,24 +301,24 @@ const Chatbot: FC<ChatbotProps> = ({ isOpen, onClose }) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const joinChat = (sessionId: string) => {
|
// const joinChat = (sessionId: string) => {
|
||||||
if (!socket || !socket.connected) {
|
// if (!socket || !socket.connected) {
|
||||||
addSystemMessage("اتصال Socket.IO برقرار نیست", "error");
|
// addSystemMessage("اتصال Socket.IO برقرار نیست", "error");
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
|
||||||
// Get user ID from localStorage or use a default
|
// // Get user ID from localStorage or use a default
|
||||||
const userId =
|
// const userId =
|
||||||
localStorage.getItem(import.meta.env.VITE_USER_ID_KEY || "user_id") ||
|
// localStorage.getItem(import.meta.env.VITE_USER_ID_KEY || "user_id") ||
|
||||||
localStorage.getItem("userId") ||
|
// localStorage.getItem("userId") ||
|
||||||
"anonymous_user";
|
// "anonymous_user";
|
||||||
|
|
||||||
console.log(`🔄 Joining chat session: ${sessionId}`);
|
// console.log(`🔄 Joining chat session: ${sessionId}`);
|
||||||
socket.emit(SOCKET_EVENTS.JOIN_CHAT, {
|
// socket.emit(SOCKET_EVENTS.JOIN_CHAT, {
|
||||||
sessionId: sessionId,
|
// sessionId: sessionId,
|
||||||
userId: userId,
|
// userId: userId,
|
||||||
});
|
// });
|
||||||
};
|
// };
|
||||||
|
|
||||||
const handleSendMessage = () => {
|
const handleSendMessage = () => {
|
||||||
const message = inputValue.trim();
|
const message = inputValue.trim();
|
||||||
@@ -459,35 +458,32 @@ const Chatbot: FC<ChatbotProps> = ({ isOpen, onClose }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`fixed bottom-20 right-4 w-80 sm:w-96 bg-white rounded-xl shadow-xl flex flex-col z-50 border border-gray-200 transition-all duration-300 ease-in-out ${
|
className={`fixed bottom-20 right-4 w-80 sm:w-96 bg-white rounded-xl shadow-xl flex flex-col z-50 border border-gray-200 transition-all duration-300 ease-in-out ${showChatbot
|
||||||
showChatbot
|
? "opacity-100 transform translate-y-0"
|
||||||
? "opacity-100 transform translate-y-0"
|
: "opacity-0 transform translate-y-10"
|
||||||
: "opacity-0 transform translate-y-10"
|
}`}
|
||||||
}`}
|
|
||||||
style={{ height: "500px", direction: "rtl" }}
|
style={{ height: "500px", direction: "rtl" }}
|
||||||
>
|
>
|
||||||
{/* Header */}
|
{/* Header */}
|
||||||
<div className="bg-gradient-to-l from-blue-500 to-blue-600 text-white p-3.5 rounded-t-xl flex justify-between items-center shadow-sm">
|
<div className="bg-gradient-to-l from-blue-500 to-blue-600 text-white p-3.5 rounded-t-xl flex justify-between items-center shadow-sm">
|
||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
<div
|
<div
|
||||||
className={`w-3 h-3 rounded-full ml-2 ${
|
className={`w-3 h-3 rounded-full ml-2 ${connectionStatus === "connected"
|
||||||
connectionStatus === "connected"
|
? "bg-green-400 animate-pulse"
|
||||||
? "bg-green-400 animate-pulse"
|
: connectionStatus === "connecting"
|
||||||
: connectionStatus === "connecting"
|
|
||||||
? "bg-yellow-400 animate-pulse"
|
? "bg-yellow-400 animate-pulse"
|
||||||
: "bg-red-400"
|
: "bg-red-400"
|
||||||
}`}
|
}`}
|
||||||
></div>
|
></div>
|
||||||
<h3 className="font-bold text-base">چت بات داناک</h3>
|
<h3 className="font-bold text-base">چت بات داناک</h3>
|
||||||
{/* Always show a compact connection status */}
|
{/* Always show a compact connection status */}
|
||||||
<div
|
<div
|
||||||
className={`flex items-center text-xs mr-2 ml-2 ${
|
className={`flex items-center text-xs mr-2 ml-2 ${connectionStatus === "connected"
|
||||||
connectionStatus === "connected"
|
? "text-green-200"
|
||||||
? "text-green-200"
|
: connectionStatus === "connecting"
|
||||||
: connectionStatus === "connecting"
|
|
||||||
? "text-yellow-200"
|
? "text-yellow-200"
|
||||||
: "text-red-200"
|
: "text-red-200"
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
{connectionInfo.icon}
|
{connectionInfo.icon}
|
||||||
</div>
|
</div>
|
||||||
@@ -520,9 +516,8 @@ const Chatbot: FC<ChatbotProps> = ({ isOpen, onClose }) => {
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={message.id}
|
key={message.id}
|
||||||
className={`mb-3 flex ${
|
className={`mb-3 flex ${message.isUser ? "justify-start" : "justify-end"
|
||||||
message.isUser ? "justify-start" : "justify-end"
|
} animate-fade-in`}
|
||||||
} animate-fade-in`}
|
|
||||||
>
|
>
|
||||||
{message.isUser && (
|
{message.isUser && (
|
||||||
<div className="w-7 h-7 rounded-full bg-blue-600 flex items-center justify-center ml-2 flex-shrink-0">
|
<div className="w-7 h-7 rounded-full bg-blue-600 flex items-center justify-center ml-2 flex-shrink-0">
|
||||||
@@ -530,41 +525,37 @@ const Chatbot: FC<ChatbotProps> = ({ isOpen, onClose }) => {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div
|
<div
|
||||||
className={`relative px-3.5 py-2.5 pb-4 rounded-lg max-w-[85%] ${
|
className={`relative px-3.5 py-2.5 pb-4 rounded-lg max-w-[85%] ${message.isUser
|
||||||
message.isUser
|
? "bg-blue-600 text-white rounded-tr-none shadow-sm animate-slide-right"
|
||||||
? "bg-blue-600 text-white rounded-tr-none shadow-sm animate-slide-right"
|
: message.isSystem
|
||||||
: message.isSystem
|
|
||||||
? message.metadata?.type === "error"
|
? message.metadata?.type === "error"
|
||||||
? "bg-red-100 text-red-800 rounded-tl-none"
|
? "bg-red-100 text-red-800 rounded-tl-none"
|
||||||
: message.metadata?.type === "success"
|
: message.metadata?.type === "success"
|
||||||
? "bg-green-100 text-green-800 rounded-tl-none"
|
? "bg-green-100 text-green-800 rounded-tl-none"
|
||||||
: "bg-yellow-100 text-yellow-800 rounded-tl-none"
|
: "bg-yellow-100 text-yellow-800 rounded-tl-none"
|
||||||
: message.metadata && "confidence" in message.metadata
|
: message.metadata && "confidence" in message.metadata
|
||||||
? message.metadata.confidence === 1
|
? message.metadata.confidence === 1
|
||||||
? "bg-green-100 text-green-800 rounded-tl-none"
|
? "bg-green-100 text-green-800 rounded-tl-none"
|
||||||
: message.metadata.confidence === 0
|
: message.metadata.confidence === 0
|
||||||
? "bg-red-100 text-red-800 rounded-tl-none"
|
? "bg-red-100 text-red-800 rounded-tl-none"
|
||||||
: "bg-yellow-100 text-yellow-800 rounded-tl-none"
|
: "bg-yellow-100 text-yellow-800 rounded-tl-none"
|
||||||
: "bg-white text-gray-800 rounded-tl-none shadow-sm animate-slide-left"
|
: "bg-white text-gray-800 rounded-tl-none shadow-sm animate-slide-left"
|
||||||
} ${
|
} ${message.streaming
|
||||||
message.streaming
|
|
||||||
? "border-r-4 border-blue-400 streaming-message animate-pulse"
|
? "border-r-4 border-blue-400 streaming-message animate-pulse"
|
||||||
: ""
|
: ""
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
id={`message-${message.id}`}
|
id={`message-${message.id}`}
|
||||||
className={`text-sm leading-6 font-light whitespace-pre-line break-words text-right mb-2 ${
|
className={`text-sm leading-6 font-light whitespace-pre-line break-words text-right mb-2 ${message.streaming ? "streaming-content" : ""
|
||||||
message.streaming ? "streaming-content" : ""
|
}`}
|
||||||
}`}
|
|
||||||
dangerouslySetInnerHTML={{ __html: formatText(message.text) }}
|
dangerouslySetInnerHTML={{ __html: formatText(message.text) }}
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
className={`text-[8px] opacity-70 absolute bottom-1 ${
|
className={`text-[8px] opacity-70 absolute bottom-1 ${message.isUser
|
||||||
message.isUser
|
? "left-2.5 text-left"
|
||||||
? "left-2.5 text-left"
|
: "right-2.5 text-right"
|
||||||
: "right-2.5 text-right"
|
}`}
|
||||||
}`}
|
|
||||||
>
|
>
|
||||||
{message.timestamp.toLocaleTimeString("fa-IR", {
|
{message.timestamp.toLocaleTimeString("fa-IR", {
|
||||||
hour: "2-digit",
|
hour: "2-digit",
|
||||||
@@ -626,23 +617,21 @@ const Chatbot: FC<ChatbotProps> = ({ isOpen, onClose }) => {
|
|||||||
isProcessing ||
|
isProcessing ||
|
||||||
connectionStatus !== "connected"
|
connectionStatus !== "connected"
|
||||||
}
|
}
|
||||||
className={`ml-2 ${
|
className={`ml-2 ${inputValue.trim() === "" ||
|
||||||
inputValue.trim() === "" ||
|
|
||||||
isProcessing ||
|
isProcessing ||
|
||||||
connectionStatus !== "connected"
|
connectionStatus !== "connected"
|
||||||
? "bg-gray-300"
|
? "bg-gray-300"
|
||||||
: "bg-blue-600 hover:bg-blue-700"
|
: "bg-blue-600 hover:bg-blue-700"
|
||||||
} text-white rounded-full w-9 h-9 flex items-center justify-center focus:outline-none transition-colors flex-shrink-0`}
|
} text-white rounded-full w-9 h-9 flex items-center justify-center focus:outline-none transition-colors flex-shrink-0`}
|
||||||
>
|
>
|
||||||
<Send
|
<Send
|
||||||
size={18}
|
size={18}
|
||||||
className={`transform rotate-180 ${
|
className={`transform rotate-180 ${inputValue.trim() !== "" &&
|
||||||
inputValue.trim() !== "" &&
|
|
||||||
!isProcessing &&
|
!isProcessing &&
|
||||||
connectionStatus === "connected"
|
connectionStatus === "connected"
|
||||||
? "animate-pulse"
|
? "animate-pulse"
|
||||||
: ""
|
: ""
|
||||||
}`}
|
}`}
|
||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ export const useSocketHandlers = ({
|
|||||||
updateMessage,
|
updateMessage,
|
||||||
addSystemMessage,
|
addSystemMessage,
|
||||||
setCurrentSessionId,
|
setCurrentSessionId,
|
||||||
isProcessing,
|
|
||||||
}: UseSocketHandlersProps) => {
|
}: UseSocketHandlersProps) => {
|
||||||
// Keep track of the current bot message like in the JS version
|
// Keep track of the current bot message like in the JS version
|
||||||
const botMessageRef = useRef<{
|
const botMessageRef = useRef<{
|
||||||
@@ -325,30 +324,30 @@ export const useSocketHandlers = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Helper function to format text with markdown-like syntax
|
// Helper function to format text with markdown-like syntax
|
||||||
const formatText = (text: string) => {
|
// const formatText = (text: string) => {
|
||||||
if (!text) return "";
|
// if (!text) return "";
|
||||||
|
|
||||||
// Clean the text first to avoid HTML injection
|
// // Clean the text first to avoid HTML injection
|
||||||
const cleanedText = text
|
// const cleanedText = text
|
||||||
.replace(/&/g, "&")
|
// .replace(/&/g, "&")
|
||||||
.replace(/</g, "<")
|
// .replace(/</g, "<")
|
||||||
.replace(/>/g, ">")
|
// .replace(/>/g, ">")
|
||||||
.replace(/"/g, """)
|
// .replace(/"/g, """)
|
||||||
.replace(/'/g, "'");
|
// .replace(/'/g, "'");
|
||||||
|
|
||||||
// Format with markdown-like syntax and handle newlines properly
|
// // Format with markdown-like syntax and handle newlines properly
|
||||||
const formattedText = cleanedText
|
// const formattedText = cleanedText
|
||||||
// Bold text
|
// // Bold text
|
||||||
.replace(/\*\*(.*?)\*\*/g, "<strong>$1</strong>")
|
// .replace(/\*\*(.*?)\*\*/g, "<strong>$1</strong>")
|
||||||
// Italic text
|
// // Italic text
|
||||||
.replace(/\*(.*?)\*/g, "<em>$1</em>")
|
// .replace(/\*(.*?)\*/g, "<em>$1</em>")
|
||||||
// Line breaks - ensure they work properly with proper spacing
|
// // Line breaks - ensure they work properly with proper spacing
|
||||||
.replace(/\n/g, "<br class='message-line-break' />")
|
// .replace(/\n/g, "<br class='message-line-break' />")
|
||||||
// Links (optional)
|
// // Links (optional)
|
||||||
.replace(
|
// .replace(
|
||||||
/\[([^\]]+)\]\(([^)]+)\)/g,
|
// /\[([^\]]+)\]\(([^)]+)\)/g,
|
||||||
'<a href="$2" target="_blank" rel="noopener noreferrer" class="text-blue-500 underline">$1</a>'
|
// '<a href="$2" target="_blank" rel="noopener noreferrer" class="text-blue-500 underline">$1</a>'
|
||||||
);
|
// );
|
||||||
|
|
||||||
return formattedText;
|
// return formattedText;
|
||||||
};
|
// };
|
||||||
|
|||||||
Reference in New Issue
Block a user