diff --git "a/C:\\chatknot\\app/(dashboard)/chat/page.js" "b/C:\\chatknot\\old backup\\app/(dashboard)/chat/page.js" index 920a683..62a866b 100644 --- "a/C:\\chatknot\\app/(dashboard)/chat/page.js" +++ "b/C:\\chatknot\\old backup\\app/(dashboard)/chat/page.js" @@ -14,10 +14,9 @@ import firefox from "@/public/assets/images/firefox-icon.png"; import edge from "@/public/assets/images/edge.png"; import safari from "@/public/assets/images/safari-icon.png"; -import { FaMobileAlt, FaDesktop, FaTabletAlt } from "react-icons/fa"; import ubunto from "@/public/assets/images/ubunto.png"; import android from "@/public/assets/images/android.png"; -const notificationSound = "/sounds/chatalert.mp3"; +import notificationSound from "@/public/sounds/chatalert.mp3"; import { addTab, minimize } from "../../lib/features/chat/chatSlice"; import FilterChats from "./FilterChats"; import axios from "axios"; @@ -32,15 +31,13 @@ const Chat = () => { const [visitors, setVisitors] = useState([]); const [hideColumns, setHideColumns] = useState(false); const [blinkingVisitor, setBlinkingVisitor] = useState([]); - const { activeTab } = useSelector((state) => state.chat); + const { activeTab } = useSelector((state) => state.chat); const [IsShowPK, setIsShowPK] = useState(false); const [ShowAlert, setShowAlert] = useState(false); const [showFilter, setShowFilter] = useState(false); - const selectedBrands = useSelector( - (state) => state.selectedBrands.selectedBrands, - ); + const selectedBrands = useSelector((state) => state.selectedBrands.selectedBrands); const [filteredVisitors, setFilteredVisitors] = useState([]); - + const [brands, setBrands] = useState([]); const [filteredBrand, setFilteredBrand] = useState([]); const toggleFilterChats = () => { @@ -92,7 +89,7 @@ const Chat = () => { second: "2-digit", hour12: true, // Change to false for 24-hour format if desired }).format(serverUtcTime); - + return userLocalTime; } @@ -118,51 +115,54 @@ const Chat = () => { // } // ); // setBrands(response.data); - // + // // setFilteredBrand(response.data); - + // } catch (error) { // console.error("Error fetching brands:", error); - + // } // }; const fetchBrands = async () => { try { - const forchat = { - forChat: true, - }; const response = await apiRequest( `/api/companies/${user.company_id}/brands`, - "GET", - forchat, + 'GET' ); - setBrands(response); - // + + setBrands(response); + // setFilteredBrand(response); + } catch (error) { console.error("Error fetching brands:", error.message); + + } }; - + if (user?.company_id) { fetchBrands(); } }, []); useEffect(() => { + + if (selectedBrands.length > 0) { // Filter visitors based on selected brands setFilteredVisitors((prevVisitors) => { // Only keep visitors whose public_key is in selectedBrands return visitors.filter((visitor) => - selectedBrands.includes(visitor.public_key), + selectedBrands.includes(visitor.public_key) ); }); } else { // If no brand is selected, reset the filtered visitors to show all visitors setFilteredVisitors(visitors); } - }, [selectedBrands, visitors]); // Re-run the effect when selectedBrands or visitors changes + }, [selectedBrands,visitors]); // Re-run the effect when selectedBrands or visitors changes + useEffect(() => { // Ensure socket instance is created once @@ -170,18 +170,18 @@ const Chat = () => { if (!socketinst) return; setSocket(socketinst); - + // Emit brand ID to the backend when the page loads socketinst.emit("page load", { brand_id: bid }); const handleActiveVisitors = async (data) => { const decryptedData = await decryptData(data); - + if (!decryptedData || typeof decryptedData !== "object") { console.error("Decryption failed or returned invalid data"); return; } - + let { client_id, public_key, @@ -198,16 +198,15 @@ const Chat = () => { browser, brand_name, totalMsgCount, - device_size, } = decryptedData; - - // Now this should work correctly - - // if (country === 'Pakistan' && !IsShowPK) { + + // Now this should work correctly + + // if (country === 'Pakistan' && !IsShowPK) { // return; // } - const j_time = emitTimeInUserTimezone(join_time); + const j_time = emitTimeInUserTimezone(join_time); // Save the original join_time with client_id setOriginalJoinTimes((prevTimes) => ({ ...prevTimes, @@ -221,6 +220,8 @@ const Chat = () => { hour12: true, }); + + const newVisitor = { name: client_name ? client_name : null, client_id: client_id, @@ -239,16 +240,18 @@ const Chat = () => { unseenMsg: unseenMsg, brand_name: brand_name, totalMessages: totalMsgCount, - device_size: device_size, }; - + setVisitors((prevVisitors) => { + // Check if the visitor with the same client_id already exists const existingVisitorIndex = prevVisitors.findIndex( - (v) => v.client_id === client_id, + (v) => v.client_id === client_id ); - + + if (existingVisitorIndex > -1) { + // Update existing visitor const updatedVisitors = [...prevVisitors]; updatedVisitors[existingVisitorIndex] = newVisitor; @@ -259,23 +262,26 @@ const Chat = () => { } }); if (selectedBrands.length === 0 || selectedBrands.includes(public_key)) { - setFilteredVisitors((prevVisitors) => { - // Check if the visitor with the same client_id already exists - const existingVisitorIndex = prevVisitors.findIndex( - (v) => v.client_id === client_id, - ); - - if (existingVisitorIndex > -1) { - // Update existing visitor - const updatedVisitors = [...prevVisitors]; - updatedVisitors[existingVisitorIndex] = newVisitor; - return updatedVisitors; - } else { - // Add new visitor only if it doesn't already exist - return [...prevVisitors, newVisitor]; - } - }); - } + setFilteredVisitors((prevVisitors) => { + + // Check if the visitor with the same client_id already exists + const existingVisitorIndex = prevVisitors.findIndex( + (v) => v.client_id === client_id + ); + + + if (existingVisitorIndex > -1) { + + // Update existing visitor + const updatedVisitors = [...prevVisitors]; + updatedVisitors[existingVisitorIndex] = newVisitor; + return updatedVisitors; + } else { + // Add new visitor only if it doesn't already exist + return [...prevVisitors, newVisitor]; + } + }); + } }; const handleNewClient = (data) => { @@ -293,7 +299,6 @@ const Chat = () => { country, status, browser, - device_size, } = decryptedData; // if (country === 'Pakistan' && !IsShowPK) { @@ -316,7 +321,7 @@ const Chat = () => { }); const newVisitor = { - name: client_name ? client_name : null, + name: client_name ? client_name : null, client_id: client_id, online: joinDate, servedBy: "", @@ -332,65 +337,73 @@ const Chat = () => { browser: browser, brand_name: brand_name, totalMessages: 0, - device_size: device_size, }; // Update the state with the new visitor setVisitors((prevVisitors) => { + const updatedVisitors = [newVisitor, ...prevVisitors]; // Log inside setState to ensure proper order return updatedVisitors; }); + + + + +// Determine whether to update filtered visitors +if (selectedBrands.length === 0 || selectedBrands.includes(public_key)) { + setFilteredVisitors((prevVisitors) => { + // Only add newVisitor if the public_key is in selectedBrands or selectedBrands is empty + return [newVisitor, ...prevVisitors]; + }); +} - // Determine whether to update filtered visitors - if (selectedBrands.length === 0 || selectedBrands.includes(public_key)) { - setFilteredVisitors((prevVisitors) => { - // Only add newVisitor if the public_key is in selectedBrands or selectedBrands is empty - return [newVisitor, ...prevVisitors]; - }); - } }; const handleVisitorServedByUpdate = (data) => { - const decryptedData = decryptData(data); + const decryptedData = decryptData(data) const { client_id, served_by } = decryptedData; setVisitors((prevVisitors) => { + return prevVisitors.map((visitor) => visitor.client_id === client_id ? { ...visitor, servedBy: served_by } - : visitor, - ); - }); - - setFilteredVisitors((prevVisitors) => { - return prevVisitors.map((visitor) => - visitor.client_id === client_id - ? { ...visitor, servedBy: served_by } - : visitor, + : visitor ); }); + + setFilteredVisitors((prevVisitors) => { + return prevVisitors.map((visitor) => + visitor.client_id === client_id + ? { ...visitor, servedBy: served_by } + : visitor + ); + }); + }; const handleVisitorStatusChange = (data) => { - const decryptedData = decryptData(data); - - const { client_id, served_by, status, visitor_id } = decryptedData; - setVisitors((prevVisitors) => { + const decryptedData = decryptData(data) + + const { client_id, served_by ,status,visitor_id} = decryptedData; + setVisitors((prevVisitors) => { + if (status === 4) { if (currentChat?.client_id == client_id) { setHideColumns(false); setCurrentChat(null); } return prevVisitors.filter( - (visitor) => visitor.client_id !== client_id, + (visitor) => visitor.client_id !== client_id ); } else { // Update visitor's status in the list - + + const updatedVisitors = prevVisitors.map((visitor) => visitor.client_id === client_id ? { ...visitor, visitorStatus: status } - : visitor, + : visitor ); // If the current chat's visitor's status is updated, also update the currentChat state @@ -404,36 +417,39 @@ const Chat = () => { return updatedVisitors; } }); + + setFilteredVisitors((prevVisitors) => { + + if (status === 4) { + if (currentChat?.client_id == client_id) { + setHideColumns(false); + setCurrentChat(null); + } + return prevVisitors.filter( + (visitor) => visitor.client_id !== client_id + ); + } else { + // Update visitor's status in the list + + + const updatedVisitors = prevVisitors.map((visitor) => + visitor.client_id === client_id + ? { ...visitor, visitorStatus: status } + : visitor + ); - setFilteredVisitors((prevVisitors) => { - if (status === 4) { - if (currentChat?.client_id == client_id) { - setHideColumns(false); - setCurrentChat(null); - } - return prevVisitors.filter( - (visitor) => visitor.client_id !== client_id, - ); - } else { - // Update visitor's status in the list - - const updatedVisitors = prevVisitors.map((visitor) => - visitor.client_id === client_id - ? { ...visitor, visitorStatus: status } - : visitor, - ); - - // If the current chat's visitor's status is updated, also update the currentChat state - if (currentChat?.client_id === client_id) { - setCurrentChat((prevChat) => ({ - ...prevChat, - visitorStatus: status, - })); - } + // If the current chat's visitor's status is updated, also update the currentChat state + if (currentChat?.client_id === client_id) { + setCurrentChat((prevChat) => ({ + ...prevChat, + visitorStatus: status, + })); + } - return updatedVisitors; - } - }); + return updatedVisitors; + } + }); + }; const playNotificationSound = () => { const audio = new Audio(notificationSound); @@ -441,52 +457,56 @@ const Chat = () => { }; const handleNewMessageBlink = (data) => { - const decryptedData = decryptData(data); - const message = decryptedData; - - setVisitors((prevVisitors) => { + + const decryptedData = decryptData(data) + const message = decryptedData + + + + setVisitors((prevVisitors) => { + return prevVisitors.map((visitor) => visitor.client_id === message.client_id ? { ...visitor, totalMessages: message.totalMessages } - : visitor, + : visitor ); - }); - setFilteredVisitors((prevVisitors) => { + }); setFilteredVisitors((prevVisitors) => { + return prevVisitors.map((visitor) => visitor.client_id === message.client_id ? { ...visitor, totalMessages: message.totalMessages } - : visitor, + : visitor ); }); - + // if(message.public_key != brand_pk){ // return null; // } if (message.isParticipant) { // playNotificationSound(); } - // If notifyAllAdmins is false, check if userId exists in unseenCounts - if ( - !message.notifyAllAdmins && - !message.unseenCounts.hasOwnProperty(user.userId) - ) { - // - return; - } + // If notifyAllAdmins is false, check if userId exists in unseenCounts + if (!message.notifyAllAdmins && !message.unseenCounts.hasOwnProperty(user.userId)) { + // + return; +} // Only add to blinking state if the current chat is NOT the one receiving the message if (activeTab || activeTab !== message.client_id) { + + setVisitors((prevVisitors) => { + return prevVisitors.map((visitor) => visitor.client_id === message.client_id ? { ...visitor, unseenMsg: message.unseenCount } - : visitor, + : visitor ); - }); - setFilteredVisitors((prevVisitors) => { + }); setFilteredVisitors((prevVisitors) => { + return prevVisitors.map((visitor) => visitor.client_id === message.client_id ? { ...visitor, unseenMsg: message.unseenCount } - : visitor, + : visitor ); }); setBlinkingVisitor((prevBlinkingVisitors) => { @@ -496,63 +516,70 @@ const Chat = () => { return prevBlinkingVisitors; }); } else { + // If current chat is the same as the message client, we can remove blinking removeBlinkingVisitor(message.client_id); } }; const handleClientDataUpdate = (data) => { - const decryptedData = decryptData(data); + const decryptedData = decryptData(data) const updatedData = decryptedData; - + const { client_id, name, email, phone, notes, tags } = updatedData; setVisitors((prevVisitors) => { - // Update visitor's status in the list - const updatedVisitors = prevVisitors.map((visitor) => - visitor.client_id === client_id - ? { ...visitor, name: name } - : visitor, - ); + + // Update visitor's status in the list + const updatedVisitors = prevVisitors.map((visitor) => + visitor.client_id === client_id + ? { ...visitor, name: name } + : visitor + ); - return updatedVisitors; + return updatedVisitors; }); setFilteredVisitors((prevVisitors) => { - // Update visitor's status in the list - const updatedVisitors = prevVisitors.map((visitor) => - visitor.client_id === client_id - ? { ...visitor, name: name } - : visitor, - ); + + // Update visitor's status in the list + const updatedVisitors = prevVisitors.map((visitor) => + visitor.client_id === client_id + ? { ...visitor, name: name } + : visitor + ); - return updatedVisitors; + return updatedVisitors; }); + + + }; const handleMessageSeen = (data) => { - const decryptedData = decryptData(data); - if (decryptedData.user_id != user.userId) { + const decryptedData = decryptData(data) + if(decryptedData.user_id != user.userId){ return null; } - const message = decryptedData; - setVisitors((prevVisitors) => + const message = decryptedData + setVisitors((prevVisitors) => prevVisitors.map((visitor) => visitor.client_id === message.client_id ? { ...visitor, unseenMsg: 0 } - : visitor, - ), - ); - setFilteredVisitors((prevVisitors) => + : visitor + ) + ); setFilteredVisitors((prevVisitors) => prevVisitors.map((visitor) => visitor.client_id === message.client_id ? { ...visitor, unseenMsg: 0 } - : visitor, - ), + : visitor + ) ); }; const handleChatMessage = (message) => { // const decryptedData = decryptData(data) // const message = decryptedData - - if (activeTab || activeTab !== message.client_id) { + + + + if (activeTab || activeTab !== message.client_id) { // Play sound // const audio = new Audio(notificationSound); // Adjust the path if necessary // audio.play().catch(err => { @@ -571,10 +598,10 @@ const Chat = () => { socketinst.on("visitor status change", handleVisitorStatusChange); socketinst.on("chat message", handleChatMessage); socketinst.on("New message blink", handleNewMessageBlink); - socketinst.on("client data updated", handleClientDataUpdate); + socketinst.on('client data updated', handleClientDataUpdate); socketinst.on("message_seen", handleMessageSeen); socketinst.on("visitor_already_left", (data) => { - const decryptedData = decryptData(data); + const decryptedData = decryptData(data) customOnClick(); }); @@ -587,7 +614,7 @@ const Chat = () => { socketinst.off("visitor status change", handleVisitorStatusChange); socketinst.off("New message blink", handleNewMessageBlink); socketinst.off("chat message", handleChatMessage); - socketinst.off("client data updated", handleClientDataUpdate); + socketinst.off('client data updated', handleClientDataUpdate); socketinst.off("message_seen", handleMessageSeen); // socketinst.off('chat message', handleChatMessage); }; @@ -599,9 +626,12 @@ const Chat = () => { }, 3000); }; const handleVisitorClick = (visitor) => { - if (user.is_private == 1 && visitor.servedBy == "") { - return; - } + + + + if(user.is_private == 1 && visitor.servedBy == ""){ + return + } if (activeTab && activeTab === visitor.client_id) { setHideColumns(false); dispatch(minimize({ client_id: activeTab })); @@ -609,7 +639,7 @@ const Chat = () => { chatKey: `${visitor.public_key}_${visitor.client_id}`, from: user?.pseudonym, }); - + socket.emit("admin_closed_chat", { client_id: visitor.client_id, public_key: visitor.public_key, @@ -622,7 +652,7 @@ const Chat = () => { setHideColumns(false); dispatch(minimize({ client_id: activeTab })); } - + // Create a new copy of the visitor object const updatedVisitor = { ...visitor, @@ -633,13 +663,15 @@ const Chat = () => { const visitorCopy = { ...updatedVisitor }; delete visitorCopy.online; delete visitorCopy.join_time; - + setCurrentChat(updatedVisitor); - + + socket.emit("join chat", updatedVisitor); - + let updatedVi = { ...visitorCopy }; // Clone the visitorCopy object - + + if (visitor.servedBy) { updatedVi = { ...updatedVi, // Keep existing visitor data @@ -651,13 +683,14 @@ const Chat = () => { servedBy: false, // Add/Update servedBy flag }; } - + // Dispatch action to add the updated tab in the Redux store dispatch(addTab(updatedVi)); - + setHideColumns(true); } }; + const handleVisitorNameClick = () => { setHideColumns(!hideColumns); @@ -681,20 +714,20 @@ const Chat = () => { }; const handleShowPkChange = (e) => { - setIsShowPK(e.target.checked); + setIsShowPK(e.target.checked); }; // Categorize visitors, adding "Not Served" category const categorizedVisitors = { active: filteredVisitors.filter( - (v) => (v.visitorStatus === 1 || v.visitorStatus === 5) && v.servedBy, + (v) => (v.visitorStatus === 1 || v.visitorStatus === 5) && v.servedBy ), // Exclude not served notServed: filteredVisitors.filter((v) => !v.servedBy), // New category for visitors not served idle: filteredVisitors.filter((v) => v.visitorStatus === 2 && v.servedBy), // Exclude not served from idle closed: filteredVisitors.filter((v) => v.visitorStatus === 3 && v.servedBy), // Exclude not served from closed }; const noVisitorsFound = Object.values(categorizedVisitors).every( - (category) => category.length === 0, + (category) => category.length === 0 ); const [collapsedSections, setCollapsedSections] = useState({ active: false, @@ -705,16 +738,16 @@ const Chat = () => { const countPakistaniVisitors = () => { const counts = { active: categorizedVisitors.active.filter( - (visitor) => visitor.country === "Pakistan", + (visitor) => visitor.country === "Pakistan" ).length, notServed: categorizedVisitors.notServed.filter( - (visitor) => visitor.country === "Pakistan", + (visitor) => visitor.country === "Pakistan" ).length, idle: categorizedVisitors.idle.filter( - (visitor) => visitor.country === "Pakistan", + (visitor) => visitor.country === "Pakistan" ).length, closed: categorizedVisitors.closed.filter( - (visitor) => visitor.country === "Pakistan", + (visitor) => visitor.country === "Pakistan" ).length, }; return counts; @@ -779,166 +812,171 @@ const Chat = () => {
|
@@ -1256,15 +1259,6 @@ const VisitorRow = ({
-
- {/* Device Icon with Tooltip */}
-
- {getDeviceIcon(visitor?.device_size)}
-
- Device: {getDeviceType(visitor?.device_size)}
-
-
-
|
{totalMessages} | @@ -1273,16 +1267,17 @@ const VisitorRow = ({ {visitorStatus == 1 || 5 ? onlineTime : visitorStatus == 2 - ? "idle" - : visitorStatus == 3 - ? "close chat" - : ""} + ? "idle" + : visitorStatus == 3 + ? "close chat" + : ""}{servedBy} | - {brand_name} - | + {brand_name} + + {/*{servedBy} | {brand_name} | */} @@ -1298,5 +1293,6 @@ const VisitorRow = ({
| Messages | Platform | Brand | -- Landing Page - | +Landing Page | IP | Join At | Duration | @@ -1573,26 +1098,20 @@ const History = () => { NewHistoryRecieved.some( (history) => history.visitor_session_id === - visitor.visitor_session_id, + visitor.visitor_session_id ) ? "new-history-row" : "" }`} > {/*{visitor.visitor_session_id || 'N/A'} | */} -- {visitor.client_id || "N/A"} - | -- {visitor.client_name || "N/A"} - | +{visitor.client_id || "N/A"} | +{visitor.client_name || "N/A"} | {visitor.served_by || "N/A"} - | -- {visitor.message_count} - | + +{visitor.message_count } |
{/* Browser Icon with Tooltip */}
@@ -1621,53 +1140,29 @@ const History = () => {
|
- - {visitor.brand_name || "N/A"} - | -+ | {visitor.brand_name || "N/A"} | +{visitor.landing_url || "N/A"} | - -+ + | {visitor.ip || "N/A"} | -+ | {emitTimeInUserTimezone(visitor.join_time) || "N/A"} | -+ | {calculateSessionTime( visitor.join_time, - visitor.left_time, + visitor.left_time ) || "N/A"} | -+ | {visitor.IP_Health === 1 ? "Good" : visitor.IP_Health === 0 - ? "Bad" - : "N/A"} + ? "Bad" + : "N/A"} | ))} @@ -1697,20 +1192,11 @@ const History = () => { {isFiltering && (
|---|