diff --git a/src/components/FamilyAcc/FamilyManageTabs.jsx b/src/components/FamilyAcc/FamilyManageTabs.jsx index 5904383..4da1646 100644 --- a/src/components/FamilyAcc/FamilyManageTabs.jsx +++ b/src/components/FamilyAcc/FamilyManageTabs.jsx @@ -1,26 +1,28 @@ import React, { Suspense, + lazy, useCallback, useEffect, useMemo, useRef, useState, + useTransition, } from "react"; import { useReactToPrint } from "react-to-print"; import profile from "../../assets/images/profile-info-profile.png"; import usersService from "../../services/UsersService"; import LoadingSpinner from "../Spinners/LoadingSpinner"; import AssignTaskPopout from "./FamilyPopout/AssignTaskPopout"; -import { - FamilyWaitlist, - FamilyAccount, - FamilyProfile, - FamilyTasks, - ProfileInfo, - FamilyPending, -} from "./Tabs"; import localImgLoad from "../../lib/localImgLoad"; +// Lazy Imports for components +const FamilyWaitlist = lazy(() => import("./Tabs/FamilyWaitlist")); +const FamilyAccount = lazy(() => import("./Tabs/FamilyAccount")); +const FamilyProfile = lazy(() => import("./Tabs/FamilyProfile")); +const FamilyTasks = lazy(() => import("./Tabs/FamilyTasks")); +const ProfileInfo = lazy(() => import("./Tabs/ProfileInfo")); +const FamilyPending = lazy(() => import("./Tabs/FamilyPending")); + export default function FamilyManageTabs({ className, accountDetails, @@ -35,14 +37,15 @@ export default function FamilyManageTabs({ }); const [errMsg, setErrMsg] = useState(""); const [familyTaskPopout, setFamilyTaskPopout] = useState(false); + const [profileImg, setProfileImg] = useState(profile); + const profileImgInput = useRef(null); + const [isPending, startTransition] = useTransition(); + const apiCall = useMemo(() => new usersService(), []); const familyPopUpHandler = () => { setFamilyTaskPopout((prev) => !prev); }; - const [profileImg, setProfileImg] = useState(profile); - const profileImgInput = useRef(null); - const browseProfileImg = () => { profileImgInput.current.click(); }; @@ -57,16 +60,15 @@ export default function FamilyManageTabs({ } }; - const apiCall = useMemo(() => new usersService(), []); - const manageFamily = useCallback(async () => { try { - setDetails({ + setDetails((prevDetails) => ({ + ...prevDetails, familyDetails: { loading: true }, familyTasks: { loading: true }, familyWaitList: { loading: true }, familyPending: { loading: true }, - }); + })); const { family_uid } = accountDetails; const reqData = { family_uid }; @@ -89,22 +91,26 @@ export default function FamilyManageTabs({ tasksData?.internal_return < 0 || familyWaitData?.internal_return < 0 || familyPendingData?.internal_return < 0 - ) + ) { return; + } - setDetails({ - familyDetails: { loading: false, data: familyData }, - familyTasks: { loading: false, data: tasksData }, - familyWaitList: { loading: false, data: familyWaitData }, - familyPending: { loading: false, data: familyPendingData }, + startTransition(() => { + setDetails({ + familyDetails: { loading: false, data: familyData }, + familyTasks: { loading: false, data: tasksData }, + familyWaitList: { loading: false, data: familyWaitData }, + familyPending: { loading: false, data: familyPendingData }, + }); }); } catch (error) { - setDetails({ + setDetails((prevDetails) => ({ + ...prevDetails, familyDetails: { loading: false }, familyTasks: { loading: false }, familyWaitList: { loading: false }, familyPending: { loading: false }, - }); + })); setErrMsg("An error occurred"); throw new Error(error); } @@ -119,13 +125,15 @@ export default function FamilyManageTabs({ const tabs = [ { id: 1, name: "Tasks" }, { id: 2, name: "Waiting" }, - { id: 3, name: "Pending" } + { id: 3, name: "Pending" }, ]; const [tab, setTab] = useState(tabs[0].name); const tabHandler = (value) => { - setTab(value); + startTransition(() => { + setTab(value); + }); }; const tabComponents = { @@ -174,7 +182,13 @@ export default function FamilyManageTabs({ const selectedTabComponent = tabComponents[tab] || defaultTabComponent; useEffect(() => { - manageFamily(); + let __manageFamily = true; + if (__manageFamily) { + manageFamily(); + } + return () => { + __manageFamily = false; + }; }, [tab, manageFamily]); return ( @@ -202,15 +216,25 @@ export default function FamilyManageTabs({ />
@@ -243,7 +267,11 @@ export default function FamilyManageTabs({
- {selectedTabComponent} + } + > + {selectedTabComponent} +
diff --git a/src/components/FamilyAcc/FamilyPopout/AssignTaskPopout.jsx b/src/components/FamilyAcc/FamilyPopout/AssignTaskPopout.jsx index 499ae89..94cfd3f 100644 --- a/src/components/FamilyAcc/FamilyPopout/AssignTaskPopout.jsx +++ b/src/components/FamilyAcc/FamilyPopout/AssignTaskPopout.jsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from "react"; +import React, { useState, useEffect, useTransition } from "react"; import ModalCom from "../../Helpers/ModalCom"; import Detail from "../../jobPopout/popoutcomponent/Detail"; import usersService from "../../../services/UsersService"; @@ -6,7 +6,7 @@ import LoadingSpinner from "../../Spinners/LoadingSpinner"; import { PriceFormatter } from "../../Helpers/PriceFormatter"; import { NewTasks } from "./forms"; -function AssignTaskPopout({ action, details, situation, familyDetails }) { +const AssignTaskPopout = React.memo(({ action, details, situation, familyDetails }) => { const apiCall = new usersService(); let [requestStatus, setRequestStatus] = useState({ @@ -15,7 +15,7 @@ function AssignTaskPopout({ action, details, situation, familyDetails }) { message: "", }); // HOLDS RESPONSE FOR SENDING API REQUEST - let [familyTask, setFamilyTask] = useState({ loading: true, data: [] }); + let [familyTask, setFamilyTask] = useState({ loading: false, data: [] }); let [taskType, setTaskType] = useState(details ? "new" : "select"); // SWITCHES BTW SELECT TASK AND NEW TASK @@ -156,27 +156,35 @@ function AssignTaskPopout({ action, details, situation, familyDetails }) { }; useEffect(() => { + let checkFamilyTask = true; const reqData = { limit: 30, offset: 0, job_type: "FAMILY", action: 13005, }; + apiCall .getMyJobList(reqData) .then((res) => { - setFamilyTask({ loading: false, data: res?.data?.result_list }); - if (res?.data?.result_list?.length) { - setActiveTask((prev) => ({ - ...prev, - data: res?.data?.result_list[0], - })); + if (checkFamilyTask) { + setFamilyTask({ loading: false, data: res?.data?.result_list }); + if (res?.data?.result_list?.length) { + setActiveTask((prev) => ({ + ...prev, + data: res?.data?.result_list[0], + })); + } } }) .catch((err) => { setFamilyTask({ loading: false, data: [] }); console.log("Error", err); }); + + return () => { + checkFamilyTask = false; + }; }, []); return ( @@ -428,6 +436,6 @@ function AssignTaskPopout({ action, details, situation, familyDetails }) { ); -} +}) -export default AssignTaskPopout; +export default AssignTaskPopout; \ No newline at end of file diff --git a/src/components/FamilyAcc/FamilyPopout/forms/NewTasks.jsx b/src/components/FamilyAcc/FamilyPopout/forms/NewTasks.jsx index 508d47e..5c2b0fa 100644 --- a/src/components/FamilyAcc/FamilyPopout/forms/NewTasks.jsx +++ b/src/components/FamilyAcc/FamilyPopout/forms/NewTasks.jsx @@ -2,7 +2,6 @@ import React, { useEffect, useState } from "react"; import usersService from "../../../../services/UsersService"; import InputCom from "../../../Helpers/Inputs/InputCom"; -// const DEFAULT_IMAGE = export default function NewTasks({ formState, setFormState }) { let [currency, setCurrency] = useState({ loading: true, diff --git a/src/components/FamilyAcc/FamilyTable.jsx b/src/components/FamilyAcc/FamilyTable.jsx index 81b6d8a..1a27a76 100644 --- a/src/components/FamilyAcc/FamilyTable.jsx +++ b/src/components/FamilyAcc/FamilyTable.jsx @@ -8,10 +8,7 @@ import PaginatedList from "../Pagination/PaginatedList"; import familyImage from '../../assets/images/no-family-side.png' export default function FamilyTable({ className, familyList, loader, popUpHandler }) { - const filterCategories = ["All Categories", "Explore", "Featured"]; - const [selectedCategory, setCategory] = useState(filterCategories[0]); const navigate = useNavigate(); - // let location = useLocation(); const [currentPage, setCurrentPage] = useState(0); const indexOfFirstItem = Number(currentPage); diff --git a/src/components/FamilyAcc/Tabs/FamilyAccount.jsx b/src/components/FamilyAcc/Tabs/FamilyAccount.jsx index dcfb3b8..739dc0b 100644 --- a/src/components/FamilyAcc/Tabs/FamilyAccount.jsx +++ b/src/components/FamilyAcc/Tabs/FamilyAccount.jsx @@ -1,56 +1,56 @@ -import { forwardRef } from 'react' -import QRCode from 'react-qr-code'; +import { forwardRef } from "react"; +import QRCode from "react-qr-code"; const FamilyAccount = forwardRef(({ familyData, myRef, handlePrint }, ref) => { - return ( -
-
-
-
-

- Username:{" "} - - {familyData?.username ? familyData?.username : "please wait..."} - -

-

- Pin:{" "} - - {familyData?.pin ? familyData?.pin : "please wait..."} - -

-
- - - or - - -
-

- Scan the code from mobile app -

- -
+ return ( +
+
+
+
+

+ Username:{" "} + + {familyData?.username ? familyData?.username : "please wait..."} + +

+

+ Pin:{" "} + + {familyData?.pin ? familyData?.pin : "please wait..."} + +

-
- + + + or + + +
+

+ Scan the code from mobile app +

+
+
+ +
- ); - }); +
+ ); +}); -export default FamilyAccount \ No newline at end of file +export default FamilyAccount; \ No newline at end of file diff --git a/src/components/FamilyAcc/Tabs/FamilyPending.jsx b/src/components/FamilyAcc/Tabs/FamilyPending.jsx index b3d5e87..08ad302 100644 --- a/src/components/FamilyAcc/Tabs/FamilyPending.jsx +++ b/src/components/FamilyAcc/Tabs/FamilyPending.jsx @@ -1,4 +1,4 @@ -import { useState } from "react"; +import { useMemo, useState } from "react"; import { PaginatedList, handlePagingFunc } from "../../Pagination"; import { PriceFormatter } from "../../Helpers/PriceFormatter"; import dataImage2 from "../../../assets/images/data-table-user-2.png"; @@ -13,8 +13,12 @@ export default function FamilyPending({ }) { let [jobPopout, setJobPopout] = useState({ show: false, data: {} }); // STATE TO HOLD THE VALUE OF THE ALERT DETAILS AND DETERMINE WHEN TO SHOW - let filteredFamilyData = familyData?.result_list?.filter( - (data) => data?.family_uid === accountDetails?.family_uid + let filteredFamilyData = useMemo( + () => + familyData?.result_list?.filter( + (data) => data?.family_uid === accountDetails?.family_uid + ), + [accountDetails?.family_uid, familyData?.result_list] ); const [currentPage, setCurrentPage] = useState(0); @@ -51,7 +55,7 @@ export default function FamilyPending({ value?.currency_code, value?.currency ); - let image = value.banner ? value.banner : 'default.jpg' + let image = value.banner ? value.banner : "default.jpg"; return (
data diff --git a/src/components/FamilyAcc/Tabs/FamilyWaitlist.jsx b/src/components/FamilyAcc/Tabs/FamilyWaitlist.jsx index fd4b968..e146ba2 100644 --- a/src/components/FamilyAcc/Tabs/FamilyWaitlist.jsx +++ b/src/components/FamilyAcc/Tabs/FamilyWaitlist.jsx @@ -1,31 +1,50 @@ -import { useState } from "react"; +import { useState, useMemo, memo } from "react"; import { handlePagingFunc, PaginatedList } from "../../Pagination"; import LoadingSpinner from "../../Spinners/LoadingSpinner"; import SuggestTask from "../../FamilyPopup/SuggestTask"; import AssignTaskPopout from "../FamilyPopout/AssignTaskPopout"; -const FamilyWaitlist = ({ familyData, className, accountDetails, loader }) => { +const FamilyWaitlist = memo(({ familyData, className, accountDetails, loader }) => { const [popUp, setPopUp] = useState({ show: false, data: {} }); const [continueTaskPopup, setContinueTaskPopup] = useState({ show: false, data: {}, }); - - let filteredFamilyData = familyData?.result_list?.filter( - (data) => data?.family_uid === accountDetails?.family_uid + const filteredFamilyData = useMemo( + () => + familyData?.result_list?.filter( + (data) => data?.family_uid === accountDetails?.family_uid + ), + [familyData, accountDetails] ); const [currentPage, setCurrentPage] = useState(0); const itemsPerPage = Number(process.env.REACT_APP_ITEM_PER_PAGE); const indexOfFirstItem = currentPage; const indexOfLastItem = currentPage + itemsPerPage; - const currentTask = filteredFamilyData?.slice( - indexOfFirstItem, - indexOfLastItem + const currentTask = useMemo( + () => filteredFamilyData?.slice(indexOfFirstItem, indexOfLastItem), + [filteredFamilyData, indexOfFirstItem, indexOfLastItem] ); const handlePagination = (e) => handlePagingFunc(e, setCurrentPage); + const openPopUp = (value) => { + setPopUp({ show: true, data: { ...value } }); + }; + + const closePopUp = () => { + setPopUp({ show: false, data: {} }); + }; + + const openContinueTaskPopup = (value) => { + setContinueTaskPopup({ show: true, data: { ...value } }); + }; + + const closeContinueTaskPopup = () => { + setContinueTaskPopup({ show: false, data: {} }); + }; + return (
{
); -}; +}); export default FamilyWaitlist; diff --git a/src/components/FamilyAcc/index.jsx b/src/components/FamilyAcc/index.jsx index 3b06dc7..0c3cee1 100644 --- a/src/components/FamilyAcc/index.jsx +++ b/src/components/FamilyAcc/index.jsx @@ -1,9 +1,16 @@ -import React, { useCallback, useEffect, useMemo, useState } from "react"; +import React, { + Suspense, + useCallback, + useEffect, + useMemo, + useState, +} from "react"; import InputCom from "../Helpers/Inputs/InputCom"; import Layout from "../Partials/Layout"; import FamilyTable from "./FamilyTable"; import SiteService from "../../services/SiteService"; import ModalCom from "../Helpers/ModalCom"; +import LoadingSpinner from "../Spinners/LoadingSpinner"; export default function FamilyAcc() { const [selectTab, setValue] = useState("today"); @@ -20,60 +27,50 @@ export default function FamilyAcc() { const apiCall = useMemo(() => new SiteService(), []); - // This is to make sure it's called once and used everywhere - let memberId = localStorage.getItem("member_id"); - let uid = localStorage.getItem("uid"); - let sessionId = localStorage.getItem("session_token"); - const popUpHandler = () => { setPopUp((prev) => !prev); }; - // tab handler const filterHandler = (value) => { setValue(value); }; - // For the age drop down - let startAge = 5; - let endAge = 16; - // creates an array of age values ranging from 16 to 70 - const ageRange = Array.from( - { length: endAge - startAge + 1 }, - (_, index) => startAge + index - ); - // age handler + const ageRange = useMemo(() => { + const startAge = 5; + const endAge = 16; + return Array.from( + { length: endAge - startAge + 1 }, + (_, index) => startAge + index + ); + }, []); + const handleAgeSelect = (event) => { setSelectedAge(parseInt(event.target.value)); }; - // Input handler + const handleInputChange = (event) => { const { name, value } = event?.target; - setFormData({ ...formData, [name]: value }); + setFormData((prevFormData) => ({ ...prevFormData, [name]: value })); }; - // Add member const addMember = async () => { const { first_name, last_name } = formData; setLoader(true); try { if (first_name !== "" && last_name !== "") { - let reqData = { - member_id: memberId, - uid: uid, - session_id: sessionId, + const reqData = { firstname: first_name, lastname: last_name, age: selectedAge, }; - let res = await apiCall.addFamily(reqData); + const res = await apiCall.addFamily(reqData); const { data } = res; - if (data?.internal_return > 0 && data?.status == "OK") { + if (data?.internal_return > 0 && data?.status === "OK") { setLoader(false); setListReload((prev) => !prev); - popUpHandler() + popUpHandler(); } else { setLoader(false); setMsgErr("Sorry, something went wrong"); @@ -94,38 +91,42 @@ export default function FamilyAcc() { first_name: "", last_name: "", }); - setSelectedAge("") + setSelectedAge(""); } }; - // member listing const memberList = useCallback(async () => { setLoader(true); try { - let reqData = { - member_id: memberId, - uid: uid, - session_id: sessionId, + const reqData = { limit: 20, offset: 0, action: 22010, }; - let res = await apiCall.familyListings(reqData); + const res = await apiCall.familyListings(reqData); const { data } = res; - if (data?.internal_return >= 0 && data?.status == "OK") { - let { result_list } = data; + if (data?.internal_return >= 0 && data?.status === "OK") { + const { result_list } = data; setFamilyList(result_list); setLoader(false); - } else return; + } else { + return; + } } catch (error) { setLoader(false); throw new Error(error); } - }, [apiCall, memberId, sessionId, uid]); + }, [apiCall]); useEffect(() => { - memberList(); + let checkMemberList = true; + if (checkMemberList) { + memberList(); + } + return () => { + checkMemberList = false; + }; }, [listReload, memberList]); return ( @@ -158,7 +159,13 @@ export default function FamilyAcc() { >
- + }> + +
{popUp && ( diff --git a/src/components/FamilyPopup/SuggestTask.jsx b/src/components/FamilyPopup/SuggestTask.jsx index 99e89f4..bd0b2ac 100644 --- a/src/components/FamilyPopup/SuggestTask.jsx +++ b/src/components/FamilyPopup/SuggestTask.jsx @@ -31,6 +31,7 @@ const SuggestTask = ({ details, onClose, situation, continuePopupData }) => { const handleSuggestedTask = async (values) => { if (!values.title && !values.description) return; + try { setSubmitTask({ loading: true }); const reqData = { ...values }; @@ -195,7 +196,8 @@ const SuggestTask = ({ details, onClose, situation, continuePopupData }) => { role="group" key={idx} htmlFor={`parent-suggested-${idx}`} - className={`transition duration-150 ease-in-out parent-suggest`} + className={`transition duration-150 ease-in-out parent-suggest group cursor-pointer`} + onClick={() => setSuggestedNextStep(title)} > { value={title} checked={suggestedNextStep === title} onChange={switchNextStep} - className={`transition duration-150 ease-in-out parent-suggest`} + className={`transition duration-150 ease-in-out parent-suggest pointer-events-none`} /> setSuggestedNextStep(title)} diff --git a/src/services/UsersService.js b/src/services/UsersService.js index 8a38d16..f315fd3 100644 --- a/src/services/UsersService.js +++ b/src/services/UsersService.js @@ -838,6 +838,27 @@ class usersService { return this.postAuxEnd("/offerinterestlistmsg", postData); } + // TO ADD FAMILY + addFamily(reqData) { + var postData = { + uid: localStorage.getItem("uid"), + member_id: localStorage.getItem("member_id"), + sessionid: localStorage.getItem("session_token"), + ...reqData, + }; + return this.postAuxEnd("/familyadd", postData); + } + + familyListings(reqData) { + var postData = { + uid: localStorage.getItem("uid"), + member_id: localStorage.getItem("member_id"), + sessionid: localStorage.getItem("session_token"), + ...reqData, + }; + return this.postAuxEnd("/familylist", postData); + } + // FUNCTION TO ASSIGN TASK TO FAMILY MEMBER assignFamilyTask(reqData) { var postData = { diff --git a/src/views/FamilyAccPage.jsx b/src/views/FamilyAccPage.jsx index 5023198..741b77e 100644 --- a/src/views/FamilyAccPage.jsx +++ b/src/views/FamilyAccPage.jsx @@ -1,9 +1,9 @@ import FamilyAcc from "../components/FamilyAcc"; export default function FamilyAccPage() { - return ( - <> - - - ); + return ( + <> + + + ); }