diff --git a/src/components/FamilyAcc/FamilyManageTabs.jsx b/src/components/FamilyAcc/FamilyManageTabs.jsx index a43f059..64dc4a5 100644 --- a/src/components/FamilyAcc/FamilyManageTabs.jsx +++ b/src/components/FamilyAcc/FamilyManageTabs.jsx @@ -1,12 +1,10 @@ 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"; @@ -29,27 +27,62 @@ export default function FamilyManageTabs({ listReload, loader, }) { + // Initial state for family details + const initialDetailState = { + loading: false, + data: null, + }; + + // State for family details, tasks, waitlist, and pending const [details, setDetails] = useState({ - familyDetails: { loading: false, data: null }, - familyTasks: { loading: false, data: null }, - familyWaitList: { loading: false, data: null }, - familyPending: { loading: false, data: null }, + familyDetails: { ...initialDetailState }, + familyTasks: { ...initialDetailState }, + familyWaitList: { ...initialDetailState }, + familyPending: { ...initialDetailState }, }); + + // Function to reset family details, tasks, waitlist, and pending + const resetDetails = () => { + setDetails({ + familyDetails: { ...initialDetailState }, + familyTasks: { ...initialDetailState }, + familyWaitList: { ...initialDetailState }, + familyPending: { ...initialDetailState }, + }); + }; + + // State for family task data + const [familyTask, setFamilyTask] = useState({ loading: false, data: [] }); + + // State for active task + const [activeTask, setActiveTask] = useState({ id: 0, data: {} }); + + // State for error messages const [errMsg, setErrMsg] = useState(""); + + // State for family task popout const [familyTaskPopout, setFamilyTaskPopout] = useState(false); + + // State for profile image const [profileImg, setProfileImg] = useState(profile); + + // Ref for profile image input const profileImgInput = useRef(null); - const [isPending, startTransition] = useTransition(); + + // Create an instance of the usersService class const apiCall = useMemo(() => new usersService(), []); + // Function to handle toggling the family task popout const familyPopUpHandler = () => { setFamilyTaskPopout((prev) => !prev); }; + // Function to trigger a click on the hidden profile image input const browseProfileImg = () => { profileImgInput.current.click(); }; + // Function to handle changes in the profile image input const profileImgChangeHandler = (e) => { if (e.target.value !== "") { const imgReader = new FileReader(); @@ -60,82 +93,30 @@ export default function FamilyManageTabs({ } }; - const manageFamily = useCallback(async () => { - try { - setDetails((prevDetails) => ({ - ...prevDetails, - familyDetails: { loading: true }, - familyTasks: { loading: true }, - familyWaitList: { loading: true }, - familyPending: { loading: true }, - })); - - const { family_uid } = accountDetails; - const reqData = { family_uid }; - - const [familyRes, tasksRes, familyWaitRes, familyPending] = - await Promise.all([ - apiCall.ManageFamily(reqData), - apiCall.ManageTasks(reqData), - apiCall.ManageFamilyWaitlist(), - apiCall.ManageFamilyPending(), - ]); - - const familyData = familyRes.data; - const tasksData = tasksRes.data; - const familyWaitData = familyWaitRes.data; - const familyPendingData = familyPending.data; - - if ( - familyData?.internal_return < 0 || - tasksData?.internal_return < 0 || - familyWaitData?.internal_return < 0 || - familyPendingData?.internal_return < 0 - ) { - return; - } - - 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((prevDetails) => ({ - ...prevDetails, - familyDetails: { loading: false }, - familyTasks: { loading: false }, - familyWaitList: { loading: false }, - familyPending: { loading: false }, - })); - setErrMsg("An error occurred"); - throw new Error(error); - } - }, [apiCall, accountDetails]); - + // Ref for the account section const accountRef = useRef(); + // React-to-Print hook for handling printing const useHandlePrint = useReactToPrint({ content: () => accountRef.current, }); + // Array of tab names const tabs = [ { id: 1, name: "Tasks" }, { id: 2, name: "Waiting" }, { id: 3, name: "Pending" }, ]; + // State for the currently selected tab const [tab, setTab] = useState(tabs[0].name); + // Function to handle tab changes const tabHandler = (value) => { - startTransition(() => { - setTab(value); - }); + setTab(value); }; + // Object that maps tab names to their corresponding components const tabComponents = { Tasks: ( ), Account: ( @@ -170,6 +151,7 @@ export default function FamilyManageTabs({ Profile: , }; + // Default tab component const defaultTabComponent = ( ); + // Selected tab component based on the current 'tab' const selectedTabComponent = tabComponents[tab] || defaultTabComponent; + // Effect to manage family details and related data useEffect(() => { - let __manageFamily = true; - if (__manageFamily) { - manageFamily(); - } - return () => { - __manageFamily = false; + const manageFamily = async () => { + try { + resetDetails(); + + setDetails({ + familyDetails: { loading: true }, + familyTasks: { loading: true }, + familyWaitList: { loading: true }, + familyPending: { loading: true }, + }); + + const { family_uid } = accountDetails; + const reqData = { family_uid }; + + const [familyRes, tasksRes, familyWaitRes, familyPending] = + await Promise.all([ + apiCall.ManageFamily(reqData), + apiCall.ManageTasks(reqData), + apiCall.ManageFamilyWaitlist(), + apiCall.ManageFamilyPending(), + ]); + + const familyData = familyRes.data; + const tasksData = tasksRes.data; + const familyWaitData = familyWaitRes.data; + const familyPendingData = familyPending.data; + + // Function to check for errors in data + const checkDataError = (data) => data?.internal_return < 0; + + if ( + checkDataError(familyData) || + checkDataError(tasksData) || + checkDataError(familyWaitData) || + checkDataError(familyPendingData) + ) { + return; + } + + setDetails({ + familyDetails: { loading: false, data: familyData }, + familyTasks: { loading: false, data: tasksData }, + familyWaitList: { loading: false, data: familyWaitData }, + familyPending: { loading: false, data: familyPendingData }, + }); + } catch (error) { + resetDetails(); + setErrMsg("An error occurred"); + throw new Error(error); + } }; - }, [tab, manageFamily]); + + // Invoke the manageFamily function when the component mounts + manageFamily(); + }, []); + + // Effect to manage family tasks + useEffect(() => { + let checkFamilyTask = true; + const reqData = { + limit: 30, + offset: 0, + job_type: "FAMILY", + action: 13005, + }; + + if (checkFamilyTask) { + setFamilyTask({ loading: true }); + 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], + })); + } + }) + .catch((err) => { + setFamilyTask({ loading: false, data: [] }); + console.log("Error", err); + }); + } + + // Cleanup function to prevent memory leaks + return () => { + checkFamilyTask = false; + }; + }, []); return (
- +
)}
diff --git a/src/components/FamilyAcc/FamilyPopout/AssignTaskPopout.jsx b/src/components/FamilyAcc/FamilyPopout/AssignTaskPopout.jsx index 7985238..af2f662 100644 --- a/src/components/FamilyAcc/FamilyPopout/AssignTaskPopout.jsx +++ b/src/components/FamilyAcc/FamilyPopout/AssignTaskPopout.jsx @@ -1,441 +1,418 @@ -import React, { useState, useEffect, useTransition } from "react"; -import ModalCom from "../../Helpers/ModalCom"; -import Detail from "../../jobPopout/popoutcomponent/Detail"; +import React, { useState } from "react"; import usersService from "../../../services/UsersService"; -import LoadingSpinner from "../../Spinners/LoadingSpinner"; +import ModalCom from "../../Helpers/ModalCom"; import { PriceFormatter } from "../../Helpers/PriceFormatter"; +import LoadingSpinner from "../../Spinners/LoadingSpinner"; +import Detail from "../../jobPopout/popoutcomponent/Detail"; import { NewTasks } from "./forms"; -const AssignTaskPopout = React.memo(({ action, details, situation, familyDetails }) => { - const apiCall = new usersService(); +const AssignTaskPopout = React.memo( + ({ + action, + details, + situation, + familyDetailsData, + familyTask, + activeTask, + setActiveTask, + }) => { + const apiCall = new usersService(); - let [requestStatus, setRequestStatus] = useState({ - loading: false, - status: false, - message: "", - }); // HOLDS RESPONSE FOR SENDING API REQUEST + let [requestStatus, setRequestStatus] = useState({ + loading: false, + status: false, + message: "", + }); // HOLDS RESPONSE FOR SENDING API REQUEST - let [familyTask, setFamilyTask] = useState({ loading: false, data: [] }); + let [taskType, setTaskType] = useState(details ? "new" : "select"); // SWITCHES BTW SELECT TASK AND NEW TASK - let [taskType, setTaskType] = useState(details ? "new" : "select"); // SWITCHES BTW SELECT TASK AND NEW TASK + const switchTaskType = ({ target: { value } }) => { + // FUNCTION TO CHANGE SELECTED ACTIVE TASK + setTaskType(value); + }; - let [activeTask, setActiveTask] = useState({ id: 0, data: {} }); // HOLDS SELECTED TASK + const handleActiveTask = (id = 0, data = {}) => { + // FUNCTION TO CHANGE SELECTED ACTIVE TASK + setActiveTask({ id, data }); + }; - const switchTaskType = ({ target: { value } }) => { - // FUNCTION TO CHANGE SELECTED ACTIVE TASK - setTaskType(value); - }; + // New Task + const [formState, setFormState] = useState({ + // Initialize form state with desired fields + banner: details?.banner || "default.jpg", + country: details?.country || "", + price: details?.price || "", + title: details?.title || "", + description: details?.description || "", + job_detail: details?.job_detail || "", + timeline_days: details?.timeline_days || "", + category: details?.category || "", + }); - const handleActiveTask = (id = 0, data = {}) => { - // FUNCTION TO CHANGE SELECTED ACTIVE TASK - setActiveTask({ id, data }); - }; - - // New Task - const [formState, setFormState] = useState({ - // Initialize form state with desired fields - banner: details?.banner || "default.jpg", - country: details?.country || "", - price: details?.price || "", - title: details?.title || "", - description: details?.description || "", - job_detail: details?.job_detail || "", - timeline_days: details?.timeline_days || "", - category: details?.category || "", - }); - - const assignFamilyTask = () => { - setRequestStatus({ loading: true, status: false, message: "" }); - let reqData = {}; - if (taskType == "select") { - // RUNS HERE IF TASK TYPE IS SELECT - if (!Object.keys(activeTask.data).length) { - setRequestStatus({ - loading: false, - status: false, - message: "No Task is seleted", - }); - return setTimeout(() => { - setRequestStatus({ loading: false, status: false, message: "" }); - }, 3000); - } - reqData = { - // API PAYLOADS - job_id: activeTask.data?.job_id, - job_uid: activeTask.data?.job_uid, - family_uid: familyDetails?.uid || details?.family_uid, - job_description: activeTask.data?.description, - assign_mode: 110011, - }; - } - - if (taskType === "new") { - const { - banner, - category, - country, - description, - job_detail, - price, - timeline_days, - title, - } = formState; - - const requiredFields = { - banner, - // category, - country, - description, - job_detail, - price, - timeline_days, - title, - }; - - for (let field in requiredFields) { - if (requiredFields[field] == "") { - // let currencyErrMsg = field == "country" && "currency" + const assignFamilyTask = () => { + setRequestStatus({ loading: true, status: false, message: "" }); + let reqData = {}; + if (taskType == "select") { + // RUNS HERE IF TASK TYPE IS SELECT + if (!Object.keys(activeTask.data).length) { setRequestStatus({ loading: false, status: false, - message: `${field} is empty`, + message: "No Task is seleted", }); return setTimeout(() => { setRequestStatus({ loading: false, status: false, message: "" }); }, 3000); } + reqData = { + // API PAYLOADS + job_id: activeTask.data?.job_id, + job_uid: activeTask.data?.job_uid, + family_uid: familyDetailsData?.uid || details?.family_uid, + job_description: activeTask.data?.description, + assign_mode: 110011, + }; } - reqData = { - banner, - category, - country, - description, - job_detail, - price: price * 100, - timeline_days, - title, - assign_mode: 110055, - family_uid: details?.family_uid || familyDetails?.uid, - }; - } + if (taskType === "new") { + const { + banner, + category, + country, + description, + job_detail, + price, + timeline_days, + title, + } = formState; - apiCall - .assignFamilyTask(reqData) - .then((res) => { - if (res.status != 200 || res.data.internal_return < 0) { + const requiredFields = { + banner, + // category, + country, + description, + job_detail, + price, + timeline_days, + title, + }; + + for (let field in requiredFields) { + if (requiredFields[field] == "") { + // let currencyErrMsg = field == "country" && "currency" + setRequestStatus({ + loading: false, + status: false, + message: `${field} is empty`, + }); + return setTimeout(() => { + setRequestStatus({ loading: false, status: false, message: "" }); + }, 3000); + } + } + + reqData = { + banner, + category, + country, + description, + job_detail, + price: price * 100, + timeline_days, + title, + assign_mode: 110055, + family_uid: details?.family_uid || familyDetailsData?.uid, + }; + } + + apiCall + .assignFamilyTask(reqData) + .then((res) => { + if (res.status != 200 || res.data.internal_return < 0) { + setRequestStatus({ + loading: false, + status: false, + message: "failed to assign task", + }); + return setTimeout(() => { + setRequestStatus({ loading: false, status: false, message: "" }); + }, 5000); + } + setRequestStatus({ + loading: false, + status: true, + message: "action successful", + }); + setTimeout(() => { + setRequestStatus({ loading: false, status: false, message: "" }); + action(); // FUNCTION THAT CLOSES THE MODAL BOX + }, 5000); + }) + .catch((err) => { setRequestStatus({ loading: false, status: false, - message: "failed to assign task", + message: "An Error occured, try again", }); - return setTimeout(() => { + setTimeout(() => { setRequestStatus({ loading: false, status: false, message: "" }); }, 5000); - } - setRequestStatus({ - loading: false, - status: true, - message: "action successful", }); - setTimeout(() => { - setRequestStatus({ loading: false, status: false, message: "" }); - action(); // FUNCTION THAT CLOSES THE MODAL BOX - }, 5000); - }) - .catch((err) => { - setRequestStatus({ - loading: false, - status: false, - message: "An Error occured, try again", - }); - setTimeout(() => { - setRequestStatus({ loading: false, status: false, message: "" }); - }, 5000); - }); - }; - - useEffect(() => { - let checkFamilyTask = true; - const reqData = { - limit: 30, - offset: 0, - job_type: "FAMILY", - action: 13005, }; - apiCall - .getMyJobList(reqData) - .then((res) => { - 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 ( - <> - -
-
-

- Assign task to {familyDetails?.firstname || details?.firstName} -

- -
- {familyTask.loading ? ( -
- + + + + +
- ) : ( - <> -
-
-
-
- - Select Task + {familyTask.loading ? ( +
+ +
+ ) : ( + <> +
+
+
+
+ + Select Task +
+
+ + New Task +
-
- - New Task -
-
- {/* Task Type === select */} - {taskType == "select" && ( -
- {familyTask?.data?.length ? ( - familyTask?.data?.map((item, index) => ( -
handleActiveTask(item.job_uid, item)} - > - + {/* Task Type === select */} + {taskType == "select" && ( +
+ {familyTask?.data?.length ? ( + familyTask?.data?.map((item, index) => ( +
handleActiveTask(item.job_uid, item) } - className="w-[15px] h-[15px] cursor-pointer" - /> -

- {item?.title} + > + + handleActiveTask(item.job_uid, item) + } + className="w-[15px] h-[15px] cursor-pointer" + /> +

+ {item?.title} +

+
+ )) + ) : ( +

+ No Task found! +

+ )} +
+ )} + {taskType == "new" && ( +
+ +
+ )} +
+ + {/*Right Hand Side for details && Task Type === select */} + {taskType == "select" && ( + <> + {familyTask?.data?.length > 0 ? ( +
+
+

+ {activeTask?.data?.title}

+
+ +
+
+
+ +

+ {PriceFormatter( + activeTask?.data?.price * 0.01, + activeTask?.data?.currency, + activeTask?.data?.curreny_code + )} +

+
+ +
+ +

{`${activeTask?.data?.timeline_days} day(s)`}

+
+
+ +
+ +
+ +
+ +