Compare commits

...

71 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
victorAnumudu b96e8a3ed5 Merged master into amount-alignment 2023-07-31 14:23:57 +01:00
victorAnumudu f3226a6cfc amount alignment changed 2023-07-31 14:22:55 +01:00
ameye ff4c503100 Merge branch 'tx_ref-change' of WrenchBoard/Users-Wrench into master 2023-07-31 12:04:22 +00:00
Ebube f543a2d893 testing topupResult 2023-07-31 13:02:31 +01:00
ameye 41badd52be Merge branch 'list-alignment-fix' of WrenchBoard/Users-Wrench into master 2023-07-30 16:29:28 +00:00
victorAnumudu eeddd4e0a5 list alignment fixed 2023-07-30 06:10:44 +01:00
tokslaw ee4d136834 wrenchboard-logo-text + image added 2023-07-29 19:04:08 -04:00
tokslaw 283efa42b3 social comment added 2023-07-29 12:16:57 -04:00
tokslaw 5cbab4933c Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench 2023-07-29 12:13:14 -04:00
ameye 4de2181c18 Merge branch 'family-login-no-captcha' of WrenchBoard/Users-Wrench into master 2023-07-29 15:45:31 +00:00
ameye c8f0161a29 Merge branch 'tx_ref-change' of WrenchBoard/Users-Wrench into master 2023-07-29 15:45:26 +00:00
tokslaw 60222b6d88 text error correction 2023-07-29 11:11:23 -04:00
victorAnumudu 9ea3963239 family login captcha removed 2023-07-29 12:25:25 +01:00
Ebube a87592623b Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into tx_ref-change 2023-07-29 07:01:22 +01:00
Ebube bfcf53f763 Not selected should appear not selected 2023-07-29 07:00:50 +01:00
CHIEFSOFT\ameye df4489c6f2 removed start top up 2023-07-29 00:09:59 -04:00
CHIEFSOFT\ameye 37185812b4 Result added 2023-07-28 16:55:45 -04:00
ameye eb3e78244d Merge branch 'tx_ref-change' of WrenchBoard/Users-Wrench into master 2023-07-28 13:25:00 +00:00
Ebube b302d7ba57 Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into tx_ref-change 2023-07-28 14:22:18 +01:00
ameye d6c16169d9 Merge branch 'Family-Tabs-Size-Fix' of WrenchBoard/Users-Wrench into master 2023-07-28 13:18:31 +00:00
Ebube 57129da0bd changed tx_ref number 2023-07-28 13:58:10 +01:00
Ebube 9eaf7123d4 reverse 2023-07-28 13:56:23 +01:00
Ebube 096da29149 Changed tx_ref no 2023-07-28 13:51:48 +01:00
CHIEFSOFT\ameye c8331c51cf removed debugger 2023-07-28 08:20:04 -04:00
tokslaw 3b7618702b env text-spell error 2023-07-27 17:04:57 -04:00
Ebube 84968b4435 balance refresh bug for withdraw 2023-07-27 16:28:21 +01:00
Ebube 98f11a3d80 Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into Family-Tabs-Size-Fix 2023-07-27 16:18:29 +01:00
CHIEFSOFT\ameye 98d734e869 Post data 2023-07-27 11:17:15 -04:00
Ebube 47004fec8c Merge branch 'master' of https://gitlab.chiefsoft.net/WrenchBoard/Users-Wrench into Family-Tabs-Size-Fix 2023-07-27 16:05:17 +01:00
CHIEFSOFT\ameye 48ce89489e console log 2023-07-27 11:04:01 -04:00
CHIEFSOFT\ameye 1ce05a3be3 add fund page 2023-07-27 11:01:22 -04:00
Ebube 28ab1116e9 Added Credit Limit & Pending Jobs Bug & removed reload for credit 2023-07-27 11:34:27 +01:00
ameye 994060d929 Merge branch 'Family-Tabs-Size-Fix' of WrenchBoard/Users-Wrench into master 2023-07-26 15:57:24 +00:00
Ebube a5c62564b7 Fixed tasks banner breaking 2023-07-26 16:54:31 +01:00
Ebube 22e61d2b41 Enforced send limit 2023-07-26 15:49:04 +01:00
ameye 6ab5eae0c0 Merge branch 'email-input-size' of WrenchBoard/Users-Wrench into master 2023-07-26 14:26:05 +00:00
victorAnumudu 3fbb47ee82 email input character size increased 2023-07-26 14:39:16 +01:00
ameye 3327b2b0df Merge branch 'Family-Tabs-Size-Fix' of WrenchBoard/Users-Wrench into master 2023-07-25 20:13:46 +00:00
Ebube ec204d0389 . 2023-07-25 20:50:56 +01:00
Ebube cb1259d2c8 Added loading height 2023-07-25 20:46:46 +01:00
Ebube 706cf141e7 Add Result Page 2023-07-25 20:26:33 +01:00
ameye 2229ebb9a0 Merge branch 'Family-Tabs-Size-Fix' of WrenchBoard/Users-Wrench into master 2023-07-25 11:17:32 +00:00
Ebube 05022c29b2 Remove the cause for the login error 2023-07-25 12:12:49 +01:00
ameye 9718cfc574 Merge branch 'job-listing-bug' of WrenchBoard/Users-Wrench into master 2023-07-25 10:39:59 +00:00
ameye aef082ac60 Merge branch 'Family-Tabs-Size-Fix' of WrenchBoard/Users-Wrench into master 2023-07-25 10:39:45 +00:00
victorAnumudu 754340fcba Merged master into job-listing-bug 2023-07-25 10:14:29 +01:00
Ebube 16afd4f90c Family Tab Sizes Fixed 2023-07-25 08:53:04 +01:00
ameye b69e2ff53b Merge branch 'blog-page' of WrenchBoard/Users-Wrench into master 2023-07-24 19:29:08 +00:00
victorAnumudu 4ac799f8c9 links to blog page added 2023-07-24 20:06:25 +01:00
ameye c93d3b61a6 Merge branch 'resource-ask-question' of WrenchBoard/Users-Wrench into master 2023-07-24 16:31:16 +00:00
ameye 4fb6dbf30f Merge branch 'my_wallet_layout' of WrenchBoard/Users-Wrench into master 2023-07-24 16:31:10 +00:00
Ebube 4876ba80c1 Changed name to back 2023-07-24 15:07:22 +01:00
Ebube 71f799d157 Checked Errors in Wallet Page and made some tiny fixes 2023-07-24 15:01:03 +01:00
victorAnumudu e098eb4626 job listing pagination bug fixed 2023-07-24 07:46:41 +01:00
40 changed files with 708 additions and 383 deletions
+1 -1
View File
@@ -46,7 +46,7 @@ REACT_APP_GOOGLE_REDIRECT_URL=http://localhost:9082/login/auth/
REACT_APP_FACEBOOK_CLIENT_ID2=390204307987009 REACT_APP_FACEBOOK_CLIENT_ID2=390204307987009
REACT_APP_FACEBOOK_CLIENT_SECRET2=19f778e312f2ab96d147bacb612910c2 REACT_APP_FACEBOOK_CLIENT_SECRET2=19f778e312f2ab96d147bacb612910c2
#developenet Account #development Account Social
REACT_APP_FACEBOOK_CLIENT_ID=677857427521030 REACT_APP_FACEBOOK_CLIENT_ID=677857427521030
REACT_APP_FACEBOOK_CLIENT_SECRET=4801375f22072d8a75f64483fdd89829 REACT_APP_FACEBOOK_CLIENT_SECRET=4801375f22072d8a75f64483fdd89829
+2
View File
@@ -56,6 +56,8 @@ export default function Routers() {
<Routes> <Routes>
{/* guest routes */} {/* guest routes */}
<Route exact path="/login" element={<LoginPage />} /> <Route exact path="/login" element={<LoginPage />} />
<Route exact path="/eoffer" element={<LoginPage />} />
<Route exact path="/signup" element={<SignupPage />} /> <Route exact path="/signup" element={<SignupPage />} />
<Route exact path="/login/auth" element={<AuthRedirect />} /> <Route exact path="/login/auth" element={<AuthRedirect />} />
<Route exact path="/login/auth/flogin" element={<FacebookRedirect />} /> <Route exact path="/login/auth/flogin" element={<FacebookRedirect />} />
Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

@@ -1,6 +1,6 @@
import React, { useState } from "react"; import React, { useState } from "react";
import { Link, useNavigate } from "react-router-dom"; import { Link, useNavigate } from "react-router-dom";
import WrenchBoard from "../../../assets/images/wrenchboard.png"; import WrenchBoard from "../../../assets/images/wrenchboard-logo-text.png";
import usersService from "../../../services/UsersService"; import usersService from "../../../services/UsersService";
import InputCom from "../../Helpers/Inputs/InputCom"; import InputCom from "../../Helpers/Inputs/InputCom";
import AuthLayout from "../AuthLayout"; import AuthLayout from "../AuthLayout";
+4 -2
View File
@@ -4,7 +4,7 @@ import linkedInLogo from "../../../assets/images/Linkedin.png";
import appleLogo from "../../../assets/images/apple-black.svg"; import appleLogo from "../../../assets/images/apple-black.svg";
import facebookLogo from "../../../assets/images/facebook-4.svg"; import facebookLogo from "../../../assets/images/facebook-4.svg";
import googleLogo from "../../../assets/images/google-logo.svg"; import googleLogo from "../../../assets/images/google-logo.svg";
import WrenchBoard from "../../../assets/images/wrenchboard.png"; import WrenchBoard from "../../../assets/images/wrenchboard-logo-text.png";
import usersService from "../../../services/UsersService"; import usersService from "../../../services/UsersService";
import InputCom from "../../Helpers/Inputs/InputCom"; import InputCom from "../../Helpers/Inputs/InputCom";
import AuthLayout from "../AuthLayout"; import AuthLayout from "../AuthLayout";
@@ -285,7 +285,7 @@ export default function Login() {
<InputCom <InputCom
labelClass="tracking-wider" labelClass="tracking-wider"
fieldClass="sm:px-6 px-2 tracking-[0.25em] text-2xl" fieldClass="sm:px-6 px-2 tracking-[0.25em] text-2xl"
value={password.replace(/./g, "●")} value={password}
inputHandler={handlePassword} inputHandler={handlePassword}
placeholder="● ● ● ● ● ●" placeholder="● ● ● ● ● ●"
label="Password" label="Password"
@@ -432,10 +432,12 @@ export default function Login() {
} }
{/* END of login component */} {/* END of login component */}
{loginType == "full" &&
<div className="pt-5 text-[#181c32] text-center font-semibold text-[13.975px] leading-[20.9625px]"> <div className="pt-5 text-[#181c32] text-center font-semibold text-[13.975px] leading-[20.9625px]">
This site is protected by hCaptcha and the our Privacy Policy This site is protected by hCaptcha and the our Privacy Policy
and Terms of Service apply. and Terms of Service apply.
</div> </div>
}
</div> </div>
</div> </div>
</div> </div>
+54 -10
View File
@@ -1,7 +1,6 @@
import React, { useCallback, useEffect, useState } from "react"; import React, { useCallback, useEffect, useState } from "react";
import { Link, useNavigate } from "react-router-dom"; import { Link, useNavigate } from "react-router-dom";
import facebookLogo from "../../../assets/images/facebook-4.svg"; import WrenchBoard from "../../../assets/images/wrenchboard-logo-text.png";
import WrenchBoard from "../../../assets/images/wrenchboard.png";
import usersService from "../../../services/UsersService"; import usersService from "../../../services/UsersService";
import InputCom from "../../Helpers/Inputs/InputCom"; import InputCom from "../../Helpers/Inputs/InputCom";
import AuthLayout from "../AuthLayout"; import AuthLayout from "../AuthLayout";
@@ -69,13 +68,17 @@ export default function SignUp() {
let regEx = /^[^0-9][a-zA-Z0-9._%+-]+@[a-zA-Z]+(\.[a-zA-Z]+)+$/; let regEx = /^[^0-9][a-zA-Z0-9._%+-]+@[a-zA-Z]+(\.[a-zA-Z]+)+$/;
if (regEx.test(email) == false) { if (regEx.test(email) == false) {
setMsgError("Invalid Email"); setMsgError("Invalid Email");
return setTimeout(()=>{setMsgError("");},3000) return setTimeout(() => {
setMsgError("");
}, 3000);
} }
//checks if terms and condition is checked //checks if terms and condition is checked
if (!checked) { if (!checked) {
setMsgError("Terms and condition required"); setMsgError("Terms and condition required");
return setTimeout(()=>{setMsgError("");},3000) return setTimeout(() => {
setMsgError("");
}, 3000);
} }
setSignUpLoading(true); setSignUpLoading(true);
@@ -95,7 +98,9 @@ export default function SignUp() {
if (res.status === 200) { if (res.status === 200) {
const { data } = res; const { data } = res;
if (data && data.acc === "DULPICATE") { if (data && data.acc === "DULPICATE") {
setMsgError("Unable to use this username. Please try another username."); setMsgError(
"Unable to use this username. Please try another username."
);
setSignUpLoading(false); setSignUpLoading(false);
} }
if (data && data.status === "1") { if (data && data.status === "1") {
@@ -211,10 +216,8 @@ export default function SignUp() {
name="password" name="password"
type={showPassword ? "text" : "password"} type={showPassword ? "text" : "password"}
onClick={togglePasswordVisibility} onClick={togglePasswordVisibility}
passIcon={ passIcon={showPassword ? "show-password" : "hide-password"}
showPassword ? "show-password" : "hide-password" value={formData.password}
}
value={formData.password.replace(/./g, "●")}
inputHandler={handleInputChange} inputHandler={handleInputChange}
/> />
</div> </div>
@@ -223,7 +226,48 @@ export default function SignUp() {
{msgError} {msgError}
</div> </div>
)} )}
<div className="forgot-password-area flex justify-between items-center mb-6"> <div className="forgot-password-area flex justify-between items-center mb-6">
<div className="remember-checkbox flex items-center space-x-2.5 group cursor-pointer">
<button
onClick={rememberMe}
type="button"
className={`w-6 h-6 border-[#4687ba] text-white flex justify-center items-center border rounded-[.45em] group-checked:text-white transition-all duration-200 group-checked:cursor-default ${
checked && "text-white bg-[#4687ba]"
}`}
>
{checked && (
<svg
xmlns="http://www.w3.org/2000/svg"
className="h-5 w-5"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fillRule="evenodd"
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
clipRule="evenodd"
/>
</svg>
)}
</button>
<span
onClick={rememberMe}
className="cursor-default text-dark-gray dark:text-white text-[15px] group-checked:text-white transition-all duration-200 group-checked:cursor-default"
>
I agree with all
<Link
href="#"
className="text-base text-[#4687ba] hover:text-[#009ef7] mx-1 inline-block"
>
terms and condition
</Link>
</span>
</div>
</div>
{/* Forgot Password */}
{/* <div className="forgot-password-area flex justify-between items-center mb-6">
<div className="remember-checkbox flex items-center space-x-2.5"> <div className="remember-checkbox flex items-center space-x-2.5">
<button <button
onClick={rememberMe} onClick={rememberMe}
@@ -258,7 +302,7 @@ export default function SignUp() {
</Link> </Link>
</span> </span>
</div> </div>
</div> </div> */}
<div className="signin-area mb-1"> <div className="signin-area mb-1">
<div className="flex justify-center"> <div className="flex justify-center">
<button <button
@@ -1,6 +1,6 @@
import { useCallback, useEffect, useState } from "react"; import { useCallback, useEffect, useState } from "react";
import { Link, useLocation, useNavigate } from "react-router-dom"; import { Link, useLocation, useNavigate } from "react-router-dom";
import WrenchBoard from "../../../assets/images/wrenchboard.png"; import WrenchBoard from "../../../assets/images/wrenchboard-logo-text.png";
import debounce from "../../../hooks/debounce"; import debounce from "../../../hooks/debounce";
import usersService from "../../../services/UsersService"; import usersService from "../../../services/UsersService";
import InputCom from "../../Helpers/Inputs/InputCom"; import InputCom from "../../Helpers/Inputs/InputCom";
@@ -1,6 +1,6 @@
import { useState } from "react"; import { useState } from "react";
import { Link, useLocation, useNavigate } from "react-router-dom"; import { Link, useLocation, useNavigate } from "react-router-dom";
import WrenchBoard from "../../../assets/images/wrenchboard.png"; import WrenchBoard from "../../../assets/images/wrenchboard-logo-text.png";
import usersService from "../../../services/UsersService"; import usersService from "../../../services/UsersService";
import InputCom from "../../Helpers/Inputs/InputCom"; import InputCom from "../../Helpers/Inputs/InputCom";
import AuthLayout from "../AuthLayout"; import AuthLayout from "../AuthLayout";
+1 -1
View File
@@ -1,6 +1,6 @@
import { useNavigate, Link } from "react-router-dom"; import { useNavigate, Link } from "react-router-dom";
import AuthLayout from "../AuthLayout"; import AuthLayout from "../AuthLayout";
import WrenchBoard from "../../../assets/images/wrenchboard.png"; import WrenchBoard from "../../../assets/images/wrenchboard-logo-text.png";
export default function VerifyYou() { export default function VerifyYou() {
const navigate = useNavigate(); const navigate = useNavigate();
+12 -3
View File
@@ -36,7 +36,16 @@ export default function BlogItem(props) {
commonHeadData={props.commonHeadData} commonHeadData={props.commonHeadData}
/> />
<div className="notification-page w-full mb-10"> <div className="notification-page w-full mb-10">
<div className="notification-wrapper w-full bg-white p-8"> <div className="mb-5">
<h1 className="text-26 font-bold text-dark-gray dark:text-white">
<span
className={`${selectTab === "today" ? "block" : "hidden"}`}
>
{blogdata.data?.blogdata?.[0]?.post_title}
</span>
</h1>
</div>
<div className="notification-wrapper w-full bg-white p-8 rounded-2xl">
{blogdata.loading ? {blogdata.loading ?
<LoadingSpinner size='8' color='sky-blue' height='h-[100px]' /> <LoadingSpinner size='8' color='sky-blue' height='h-[100px]' />
: :
@@ -44,7 +53,7 @@ export default function BlogItem(props) {
<div className="w-full"> <div className="w-full">
{/* heading */} {/* heading */}
<div className="sm:flex justify-between items-center mb-6"> <div className="sm:flex justify-between items-center mb-6">
<div className="mb-5 sm:mb-0"> {/* <div className="mb-5">
<h1 className="text-26 font-bold text-dark-gray dark:text-white"> <h1 className="text-26 font-bold text-dark-gray dark:text-white">
<span <span
className={`${selectTab === "today" ? "block" : "hidden"}`} className={`${selectTab === "today" ? "block" : "hidden"}`}
@@ -52,7 +61,7 @@ export default function BlogItem(props) {
{blogdata.data?.blogdata?.[0]?.post_title} {blogdata.data?.blogdata?.[0]?.post_title}
</span> </span>
</h1> </h1>
</div> </div> */}
{/* <div className="slider-btns flex space-x-4"> {/* <div className="slider-btns flex space-x-4">
</div> */} </div> */}
</div> </div>
@@ -16,7 +16,8 @@ export default function HomeBannerOffersCard(props) {
return ( return (
<Link <Link
to={link_result} // to={link_result}
to={link_result == '/blog-page' ? `${link_result}?blog_id=${props.itemData.blog_id}` : `${link_result}`}
className="item p-2 w-full flex items-center min-h-[340px] bg-alice-blue bg-cover bg-center" className="item p-2 w-full flex items-center min-h-[340px] bg-alice-blue bg-cover bg-center"
style={{ style={{
backgroundImage: `url('${imageUrl}')`, backgroundImage: `url('${imageUrl}')`,
+1 -1
View File
@@ -19,7 +19,7 @@ export default function OfferCard({ datas, hidden = false, setOfferPopout }) {
className="thumbnail w-full h-full rounded-xl overflow-hidden px-4 pt-4" className="thumbnail w-full h-full rounded-xl overflow-hidden px-4 pt-4"
style={{ style={{
background: `url(${localImgLoad( background: `url(${localImgLoad(
`images/taskbanners/${datas.banner}` `images/taskbanners/${datas?.banner || "default.jpg"}`
)}) center / contain no-repeat`, )}) center / contain no-repeat`,
}} }}
> >
+7 -6
View File
@@ -50,22 +50,23 @@ export default function ProductCardStyleTwo({
</div> </div>
<div className="details-area"> <div className="details-area">
{/* title */} {/* title */}
<a href={datas.guid} target="_blank" className="mb-2.5" rel="noreferrer"> <Link to={`/blog-page?blog_id=${datas.ID}`} className="mb-2.5" rel="noreferrer">
<h1 className="font-bold text-xl tracking-wide line-clamp-1 text-dark-gray dark:text-white capitalize"> <h1 className="font-bold text-xl tracking-wide line-clamp-1 text-dark-gray dark:text-white capitalize">
{datas.post_title || "dummy title..."} {datas.post_title || "dummy title..."}
</h1> </h1>
</a> </Link>
<div className="flex justify-between"> <div className="flex justify-between">
<div className="flex items-center space-x-2"></div> <div className="flex items-center space-x-2"></div>
<div className="my-1"> <div className="my-1">
<a <Link
href={datas.guid} // href={datas.guid}
target="_blank" // target="_blank"
to={`/blog-page?blog_id=${datas.ID}`}
className="px-4 py-2.5 text-white text-sm bg-pink rounded-full tracking-wide" className="px-4 py-2.5 text-white text-sm bg-pink rounded-full tracking-wide"
rel="noreferrer" rel="noreferrer"
> >
View View
</a> </Link>
</div> </div>
</div> </div>
</div> </div>
+11 -10
View File
@@ -10,10 +10,10 @@ import React, {
} from "react"; } from "react";
import { useReactToPrint } from "react-to-print"; import { useReactToPrint } from "react-to-print";
import profile from "../../assets/images/profile-info-profile.png"; import profile from "../../assets/images/profile-info-profile.png";
import localImgLoad from "../../lib/localImgLoad";
import usersService from "../../services/UsersService"; import usersService from "../../services/UsersService";
import LoadingSpinner from "../Spinners/LoadingSpinner"; import LoadingSpinner from "../Spinners/LoadingSpinner";
import AssignTaskPopout from "./FamilyPopout/AssignTaskPopout"; import AssignTaskPopout from "./FamilyPopout/AssignTaskPopout";
import localImgLoad from "../../lib/localImgLoad";
// Lazy Imports for components // Lazy Imports for components
const FamilyWaitlist = lazy(() => import("./Tabs/FamilyWaitlist")); const FamilyWaitlist = lazy(() => import("./Tabs/FamilyWaitlist"));
@@ -193,19 +193,19 @@ export default function FamilyManageTabs({
return ( return (
<div <div
className={`w-full bg-white dark:bg-dark-white overflow-y-auto rounded-2xl section-shadow min-h-[520px] max-h-[600px] ${ className={`w-full bg-white dark:bg-dark-white overflow-y-auto rounded-2xl section-shadow h-full ${
className || "" className || ""
}`} }`}
> >
<div className="relative w-full overflow-x-auto sm:rounded-lg"> <div className="relative w-full sm:rounded-lg overflow-x-auto">
<Suspense <Suspense
fallback={ fallback={
<div className="h-full min-h-[500px] w-full overflow-hidden flex justify-center items-center"> <div className="h-full min-h-[609px] w-full overflow-hidden flex justify-center items-center">
<LoadingSpinner size="16" color="sky-blue" /> <LoadingSpinner size="16" color="sky-blue" />
</div> </div>
} }
> >
<div className="w-full h-full text-sm text-left text-gray-500 dark:text-gray-400 relative grid grid-cols-4 min-h-[520px]"> <div className="w-full h-full text-sm text-left text-gray-500 dark:text-gray-400 relative grid grid-cols-4 min-h-[575px]">
<div className="border-r border-[#E3E4FE] dark:border-[#a7a9b533] p-6 h-full flex flex-col justify-between"> <div className="border-r border-[#E3E4FE] dark:border-[#a7a9b533] p-6 h-full flex flex-col justify-between">
<ProfileInfo <ProfileInfo
profileImg={profileImg} profileImg={profileImg}
@@ -239,10 +239,10 @@ export default function FamilyManageTabs({
</button> </button>
</div> </div>
</div> </div>
<div className="col-span-3 justify-self-end h-full w-full"> <div className="col-span-3 h-full w-full">
<div className="flex flex-col w-full"> <div className="flex flex-col w-full">
<div className="w-full pr-8 flex items-center gap-1"> <div className="w-full pr-8 flex items-center gap-1 border-b border-b-[#FAFAF]">
<ul className="flex gap-2 items-center border-b border-b-[#FAFAF] w-full"> <ul className="flex gap-2 items-center w-full">
{tabs.map(({ name, id }) => ( {tabs.map(({ name, id }) => (
<li <li
onClick={() => tabHandler(name)} onClick={() => tabHandler(name)}
@@ -265,8 +265,9 @@ export default function FamilyManageTabs({
Add task Add task
</button> </button>
</div> </div>
<div className="flex-[0.9] lg:min-h-[450px] h-full">
<div className="h-full p-4 border border-[#dbd9d9] relative overflow-y-auto"> <div className="flex-[0.9] h-full">
<div className="h-full relative overflow-y-auto">
<Suspense <Suspense
fallback={<LoadingSpinner size="16" color="sky-blue" />} fallback={<LoadingSpinner size="16" color="sky-blue" />}
> >
+1 -1
View File
@@ -23,7 +23,7 @@ export default function FamilyTable({ className, familyList, loader, popUpHandle
return ( return (
<div <div
className={`update-table w-full h-full p-8 bg-white dark:bg-dark-white overflow-y-auto rounded-2xl section-shadow min-h-[520px] ${ className={`update-table w-full h-full p-4 bg-white dark:bg-dark-white overflow-y-auto rounded-2xl section-shadow min-h-[520px] ${
className || "" className || ""
}`} }`}
> >
@@ -4,7 +4,7 @@ import QRCode from "react-qr-code";
const FamilyAccount = forwardRef(({ familyData, myRef, handlePrint }, ref) => { const FamilyAccount = forwardRef(({ familyData, myRef, handlePrint }, ref) => {
return ( return (
<div <div
className="w-full lg:min-h-[500px] h-full flex flex-col items-center justify-center" className="w-full lg:min-h-[538px] p-3 h-full flex flex-col items-center justify-center"
ref={myRef} ref={myRef}
> >
<div className="update-table w-full lg:min-h-[450px] h-full p-8 bg-white dark:bg-dark-white overflow-hidden rounded-2xl section-shadow "> <div className="update-table w-full lg:min-h-[450px] h-full p-8 bg-white dark:bg-dark-white overflow-hidden rounded-2xl section-shadow ">
@@ -1,9 +1,8 @@
import { useMemo, 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";
import PendingJobsPopout from "../../jobPopout/PendingJobsPopout";
import localImgLoad from "../../../lib/localImgLoad"; import localImgLoad from "../../../lib/localImgLoad";
import { PriceFormatter } from "../../Helpers/PriceFormatter";
import { PaginatedList, handlePagingFunc } from "../../Pagination";
import PendingJobsPopout from "../../jobPopout/PendingJobsPopout";
export default function FamilyPending({ export default function FamilyPending({
familyData, familyData,
@@ -37,7 +36,7 @@ export default function FamilyPending({
return ( return (
<div <div
className={`update-table w-full p-8 bg-white dark:bg-dark-white overflow-hidden rounded-2xl section-shadow min-h-[520px] ${ className={`update-table w-full p-3 bg-white dark:bg-dark-white overflow-hidden rounded-2xl section-shadow lg:min-h-[538px] ${
className || "" className || ""
}`} }`}
> >
@@ -125,8 +124,10 @@ export default function FamilyPending({
); );
}) })
) : ( ) : (
<tr className="font-bold text-xl text-dark-gray dark:text-white whitespace-nowrap"> <tr>
<td className="p-2">No Pending Task!</td> <td className="font-bold text-xl text-dark-gray dark:text-white whitespace-nowrap text-center py-4 px-2">
No Pending Task!
</td>
</tr> </tr>
)} )}
</> </>
@@ -1,3 +1,11 @@
export default function FamilyProfile() { export default function FamilyProfile({ className }) {
return <>Profile</>; return (
<div
className={`update-table w-full bg-white dark:bg-dark-white overflow-hidden rounded-2xl section-shadow lg:min-h-[538px] p-3 ${
className || ""
}`}
>
<h1>Profile</h1>
</div>
);
} }
+40 -18
View File
@@ -1,20 +1,30 @@
import React, { useState } from "react"; import React, { useMemo, useState } from "react";
import dataImage2 from "../../../assets/images/data-table-user-2.png"; import { useLocation, useNavigate } from "react-router-dom";
import { useNavigate, useLocation } from "react-router-dom"; import localImgLoad from "../../../lib/localImgLoad";
import Icons from "../../Helpers/Icons";
import { PriceFormatter } from "../../Helpers/PriceFormatter";
import { handlePagingFunc } from "../../Pagination/HandlePagination"; import { handlePagingFunc } from "../../Pagination/HandlePagination";
import PaginatedList from "../../Pagination/PaginatedList"; import PaginatedList from "../../Pagination/PaginatedList";
import LoadingSpinner from "../../Spinners/LoadingSpinner"; import LoadingSpinner from "../../Spinners/LoadingSpinner";
import Icons from "../../Helpers/Icons";
import { PriceFormatter } from "../../Helpers/PriceFormatter";
import ModalCom from "../../Helpers/ModalCom";
import Detail from "../../jobPopout/popoutcomponent/Detail";
import localImgLoad from "../../../lib/localImgLoad";
export default function FamilyTasks({
export default function FamilyTasks({ familyData, className, loader, accountDetails }) { familyData,
className,
loader,
accountDetails,
}) {
let navigate = useNavigate(); let navigate = useNavigate();
let { pathname } = useLocation(); let { pathname } = useLocation();
// ...
const filteredFamilyData = useMemo(
() =>
familyData?.result_list?.filter(
(data) => data?.family_uid === accountDetails?.family_uid
),
[familyData, accountDetails]
);
const [currentPage, setCurrentPage] = useState(0); const [currentPage, setCurrentPage] = useState(0);
const indexOfFirstItem = Number(currentPage); const indexOfFirstItem = Number(currentPage);
const indexOfLastItem = const indexOfLastItem =
@@ -26,9 +36,10 @@ export default function FamilyTasks({ familyData, className, loader, accountDeta
const handlePagination = (e) => handlePagingFunc(e, setCurrentPage); const handlePagination = (e) => handlePagingFunc(e, setCurrentPage);
return ( return (
<div <div
className={`update-table w-full bg-white dark:bg-dark-white h-full lg:min-h-[450px] overflow-hidden rounded-2xl section-shadow ${ className={`update-table w-full bg-white dark:bg-dark-white h-full lg:min-h-[538px] overflow-hidden rounded-2xl section-shadow p-3 ${
className || "" className || ""
}`} }`}
> >
@@ -45,8 +56,8 @@ export default function FamilyTasks({ familyData, className, loader, accountDeta
{ {
<> <>
{familyData && {familyData &&
familyData?.result_list && familyData?.result_list &&
familyData.result_list.length > 0 && familyData.result_list.length > 0 ? (
currentTask.map((value, index) => { currentTask.map((value, index) => {
// find due date // find due date
const dueDate = value?.delivery_date.split(" ")[0]; const dueDate = value?.delivery_date.split(" ")[0];
@@ -56,7 +67,9 @@ export default function FamilyTasks({ familyData, className, loader, accountDeta
value?.currency_code, value?.currency_code,
value?.currency value?.currency
); );
let image = value.banner ? value.banner : 'default.jpg' let image = value.banner
? value.banner
: "default.jpg";
return ( return (
<tr <tr
key={index} key={index}
@@ -66,7 +79,9 @@ export default function FamilyTasks({ familyData, className, loader, accountDeta
<div className="flex space-x-2 items-center w-full"> <div className="flex space-x-2 items-center w-full">
<div className="w-[60px] h-[60px] p-2 bg-alice-blue rounded-full overflow-hidden flex justify-center items-center"> <div className="w-[60px] h-[60px] p-2 bg-alice-blue rounded-full overflow-hidden flex justify-center items-center">
<img <img
src={localImgLoad(`images/taskbanners/${image}`)} src={localImgLoad(
`images/taskbanners/${image}`
)}
alt="data" alt="data"
className="w-full h-full rounded-full" className="w-full h-full rounded-full"
/> />
@@ -109,8 +124,8 @@ export default function FamilyTasks({ familyData, className, loader, accountDeta
state: { state: {
...value, ...value,
pathname, pathname,
accountDetails accountDetails,
} },
}); });
}} }}
className="w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white" className="w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
@@ -120,7 +135,14 @@ export default function FamilyTasks({ familyData, className, loader, accountDeta
</td> </td>
</tr> </tr>
); );
})} })
) : (
<tr>
<td colSpan="2" className="text-center py-4 font-bold text-xl text-dark-gray dark:text-white whitespace-nowrap">
No Family Task
</td>
</tr>
)}
</> </>
} }
</tbody> </tbody>
@@ -48,7 +48,7 @@ const FamilyWaitlist = memo(
return ( return (
<div <div
className={`update-table w-full bg-white dark:bg-dark-white h-full lg:min-h-[450px] overflow-hidden rounded-2xl section-shadow ${ className={`update-table w-full bg-white dark:bg-dark-white h-full lg:min-h-[538px] p-3 overflow-hidden rounded-2xl section-shadow ${
className || "" className || ""
}`} }`}
> >
@@ -22,7 +22,7 @@ export default function InputCom({
spanTag, spanTag,
inputBg, inputBg,
onInput, onInput,
maxLength = 30, maxLength = 45,
minLength = 0, minLength = 0,
direction, direction,
error, error,
@@ -124,7 +124,7 @@ export default function InputCom({
} }
const inputConfigs = { const inputConfigs = {
email: { minLength: 7, maxLength: 35 }, email: { minLength: 7, maxLength: 45 },
first_name: { minLength: 3, maxLength: 25, pattern: "[a-zA-Z]+" }, first_name: { minLength: 3, maxLength: 25, pattern: "[a-zA-Z]+" },
last_name: { minLength: 3, maxLength: 25, pattern: "[a-zA-Z]+" }, last_name: { minLength: 3, maxLength: 25, pattern: "[a-zA-Z]+" },
address: { minLength: 5, maxLength: 49, pattern: "[a-zA-Z0-9]+" }, address: { minLength: 5, maxLength: 49, pattern: "[a-zA-Z0-9]+" },
+4 -4
View File
@@ -110,13 +110,13 @@ export default function MyJobTable({ MyJobList, reloadJobList, className }) {
return ( return (
<tr <tr
key={index} key={index}
className="bg-white dark:bg-dark-white border-b dark:border-[#5356fb29] hover:bg-gray-50" className="bg-white dark:bg-dark-white border-b dark:border-[#5356fb29] hover:bg-gray-50"
> >
<td className="py-9"> <td className="py-9">
<div className="sm:flex sm:space-x-2 sm:justify-between sm:items-center job-items"> <div className="sm:flex sm:space-x-2 sm:justify-between sm:items-center job-items">
<div className="flex space-x-2 items-center job-items w-full"> <div className="flex space-x-2 items-center job-items w-full">
<div className="w-[60px] h-[60px] p-2 bg-alice-blue rounded-full overflow-hidden flex justify-center items-center"> <div className="w-[60px] h-[60px] p-2 bg-alice-blue rounded-full overflow-hidden flex justify-center items-center">
<img src={localImgLoad(`images/taskbanners/${value.banner}`)} alt="data" className="w-full h-full rounded-full" /> <img src={localImgLoad(`images/taskbanners/${value.banner ? value.banner : 'default.jpg'}`)} alt="data" className="w-full h-full rounded-full" />
</div> </div>
<div className="flex flex-col flex-[0.9]"> <div className="flex flex-col flex-[0.9]">
<h1 className="font-bold text-xl text-dark-gray dark:text-white"> <h1 className="font-bold text-xl text-dark-gray dark:text-white">
@@ -175,7 +175,7 @@ export default function MyJobTable({ MyJobList, reloadJobList, className }) {
}} }}
className="w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white" className="w-20 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
> >
Manage Assign
</button> </button>
</td> </td>
</tr> </tr>
@@ -204,7 +204,7 @@ export default function MyJobTable({ MyJobList, reloadJobList, className }) {
{MyJobList.loading ? ( {MyJobList.loading ? (
<LoadingSpinner size="16" color="sky-blue" /> <LoadingSpinner size="16" color="sky-blue" />
) : ( ) : (
<div className="relative w-full overflow-x-auto sm:rounded-lg flex flex-col justify-between h-full"> <div className="relative w-full overflow-x-auto sm:rounded-lg flex flex-col justify-between min-h-[520px]">
<table className="table-auto min-w-full text-sm text-left text-gray-500 dark:text-gray-400"> <table className="table-auto min-w-full text-sm text-left text-gray-500 dark:text-gray-400">
<tbody> <tbody>
<> <>
@@ -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
@@ -58,7 +59,7 @@ export default function MyPendingJobTable({ MyJobList, className }) {
<div className="flex space-x-2 items-center w-full"> <div className="flex space-x-2 items-center w-full">
<div className="w-[60px] h-[60px] p-2 bg-alice-blue rounded-full overflow-hidden flex justify-center items-center"> <div className="w-[60px] h-[60px] p-2 bg-alice-blue rounded-full overflow-hidden flex justify-center items-center">
<img <img
src={localImgLoad(`images/taskbanners/${value.banner}`)} src={localImgLoad(`images/taskbanners/${value.banner || "default.jpg"}`)}
alt="data" alt="data"
className="w-full h-full rounded-full" className="w-full h-full rounded-full"
/> />
+9 -2
View File
@@ -3,13 +3,14 @@ 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");
const filterHandler = (value) => { const filterHandler = (value) => {
setValue(value); setValue(value);
}; };
console.log("AMEYE LOC1", props.MyJobList); // console.log("AMEYE LOC1", props.MyJobList);
return ( return (
<Layout> <Layout>
<CommonHead <CommonHead
@@ -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>
@@ -136,6 +136,12 @@ function AddFundDollars(props) {
return; return;
} }
if (Number(props.input) * 100 > Number(props.walletItem?.transfer_limit)) {
props.setInputError("Credit limit has been exceeded");
setTimeout(() => props.setInputError(""), 5000);
return;
}
if (tab === "previous") { if (tab === "previous") {
// To check if card is empty // To check if card is empty
if (Object.keys(prevCardDetails).length === 0) { if (Object.keys(prevCardDetails).length === 0) {
@@ -487,7 +493,7 @@ function AddFundDollars(props) {
{/* Postal Code and State */} {/* Postal Code and State */}
<div className="sm:grid gap-5 grid-cols-3 my-2"> <div className="sm:grid gap-5 grid-cols-3 my-2">
<div className="field w-full mb-6 xl:mb-0 col-span-1"> <div className="field w-full xl:mb-0 col-span-1">
<InputCom <InputCom
fieldClass="px-6" fieldClass="px-6"
spanTag="*" spanTag="*"
@@ -521,7 +527,7 @@ function AddFundDollars(props) {
</div> </div>
</div> </div>
<div className="md:px-8 md:pt-4 px-4 pt-2 add-fund-btn flex justify-end items-center gap-3"> <div className="md:px-8 add-fund-btn flex justify-end items-center gap-3">
<button <button
className="px-4 py-1 h-11 max-w-[100px] w-full flex justify-center items-center border-gradient text-base rounded-full" className="px-4 py-1 h-11 max-w-[100px] w-full flex justify-center items-center border-gradient text-base rounded-full"
onClick={handleClose} onClick={handleClose}
+9 -5
View File
@@ -1,5 +1,4 @@
import React, { useState } from "react"; import React, { useState } from "react";
import { useNavigate } from "react-router-dom";
import usersService from "../../../services/UsersService"; import usersService from "../../../services/UsersService";
import Icons from "../../Helpers/Icons"; import Icons from "../../Helpers/Icons";
import InputCom from "../../Helpers/Inputs/InputCom"; import InputCom from "../../Helpers/Inputs/InputCom";
@@ -15,10 +14,9 @@ function AddFundPop({
setConfirmCredit, setConfirmCredit,
walletItem, walletItem,
}) { }) {
const navigate = useNavigate();
const apiCall = new usersService(); const apiCall = new usersService();
let countryWallet = walletItem?.country; let countryWallet = walletItem?.country;
const { payment, currency } = _payment; const { currency } = _payment;
const [inputError, setInputError] = useState(""); const [inputError, setInputError] = useState("");
let __awaitComponent = confirmCredit.show.awaitConfirm; let __awaitComponent = confirmCredit.show.awaitConfirm;
@@ -44,6 +42,12 @@ function AddFundPop({
return; return;
} }
if (Number(input) * 100 > Number(walletItem?.transfer_limit)) {
setInputError("Credit limit has been exceeded");
setTimeout(() => setInputError(""), 5000);
return;
}
if (isNaN(input)) { if (isNaN(input)) {
setConfirmCredit((prev) => ({ setConfirmCredit((prev) => ({
...prev, ...prev,
@@ -106,14 +110,14 @@ function AddFundPop({
</h1> </h1>
<div className="field w-full max-w-[250px]"> <div className="field w-full max-w-[250px]">
<InputCom <InputCom
fieldClass="px-6" fieldClass="px-6 text-right"
type="text" type="text"
name="amount" name="amount"
placeholder="0" placeholder="0"
value={input} value={input}
inputHandler={handleChange} inputHandler={handleChange}
/> />
<p className="text-base text-red-500 h-5"> <p className="text-base text-red-500 italic h-5">
{inputError && inputError} {inputError && inputError}
</p> </p>
</div> </div>
@@ -2,11 +2,6 @@ import React from "react";
function CompleteConfirmCredit({ onClose, confirmCredit }) { function CompleteConfirmCredit({ onClose, confirmCredit }) {
const { data } = confirmCredit; const { data } = confirmCredit;
const backToWallet = () => {
onClose();
window.location.reload(true);
};
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]">
@@ -22,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"
@@ -60,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>
@@ -104,7 +101,7 @@ function CompleteConfirmCredit({ onClose, confirmCredit }) {
<div className="md:p-8 p-4 add-fund-btn flex justify-end items-center py-4 gap-4"> <div className="md:p-8 p-4 add-fund-btn flex justify-end items-center py-4 gap-4">
<button <button
className="px-4 h-11 flex justify-center items-center btn-gradient text-white text-base rounded-full w-[100px]" className="px-4 h-11 flex justify-center items-center btn-gradient text-white text-base rounded-full w-[100px]"
onClick={backToWallet} onClick={onClose}
> >
Ok Ok
</button> </button>
@@ -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({
@@ -113,7 +112,7 @@ function ConfirmAddFund({
const config = { const config = {
public_key: process.env.REACT_APP_FLUTTERWAVE_APIKEY, public_key: process.env.REACT_APP_FLUTTERWAVE_APIKEY,
tx_ref: Date.now(), tx_ref: __confirmData?.credit_reference,
currency: "NGN", currency: "NGN",
amount: Number(__confirmData.amount), amount: Number(__confirmData.amount),
payment_options: "card,mobilemoney,ussd", payment_options: "card,mobilemoney,ussd",
@@ -124,27 +123,37 @@ function ConfirmAddFund({
}, },
customizations: { customizations: {
title: "WrenchBoard", title: "WrenchBoard",
description: "Topup Payment", description: "Add Credit Payment",
logo: "https://st2.depositphotos.com/4403291/7418/v/450/depositphotos_74189661-stock-illustration-online-shop-log.jpg", logo: "https://www.wrenchboard.com/assets/images/wrench-500-500-icon.png",
}, },
}; };
//debugger;
const fwConfig = { const fwConfig = {
...config, ...config,
text: "Proceed", text: "Proceed",
callback: (response) => { callback: (response) => {
onSuccessPayment(); debouncedSuccessPayment(); //delays the call for 5 secs
closePaymentModal();
setTimeout(() => {
closePaymentModal();
setConfirmCredit((prev) => ({
...prev,
show: {
awaitConfirm: { loader: false, state: false },
acceptConfirm: { loader: false, state: true },
},
data: response,
}));
}, 1500);
}, },
onClose: () => {},
}; };
const onSuccessPayment = () => { const onSuccessPayment = () => {
setRequestStatus({ message: "", loading: true, status: false }); setRequestStatus({ message: "", loading: true, status: false });
const reqData = { amount: Number(__confirmData?.amount), currency: "NGN" }; const reqData = { tx_ref: __confirmData?.credit_reference };
console.log("**** onSuccessPayment **** THIS WAS REACHED");
apiURL apiURL
.startTopUp(reqData) .resultTopUp(reqData)
.then((res) => { .then((res) => {
if (res.data.internal_return < 0) { if (res.data.internal_return < 0) {
setRequestStatus({ setRequestStatus({
@@ -152,21 +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,
});
toast.success("Account Topup was successful");
onClose()
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({
@@ -174,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;
@@ -291,6 +301,17 @@ function ConfirmAddFund({
} }
}; };
const getBack = () => {
setConfirmCredit((prev) => ({
...prev,
show: {
awaitConfirm: { loader: false, state: false },
acceptConfirm: { loader: false, state: false },
},
data: {},
}));
};
return ( return (
<div className="content-wrapper w-full h-[32rem]"> <div className="content-wrapper w-full h-[32rem]">
<div className="w-full mb-10"> <div className="w-full mb-10">
@@ -359,9 +380,9 @@ function ConfirmAddFund({
<div className="md:p-8 p-4 add-fund-btn flex justify-end items-center py-4 gap-4"> <div className="md:p-8 p-4 add-fund-btn flex justify-end items-center py-4 gap-4">
<button <button
className="px-4 h-11 flex justify-center items-center border-gradient text-base rounded-full" className="px-4 h-11 flex justify-center items-center border-gradient text-base rounded-full"
onClick={onClose} onClick={getBack}
> >
Cancel Back
</button> </button>
{__confirmCountry === "US" && ( {__confirmCountry === "US" && (
<button <button
@@ -1,10 +1,10 @@
import { useState } from "react"; import { useState } from "react";
import { useNavigate } from "react-router-dom";
import { toast } from "react-toastify";
import usersService from "../../../services/UsersService"; import usersService from "../../../services/UsersService";
import InputCom from "../../Helpers/Inputs/InputCom"; import InputCom from "../../Helpers/Inputs/InputCom";
import ModalCom from "../../Helpers/ModalCom"; import ModalCom from "../../Helpers/ModalCom";
import LoadingSpinner from "../../Spinners/LoadingSpinner"; import LoadingSpinner from "../../Spinners/LoadingSpinner";
import { useDispatch } from "react-redux";
import { tableReload } from "../../../store/TableReloads";
function ConfirmNairaWithdraw({ function ConfirmNairaWithdraw({
payment, payment,
@@ -15,7 +15,7 @@ function ConfirmNairaWithdraw({
setShowNairaWithdraw, setShowNairaWithdraw,
}) { }) {
const apiURL = new usersService(); const apiURL = new usersService();
const navigate = useNavigate(); const dispatch = useDispatch();
let [requestStatus, setRequestStatus] = useState({ let [requestStatus, setRequestStatus] = useState({
message: "", message: "",
@@ -23,9 +23,16 @@ function ConfirmNairaWithdraw({
status: false, status: false,
}); });
const [completeNairaWithdraw, setShowCompleteNairaWithdraw] = useState({
show: false,
load: false,
state: {},
}); // DETERMINES WHEN CONFIRM NAIRA WITHDRAWAL POPS UP
//FUNCTION TO HANDLE SUBMIT //FUNCTION TO HANDLE SUBMIT
const handleSubmit = () => { const handleSubmit = () => {
setRequestStatus({ message: "", loading: true, status: false }); setRequestStatus({ message: "", loading: true, status: false });
setShowCompleteNairaWithdraw({ load: true });
let reqData = { let reqData = {
amount: Number(state.amount * 100), amount: Number(state.amount * 100),
Fee: Number(state.fee), Fee: Number(state.fee),
@@ -51,57 +58,41 @@ function ConfirmNairaWithdraw({
.sendMoney(reqData) .sendMoney(reqData)
.then((res) => { .then((res) => {
if (res.data.internal_return < 0) { if (res.data.internal_return < 0) {
if (res.data?.status_message?.toLowerCase().includes("limit")) { // if (res.data?.status_message?.toLowerCase().includes("limit")) {
// setRequestStatus({
// message: ,
// loading: false,
// status: false,
// });
// }
return setTimeout(() => {
setRequestStatus({ setRequestStatus({
message: "You have exceeded the transfer limit", message: "",
loading: false, loading: false,
status: false, status: false,
}); });
} else if ( setShowCompleteNairaWithdraw({
res.data?.status_message?.toLowerCase().includes("not_found") show: true,
) { load: false,
setRequestStatus({ state: res.data,
message: "Sorry, wallet not found",
loading: false,
status: false,
}); });
} else if ( }, 5000);
res.data?.status_message
?.toLowerCase()
.includes("recipient_add_error")
) {
setRequestStatus({
message: res.data?.error,
loading: false,
status: false,
});
} else {
setRequestStatus({
message: "Could not perform transaction",
loading: false,
status: false,
});
}
return setTimeout(
() =>
setRequestStatus({
message: "",
loading: false,
status: false,
}),
1500
);
} }
setRequestStatus({
message: "transfer successful",
loading: false,
status: true,
});
toast.success("Transfer sucessful");
setTimeout(() => { setTimeout(() => {
navigate("/my-wallet", { replace: true }); setRequestStatus({
window.location.reload(true); message: "",
}, 1000); loading: false,
status: false,
});
setShowCompleteNairaWithdraw({
show: true,
load: false,
state: res.data,
});
}, 5000);
dispatch(tableReload({ type: "WALLETTABLE" }));
return;
}) })
.catch((error) => { .catch((error) => {
setRequestStatus({ setRequestStatus({
@@ -112,23 +103,26 @@ function ConfirmNairaWithdraw({
}); });
}; };
const getBack = () => {
action();
setShowNairaWithdraw({
show: true,
data: {},
});
};
return ( return (
<ModalCom action={action} situation={situation} className="edit-popup"> <ModalCom action={action} situation={situation} className="edit-popup">
<div className="logout-modal-wrapper lw-[90%] md:w-[768px] h-full lg:h-auto bg-white dark:bg-dark-white lg:rounded-2xl"> <div className="logout-modal-wrapper lw-[90%] md:w-[768px] h-full lg:h-auto bg-white dark:bg-dark-white lg:rounded-2xl">
<div className="w-full"> <div className="w-full">
<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">
<h2 className="text-26 font-bold text-dark-gray dark:text-white tracking-wide"> <h2 className="text-26 font-bold text-dark-gray dark:text-white tracking-wide">
{`Withdraw from ${wallet.description} Wallet : ${wallet.symbol}${( {completeNairaWithdraw.load ? (
wallet.amount * 0.01 "Confirming..."
).toFixed(2)}`} ) : (
<>
{" "}
{completeNairaWithdraw.show
? completeNairaWithdraw?.state?.internal_return >= 0
? "Transfer Success"
: "Transfer Error"
: `Withdraw from ${wallet.description} Wallet : ${
wallet.symbol
}${(wallet.amount * 0.01).toFixed(2)}`}
</>
)}
</h2> </h2>
<button <button
type="button" type="button"
@@ -158,123 +152,276 @@ function ConfirmNairaWithdraw({
</div> </div>
<hr /> <hr />
<div className="add-fund w-full bg-white dark:bg-dark-white rounded-2xl shadow"> <div className="add-fund w-full bg-white dark:bg-dark-white rounded-2xl shadow">
<div className="px-4 md:px-8 py-4 add-fund-info"> {completeNairaWithdraw.load ? (
<h2 className="my-2 text-slate-900 dark:text-white text-sm xl:text-xl font-medium"> <div className="h-[35rem] flex items-center justify-center">
{/* Confirm Withdraw to Account */} <LoadingSpinner size="12" color="sky-blue" />
</h2>
{/* AMOUNT */}
<div className="field w-full mb-3">
<InputCom
fieldClass="px-6"
label="Amount:"
type="text"
name="amount"
value={state?.amount || ""}
disable={true}
/>
</div> </div>
) : completeNairaWithdraw.show ? (
{state?.choice === "prev" && ( <div className="px-4 md:p-8 py-4 add-fund-info">
<> <div className="field w-full mb-3 min-h-[23rem]">
{/* RECIPIENT ACC: */} <div className="flex items-center w-full justify-center mb-3">
<div className="field w-full mb-3"> {completeNairaWithdraw.state?.sendmoney_message
<InputCom ?.toLowerCase()
fieldClass="px-6" ?.includes("completed") ? (
label="Recipient Acc:" <svg
type="text" xmlns="http://www.w3.org/2000/svg"
name="recipient" width="100"
value={state?.details?.recipient || ""} height="100"
disable={true} viewBox="0 0 24 24"
/> fill="none"
stroke="green"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
className="feather feather-check-circle"
>
<path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"></path>
<polyline points="22 4 12 14.01 9 11.01"></polyline>
</svg>
) : (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
width="100"
height="100"
stroke="red"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
className="feather feather-x-circle"
>
<circle cx="12" cy="12" r="10"></circle>
<line x1="15" y1="9" x2="9" y2="15"></line>
<line x1="9" y1="9" x2="15" y2="15"></line>
</svg>
)}
</div> </div>
</>
)}
{state?.choice === "new" && ( {completeNairaWithdraw.state?.internal_return >= 0 ? (
<> <>
{/* RECIPIENT ACC: */} <div className={`flex items-center`}>
<div className="field w-full mb-3"> <h1 className="text-xl font-semibold text-dark-gray dark:text-white tracking-tighter my-1">
<InputCom {completeNairaWithdraw.state?.sendmoney_message || ""}
fieldClass="px-6" </h1>
label="Bank Acc:" </div>
type="text" <div className="flex items-center gap-8">
name="bank" <h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
value={ Amount(
`${state?.details?.name} ${state?.details?.country}` || {completeNairaWithdraw.state
"" ?.terminatingcountrycode || ""}
} )
disable={true} </h1>
/> <span className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
</div> {Number(
</> completeNairaWithdraw.state?.TerminatingAmount *
)} 0.01
).toLocaleString() || ""}
{/* PROCESSING FEE: */} </span>
<div className="field w-full mb-3"> </div>
<InputCom <div className="flex items-center gap-8">
fieldClass="px-6" <h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
label="Processing Fee:" Recipient
type="text" </h1>
name="processingFee" <span className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
value={(state?.fee * 0.01).toFixed(2) || ""} {completeNairaWithdraw.state?.recitient}
disable={true} </span>
/> </div>
<div className="flex items-center gap-8">
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
Confirmation Number
</h1>
<span className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
{completeNairaWithdraw.state?.confirmation}
</span>
</div>{" "}
</>
) : (
<>
<div className={`flex items-center`}>
<h1 className="text-xl font-semibold text-dark-gray dark:text-white tracking-tighter my-1">
{completeNairaWithdraw.state?.status_message
?.toLowerCase()
.includes("not_found")
? "Wallet Error Occurred"
: completeNairaWithdraw.state?.status_message
?.toLowerCase()
.includes("recipient_add_error")
? "Recipient Error Occurred"
: completeNairaWithdraw.state?.status_message
?.toLowerCase()
.includes("limit")
? "Transfer limit Error"
: completeNairaWithdraw.state?.bad_param
?.toLowerCase()
.includes("balance")
? "Insufficient Balance"
: "An Error Occurred"}{" "}
</h1>
</div>
<div className="flex items-center gap-8">
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
Message:
</h1>
<span className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
{completeNairaWithdraw.state?.status_message
?.toLowerCase()
.includes("not_found")
? "This Wallet is not Found"
: completeNairaWithdraw.state?.status_message
?.toLowerCase()
.includes("recipient_add_error")
? "No Recipient Found"
: completeNairaWithdraw.state?.status_message
?.toLowerCase()
.includes("limit")
? "The transfer limit has been exceeded"
: completeNairaWithdraw.state?.bad_param
?.toLowerCase()
.includes("balance")
? "Insufficient Balance for Transaction"
: "Could not perform transaction"}
</span>
</div>
</>
)}
</div>
</div> </div>
) : (
<div className="px-4 md:px-8 py-4 add-fund-info">
<h2 className="my-2 text-slate-900 dark:text-white text-sm xl:text-xl font-medium">
{/* Confirm Withdraw to Account */}
</h2>
{/* AMOUNT */}
<div className="field w-full mb-3">
<InputCom
fieldClass="px-6"
label="Amount:"
type="text"
name="amount"
value={state?.amount || ""}
disable={true}
/>
</div>
{/* TOTAL */} {state?.choice === "prev" && (
<div className="field w-full mb-3"> <>
<InputCom {/* RECIPIENT ACC: */}
fieldClass="px-6" <div className="field w-full mb-3">
label="Total" <InputCom
type="text" fieldClass="px-6"
name="total" label="Recipient Acc:"
value={(state?.total * 0.01).toFixed(2) || ""} type="text"
disable={true} name="recipient"
/> value={state?.details?.recipient || ""}
</div> disable={true}
/>
{/* COMMENT/NOTE */} </div>
<div className="field w-full mb-3"> </>
<InputCom
fieldClass="px-6"
label="Comment/Note:"
type="text"
name="comment"
value={state?.comment || ""}
disable={true}
/>
</div>
</div>
<hr />
<p
className={`text-base ${
requestStatus.status ? "text-green-500" : "text-red-500"
} px-4 md:px-8 py-4 h-5`}
>
{requestStatus.message && requestStatus.message}
</p>
<div className="px-4 md:px-8 py-4 add-fund-btn flex justify-end items-center gap-2">
<button
type="button"
onClick={state?.choice === "prev" ? getBack : action}
className="border-gradient text-base tracking-wide px-4 py-2 rounded-full"
>
<span className="text-gradient">
{state?.choice === "prev" ? "Back" : "Cancel"}
</span>
</button>
<button
onClick={handleSubmit}
className="btn-gradient text-base tracking-wide px-4 py-2 rounded-full text-white cursor-pointer min-w-[100px]"
>
{requestStatus.loading ? (
<LoadingSpinner size="6" color="sky-blue" />
) : (
"Transfer"
)} )}
</button>
</div> {state?.choice === "new" && (
<>
{/* RECIPIENT ACC: */}
<div className="field w-full mb-3">
<InputCom
fieldClass="px-6"
label="Bank Acc:"
type="text"
name="bank"
value={
`${state?.details?.name} ${state?.details?.country}` ||
""
}
disable={true}
/>
</div>
</>
)}
{/* PROCESSING FEE: */}
<div className="field w-full mb-3">
<InputCom
fieldClass="px-6"
label="Processing Fee:"
type="text"
name="processingFee"
value={(state?.fee * 0.01).toFixed(2) || ""}
disable={true}
/>
</div>
{/* TOTAL */}
<div className="field w-full mb-3">
<InputCom
fieldClass="px-6"
label="Total"
type="text"
name="total"
value={(state?.total * 0.01).toFixed(2) || ""}
disable={true}
/>
</div>
{/* COMMENT/NOTE */}
<div className="field w-full mb-3">
<InputCom
fieldClass="px-6"
label="Comment/Note:"
type="text"
name="comment"
value={state?.comment || ""}
disable={true}
/>
</div>
</div>
)}
{!completeNairaWithdraw.load && (
<>
{" "}
<hr />
<p
className={`text-base ${
requestStatus.status ? "text-green-500" : "text-red-500"
} px-4 md:px-8 py-4 h-5`}
>
{requestStatus.message && requestStatus.message}
</p>
<div className="px-4 md:px-8 py-4 add-fund-btn flex justify-end items-center gap-2">
{!completeNairaWithdraw.show && (
<button
type="button"
onClick={action}
className="border-gradient text-base tracking-wide px-4 py-2 rounded-full"
>
<span className="text-gradient">Cancel</span>
</button>
)}
<button
onClick={
completeNairaWithdraw.show
? action
: completeNairaWithdraw?.state?.internal_return < 0
? action
: handleSubmit
}
className="btn-gradient text-base tracking-wide px-4 py-2 rounded-full text-white cursor-pointer min-w-[100px]"
>
{requestStatus.loading ? (
<LoadingSpinner size="6" color="sky-blue" />
) : completeNairaWithdraw.show ? (
"Okay"
) : completeNairaWithdraw?.state?.internal_return < 0 ? (
"Cancel"
) : (
"Transfer"
)}
</button>
</div>
</>
)}
</div> </div>
</div> </div>
</div> </div>
@@ -60,14 +60,6 @@ function ConfirmTransfer({ payment, wallet }) {
}); });
}; };
useEffect(() => {
// what happens if not state redirect user
if (!state) {
navigate("/my-wallet/transfer-fund", { replace: true });
} else {
setPageLoading(false);
}
}, []);
return ( return (
<div className="content-wrapper w-full lg:flex xl:space-x-8 lg:space-x-4 bottomMargin"> <div className="content-wrapper w-full lg:flex xl:space-x-8 lg:space-x-4 bottomMargin">
{pageLoading ? ( {pageLoading ? (
@@ -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"
) : ( ) : (
<> <>
@@ -1,6 +1,5 @@
import { Form, Formik } from "formik"; import { Form, Formik } from "formik";
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";
import usersService from "../../../services/UsersService"; import usersService from "../../../services/UsersService";
import InputCom from "../../Helpers/Inputs/InputCom"; import InputCom from "../../Helpers/Inputs/InputCom";
import ModalCom from "../../Helpers/ModalCom"; import ModalCom from "../../Helpers/ModalCom";
@@ -172,7 +171,12 @@ function NairaWithdraw({
setErrorMsgs({ amount: "amount required" }); setErrorMsgs({ amount: "amount required" });
setTimeout(() => setErrorMsgs({ amount: "" }), 3000); setTimeout(() => setErrorMsgs({ amount: "" }), 3000);
return; return;
}else if (Number(values.amount * 100) > Number(wallet?.transfer_limit)) {
setErrorMsgs({ amount: "Withdraw limit has been exceeded" });
setTimeout(() => setErrorMsgs({ amount: "" }), 3000);
return;
} }
if (values?.comment?.length >= 50) { if (values?.comment?.length >= 50) {
setErrorMsgs({ comment: "50 chars max" }); setErrorMsgs({ comment: "50 chars max" });
setTimeout(() => setErrorMsgs({ comment: "" }), 1000); setTimeout(() => setErrorMsgs({ comment: "" }), 1000);
@@ -320,15 +324,14 @@ function NairaWithdraw({
<div className="flex flex-col"> <div className="flex flex-col">
<div className="field w-full"> <div className="field w-full">
<InputCom <InputCom
fieldClass="px-4" fieldClass="px-4 text-end"
parentClass="flex items-center gap-1 justify-between" parentClass="flex items-center gap-1 justify-between"
labelClass="flex-[0.3] mb-0" labelClass="flex-[0.4] mb-0"
inputClass="flex-[0.7] max-w-[12rem]" inputClass="flex-[0.6] max-w-[12rem]"
label="Amount:" label="Amount:"
type="number" type="number"
name="amount" name="amount"
placeholder="0" placeholder="0"
direction="rtl"
value={props.values.amount} value={props.values.amount}
inputHandler={props.handleChange} inputHandler={props.handleChange}
blurHandler={(e) => { blurHandler={(e) => {
@@ -445,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
} }
@@ -470,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
@@ -630,7 +633,9 @@ function NairaWithdraw({
className="text-slate-500 text-lg" className="text-slate-500 text-lg"
value="" value=""
> >
No Options Found! {allCountries.data?.length
? "Select..."
: "No Options Found!"}
</option> </option>
)} )}
</select> </select>
-3
View File
@@ -67,9 +67,6 @@ const WalletRoutes = () => {
getPaymentHistory() getPaymentHistory()
}, [walletTable]); }, [walletTable]);
console.log('TESTING',walletTable);
return ( return (
<Layout> <Layout>
<Suspense fallback={<LoadingSpinner size="16" color="sky-blue" />}> <Suspense fallback={<LoadingSpinner size="16" color="sky-blue" />}>
+1 -19
View File
@@ -8,30 +8,12 @@ function WalletAction({ walletItem, payment, openPopUp }) {
show: false, show: false,
state: {}, state: {},
}); // DETERMINES WHEN NAIRA WITHDRAWAL POPS UP }); // DETERMINES WHEN NAIRA WITHDRAWAL POPS UP
const [countries, setCountries] = useState([]);
const [showConfirmNairaWithdraw, setShowConfirmNairaWithdraw] = useState({ const [showConfirmNairaWithdraw, setShowConfirmNairaWithdraw] = useState({
show: false, show: false,
state: {}, state: {},
}); // DETERMINES WHEN CONFIRM NAIRA WITHDRAWAL POPS UP }); // DETERMINES WHEN CONFIRM NAIRA WITHDRAWAL POPS UP
const userApi = new usersService();
// Get Country Api
const getCountryList = useCallback(async () => {
const res = await userApi.getSignupCountryData();
try {
if (res.status === 200) {
const { signup_country } = await res.data;
setCountries(signup_country);
} else if (res.data.result !== 100) {
setCountries("Nothing see here!");
}
} catch (error) {
throw new Error(error);
}
}, []);
return ( return (
<div className="counters w-full flex justify-between gap-2"> <div className="counters w-full flex justify-between gap-2">
<div className="w-1/2 flex justify-center items-center"> <div className="w-1/2 flex justify-center items-center">
+1 -1
View File
@@ -14,7 +14,7 @@ import WalletHeader from "../MyWallet/WalletHeader";
import { useDispatch, useSelector } from "react-redux"; import { useDispatch, useSelector } from "react-redux";
import Flag from "../../assets/images/united-states.svg"; import Flag from "../../assets/images/united-states.svg";
import siteLogo from "../../assets/images/wrenchboard.png"; import siteLogo from "../../assets/images/wrenchboard-logo-text.png";
import formattedDate from "../../lib/fomattedDate"; import formattedDate from "../../lib/fomattedDate";
import { updateNotifications } from "../../store/notifications"; import { updateNotifications } from "../../store/notifications";
import TimeDifference from "../Helpers/TimeDifference"; import TimeDifference from "../Helpers/TimeDifference";
+1 -1
View File
@@ -4,7 +4,7 @@ import { NavLink } from "react-router-dom";
import { import {
default as logo, default as logo,
default as logo3, default as logo3,
} from "../../assets/images/wrenchboard.png"; //logo-2.svg"; } from "../../assets/images/wrenchboard-logo-text.png"; //logo-2.svg";
import DarkModeContext from "../Contexts/DarkModeContext"; import DarkModeContext from "../Contexts/DarkModeContext";
import Icons from "../Helpers/Icons"; import Icons from "../Helpers/Icons";
+1 -1
View File
@@ -4,7 +4,7 @@ import { NavLink } from "react-router-dom";
import { import {
default as logo, default as logo,
default as logo3, default as logo3,
} from "../../assets/images/wrenchboard.png"; } from "../../assets/images/wrenchboard-logo-text.png";
import DarkModeContext from "../Contexts/DarkModeContext"; import DarkModeContext from "../Contexts/DarkModeContext";
import Icons from "../Helpers/Icons"; import Icons from "../Helpers/Icons";
+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"
+19 -4
View File
@@ -577,16 +577,31 @@ class usersService {
return this.postAuxEnd("/familymanage", postData); return this.postAuxEnd("/familymanage", postData);
} }
//END POINT CALL FOR ACCOUNT TOP // END POINT CALL FOR ACCOUNT TOP
startTopUp(post) { startTopUp(post) {
alert("WHY ARE WE CALLING THIS ?");
// var postData = {
// uid: localStorage.getItem("uid"),
// member_id: localStorage.getItem("member_id"),
// sessionid: localStorage.getItem("session_token"),
// action: 11062,
// ...post,
// };
// console.log("starttopup",postData);
// return this.postAuxEnd("/starttopup", postData);
}
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: 11062, action: 11061,
...post, ...post,
}; };
return this.postAuxEnd("/starttopup", postData); console.log("topupresult",postData);
return this.postAuxEnd("/topupresult", postData);
} }
//END POINT CALL FOR SENDING REFERRAL MESSAGE //END POINT CALL FOR SENDING REFERRAL MESSAGE
+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 (