Compare commits

...

17 Commits

Author SHA1 Message Date
victorAnumudu bce00b5c0e request message changed 2023-08-01 16:10:56 +01:00
ameye 312cd54f87 Merge branch 'pending-wrong-assign' of WrenchBoard/Users-Wrench into master 2023-08-01 14:47:44 +00:00
victorAnumudu a0c3437eae pending assign value changed 2023-08-01 15:42:28 +01:00
ameye 711226f913 Merge branch 'tx_ref-change' of WrenchBoard/Users-Wrench into master 2023-08-01 11:07:16 +00:00
Ebube f46c6232b0 updated error scenario for the modal header 2023-08-01 12:05:27 +01:00
Ebube 172f0ccbce cleanup 2 2023-08-01 11:46:33 +01:00
Ebube a2047cc2de clean up 2023-08-01 11:41:57 +01:00
Ebube 6ea52e6481 Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into tx_ref-change 2023-08-01 11:38:26 +01:00
Ebube a7bbcfdc1b complete popup fixed 2023-08-01 11:37:56 +01:00
ameye ff28be3e70 Merge branch 'tx_ref-change' of WrenchBoard/Users-Wrench into master 2023-08-01 09:24:46 +00:00
Ebube e91b4a4424 Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into tx_ref-change 2023-07-31 23:58:36 +01:00
Ebube 9960033b72 debounced success payment and and fixed credit refresh 2023-07-31 23:55:23 +01:00
ameye ef135f1a9b Merge branch 'tx_ref-change' of WrenchBoard/Users-Wrench into master 2023-07-31 17:56:15 +00:00
Ebube 1df6380c4a Correct Drop Down Style for naira withdrawal 2023-07-31 15:09:12 +01:00
Ebube fc8cf551e5 Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into tx_ref-change 2023-07-31 14:47:15 +01:00
Ebube b1feb0438a still testing 2023-07-31 14:46:29 +01:00
ameye a89649f774 Merge branch 'amount-alignment' of WrenchBoard/Users-Wrench into master 2023-07-31 13:36:56 +00:00
9 changed files with 149 additions and 77 deletions
@@ -6,6 +6,7 @@ import PendingJobsPopout from "../jobPopout/PendingJobsPopout";
import { PriceFormatter } from "../Helpers/PriceFormatter"; import { PriceFormatter } from "../Helpers/PriceFormatter";
import localImgLoad from "../../lib/localImgLoad"; import localImgLoad from "../../lib/localImgLoad";
export default function MyPendingJobTable({ MyJobList, className }) { export default function MyPendingJobTable({ MyJobList, className }) {
let [jobPopout, setJobPopout] = useState({ show: false, data: {} }); // STATE TO HOLD THE VALUE OF THE ALERT DETAILS AND DETERMINE WHEN TO SHOW let [jobPopout, setJobPopout] = useState({ show: false, data: {} }); // STATE TO HOLD THE VALUE OF THE ALERT DETAILS AND DETERMINE WHEN TO SHOW
+8 -1
View File
@@ -3,6 +3,7 @@ import { Link } from "react-router-dom";
import Layout from "../Partials/Layout"; import Layout from "../Partials/Layout";
import CommonHead from "../UserHeader/CommonHead"; import CommonHead from "../UserHeader/CommonHead";
import MyPendingJobTable from "./MyPendingJobTable"; import MyPendingJobTable from "./MyPendingJobTable";
import LoadingSpinner from "../Spinners/LoadingSpinner";
export default function MyPendingJobs(props) { export default function MyPendingJobs(props) {
const [selectTab, setValue] = useState("today"); const [selectTab, setValue] = useState("today");
@@ -35,7 +36,13 @@ export default function MyPendingJobs(props) {
></div> ></div>
</div> </div>
</div> </div>
<MyPendingJobTable MyJobList={props.MyJobList} /> {props.MyJobList.loading ?
<div className="bg-white">
<LoadingSpinner size='16' color='sky-blue' height='min-h-[300px]' />
</div>
:
<MyPendingJobTable MyJobList={props.MyJobList.data} />
}
</div> </div>
</div> </div>
</Layout> </Layout>
@@ -1,7 +1,7 @@
import React from "react"; import React from "react";
function CompleteConfirmCredit({ onClose, confirmCredit }) { function CompleteConfirmCredit({ onClose, confirmCredit }) {
const { data } = confirmCredit const { data } = confirmCredit;
return ( return (
<div className="logout-modal-body w-full flex flex-col items-center"> <div className="logout-modal-body w-full flex flex-col items-center">
<div className="content-wrapper w-full h-[32rem]"> <div className="content-wrapper w-full h-[32rem]">
@@ -17,7 +17,8 @@ function CompleteConfirmCredit({ onClose, confirmCredit }) {
> >
{/* Success Icon for now */} {/* Success Icon for now */}
<div className="flex items-center w-full justify-center"> <div className="flex items-center w-full justify-center">
{data?.result == "Charge success" ? ( {data?.result == "Charge success" ||
data?.status == "successful" ? (
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
width="100" width="100"
@@ -55,7 +56,8 @@ function CompleteConfirmCredit({ onClose, confirmCredit }) {
<div className={`flex items-center`}> <div className={`flex items-center`}>
<h1 className="text-xl font-semibold text-dark-gray dark:text-white tracking-tighter my-1"> <h1 className="text-xl font-semibold text-dark-gray dark:text-white tracking-tighter my-1">
{data?.result == "Charge success" {data?.result == "Charge success" ||
data?.status == "successful"
? "Credit was Successful!" ? "Credit was Successful!"
: "Credit was Unsuccessful"} : "Credit was Unsuccessful"}
</h1> </h1>
@@ -1,8 +1,8 @@
import { FlutterWaveButton, closePaymentModal } from "flutterwave-react-v3"; import { FlutterWaveButton, closePaymentModal } from "flutterwave-react-v3";
import React, { useState } from "react"; import React, { useState } from "react";
import { useDispatch, useSelector } from "react-redux"; import { useDispatch, useSelector } from "react-redux";
import { useNavigate } from "react-router-dom";
import { toast } from "react-toastify"; import { toast } from "react-toastify";
import debounce from "../../../hooks/debounce";
import usersService from "../../../services/UsersService"; import usersService from "../../../services/UsersService";
import { tableReload } from "../../../store/TableReloads"; import { tableReload } from "../../../store/TableReloads";
import LoadingSpinner from "../../Spinners/LoadingSpinner"; import LoadingSpinner from "../../Spinners/LoadingSpinner";
@@ -102,7 +102,6 @@ function ConfirmAddFund({
const { userDetails } = useSelector((state) => state?.userDetails); const { userDetails } = useSelector((state) => state?.userDetails);
const navigate = useNavigate();
const dispatch = useDispatch(); const dispatch = useDispatch();
const [requestStatus, setRequestStatus] = useState({ const [requestStatus, setRequestStatus] = useState({
@@ -133,10 +132,19 @@ function ConfirmAddFund({
...config, ...config,
text: "Proceed", text: "Proceed",
callback: (response) => { callback: (response) => {
onSuccessPayment(); debouncedSuccessPayment(); //delays the call for 5 secs
setTimeout(() => { setTimeout(() => {
closePaymentModal(); closePaymentModal();
}, 2000); setConfirmCredit((prev) => ({
...prev,
show: {
awaitConfirm: { loader: false, state: false },
acceptConfirm: { loader: false, state: true },
},
data: response,
}));
}, 1500);
}, },
}; };
@@ -153,28 +161,9 @@ function ConfirmAddFund({
loading: false, loading: false,
status: false, status: false,
}); });
toast.success("Opps! something went wrong");
} else {
setRequestStatus({
message: "Topup successful",
loading: false,
status: true,
});
setConfirmCredit((prev) => ({
...prev,
show: {
awaitConfirm: { loader: false, state: false },
acceptConfirm: { loader: false, state: true },
},
data: res,
}));
dispatch(tableReload({ type: "WALLETTABLE" }));
navigate("/my-wallet", { replace: true });
// setTimeout(() => {
// navigate("/my-wallet", { replace: true });
// }, 1000);
} }
return dispatch(tableReload({ type: "WALLETTABLE" }));
}) })
.catch((err) => { .catch((err) => {
setRequestStatus({ setRequestStatus({
@@ -182,10 +171,23 @@ function ConfirmAddFund({
loading: false, loading: false,
status: false, status: false,
}); });
setTimeout(() => {
setConfirmCredit((prev) => ({
...prev,
show: {
awaitConfirm: { loader: false, state: false },
acceptConfirm: { loader: false, state: true },
},
data: err,
}));
}, 1500);
toast.success("Opps! something went wrong"); toast.success("Opps! something went wrong");
}); });
}; };
const debouncedSuccessPayment = debounce(onSuccessPayment, 5000);
const handlePrevCard = async () => { const handlePrevCard = async () => {
const { amount, credit_reference, currency } = __confirmData; const { amount, credit_reference, currency } = __confirmData;
const { card_uid } = __confirmCardDetails; const { card_uid } = __confirmCardDetails;
@@ -25,7 +25,8 @@ const CreditPopup = ({ details, onClose, situation, walletItem }) => {
<div className="logout-modal-header w-full flex items-center justify-between lg:p-6 px-[30px] py-[23px] border-b dark:border-[#5356fb29] border-light-purple"> <div className="logout-modal-header w-full flex items-center justify-between lg:p-6 px-[30px] py-[23px] border-b dark:border-[#5356fb29] border-light-purple">
<h1 className="text-26 font-bold text-dark-gray dark:text-white tracking-wide"> <h1 className="text-26 font-bold text-dark-gray dark:text-white tracking-wide">
{confirmCredit?.show?.acceptConfirm?.state && {confirmCredit?.show?.acceptConfirm?.state &&
confirmCredit?.data?.internal_return < 0 ? ( (confirmCredit?.data?.internal_return < 0 ||
confirmCredit?.data?.status !== "successful") ? (
"Credit Unsuccessful" "Credit Unsuccessful"
) : ( ) : (
<> <>
@@ -448,7 +448,7 @@ function NairaWithdraw({
{/* <label className="text-[#181c32] dark:text-white text-base font-semibold block flex-[0.2] mb-0 mt-3"></label> */} {/* <label className="text-[#181c32] dark:text-white text-base font-semibold block flex-[0.2] mb-0 mt-3"></label> */}
<div className="flex flex-col gap-3 flex-[0.8] items-center"> <div className="flex flex-col gap-3 flex-[0.8] items-center">
<select <select
className="sm:w-full w-48 text-base p-2 text-dark-gray dark:text-white rounded-md border border-slate-300 outline-0 flex-[0.8]" className="sm:w-full w-48 text-dark-gray border-slate-300 outline-0 flex-[0.8] my-3 rounded-full p-2 outline-none text-base dark:text-gray-100 bg-[#FAFAFA] dark:bg-[#11131F] border appearance-none"
value={ value={
props.values.previousAccount?.recipientID props.values.previousAccount?.recipientID
} }
@@ -473,7 +473,7 @@ function NairaWithdraw({
?.recipientID ?.recipientID
? errorMsgs.previousAccount ? errorMsgs.previousAccount
.recipientID .recipientID
: "Select..."} : "Select an account"}
</option> </option>
{recipients.data.map((item, index) => ( {recipients.data.map((item, index) => (
<option <option
+94 -41
View File
@@ -1,10 +1,14 @@
import React, { useCallback, useMemo, useState } from "react"; import React, { useMemo, useState } from "react";
import Detail from "./popoutcomponent/Detail";
import ModalCom from "../Helpers/ModalCom";
import usersService from "../../services/UsersService";
import { toast } from "react-toastify"; import { toast } from "react-toastify";
import LoadingSpinner from "../Spinners/LoadingSpinner"; import usersService from "../../services/UsersService";
import ModalCom from "../Helpers/ModalCom";
import { PriceFormatter } from "../Helpers/PriceFormatter"; import { PriceFormatter } from "../Helpers/PriceFormatter";
import LoadingSpinner from "../Spinners/LoadingSpinner";
import Detail from "./popoutcomponent/Detail";
import { useNavigate } from "react-router-dom";
import { useDispatch } from "react-redux";
import { tableReload } from "../../store/TableReloads";
const showSuccessToast = (message) => { const showSuccessToast = (message) => {
toast.success(message, { toast.success(message, {
@@ -14,48 +18,85 @@ const showSuccessToast = (message) => {
}; };
function PendingJobsPopout({ details, onClose, situation }) { function PendingJobsPopout({ details, onClose, situation }) {
const dispatch = useDispatch()
const navigate = useNavigate()
const [pendingJobLoader, setPendingJobLoader] = useState({ const [pendingJobLoader, setPendingJobLoader] = useState({
extend: false, extend: false,
offer: false, offer: false,
}); });
const apiCall = useMemo(() => new usersService(), []);
const handlePendingJobsBtn = useCallback( let [requestMessage, setRequestMessage] = useState({status: false, message: ''})
async ({ target: { name } }) => {
const apiCall = new usersService();
const handlePendingJobsBtn = ({ target: { name } }) => {
let { job_uid, offer_code } = details; let { job_uid, offer_code } = details;
let reqData; let reqData;
let pendingData = { job_uid, offer_code }; let pendingData = { job_uid, offer_code };
if(name=='extend'){ // RUNS THIS TO EXTEND JOB EXPIRY BY ONE WEEK
reqData = { ...pendingData };
setPendingJobLoader({ extend: true });
apiCall.pendingJobExtend(reqData).then(res => {
setRequestMessage({status: true, message: res.data.status})
dispatch(tableReload({ type: "PENDINGTABLE" }));
setTimeout(() => {
setPendingJobLoader({ extend: false, offer: false });
setRequestMessage({status: false, message: ''})
onClose();
}, 2700);
}).catch(error => {
setRequestMessage({status: false, message:'Try Again'})
setTimeout(() => {
setPendingJobLoader({ extend: false, offer: false });
setRequestMessage({status: false, message: ''})
}, 2700);
})
}else if(name=='offer'){ // RUNS THIS IF JOB IS SENT TO USER
reqData = { ...pendingData };
setPendingJobLoader({ offer: true });
apiCall.pendingJobSendTome(reqData).then(res => {
setRequestMessage({status: true, message: res.data.status})
setTimeout(() => {
setPendingJobLoader({ extend: false, offer: false });
setRequestMessage({status: false, message: ''})
}, 2700);
}).catch(error => {
setRequestMessage('Try Again')
setTimeout(() => {
setPendingJobLoader({ extend: false, offer: false });
setRequestMessage({status: false, message: ''})
}, 2700);
})
} else return
// try {
// if (name === "extend") {
// setPendingJobLoader({ extend: true });
// reqData = { ...pendingData };
// // let { data } =
// await apiCall.pendingJobExtend(reqData);
// showSuccessToast("Job has been extended by a week!");
// dispatch(tableReload({ type: "PENDINGTABLE" }));
// } else if (name === "offer") {
// setPendingJobLoader({ offer: true });
// reqData = { ...pendingData };
// // let { data } =
// await apiCall.pendingJobSendTome(reqData);
// showSuccessToast("Offer sent, check your email");
// } else return;
try { // setTimeout(() => {
if (name === "extend") { // setPendingJobLoader({ extend: false, offer: false });
setPendingJobLoader({ extend: true }); // onClose();
reqData = { ...pendingData }; // }, 2700);
// let { data } = // } catch (error) {
await apiCall.pendingJobExtend(reqData); // setPendingJobLoader({ extend: false, offer: false });
// console.log("This is for extend", data); // throw new Error(error);
showSuccessToast("Job has been extended by a week!"); // }
} else if (name === "offer") { }
setPendingJobLoader({ offer: true });
reqData = { ...pendingData };
// let { data } =
await apiCall.pendingJobSendTome(reqData);
// console.log("This is for offer", data);
showSuccessToast("Offer sent, check your email");
} else return;
setTimeout(() => {
setPendingJobLoader({ extend: false, offer: false });
onClose();
}, 2700);
} catch (error) {
setPendingJobLoader({ extend: false, offer: false });
throw new Error(error);
}
},
[onClose, apiCall, details]
);
return ( return (
<ModalCom action={onClose} situation={situation} className="edit-popup"> <ModalCom action={onClose} situation={situation} className="edit-popup">
@@ -101,7 +142,8 @@ function PendingJobsPopout({ details, onClose, situation }) {
</span> </span>
<div className=""> <div className="">
<p className="text-sm"> <p className="text-sm">
This Job have been sent to public view {/* This Job have been sent to public view */}
This Job have been sent to {details.job_to}
</p> </p>
<p className="text-sm text-slate-600">This Job will expire</p> <p className="text-sm text-slate-600">This Job will expire</p>
</div> </div>
@@ -153,13 +195,13 @@ function PendingJobsPopout({ details, onClose, situation }) {
/> />
</div> </div>
<div className="my-2 md:flex"> {/* <div className="my-2 md:flex">
<Detail <Detail
label="Public Link" label="Public Link"
value="https://work.wrenchboard.com/plb/viewjob/218B4BWB83" value="https://work.wrenchboard.com/plb/viewjob/218B4BWB83"
bg="bg-slate-200" bg="bg-slate-200"
/> />
</div> </div> */}
</div> </div>
{/* ACTION SECTION */} {/* ACTION SECTION */}
@@ -168,11 +210,11 @@ function PendingJobsPopout({ details, onClose, situation }) {
<div className="mb-3"> <div className="mb-3">
<p className="px-2 py-1 text-sm bg-slate-100"> <p className="px-2 py-1 text-sm bg-slate-100">
Job sent to public view Job sent to {details.job_to}
</p> </p>
</div> </div>
<div className="my-3"> <div className="mt-3 mb-8">
<button <button
className="px-2 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white" className="px-2 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
onClick={handlePendingJobsBtn} onClick={handlePendingJobsBtn}
@@ -187,6 +229,11 @@ function PendingJobsPopout({ details, onClose, situation }) {
)} )}
</button> </button>
</div> </div>
{pendingJobLoader.extend && requestMessage.message &&
<div className={`p-1 ${requestMessage.status ? 'bg-green-500':'bg-red-500'} text-white rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]`}>
<p>{requestMessage.message}</p>
</div>
}
<div className="my-3"> <div className="my-3">
<button <button
@@ -204,6 +251,12 @@ function PendingJobsPopout({ details, onClose, situation }) {
</button> </button>
</div> </div>
{pendingJobLoader.offer && requestMessage.message &&
<div className={`p-1 ${requestMessage.status ? 'bg-green-500':'bg-red-500'} text-white rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]`}>
<p>{requestMessage.message}</p>
</div>
}
<div className="mt-10 md:mt-32 md:flex md:justify-center"> <div className="mt-10 md:mt-32 md:flex md:justify-center">
<button <button
className="px-2 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white" className="px-2 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
+1 -1
View File
@@ -595,7 +595,7 @@ class usersService {
resultTopUp(post) { resultTopUp(post) {
var postData = { var postData = {
uid: localStorage.getItem("uid"), uid: localStorage.getItem("uid"),
member_id: localStorage.getItem("member_id"), member_id: Number(localStorage.getItem("member_id")),
sessionid: localStorage.getItem("session_token"), sessionid: localStorage.getItem("session_token"),
action: 11061, action: 11061,
...post, ...post,
+9 -3
View File
@@ -5,20 +5,26 @@ import { useSelector } from "react-redux";
export default function MyPendingJobsPage() { export default function MyPendingJobsPage() {
let { commonHeadBanner } = useSelector((state) => state.commonHeadBanner); let { commonHeadBanner } = useSelector((state) => state.commonHeadBanner);
const [MyJobList, setMyJobList] = useState([]); let { pendingListTable } = useSelector((state) => state.tableReload);
console.log('TESTING', pendingListTable)
const [MyJobList, setMyJobList] = useState({loading: true, data: []});
const api = new usersService(); const api = new usersService();
const getMyJobList = async () => { const getMyJobList = async () => {
try { try {
const res = await api.getMyPendingJobList(); const res = await api.getMyPendingJobList();
setMyJobList(res.data); setMyJobList({loading: false, data: res.data});
} catch (error) { } catch (error) {
setMyJobList({loading: false, data: []});
console.log("Error getting mode"); console.log("Error getting mode");
} }
}; };
useEffect(() => { useEffect(() => {
getMyJobList(); getMyJobList();
}, []); }, [pendingListTable]);
// debugger; // debugger;
return ( return (