import { useCallback, useEffect, useMemo, useState, useContext } 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"; import DarkModeContext from '../components/Contexts/DarkModeContext' const AuthRoute = ({ redirectPath = "/login", children }) => { let {joinRoom} = SocketValues() // destructures 'SEND MESSAGE' and 'JOIN ROOM' FUNCTIONS FROM SOCKET // const [nocache, setNoCache] = useState(false) // holds cache/nocache value const {nocache, setNoCache} = useContext(DarkModeContext); // Destructures nocache and set nocache from context API const apiCall = useMemo(() => new usersService(), []); const dispatch = useDispatch(); const [lastActivityTime, setLastActivityTime] = useState(Date.now()); const [isLogin, setIsLogin] = useState({ loading: true, status: false }); const navigate = useNavigate(); const { jobListTable, marketTableList, walletTable, familyBannersListTable, homeBanners } = 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(() => { if (account_type === "FAMILY") { if (Date.now() - Number(lastActivityTime) > Number(process.env.REACT_APP_SESSION_EXPIRE_MINUTES_FAMILY)) { expireSession(); } } else { if (Date.now() - Number(lastActivityTime) > Number(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, isLogin.status]); // 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; } dispatch(updateUserDetails({ ...res.data })); setIsLogin({ loading: false, status: true }); setNoCache(true) // Sets no cache to true, so as to trigger nocache whenever used in api call }) .catch((error) => { setIsLogin({ loading: false, status: false }); }); }; loadProfile(); }else{ setIsLogin({ loading: false, status: true }); setNoCache(true) // Sets no cache to true, so as to trigger nocache whenever used in api call } }, []); //FUNCTION TO GET COMMON HEAD DATA useEffect(() => { if((!loggedIn && !isLogin.status) || isLogin.loading || account_type == 'FAMILY'){ // DO NOT CALL THIS, IF USER ACCOUNT TYPE IS FAMILY return } dispatch(commonHeadBanner({loading:true, data:{}})); apiCall .getHeroJBanners() .then((res) => { if (res?.data?.internal_return < 0) { return; } dispatch(commonHeadBanner({loading:false, data:res.data})); }) .catch((error) => { dispatch(commonHeadBanner({loading:false, data:{}})); }); }, [isLogin.status, homeBanners]); useEffect(() => { // FUNCTION TO GET NOTIFICATIONS LIST const notifications = () => { // 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; } 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 })); }); }; // delay verify requests by 10000ms const delay15secs = setTimeout(notifications, 15000) return ()=> clearTimeout(delay15secs) }, []); useEffect(() => { if((!loggedIn && !isLogin.status) || isLogin.loading || 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]); //FUNCTION TO GET FULL USER WALLETS useEffect(() => { if((!loggedIn && !isLogin.status) || isLogin.loading || 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]); // FUNCTION TO GET MARKET JOB LIST useEffect(() => { if((!loggedIn && !isLogin.status) || isLogin.loading || 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) || isLogin.loading || 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) || isLogin.loading || isLogin.loading || 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:[]}); dispatch(familyBannersList({loading:true})) const noCache = (isLogin.status && nocache )? 1 : 0 const reqData = {nocache: noCache} try { const res = await apiCall.getFamilyBannersList(reqData); 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) || isLogin.loading || 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) || isLogin.loading || 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;