diff --git "a/C:\\chatknot\\app\\ProtectApp.js" "b/C:\\chatknot\\old backup\\app\\ProtectApp.js" index 973b288..c8b7230 100644 --- "a/C:\\chatknot\\app\\ProtectApp.js" +++ "b/C:\\chatknot\\old backup\\app\\ProtectApp.js" @@ -6,18 +6,19 @@ import { deleteCookie, getCookie, setCookie } from "cookies-next"; import { useDispatch, useSelector } from "react-redux"; import { verifyUserRole } from "./lib/features/user/UserSlice"; import { initializeSocket, disconnectSocket } from "./lib/socketManager"; +import notificationSound from "@/public/sounds/notification.wav"; import LoadingSpinner from "./LoadingSpinner"; import getDeviceId from "./hooks/useVisitorId"; import axios from "axios"; import { reset } from "./lib/features/chat/chatSlice"; import { fetchShortcuts } from "./lib/features/shortcuts/shortcutsSlice"; - -import swal from "sweetalert"; + +import swal from 'sweetalert'; import apiRequest from "./lib/InterceptorAxios/axios"; import { fetchTones } from "./lib/features/tones/tonesSlice"; import handlelogout from "./utils/handlelogout"; import { decryptData } from "./utils/DecryptData"; - + const ProtectApp = ({ children }) => { const status = useSelector((state) => state.user.status); const token = getCookie("token"); @@ -26,19 +27,15 @@ const ProtectApp = ({ children }) => { const [isLoading, setIsLoading] = useState(true); const router = useRouter(); const dispatch = useDispatch(); - const [deviceId, setdeviceId] = useState(); + const [deviceId, setdeviceId] = useState() const userId = useSelector((state) => state.user.userInfo.userId); - const [Tones, setTones] = useState(); - const selectedBrands = useSelector( - (state) => state.selectedBrands.selectedBrands, - ); - // Accessing tones from Redux state - const { newVisitorTone, messageTone, toneStatus } = useSelector( - (state) => state.tones, - ); - const newVisitorToneRef = useRef(null); + const [Tones, setTones] = useState() + const selectedBrands = useSelector((state) => state.selectedBrands.selectedBrands); + // Accessing tones from Redux state + const { newVisitorTone, messageTone,toneStatus } = useSelector(state => state.tones); + const newVisitorToneRef = useRef(null); const { tabs, activeTab } = useSelector((state) => state.chat); - const socketRef = useRef(null); + const socketRef = useRef(null); const roleBasedRoutes = { 1: [ @@ -52,7 +49,7 @@ const ProtectApp = ({ children }) => { "team", "all-brands", "alerts", - "all-widgets", + "all-widgets" ], // Role 1 can access all routes 2: [ "brands", @@ -62,7 +59,7 @@ const ProtectApp = ({ children }) => { "profile", "settings", "team", - "test-page", + "test-page" ], // Role 2 can access only 'brands' and 'chat' 4: [ "brands", @@ -73,10 +70,12 @@ const ProtectApp = ({ children }) => { "settings", "team", ], // Role 2 can access only 'brands' and 'chat' - 3: ["chat", "brands", "chat", "history", "profile", "settings"], // Role 3 can only access 'chat' + 3: ["chat", "brands", "chat", "history", "profile", "settings",], // Role 3 can only access 'chat' }; // Function to check route permission dynamically based on the user's role const checkRoute = (role) => { + + const currentPath = window.location.pathname.split("/")[1]; // Get the first part of the route const allowedRoutes = roleBasedRoutes[role] || []; // Get allowed routes for the role @@ -90,9 +89,9 @@ const ProtectApp = ({ children }) => { const handleVisibilityChange = () => { if (document.hidden) { // Tab is inactive - } else { + } else { // Tab is active - } + } }; // Listen for visibility change @@ -103,33 +102,42 @@ const ProtectApp = ({ children }) => { document.removeEventListener("visibilitychange", handleVisibilityChange); }; }, []); - + useEffect(() => { - if (toneStatus === "succeeded") { - newVisitorToneRef.current = newVisitorTone; + if (toneStatus === 'succeeded') { + + + newVisitorToneRef.current = newVisitorTone } }, [toneStatus]); + const selectedBrandsRef = useRef(selectedBrands); useEffect(() => { selectedBrandsRef.current = selectedBrands; }, [selectedBrands]); - + + useEffect(() => { if (!token) return; // Exit if no token - + // Initialize socket with token const initialize = async () => { try { - const socketinst = await initializeSocket(token, refreshToken); - + const socketinst = await initializeSocket(token,refreshToken); + if (!socketinst) return; - socketRef.current = socketinst; + socketRef.current = socketinst; // Handle new chat initiation const handleNewClient = async (data) => { const decryptedData = await decryptData(data); - const { client_id, public_key, join_time, brand_id } = decryptedData; + const { + client_id, + public_key, + join_time, + brand_id, + } = decryptedData const joinDate = new Date(join_time); const now = new Date(); const isToday = joinDate.toDateString() === now.toDateString(); @@ -138,24 +146,25 @@ const ProtectApp = ({ children }) => { minute: "numeric", hour12: true, }); - + + + const playNotificationSound = () => { - const audio = new Audio( - `/sounds/${newVisitorToneRef.current?.file}`, - ); + + const audio = new Audio(`/sounds/${newVisitorToneRef.current?.file}`); audio .play() .catch((err) => console.error("Error playing sound:", err)); }; - - if ( - selectedBrandsRef.current.length === 0 || - selectedBrandsRef.current.includes(public_key) - ) { + + if ( selectedBrandsRef.current.length ===0 || selectedBrandsRef.current.includes(public_key)) { + + playNotificationSound(); } else { + } - + const showNotification = () => { const arrivalTime = new Date().toLocaleTimeString(); if (Notification.permission === "granted") { @@ -164,14 +173,14 @@ const ProtectApp = ({ children }) => { tag: client_id, requireInteraction: false, }); - + notification.onclick = () => { window.focus(); window.location.href = `/chat`; }; } }; - + if ("Notification" in window) { if (Notification.permission === "default") { Notification.requestPermission() @@ -181,6 +190,7 @@ const ProtectApp = ({ children }) => { selectedBrandsRef.current.length === 0 || selectedBrandsRef.current.includes(public_key) ) { + showNotification(); } } else { @@ -195,11 +205,12 @@ const ProtectApp = ({ children }) => { selectedBrandsRef.current.length === 0 || selectedBrandsRef.current.includes(public_key) ) { + showNotification(); } } else { console.warn( - "Notifications are blocked. Please enable them in your browser settings.", + "Notifications are blocked. Please enable them in your browser settings." ); } } else { @@ -208,46 +219,51 @@ const ProtectApp = ({ children }) => { }; const handleClientRejoinChat = async (data) => { const decryptedData = await decryptData(data); - const { client_id, public_key } = decryptedData; - + const { + client_id, + public_key, + + } = decryptedData + + const now = new Date(); - + + + + + const playNotificationSound = () => { - const audio = new Audio( - `/sounds/${newVisitorToneRef.current?.file}`, - ); + + const audio = new Audio(`/sounds/${newVisitorToneRef.current?.file}`); audio .play() .catch((err) => console.error("Error playing sound:", err)); }; - - if ( - selectedBrandsRef.current.length === 0 || - selectedBrandsRef.current.includes(public_key) - ) { + + if ( selectedBrandsRef.current.length ===0 || selectedBrandsRef.current.includes(public_key)) { + + playNotificationSound(); } else { + } - + const showNotification = () => { const arrivalTime = new Date().toLocaleTimeString(); if (Notification.permission === "granted") { - const notification = new Notification( - "Rejoin Visitor Alert 🚀", - { - body: `Visitor ${client_id} started revisiting the website at ${arrivalTime}.`, - tag: client_id, - requireInteraction: false, - }, - ); - + const notification = new Notification("Rejoin Visitor Alert 🚀", { + body: `Visitor ${client_id} started revisiting the website at ${arrivalTime}.`, + tag: client_id, + requireInteraction: false, + }); + notification.onclick = () => { window.focus(); window.location.href = `/chat`; }; } }; - + if ("Notification" in window) { if (Notification.permission === "default") { Notification.requestPermission() @@ -257,6 +273,7 @@ const ProtectApp = ({ children }) => { selectedBrandsRef.current.length === 0 || selectedBrandsRef.current.includes(public_key) ) { + showNotification(); } } else { @@ -271,11 +288,12 @@ const ProtectApp = ({ children }) => { selectedBrandsRef.current.length === 0 || selectedBrandsRef.current.includes(public_key) ) { + showNotification(); } } else { console.warn( - "Notifications are blocked. Please enable them in your browser settings.", + "Notifications are blocked. Please enable them in your browser settings." ); } } else { @@ -284,29 +302,34 @@ const ProtectApp = ({ children }) => { }; const handleNewUserAssigned = async (data) => { const decryptedData = await decryptData(data); - const { msg, assigned_user, createdBy } = decryptedData; - + const { + msg, + assigned_user, + createdBy + + } = decryptedData + + const now = new Date(); - + + + const showNotification = () => { const arrivalTime = new Date().toLocaleTimeString(); if (Notification.permission === "granted") { - const notification = new Notification( - "New Visitor Assigned 🚀", - { - body: `${msg}`, - - requireInteraction: false, - }, - ); - + const notification = new Notification("New Visitor Assigned 🚀", { + body: `${msg}`, + + requireInteraction: false, + }); + notification.onclick = () => { window.focus(); window.location.href = `/all-users`; }; } }; - + if ("Notification" in window) { if (Notification.permission === "default") { Notification.requestPermission() @@ -316,6 +339,8 @@ const ProtectApp = ({ children }) => { selectedBrandsRef.current.length === 0 || selectedBrandsRef.current.includes(public_key) ) { + + showNotification(); } } else { @@ -330,11 +355,12 @@ const ProtectApp = ({ children }) => { selectedBrandsRef.current.length === 0 || selectedBrandsRef.current.includes(public_key) ) { + showNotification(); } } else { console.warn( - "Notifications are blocked. Please enable them in your browser settings.", + "Notifications are blocked. Please enable them in your browser settings." ); } } else { @@ -346,79 +372,88 @@ const ProtectApp = ({ children }) => { socketinst.on("user-assigned-to-brand", handleNewUserAssigned); socketinst.on("tokens_updated", handleTokenUpdate); socketinst.on("refresh_token_error", handleRefreshTokenError); - + socketinst.on("Logged_in_to_other_device", (data) => { - const decryptedData = decryptData(data); + + const decryptedData = decryptData(data) const { message } = decryptedData; - + handlelogout(dispatch); swal("Oops!", message, "error"); }); - + socketinst.emit("get_online_users", { user_id: user.userId, }); - + const device_id = localStorage.getItem("visitorId"); - - // if (device_id && user?.userId) { - // socketinst.emit("Check_Logged_in_to_other_device", { - // user_id: user.userId, - // device_id, - // }); - // } - + +// if (device_id && user?.userId) { +// socketinst.emit("Check_Logged_in_to_other_device", { +// user_id: user.userId, +// device_id, +// }); +// } + + // Clean up on unmount return () => { - socketinst.off("new client", handleNewClient); - socketinst.off("client rejoin", handleClientRejoinChat); - socketinst.off("user-assigned-to-brand", handleNewUserAssigned); - socketinst.off("tokens_updated", handleTokenUpdate); - socketinst.off("refresh_token_error", handleRefreshTokenError); - socketinst.off("Logged_in_to_other_device"); + socketinst.off("new client", handleNewClient); + socketinst.off("client rejoin", handleClientRejoinChat); + socketinst.off("user-assigned-to-brand", handleNewUserAssigned); + socketinst.off("tokens_updated", handleTokenUpdate); + socketinst.off("refresh_token_error", handleRefreshTokenError); + socketinst.off("Logged_in_to_other_device"); }; } catch (error) { console.error("Error initializing socket:", error); } }; - + initialize(); }, [token]); // Only reinitialize if `token` changes useEffect(() => { - const device_id = localStorage.getItem("visitorId"); - if (socketRef.current && device_id && user?.userId) { - // console.log("Checking logged in to other device with userId:", user.userId, "and device_id:", device_id); - socketRef.current.emit("Check_Logged_in_to_other_device", { - user_id: user.userId, - device_id, - }); - } - }, [user?.userId]); // 🚨 Separate effect, runs when userId is available - const handleTokenUpdate = ({ accessToken, refreshToken }) => { - setCookie("token", accessToken); - setCookie("refreshToken", refreshToken); - }; + const device_id = localStorage.getItem("visitorId"); + if (socketRef.current && device_id && user?.userId) { + // console.log("Checking logged in to other device with userId:", user.userId, "and device_id:", device_id); + socketRef.current.emit("Check_Logged_in_to_other_device", { + user_id: user.userId, + device_id, + }); + } +}, [user?.userId]); // 🚨 Separate effect, runs when userId is available + const handleTokenUpdate = ({ + accessToken, + refreshToken + })=>{ + setCookie('token', accessToken); + setCookie('refreshToken', refreshToken); + + } const handleRefreshTokenError = () => { // Handle refresh token error console.error("Refresh token error"); - handlelogout(dispatch); - }; - + handlelogout(dispatch); + }; + useEffect(() => { if (!token) { + // If there's no token, redirect to login page router.push("/login"); setIsLoading(false); // Stop loading once redirected } else { if (user && user.length > 0) { // If user data exists, verify the role and check routes - + + const isAllowed = checkRoute(user.role); if (!isAllowed) { router.push("/"); // Redirect to "not authorized" page } setIsLoading(false); // Stop loading once checks are done } else { + // If no user data, dispatch to verify user role dispatch(verifyUserRole(token)).then((userData) => { if (userData?.payload?.role) { @@ -426,11 +461,11 @@ const ProtectApp = ({ children }) => { if (!isAllowed) { router.push("/"); // Redirect to "not authorized" page } - + dispatch(fetchTones(userData.payload.userId)); - const companyId = userData.payload.company_id; - const userId = userData.payload.userId; - dispatch(fetchShortcuts({ companyId, userId })); + const companyId = userData.payload.company_id + const userId = userData.payload.userId + dispatch(fetchShortcuts({companyId,userId})); setIsLoading(false); // Stop loading once checks are done } }); @@ -440,6 +475,7 @@ const ProtectApp = ({ children }) => { useEffect(() => { if (status === "succeeded") { + return () => { // disconnectSocket(); }; @@ -448,7 +484,7 @@ const ProtectApp = ({ children }) => { if (isLoading) { return ; } - + return <>{user.roleVerified == true ? <>{children} : null}; };