import { useCallback, useEffect, useMemo, useState } from "react"; import { useDispatch, useSelector } from "react-redux"; import { Navigate, Outlet, useNavigate } from "react-router-dom"; import LoadingSpinner from "../components/Spinners/LoadingSpinner"; import { formattedDate } from "../lib"; import usersService from "../services/UsersService"; import { commonHeadBanner } from "../store/CommonHeadBanner"; import { recentActivitiesData } from "../store/RecentActivitiesData"; import { updateUserDetails } from "../store/UserDetails"; import { updateJobs } from "../store/jobLists"; import { updateNotifications } from "../store/notifications"; import { updateUserJobList } from "../store/userJobList"; import { updateWalletDetails } from "../store/walletDetails"; import { familyBannersList } from "../store/FamilyBannerList"; import { familyResources } from "../store/FamilyResources"; import {familyWalletRedeemOptList} from '../store/FamilyWalletRedeemOpt' import { SocketValues } from "../components/Contexts/SocketIOContext"; const AuthRoute = ({ redirectPath = "/login", children }) => { let {joinRoom} = SocketValues() // destructures 'SEND MESSAGE' and 'JOIN ROOM' FUNCTIONS FROM SOCKET const apiCall = useMemo(() => new usersService(), []); const dispatch = useDispatch(); const [lastActivityTime, setLastActivityTime] = useState(Date.now()); const [isLogin, setIsLogin] = useState({ loading: true, status: false }); const [loadProfileDetails, setLoadProfileDetails] = useState([]); const navigate = useNavigate(); const { jobListTable, marketTableList, walletTable, familyBannersListTable } = useSelector( (state) => state.tableReload ); const { userDetails: { username, uid, session, account_type, parent_uid }, } = useSelector((state) => state?.userDetails); // CHECKS IF USER Details are avaliable, to determine if user is active let loggedIn = username && session && uid ? true : false; // variable to determine if user is logged in useEffect(() => { //Removing Data stored at localStorage after session expires const expireSession = () => { sessionStorage.clear(); localStorage.clear(); navigate("/login", { replace: true }); // redirects user to login page after session expires }; const checkInactivity = setInterval(() => { let { account_type } = loadProfileDetails; if (account_type === "FAMILY") { if ( Date.now() - lastActivityTime > process.env.REACT_APP_SESSION_EXPIRE_MINUTES_FAMILY ) { expireSession(); } } else { if ( Date.now() - lastActivityTime > process.env.REACT_APP_SESSION_EXPIRE_MINUTES ) { expireSession(); } } }, process.env.REACT_APP_SESSION_EXPIRE_CHECKER); // Checks for inactivity every minute // cleaning up listeners return () => { clearInterval(checkInactivity); }; }, [lastActivityTime, navigate]); // Reset last activity time on user input const resetTime = useCallback(() => { setLastActivityTime(Date.now()); }, []); useEffect(() => { window.addEventListener("mousemove", resetTime); window.addEventListener("keydown", resetTime); return () => { window.removeEventListener("mousemove", resetTime); window.removeEventListener("keydown", resetTime); }; }, [resetTime]); useEffect(() => { if (!loggedIn) { const loadProfile = () => { // function to load user profile setIsLogin({ loading: true, status: false }); apiCall .loadProfile() .then((res) => { if (res.data.internal_return < 0) { setIsLogin({ loading: false, status: false }); return; } setLoadProfileDetails(res.data); dispatch(updateUserDetails({ ...res.data })); setIsLogin({ loading: false, status: true }); }) .catch((error) => { setIsLogin({ loading: false, status: false }); }); }; loadProfile(); }else{ setIsLogin({ loading: false, status: true }); } }, []); useEffect(() => { const getNotifications = () => { // function to load user notification dispatch(updateNotifications({ loading: true })); apiCall .getMyNotifications() .then((res) => { if (res.data.internal_return < 0) { dispatch(updateNotifications({ loading: false, data: null })); return; } setLoadProfileDetails(res.data); const _raw = res.data?.result_list; //Sort the notifications in ascending order based on the API time const _sorted = _raw?.sort((a, b) => { const timeA = new Date(a?.date)?.getTime(); const timeB = new Date(b?.date)?.getTime(); return timeA - timeB; }); // header component const _header = _sorted?.slice(0, 5); // Notification Layout const _today = _sorted?.slice(0, 7); const _days = () => { const sevenDaysAgo = new Date(); sevenDaysAgo.setDate(new Date() - 7); return _sorted?.filter((notification) => { const notificationDate = new Date( formattedDate(notification?.date) ); return notificationDate >= sevenDaysAgo; }); }; // Dispatch all notifications, sorted, and recent based on their filter type dispatch( updateNotifications({ loading: false, // data: { // raw: _raw, // today: _today, // // days: _days(), // sort: _sorted, // header: _header, // }, data: _sorted, }) ); }) .catch((error) => { dispatch(updateNotifications({ loading: false, data: null })); }); }; getNotifications(); }, []); useEffect(() => { if((!loggedIn && !isLogin.status) || account_type == 'FAMILY'){ // DO NOT CALL THIS, IF USER ACCOUNT TYPE IS FAMILY return } const getMyJobList = async () => { dispatch(updateUserJobList({ loading: true, data: [] })); try { const res = await apiCall.getMyJobList(); // setMyJobList({loading: false, data:res.data}) // setMyJobList(res.data); dispatch(updateUserJobList({ loading: false, data: res.data })); } catch (error) { dispatch(updateUserJobList({ loading: false, data: [] })); // setMyJobList({loading: false, data:[]}) console.log("Error getting mode"); } }; getMyJobList(); }, [jobListTable, isLogin.status]); useEffect(() => { if((!loggedIn && !isLogin.status) || account_type == 'FAMILY'){ // DO NOT CALL THIS, IF USER ACCOUNT TYPE IS FAMILY return } const getMyWalletList = async () => { dispatch(updateWalletDetails({ loading: true, data: [] })); try { const res = await apiCall.getUserWallets(); console.log("wallet - >", res.data); dispatch( updateWalletDetails({ loading: false, data: res.data?.result_list }) ); } catch (error) { dispatch(updateWalletDetails({ loading: false, data: [] })); console.log("Error getting mode"); } }; getMyWalletList(); }, [walletTable, isLogin.status]); useEffect(() => { if((!loggedIn && !isLogin.status) || account_type == 'FAMILY'){ // DO NOT CALL THIS, IF USER ACCOUNT TYPE IS FAMILY return } // Getting market data const getMarketActiveJobList = async () => { dispatch(updateJobs({loading: true})); try { const res = await apiCall.getActiveJobList(); dispatch(updateJobs({loading: false, ...res.data})); } catch (error) { dispatch(updateJobs({loading: false})); console.log("Error getting mode"); } }; getMarketActiveJobList(); }, [apiCall, dispatch, marketTableList, isLogin.status]); //FUNCTION TO GET COMMON HEAD DATA useEffect(() => { if((!loggedIn && !isLogin.status) || account_type == 'FAMILY'){ // DO NOT CALL THIS, IF USER ACCOUNT TYPE IS FAMILY return } apiCall .getHeroJBanners() .then((res) => { if (res.data?.internal_return < 0) { return; } dispatch(commonHeadBanner(res.data)); }) .catch((error) => { console.log("ERROR ", error); }); }, [isLogin.status]); //FUNCTION TO GET COMMON HEAD DATA useEffect(() => { if((!loggedIn && !isLogin.status) || account_type == 'FAMILY'){ // DO NOT CALL THIS, IF USER ACCOUNT TYPE IS FAMILY return } apiCall .getRecentActivitiedData() .then((res) => { // debugger; if (res?.data?.internal_return < 0) { return; } dispatch(recentActivitiesData(res.data)); }) .catch((error) => { console.log("ERROR ", error); }); }, [isLogin.status]); //FUNCTION TO GET FAMILY BANNERS useEffect(() => { if((!loggedIn && !isLogin.status) || account_type == 'FULL'){ // DO NOT CALL THIS, IF USER ACCOUNT TYPE IS FULL return } const getFamilyBanners = async () => { // FUNCTION TO GET FAMILY BANNERS // setFamilyBannersList({loading:true, result:[]}); try { const res = await apiCall.getFamilyBannersList(); dispatch(familyBannersList({...res.data, loading:false})) } catch (error) { dispatch(familyBannersList({loading:false})) console.log("Error getting tasks"); } }; getFamilyBanners() }, [isLogin.status, familyBannersListTable]); //FUNCTION TO GET FAMILY RESOURCES useEffect(() => { if((!loggedIn && !isLogin.status) || account_type == 'FULL'){ // DO NOT CALL THIS, IF USER ACCOUNT TYPE IS FULL return } const getFamilyResourcesList = async () => { // FUNCTION TO GET FAMILY BANNERS try { const res = await apiCall.getFamilyResources(); dispatch(familyResources(res?.data?.result_list)) // console.log('RESPONSE', res?.data?.result_list) } catch (error) { console.log("Error getting tasks"); } }; getFamilyResourcesList() }, [isLogin.status]); //FUNCTION TO GET FAMILY WALLET REDEEM OPTIONS useEffect(() => { if((!loggedIn && !isLogin.status) || account_type == 'FULL'){ // DO NOT CALL THIS, IF USER ACCOUNT TYPE IS FULL return } const familyWalletRedeemOptions = async () => { // FUNCTION TO GET FAMILY WALLET REDDEM OPTIONS dispatch(familyWalletRedeemOptList({loading: true, image: '', data:{}})) apiCall.getFamilyWalletRedeemOptions().then((res)=>{ dispatch(familyWalletRedeemOptList({loading: false, image: res?.data?.session_image_server, data:res?.data?.result_list})) }).catch((err)=>{ console.log(err) dispatch(familyWalletRedeemOptList({loading: false, image: '', data:{}})) }) }; familyWalletRedeemOptions() }, [isLogin.status]); useEffect(()=>{ // sends an event to the socket to enable user join a room to be able to receive update when jobs enters the market joinRoom('full-markets-jobs') },[isLogin.status]) useEffect(()=>{ // sends an event to the socket to enable user join a room to be able to receive update for parent child job assign if(loggedIn || isLogin.status){ joinRoom(`FAMILY-${account_type == 'FULL' ? uid : sessionStorage.getItem('parent_uid')}`) console.log(`Room joined for parent child task assign as ${account_type} with ${account_type == 'FULL' ? uid : sessionStorage.getItem('parent_uid')}}`) } },[isLogin.status]) // RENDER PAGE return isLogin.loading && !loggedIn ? ( ) : !isLogin.status && !loggedIn ? ( ) : ( children || ); }; export default AuthRoute;