import React, { useEffect, useRef, useState } from "react"; import { useSelector } from "react-redux"; import { useNavigate } from "react-router-dom"; import { useReactToPrint } from "react-to-print"; import CountDown from "../Helpers/CountDown"; import ModalCom from "../Helpers/ModalCom"; import Layout from "../Partials/Layout"; import LoadingSpinner from "../Spinners/LoadingSpinner"; import ActiveJobMessage from "./ActiveJobMessage"; import IndexJobActions from "./JobActions/IndexJobActions"; import usersService from "../../services/UsersService"; import { PriceFormatter } from "../Helpers/PriceFormatter"; import { SocketValues } from "../Contexts/SocketIOContext"; function ActiveJobs(props) { let {sendMessage, joinRoom} = SocketValues() // destructures 'SEND MESSAGE' and 'JOIN ROOM' FUNCTIONS FROM SOCKET const ApiCall = new usersService(); const navigate = useNavigate(); const { userDetails } = useSelector((state) => state.userDetails); const [passDue, setPassDue] = useState( new Date() > new Date(props.details?.delivery_date) ); // STATE TO KNOW IF TASK IS PASSED DUE TIME const [messageToSend, setMessageToSend] = useState(""); // State to hold the value of message to be sent const [filesToSend, setFilesToSend] = useState([]); // State to hold the value of files to be sent const [tab, setTab] = useState("message"); const [requestStatus, setRequestStatus] = useState({ loading: false, status: false, message: "", }); let [popUp, setPopUp] = useState(false); // STATE FOR POPOUT MODAL const printRef = useRef(); // to handle printing const handlePrint = useReactToPrint({ content: () => printRef.current, }); const popUpHandler = () => { // FUNCTION TO HANDLE POPOUT setPopUp((prev) => !prev); }; // FUNCTION TO HANDLE MESSAGE CHANGE const handleMessageChange = ({ target: { value } }) => { setMessageToSend(value); }; // FUNCTION TO HANDLE FILE UPlOAD CHANGE const handleFileChange = ({ target: { files } }) => { setRequestStatus({ loading: false, status: false, message: "" }); // State to determine error state if (!files[0]) { // IF NO FILE SELECTED RETURN return; } if (files[0].size > Number(process.env.REACT_APP_MAX_FILE_SIZE)) { setRequestStatus({ loading: false, status: false, message: "File must be <= 1mb", }); setTimeout(() => { setRequestStatus({ loading: false, status: false, message: "" }); }, 5000); return; } if (filesToSend.length >= Number(process.env.REACT_APP_TOTAL_NUM_FILE)) { setRequestStatus({ loading: false, status: false, message: `Total number of attachment is ${Number( process.env.REACT_APP_TOTAL_NUM_FILE )}`, }); setTimeout(() => { setRequestStatus({ loading: false, status: false, message: "" }); }, 5000); return; } // INCLUDE FILE IF NO ERROR setFilesToSend((prev) => [...prev, files[0]]); }; // FUNCTION TO CLEAR ALL TYPED MESSAGE OR FILES const handleClearAll = ({ target: { name } }) => { if (tab == "message") { setMessageToSend(""); } else if (tab == "files") { setFilesToSend([]); } else { return; } }; // FUNCTION TO REMOVE AND IMAGE const handleRemoveImage = (imageToDelete) => { setFilesToSend((prev) => prev.filter((item) => item.name != imageToDelete.name) ); }; // FUNCTION TO SEND TASK MESSAGE const sendTaskMessage = () => { let reqData = { message: messageToSend, msg_type: "TEXT", contract: props.details.contract, }; if (!reqData.message) { setRequestStatus({ loading: false, status: false, message: "Message is empty", }); return setTimeout(() => { setRequestStatus({ loading: false, status: false, message: "" }); }, 5000); } setRequestStatus({ loading: true, status: false, message: "" }); ApiCall.sendTaskMessage(reqData) .then((res) => { if (res.status != 200 || res.data.internal_return < 0) { setRequestStatus({ loading: false, status: false, message: "Message could not be sent, try again later", }); return; } setRequestStatus({ loading: false, status: true, message: "Message Sent Successfully", }); // function to trigger socket to emit 'send_message' sendMessage(messageToSend, `${props.details.contract}-${props.details.contract_uid}`) props.reloadActiveJobList((prev) => !prev); // MAKES ACTIVE JOB MESSAGE LIST TO RELOAD setMessageToSend(""); // SENDS MESSAGE TO SEND BACK TO EMPTY STRINGS }) .catch((error) => { setRequestStatus({ loading: false, status: false, message: "Opps! something went wrong", }); }) .finally(() => { setTimeout(() => { setRequestStatus({ loading: false, status: false, message: "" }); }, 5000); }); }; // FUNCTION TO SEND FILES const sendFile = async () => { setRequestStatus({ loading: true, status: false, message: "" }); if (!filesToSend.length) { // checks if file to send is empty setRequestStatus({ loading: false, status: false, message: "No File(s) selected", }); return setTimeout(() => { setRequestStatus({ loading: false, status: false, message: "" }); }, 5000); } for (let i = 0; i <= filesToSend.length - 1; i++) { // Loops through files to send array and trigger upload API call const fileToBase64 = async () => { // Converts file data to base64 string try { const base64String = await convertFileToBase64(filesToSend[i]); return base64String; } catch (error) { return false; } }; // if(await !fileToBase64()){ // return // } let reqData = { file_name: filesToSend[i].name, file_size: filesToSend[i].size, file_type: "image/png", file_data: await fileToBase64(), msg_type: "FILE", contract: props.details.contract, }; ApiCall.sendFiles(reqData) .then((res) => { // if(res.status != 200 || res.data.internal_return < 0){ // setRequestStatus({loading: false, status: false, message: 'Files(s) could not be sent, try again later'}) // return // } // setRequestStatus({loading: false, status: true, message: 'File(s) Uploaded Successfully'}) // props.reloadActiveJobList(prev => !prev) // MAKES ACTIVE JOB MESSAGE LIST TO RELOAD // setFilesToSend([]) // SETS FILES TO SEND TO SEND BACK TO EMPTY ARRAY }) .catch((error) => { // setRequestStatus({loading: false, status: false, message: 'Opps! something went wrong'}) }) .finally(() => { if (i == filesToSend.length - 1) { setRequestStatus({ loading: false, status: true, message: "File(s) Uploaded Successfully", }); setFilesToSend([]); // SETS FILES TO SEND TO SEND BACK TO EMPTY ARRAY props.reloadActiveJobList((prev) => !prev); // MAKES ACTIVE JOB MESSAGE LIST TO RELOAD setTimeout(() => { setRequestStatus({ loading: false, status: false, message: "" }); }, 5000); } }); } }; // FUNCTION TO CHECK IF TASK PASS DUE IS REACHED let isPassedDue = () => { // console.log('TESTING',new Date() > new Date(props.details?.delivery_date) ) if (new Date() > new Date(props.details?.delivery_date)) { setPassDue(true); } else { setPassDue(false); } }; useEffect(() => { if (!passDue) { let passDueInterval = setInterval(() => { isPassedDue(); }, 1000); return () => { clearInterval(passDueInterval); }; } }, [passDue]); let thePrice = PriceFormatter( props.details?.price * 0.01, props.details?.currency_code, props.details?.currency ); useEffect(()=>{ // calls function to add user to a room joinRoom(`${props.details.contract}-${props.details.contract_uid}`) },[props.details.contract, props.details.contract_uid]) return (
{/* job title */}

{props.details?.title && props.details.title}

{props?.details && props.details.job_to}

Description:{" "}

{props?.details && props.details.description}

{/* end of job title */} {/* job details */}

Delivery Detail

{passDue ? (

Due: {props?.details && props.details.delivery_date.split(" ")[0]}

{props?.delivery_date && (

{props.details.delivery_date.split(" ")[1]}

)}
) : (

Due:

Hrs Min Sec
)}
Price:{" "} {thePrice}
Duration:{" "} {props.details?.timeline_days && props.details.timeline_days}{" "} day(s)
No:{" "} {props.details?.contract && props.details.contract}
{/* end of job details */}

Actions

{/*

Waiting for the completion message from the client before you can approve.

*/}
{/* TEXTAREA SECTION */}
{tab == "message" ? (