Compare commits
26 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9b6c5b72ad | |||
| afc5e25cfc | |||
| 58fe5eb82c | |||
| 2f3fdc0695 | |||
| 0a465fceb0 | |||
| 5e968db2f5 | |||
| 1916bc1a65 | |||
| 1103127cae | |||
| 751369071c | |||
| 4cc8f27c14 | |||
| aab455c2c3 | |||
| 21843c4bc7 | |||
| 8702728ffa | |||
| 79dcd0f2b5 | |||
| 47b25f3dfe | |||
| 89925a6af9 | |||
| 3c0f951b6e | |||
| ffbfb1da35 | |||
| a8416a8433 | |||
| 70c9d1778c | |||
| 930559c96b | |||
| c4af2dfcc8 | |||
| b186549b8d | |||
| ab191b6a72 | |||
| d130687cf9 | |||
| 5e9a442eac |
@@ -84,4 +84,11 @@ REACT_APP_MAX_CREDIT_BANK_ACCOUNT=4
|
||||
#Family
|
||||
REACT_APP_MAX_FAMILY_MEMBERS=8
|
||||
|
||||
REACT_APP_SHOW_OFFER_GROUP_JOB=0
|
||||
REACT_APP_SHOW_OFFER_GROUP_JOB=0
|
||||
|
||||
#UPLOAD PROFILE PICTURE
|
||||
REACT_APP_SHOW_UPLOAD_PROFILE_PICTURE=0
|
||||
|
||||
#GOOGLE RECAPTCHA SITEKEY
|
||||
REACT_APP_GOOGLE_RECAPTCHA_SITEKEY=6Ld_qKooAAAAADNL1TPzRLmcBA8vlpvx__39Rj39
|
||||
#6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI
|
||||
+8
-1
@@ -52,4 +52,11 @@ REACT_APP_MAX_CREDIT_BANK_ACCOUNT=4
|
||||
|
||||
REACT_APP_MAX_FAMILY_MEMBERS=8
|
||||
|
||||
REACT_APP_SHOW_OFFER_GROUP_JOB=0
|
||||
REACT_APP_SHOW_OFFER_GROUP_JOB=0
|
||||
|
||||
#UPLOAD PROFILE PICTURE
|
||||
REACT_APP_SHOW_UPLOAD_PROFILE_PICTURE=0
|
||||
|
||||
#GOOGLE RECAPTCHA SITEKEY
|
||||
REACT_APP_GOOGLE_RECAPTCHA_SITEKEY=6Ld_qKooAAAAADNL1TPzRLmcBA8vlpvx__39Rj39
|
||||
#6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI
|
||||
@@ -59,3 +59,10 @@ REACT_APP_MAX_CREDIT_BANK_ACCOUNT=4
|
||||
REACT_APP_MAX_FAMILY_MEMBERS=8
|
||||
|
||||
REACT_APP_SHOW_OFFER_GROUP_JOB=0
|
||||
|
||||
#UPLOAD PROFILE PICTURE
|
||||
REACT_APP_SHOW_UPLOAD_PROFILE_PICTURE=0
|
||||
|
||||
#GOOGLE RECAPTCHA SITEKEY
|
||||
REACT_APP_GOOGLE_RECAPTCHA_SITEKEY=6Ld_qKooAAAAADNL1TPzRLmcBA8vlpvx__39Rj39
|
||||
#6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
"react-chartjs-2": "^4.1.0",
|
||||
"react-countup": "^6.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-google-recaptcha": "^3.1.0",
|
||||
"react-qr-code": "^2.0.11",
|
||||
"react-redux": "^8.0.5",
|
||||
"react-router-dom": "^6.0.2",
|
||||
|
||||
@@ -24,7 +24,7 @@ const ForgetPwdResponse = ({title, message, type}) => {
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => navigate("/login")}
|
||||
className={`rounded-[0.475rem] mb-6 text-[15px] font-semibold text-white flex justify-center bg-[#4687ba] hover:bg-[#009ef7] transition-all duration-300 items-center py-[0.8875rem] px-[1.81rem]`}
|
||||
className={`h-[48px] rounded-full mb-6 text-[15px] font-semibold text-white flex justify-center bg-[#4687ba] hover:bg-[#009ef7] transition-all duration-300 items-center py-[0.8875rem] px-[1.81rem]`}
|
||||
>
|
||||
<span>Home</span>
|
||||
</button>
|
||||
|
||||
@@ -7,6 +7,8 @@ import AuthLayout from "../AuthLayout";
|
||||
import EmailValidator from "../../../lib/EmailValidator";
|
||||
import ForgetPwdResponse from "../ForgetPwdResponse";
|
||||
|
||||
import ReCAPTCHA from "react-google-recaptcha";
|
||||
|
||||
export default function ForgotPassword() {
|
||||
const [checked, setValue] = useState(false);
|
||||
const [resetLoading, setResetLoading] = useState(false);
|
||||
@@ -22,9 +24,18 @@ export default function ForgotPassword() {
|
||||
setMail(e?.target.value);
|
||||
};
|
||||
|
||||
const humanChecker = () => {
|
||||
setValue(!checked);
|
||||
};
|
||||
// const humanChecker = () => {
|
||||
// setValue(!checked);
|
||||
// };
|
||||
|
||||
function humanChecker(value) {
|
||||
// console.log("Captcha value:", value);
|
||||
if(value){
|
||||
setValue(true)
|
||||
}else{
|
||||
setValue(false)
|
||||
}
|
||||
}
|
||||
|
||||
const resetHandler = async () => {
|
||||
if (email == "") {
|
||||
@@ -113,10 +124,16 @@ export default function ForgotPassword() {
|
||||
/>
|
||||
</div>
|
||||
{/* hCaptha clone for the time being */}
|
||||
<div className="mb-10">
|
||||
<div className="mb-10 flex justify-center w-full">
|
||||
<ReCAPTCHA
|
||||
sitekey={process.env.REACT_APP_GOOGLE_RECAPTCHA_SITEKEY}
|
||||
onChange={humanChecker}
|
||||
/>
|
||||
</div>
|
||||
{/* <div className="mb-10">
|
||||
<div className="w-[303px] h-[78px] mx-auto overflow-hidden">
|
||||
<div className="w-[300px] h-[74px] bg-white bottom-[1px] rounded border-gray-100 overflow-hidden cursor-pointer">
|
||||
{/* Checkbox */}
|
||||
|
||||
<div className="h-full relative inline-block">
|
||||
<div className="relative table top-0 h-full">
|
||||
<div className="table-cell align-middle">
|
||||
@@ -148,18 +165,25 @@ export default function ForgotPassword() {
|
||||
<div className="h-full relative inline-block w-16"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> */}
|
||||
{msgError && (
|
||||
<div className="relative p-4 text-[#912741] bg-[#fcd9e2] border-[#fbc6d3] mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]">
|
||||
{msgError}
|
||||
</div>
|
||||
)}
|
||||
<div className="signin-area mb-3.5">
|
||||
<div className="flex justify-center items-center gap-2">
|
||||
<div className="flex justify-center items-center gap-4">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => navigate("/login")}
|
||||
className={`h-[48px] rounded-full mb-6 text-[15px] font-semibold text-white hover:text-white flex justify-center bg-red-500 hover:bg-red-600 transition-all duration-300 items-center py-[0.8875rem] px-[1.8125rem] `}
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={resetHandler}
|
||||
className={`rounded-[0.475rem] mb-6 text-[15px] font-semibold text-white flex justify-center bg-[#4687ba] hover:bg-[#009ef7] transition-all duration-300 items-center py-[0.8875rem] px-[1.81rem]`}
|
||||
className={`h-[48px] rounded-full mb-6 text-[15px] font-semibold text-white flex justify-center bg-[#4687ba] hover:bg-[#009ef7] transition-all duration-300 items-center py-[0.8875rem] px-[1.81rem]`}
|
||||
>
|
||||
{resetLoading ? (
|
||||
<div className="signup btn-loader"></div>
|
||||
@@ -167,13 +191,6 @@ export default function ForgotPassword() {
|
||||
<span>Send Code</span>
|
||||
)}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => navigate("/login")}
|
||||
className={`rounded-[0.475rem] mb-6 text-[15px] font-semibold text-[#009ef7] hover:text-white flex justify-center bg-[#f1faff] hover:bg-[#009ef7] transition-all duration-300 items-center py-[0.8875rem] px-[1.8125rem] `}
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -14,10 +14,14 @@ import { useGoogleLogin } from "@react-oauth/google";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { updateUserDetails } from "../../../store/UserDetails";
|
||||
|
||||
import ReCAPTCHA from "react-google-recaptcha";
|
||||
|
||||
export default function Login() {
|
||||
const dispatch = useDispatch();
|
||||
const { state } = useLocation();
|
||||
|
||||
const [validCaptcha, setValidCaptcha] = useState({show: false, valid:''}); // FOR CAPTCHA
|
||||
|
||||
let [loginType, setLoginType] = useState("");
|
||||
|
||||
const [loginLoading, setLoginLoading] = useState(false);
|
||||
@@ -107,6 +111,14 @@ export default function Login() {
|
||||
}, Number(process.env.REACT_APP_LOGIN_ERROR_TIMEOUT));
|
||||
return;
|
||||
}
|
||||
if(name == "full" && !validCaptcha.valid && validCaptcha.show){ // RUNS AND DISPLAYS CAPTCHA, IF ERROR OCCURED DURING LOGIN FOR FULL LOGIN ALONE
|
||||
setMsgError("Please Verify Captcha");
|
||||
setLoginLoading(false);
|
||||
setTimeout(() => {
|
||||
setMsgError("");
|
||||
}, Number(process.env.REACT_APP_LOGIN_ERROR_TIMEOUT));
|
||||
return;
|
||||
}
|
||||
userApi
|
||||
.logInUser(postData)
|
||||
.then((res) => {
|
||||
@@ -120,6 +132,7 @@ export default function Login() {
|
||||
// setMsgError("Wrong, email/password");
|
||||
setLoginError(true);
|
||||
setLoginLoading(false);
|
||||
setValidCaptcha(prev => ({...prev, show:true})) // DISPLAYS CAPTCHA IF ERROR
|
||||
return;
|
||||
}
|
||||
localStorage.setItem("member_id", `${res.data.member_id}`);
|
||||
@@ -135,6 +148,7 @@ export default function Login() {
|
||||
.catch((error) => {
|
||||
setMsgError("Unable to login, try again");
|
||||
setLoginLoading(false);
|
||||
setValidCaptcha(prev => ({...prev, show:true})) // DISPLAYS CAPTCHA IF ERROR
|
||||
})
|
||||
.finally(() => {
|
||||
setTimeout(() => {
|
||||
@@ -145,6 +159,14 @@ export default function Login() {
|
||||
});
|
||||
};
|
||||
|
||||
function captchaChecker(value) { // FUNCTION TO VALIDATE CAPTCHA
|
||||
if(value){
|
||||
setValidCaptcha({show: true, valid:value})
|
||||
}else{
|
||||
setValidCaptcha({show: true, valid:''})
|
||||
}
|
||||
}
|
||||
|
||||
const googleLogin = useGoogleLogin({
|
||||
flow: "auth-code",
|
||||
ux_mode: "redirect",
|
||||
@@ -296,6 +318,17 @@ export default function Login() {
|
||||
forgotPassword
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* hCaptha clone for the time being */}
|
||||
{validCaptcha.show &&
|
||||
<div className="mb-5 flex justify-center w-full">
|
||||
<ReCAPTCHA
|
||||
sitekey={process.env.REACT_APP_GOOGLE_RECAPTCHA_SITEKEY}
|
||||
onChange={captchaChecker}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
|
||||
{loginError && (
|
||||
<div className="relative p-4 text-[#912741] bg-[#fcd9e2] border-[#fbc6d3] mb-4 rounded-[0.475rem] text-md font-thin leading-[19.5px] text-[13px]">
|
||||
Invalid username or password- Please{" "}
|
||||
@@ -320,7 +353,7 @@ export default function Login() {
|
||||
onClick={doLogin}
|
||||
type="button"
|
||||
disabled={loginLoading}
|
||||
className={`btn-login rounded-[0.475rem] mb-6 text-xl text-white flex justify-center bg-[#4687ba] hover:bg-[#009ef7] transition-all duration-300 items-center text-[15px]`}
|
||||
className={`btn-login rounded-full mb-6 text-xl text-white flex justify-center bg-[#4687ba] hover:bg-[#009ef7] transition-all duration-300 items-center text-[15px]`}
|
||||
>
|
||||
{loginLoading ? (
|
||||
<div className="signup btn-loader"></div>
|
||||
@@ -433,7 +466,7 @@ export default function Login() {
|
||||
onClick={doLogin}
|
||||
disabled={loginLoading}
|
||||
type="button"
|
||||
className={`btn-login rounded-[0.475rem] text-xl text-white flex justify-center bg-[#4687ba] hover:bg-[#009ef7] transition-all duration-300 items-center text-[15px]`}
|
||||
className={`btn-login rounded-full text-xl text-white flex justify-center bg-[#4687ba] hover:bg-[#009ef7] transition-all duration-300 items-center text-[15px]`}
|
||||
>
|
||||
{loginLoading ? (
|
||||
<div className="signup btn-loader"></div>
|
||||
|
||||
@@ -325,7 +325,7 @@ export default function SignUp() {
|
||||
disabled={countries.loading}
|
||||
type="button"
|
||||
onClick={handleSignUp}
|
||||
className={`rounded-[0.475rem] mb-6 text-white flex justify-center bg-[#4687ba] hover:bg-[#009ef7] transition-all duration-300 items-center h-[42px] py-[0.8875rem] px-[1.81rem] text-[14.95px] btn-login`}
|
||||
className={`rounded-full mb-6 text-white flex justify-center bg-[#4687ba] hover:bg-[#009ef7] transition-all duration-300 items-center h-[42px] py-[0.8875rem] px-[1.81rem] text-[14.95px] btn-login`}
|
||||
>
|
||||
{signUpLoading ? (
|
||||
<div className="signup btn-loader"></div>
|
||||
|
||||
@@ -7,7 +7,7 @@ import React, {
|
||||
useState,
|
||||
} from "react";
|
||||
import { useReactToPrint } from "react-to-print";
|
||||
import profile from "../../assets/images/profile-info-profile.png";
|
||||
import profile from "../../assets/images/icons/family.svg";
|
||||
import localImgLoad from "../../lib/localImgLoad";
|
||||
import usersService from "../../services/UsersService";
|
||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||
@@ -51,6 +51,8 @@ export default function FamilyManageTabs({
|
||||
});
|
||||
};
|
||||
|
||||
const [updatePage, setUpdatePage] = useState(false) // State to determine when to update the page
|
||||
|
||||
// State for family task data
|
||||
const [familyTask, setFamilyTask] = useState({ loading: false, data: [] });
|
||||
|
||||
@@ -82,14 +84,29 @@ export default function FamilyManageTabs({
|
||||
profileImgInput.current.click();
|
||||
};
|
||||
|
||||
// Function to handle changes in the profile image input
|
||||
/**
|
||||
* Handles the change event of the profile image input field.
|
||||
* Checks if the selected file exceeds the maximum file size limit and displays an alert if it does.
|
||||
* If the file is within the size limit, it reads the file using the FileReader API and sets the profile image state with the result.
|
||||
*/
|
||||
const profileImgChangeHandler = (e) => {
|
||||
if (e.target.value !== "") {
|
||||
const MAX_FILE_SIZE = 5 * 1024 * 1024; // 5MB
|
||||
|
||||
const file = e.target.files[0];
|
||||
if (file && file.size > MAX_FILE_SIZE) {
|
||||
alert("File size exceeds the limit.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (file) {
|
||||
const imgReader = new FileReader();
|
||||
imgReader.onload = (event) => {
|
||||
setProfileImg(event.target.result);
|
||||
imgReader.onload = () => {
|
||||
const imageDataUrl = imgReader.result;
|
||||
|
||||
// Set the profile image
|
||||
setProfileImg(imageDataUrl);
|
||||
};
|
||||
imgReader.readAsDataURL(e.target.files[0]);
|
||||
imgReader.readAsDataURL(file);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -220,7 +237,7 @@ export default function FamilyManageTabs({
|
||||
|
||||
// Invoke the manageFamily function when the component mounts
|
||||
manageFamily();
|
||||
}, []);
|
||||
}, [updatePage]);
|
||||
|
||||
// Effect to manage family tasks
|
||||
useEffect(() => {
|
||||
@@ -356,6 +373,7 @@ export default function FamilyManageTabs({
|
||||
setActiveTask={setActiveTask}
|
||||
activeTask={activeTask}
|
||||
familyDetailsData={details.familyDetails.data}
|
||||
setUpdatePage={setUpdatePage}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -15,6 +15,7 @@ const AssignTaskPopout = React.memo(
|
||||
familyTask,
|
||||
activeTask,
|
||||
setActiveTask,
|
||||
setUpdatePage
|
||||
}) => {
|
||||
const apiCall = new usersService();
|
||||
|
||||
@@ -143,6 +144,7 @@ const AssignTaskPopout = React.memo(
|
||||
status: true,
|
||||
message: "action successful",
|
||||
});
|
||||
setUpdatePage(prev => !prev) // Updates family task page by calling the useeffect hook
|
||||
setTimeout(() => {
|
||||
setRequestStatus({ loading: false, status: false, message: "" });
|
||||
action(); // FUNCTION THAT CLOSES THE MODAL BOX
|
||||
|
||||
@@ -1,26 +1,31 @@
|
||||
import React from "react";
|
||||
import localImgLoad from "../../../lib/localImgLoad";
|
||||
|
||||
|
||||
export default function ProfileInfo({
|
||||
profileImg,
|
||||
profileImgInput,
|
||||
profileImgChangHandler,
|
||||
profileImgChangeHandler,
|
||||
browseProfileImg,
|
||||
accountDetails,
|
||||
}) {
|
||||
// console.log(accountDetails.banner)
|
||||
return (
|
||||
<div className="flex flex-col items-center gap-4">
|
||||
<div className="flex justify-center">
|
||||
<div className="w-full relative">
|
||||
<img
|
||||
src={localImgLoad(`images/icons/${accountDetails.banner}`)}
|
||||
alt=""
|
||||
src={
|
||||
profileImg
|
||||
? profileImg
|
||||
: localImgLoad(`images/icons/${accountDetails.banner}`)
|
||||
}
|
||||
alt="profile"
|
||||
className="sm:w-[180px] sm:h-[180px] w-[120px] h-[120px] rounded-full overflow-hidden object-cover"
|
||||
/>
|
||||
<input
|
||||
ref={profileImgInput}
|
||||
onChange={(e) => profileImgChangHandler(e)}
|
||||
accept="image/*"
|
||||
onChange={profileImgChangeHandler}
|
||||
type="file"
|
||||
className="hidden"
|
||||
/>
|
||||
|
||||
@@ -225,7 +225,7 @@ const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="w-full md:w-[23%] h-full ">
|
||||
<div className="w-full md:w-[23%] h-full flex flex-col">
|
||||
<div className="mx-auto bg-[#f1f8ff] dark:bg-[#C2C8D3] p-4 rounded-md md:min-h-[498px] flex flex-col justify-between">
|
||||
<div className="w-full flex flex-col justify-center py-4 gap-2">
|
||||
<p className="w-full text-slate-900 tracking-wide my-1">
|
||||
@@ -270,7 +270,7 @@ const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
className="self-end w-[150px] mt-2 h-[52px] rounded-md text-base bg-transparent border border-red-500 text-red-500 mx-auto"
|
||||
className="self-center w-[150px] mt-2 h-[48px] rounded-full text-base bg-transparent border border-red-500 text-red-500 mx-auto"
|
||||
name="cancel"
|
||||
onClick={onClose}
|
||||
>
|
||||
|
||||
@@ -118,7 +118,11 @@ function PastDueJobAction({jobDetails}) {
|
||||
<tr>
|
||||
<td>
|
||||
<div className="flex justify-center items-center">
|
||||
<button type="button" onClick={popUpHandler} className="w-[180px] h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white">
|
||||
<button
|
||||
type="button"
|
||||
onClick={popUpHandler}
|
||||
className="px-4 h-[48px] flex justify-center items-center btn-gradient text-base rounded-full text-white"
|
||||
>
|
||||
Cancel or Extend Timeline
|
||||
</button>
|
||||
</div>
|
||||
@@ -230,8 +234,12 @@ function PastDueJobAction({jobDetails}) {
|
||||
|
||||
{/* cancel btn */}
|
||||
<div className='flex justify-end items-center'>
|
||||
<button onClick={popUpHandler} type="button" className="w-20 h-11 flex justify-center items-center border-gradient text-base rounded-full text-white">
|
||||
<span className='text-gradient'>Cancel</span>
|
||||
<button onClick={popUpHandler} type="button"
|
||||
// className="w-20 h-11 flex justify-center items-center border-gradient text-base rounded-full text-white"
|
||||
className='w-[150px] mt-2 h-[48px] rounded-full text-base bg-transparent border border-red-500 text-red-500'
|
||||
>
|
||||
Cancel
|
||||
{/* <span className='text-gradient'>Cancel</span> */}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -12,8 +12,7 @@ function NairaWithdraw({
|
||||
state,
|
||||
setShowConfirmNairaWithdraw,
|
||||
}) {
|
||||
|
||||
let MaxNoOfBanks = process.env.REACT_APP_MAX_CREDIT_BANK_ACCOUNT // HOLDS THE VALUE OF THE MAX NUMBER OF BANKS USER CAN ADD
|
||||
let MaxNoOfBanks = process.env.REACT_APP_MAX_CREDIT_BANK_ACCOUNT; // HOLDS THE VALUE OF THE MAX NUMBER OF BANKS USER CAN ADD
|
||||
const apiCall = new usersService();
|
||||
const [tab, setTab] = useState("previous");
|
||||
let [requestStatus, setRequestStatus] = useState(false);
|
||||
@@ -25,7 +24,9 @@ function NairaWithdraw({
|
||||
recipientID: state?.previousAccount?.recipientID || "",
|
||||
},
|
||||
newAccount: {
|
||||
country: state?.newAccount?.amount || "",
|
||||
country: wallet.walletCountry
|
||||
? wallet.walletCountry[0][0]
|
||||
: wallet.country,
|
||||
bank: state?.newAccount?.amount || "",
|
||||
accountNumber: state?.newAccount?.amount || "",
|
||||
accountType: state?.newAccount?.amount || "",
|
||||
@@ -67,10 +68,14 @@ function NairaWithdraw({
|
||||
|
||||
// Handling card change
|
||||
const handleBankOptions = (event) => {
|
||||
const { value } = event.target;
|
||||
let bankCountry = wallet.walletCountry
|
||||
? wallet.walletCountry[0][0]
|
||||
: wallet.country
|
||||
setBankName((prev) => ({ loading: true, data: [] }));
|
||||
apiCall
|
||||
.getCountryBank({ country: value })
|
||||
.getCountryBank({
|
||||
country: bankCountry
|
||||
})
|
||||
.then((res) => {
|
||||
if (res.data.internal_return < 0) {
|
||||
setBankName((prev) => ({ loading: false, data: [] }));
|
||||
@@ -140,6 +145,7 @@ function NairaWithdraw({
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
handleBankOptions()
|
||||
getCountry(); // TO LOAD LIST COUNTRY
|
||||
getAccountTypes(); // TO LOAD LIST ACCOUNT TYPES
|
||||
}, []);
|
||||
@@ -226,7 +232,7 @@ function NairaWithdraw({
|
||||
setShowConfirmNairaWithdraw({ show: true, state: stateData });
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
|
||||
if (tab === "new") {
|
||||
const { accountNumber, accountType, bank, city, country, state } =
|
||||
values?.newAccount;
|
||||
@@ -281,6 +287,8 @@ function NairaWithdraw({
|
||||
getRecipients();
|
||||
}, []);
|
||||
|
||||
console.log("Testing Wallet Country", wallet?.walletCountry[0][0]);
|
||||
|
||||
return (
|
||||
<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">
|
||||
@@ -424,7 +432,11 @@ function NairaWithdraw({
|
||||
<label
|
||||
onClick={() => setTab("new")}
|
||||
htmlFor="new"
|
||||
className={`cursor-pointer flex items-center gap-1 ${recipients.data.length >= MaxNoOfBanks ? 'pointer-events-none':''}`}
|
||||
className={`cursor-pointer flex items-center gap-1 ${
|
||||
recipients.data.length >= MaxNoOfBanks
|
||||
? "pointer-events-none"
|
||||
: ""
|
||||
}`}
|
||||
>
|
||||
<input
|
||||
id="new"
|
||||
@@ -436,7 +448,12 @@ function NairaWithdraw({
|
||||
tab == "new" ? "" : ""
|
||||
} tracking-wide transition duration-200`}
|
||||
/>
|
||||
New Account{" "} {recipients.data.length >= MaxNoOfBanks && <span className="text-[14px] text-red-500">Max Reached</span>}
|
||||
New Account{" "}
|
||||
{recipients.data.length >= MaxNoOfBanks && (
|
||||
<span className="text-[14px] text-red-500">
|
||||
Max Reached
|
||||
</span>
|
||||
)}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
@@ -523,12 +540,12 @@ function NairaWithdraw({
|
||||
</>
|
||||
)}
|
||||
|
||||
{tab == "new" && (
|
||||
recipients.loading ?
|
||||
{tab == "new" &&
|
||||
(recipients.loading ? (
|
||||
<div className="mt-3 flex flex-col w-full h-[188px] justify-center items-center">
|
||||
<LoadingSpinner size='10' color='sky-blue' />
|
||||
<LoadingSpinner size="10" color="sky-blue" />
|
||||
</div>
|
||||
:recipients.data.length < MaxNoOfBanks ?
|
||||
) : recipients.data.length < MaxNoOfBanks ? (
|
||||
<div className="w-full mt-3 rounded-md bg-slate-100">
|
||||
<div className="relative fields w-full flex flex-col p-4">
|
||||
<div className="flex flex-[2] min-h-[52px]">
|
||||
@@ -541,7 +558,12 @@ function NairaWithdraw({
|
||||
Country{" "}
|
||||
<span className="text-red-500">*</span>
|
||||
</label>
|
||||
<select
|
||||
<div className="w-full text-base p-2 text-dark-gray dark:text-white border border-slate-300 outline-0 flex-[0.6] rounded-full h-[42px] overflow-hidden relative font-medium leading-6 bg-clip-padding tracking-[1.5px] flex items-center pointer-events-none">
|
||||
<span className="text-slate-500 text-lg italic">
|
||||
{wallet.walletCountry[0][1]}
|
||||
</span>
|
||||
</div>
|
||||
{/* <select
|
||||
className="w-full text-base p-2 text-dark-gray dark:text-white border border-slate-300 outline-0 flex-[0.6] rounded-full h-[42px] overflow-hidden relative font-medium leading-6 bg-clip-padding tracking-[1.5px]"
|
||||
name="newAccount.country"
|
||||
value={props.values.newAccount?.country}
|
||||
@@ -552,7 +574,7 @@ function NairaWithdraw({
|
||||
>
|
||||
{allCountries.loading ? (
|
||||
<option
|
||||
className="text-slate-500 text-lg"
|
||||
className="text-slate-500 text-lg"
|
||||
value=""
|
||||
>
|
||||
Loading...
|
||||
@@ -585,13 +607,7 @@ function NairaWithdraw({
|
||||
No Options Found!
|
||||
</option>
|
||||
)}
|
||||
</select>
|
||||
{/* {props.errors.country &&
|
||||
props.touched.country && (
|
||||
<p className="text-sm text-red-500">
|
||||
{props.errors.country}
|
||||
</p>
|
||||
)} */}
|
||||
</select> */}
|
||||
</div>
|
||||
|
||||
{/* bank name */}
|
||||
@@ -646,11 +662,6 @@ function NairaWithdraw({
|
||||
</option>
|
||||
)}
|
||||
</select>
|
||||
{/* {props.errors.bank && props.touched.bank && (
|
||||
<p className="text-sm text-red-500">
|
||||
{props.errors.bank}
|
||||
</p>
|
||||
)} */}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -671,16 +682,12 @@ function NairaWithdraw({
|
||||
name="newAccount.accountNumber"
|
||||
placeholder="Account No"
|
||||
maxLength={10}
|
||||
value={props.values.newAccount?.accountNumber}
|
||||
value={
|
||||
props.values.newAccount?.accountNumber
|
||||
}
|
||||
inputHandler={props.handleChange}
|
||||
blurHandler={props.handleBlur}
|
||||
/>
|
||||
{/* {props.errors.accountNumber &&
|
||||
props.touched.accountNumber && (
|
||||
<p className="text-sm text-red-500">
|
||||
{props.errors.accountNumber}
|
||||
</p>
|
||||
)} */}
|
||||
</div>
|
||||
|
||||
{/* Account Type */}
|
||||
@@ -732,12 +739,6 @@ function NairaWithdraw({
|
||||
</option>
|
||||
)}
|
||||
</select>
|
||||
{/* {props.errors.accountType &&
|
||||
props.touched.accountType && (
|
||||
<p className="text-sm text-red-500">
|
||||
{props.errors.accountType}
|
||||
</p>
|
||||
)} */}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -748,7 +749,8 @@ function NairaWithdraw({
|
||||
htmlFor="newAccount.state"
|
||||
className="input-label text-[#181c32] dark:text-white text-base font-semibold inline-flex flex-[0.4]"
|
||||
>
|
||||
State <span className="text-red-500">*</span>
|
||||
State{" "}
|
||||
<span className="text-red-500">*</span>
|
||||
</label>
|
||||
<InputCom
|
||||
fieldClass="px-6 tracking-[1.5px]"
|
||||
@@ -760,11 +762,6 @@ function NairaWithdraw({
|
||||
inputHandler={props.handleChange}
|
||||
blurHandler={props.handleBlur}
|
||||
/>
|
||||
{/* {props.errors.state && props.touched.state && (
|
||||
<p className="text-sm text-red-500">
|
||||
{props.errors.state}
|
||||
</p>
|
||||
)} */}
|
||||
</div>
|
||||
|
||||
{/* city */}
|
||||
@@ -785,20 +782,15 @@ function NairaWithdraw({
|
||||
inputHandler={props.handleChange}
|
||||
blurHandler={props.handleBlur}
|
||||
/>
|
||||
{/* {props.errors.city && props.touched.city && (
|
||||
<p className="text-sm text-red-500">
|
||||
{props.errors.city}
|
||||
</p>
|
||||
)} */}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* end of inputs for new accounts */}
|
||||
</div>
|
||||
</div>
|
||||
:
|
||||
) : (
|
||||
<div className="mt-3 flex w-full h-[188px] justify-center items-center"></div>
|
||||
)}
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="transfer-fund-btn flex justify-end items-center gap-2 py-4">
|
||||
|
||||
@@ -5,7 +5,6 @@ import Layout from "../Partials/Layout";
|
||||
import LoadingSpinner from "../Spinners/LoadingSpinner";
|
||||
const WalletBox = lazy(() => import("./WalletBox"));
|
||||
|
||||
|
||||
const WalletRoutes = () => {
|
||||
const apiCall = new usersService();
|
||||
const { walletDetails } = useSelector((state) => state?.walletDetails); // WALLET STORE
|
||||
@@ -16,6 +15,12 @@ const WalletRoutes = () => {
|
||||
data: [],
|
||||
});
|
||||
|
||||
const [allCountries, setAllCountries] = useState({
|
||||
// STATE TO HOLD LIST OF COUNTRIES
|
||||
loading: true,
|
||||
data: [],
|
||||
});
|
||||
|
||||
const getPaymentHistory = () => {
|
||||
apiCall
|
||||
.getPaymentHx()
|
||||
@@ -31,14 +36,45 @@ const WalletRoutes = () => {
|
||||
});
|
||||
};
|
||||
|
||||
// FUNCTION TO GET COUNTRIES
|
||||
const getCountry = () => {
|
||||
apiCall
|
||||
.getSignupCountryData()
|
||||
.then((res) => {
|
||||
if (res.data.internal_return < 0) {
|
||||
setAllCountries((prev) => ({ loading: false, data: [] }));
|
||||
return;
|
||||
}
|
||||
setAllCountries((prev) => ({
|
||||
loading: false,
|
||||
data: res.data.signup_country,
|
||||
}));
|
||||
})
|
||||
.catch((error) => {
|
||||
setAllCountries((prev) => ({ loading: false, data: [] }));
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
getCountry();
|
||||
getPaymentHistory();
|
||||
}, [walletTable]);
|
||||
|
||||
console.log(
|
||||
"Testing all country: ",
|
||||
allCountries,
|
||||
"Testing wallet: ",
|
||||
walletDetails
|
||||
);
|
||||
|
||||
return (
|
||||
<Layout>
|
||||
<Suspense fallback={<LoadingSpinner size="16" color="sky-blue" />}>
|
||||
<WalletBox wallet={walletDetails} payment={paymentHistory} />
|
||||
<WalletBox
|
||||
wallet={walletDetails}
|
||||
payment={paymentHistory}
|
||||
countries={allCountries.data}
|
||||
/>
|
||||
</Suspense>
|
||||
</Layout>
|
||||
);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useCallback, useState } from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import usersService from "../../services/UsersService";
|
||||
import ConfirmNairaWithdraw from "./Popup/ConfirmNairaWithdraw";
|
||||
import NairaWithdraw from "./Popup/NairaWithdraw";
|
||||
@@ -8,7 +8,7 @@ function WalletAction({ walletItem, payment, openPopUp }) {
|
||||
show: false,
|
||||
state: {},
|
||||
}); // DETERMINES WHEN NAIRA WITHDRAWAL POPS UP
|
||||
|
||||
|
||||
const [showConfirmNairaWithdraw, setShowConfirmNairaWithdraw] = useState({
|
||||
show: false,
|
||||
state: {},
|
||||
|
||||
@@ -4,7 +4,7 @@ import WalletItemCard from "./WalletItemCard";
|
||||
/**
|
||||
* Renders a list of wallet items or a loading spinner depending on the state of the `wallet` object.
|
||||
*/
|
||||
export default function WalletBox({ wallet, payment }) {
|
||||
export default function WalletBox({ wallet, payment, countries }) {
|
||||
const { loading, data } = wallet;
|
||||
|
||||
return (
|
||||
@@ -18,7 +18,7 @@ export default function WalletBox({ wallet, payment }) {
|
||||
) : (
|
||||
data.length > 0 && data.map((item) => (
|
||||
<div key={item.wallet_uid} className="lg:w-full h-full mb-10 lg:mb-0">
|
||||
<WalletItemCard walletItem={item} payment={payment} />
|
||||
<WalletItemCard walletItem={item} payment={payment} countries={countries} />
|
||||
</div>
|
||||
))
|
||||
)}
|
||||
|
||||
@@ -10,7 +10,7 @@ import WalletAction from "./WalletAction";
|
||||
/**
|
||||
* Renders a card displaying information about a wallet item.
|
||||
*/
|
||||
export default function WalletItemCard({ walletItem, payment }) {
|
||||
export default function WalletItemCard({ walletItem, payment, countries }) {
|
||||
const { userDetails } = useSelector((state) => state.userDetails);
|
||||
const accountType = userDetails?.account_type === "FAMILY";
|
||||
const dispatch = useDispatch();
|
||||
@@ -35,10 +35,15 @@ export default function WalletItemCard({ walletItem, payment }) {
|
||||
dispatch(tableReload({ type: "WALLETTABLE" }));
|
||||
};
|
||||
|
||||
const currentWalletCurrency = countries
|
||||
.map((country) => country)
|
||||
.filter((country) => country[0] === walletItem.country);
|
||||
|
||||
const image = walletItem.code
|
||||
? `${walletItem.code.toLowerCase()}.svg`
|
||||
: "default.png";
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
@@ -88,7 +93,7 @@ export default function WalletItemCard({ walletItem, payment }) {
|
||||
|
||||
{!accountType && (
|
||||
<WalletAction
|
||||
walletItem={walletItem}
|
||||
walletItem={{ ...walletItem, walletCountry: currentWalletCurrency }}
|
||||
payment={payment}
|
||||
openPopUp={openPopUp}
|
||||
/>
|
||||
|
||||
@@ -51,6 +51,7 @@ export default function PersonalInfoTab({
|
||||
coverImgInput,
|
||||
browseCoverImg,
|
||||
coverImgChangHandler,
|
||||
uploadStatus
|
||||
}) {
|
||||
let { userDetails } = useSelector((state) => state.userDetails);
|
||||
|
||||
@@ -361,63 +362,67 @@ export default function PersonalInfoTab({
|
||||
{/* inputs ends here */}
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-[232px] mb-10">
|
||||
<div className="update-profile w-full mb-9">
|
||||
<h1 className="text-xl tracking-wide font-bold text-dark-gray dark:text-white flex items-center mb-2">
|
||||
Update Profile
|
||||
<span className="ml-1">
|
||||
<Icons name="block-question" />
|
||||
</span>
|
||||
</h1>
|
||||
<p className="text-base text-thin-light-gray mb-5">
|
||||
Profile of at least Size
|
||||
<span className="ml-1 text-dark-gray dark:text-white">
|
||||
300x300
|
||||
</span>
|
||||
. Gifs work too.
|
||||
<span className="ml-1 text-dark-gray dark:text-white">
|
||||
Max 5mb
|
||||
</span>
|
||||
.
|
||||
</p>
|
||||
<div className="flex justify-center">
|
||||
<div className="w-full relative">
|
||||
<img
|
||||
src={profileImg}
|
||||
alt="profile"
|
||||
className="sm:w-[198px] sm:h-[198px] w-[120px] h-[120px] rounded-full overflow-hidden object-contain object-center"
|
||||
/>
|
||||
<input
|
||||
ref={profileImgInput}
|
||||
onChange={(e) => profileImgChangHandler(e)}
|
||||
type="file"
|
||||
className="hidden"
|
||||
/>
|
||||
<div
|
||||
onClick={browseProfileImg}
|
||||
className="w-[32px] h-[32px] absolute bottom-7 sm:right-10 right-[105px] hover:bg-pink bg-dark-gray rounded-full cursor-pointer"
|
||||
>
|
||||
<svg
|
||||
width="32"
|
||||
height="32"
|
||||
viewBox="0 0 32 32"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
{/* {process.env.REACT_APP_SHOW_UPLOAD_PROFILE_PICTURE != 0 && */}
|
||||
<div className="w-[232px] mb-10">
|
||||
<div className="update-profile w-full mb-9">
|
||||
<h1 className="text-xl tracking-wide font-bold text-dark-gray dark:text-white flex items-center mb-2">
|
||||
Update Profile
|
||||
<span className="ml-1">
|
||||
<Icons name="block-question" />
|
||||
</span>
|
||||
</h1>
|
||||
<p className="text-base text-thin-light-gray mb-5">
|
||||
Profile of at least Size
|
||||
<span className="ml-1 text-dark-gray dark:text-white">
|
||||
300x300
|
||||
</span>
|
||||
. Gifs work too.
|
||||
<span className="ml-1 text-dark-gray dark:text-white">
|
||||
Max 5mb
|
||||
</span>
|
||||
.
|
||||
</p>
|
||||
<div className="flex justify-center">
|
||||
<div className="w-full relative">
|
||||
<img
|
||||
src={profileImg}
|
||||
alt="profile"
|
||||
className="sm:w-[198px] sm:h-[198px] w-[120px] h-[120px] rounded-full overflow-hidden object-contain object-center"
|
||||
/>
|
||||
<input
|
||||
ref={profileImgInput}
|
||||
onChange={(e) => profileImgChangHandler(e)}
|
||||
type="file"
|
||||
className="hidden"
|
||||
/>
|
||||
<div
|
||||
onClick={browseProfileImg}
|
||||
className="w-[32px] h-[32px] absolute bottom-7 sm:right-10 right-[105px] hover:bg-pink bg-dark-gray rounded-full cursor-pointer"
|
||||
>
|
||||
<path
|
||||
d="M16.5147 11.5C17.7284 12.7137 18.9234 13.9087 20.1296 15.115C19.9798 15.2611 19.8187 15.4109 19.6651 15.5683C17.4699 17.7635 15.271 19.9587 13.0758 22.1539C12.9334 22.2962 12.7948 22.4386 12.6524 22.5735C12.6187 22.6034 12.5663 22.6296 12.5213 22.6296C11.3788 22.6334 10.2362 22.6297 9.09365 22.6334C9.01498 22.6334 9 22.6034 9 22.536C9 21.4009 9 20.2621 9.00375 19.1271C9.00375 19.0746 9.02997 19.0109 9.06368 18.9772C10.4123 17.6249 11.7609 16.2763 13.1095 14.9277C14.2295 13.8076 15.3459 12.6913 16.466 11.5712C16.4884 11.5487 16.4997 11.5187 16.5147 11.5Z"
|
||||
fill="white"
|
||||
/>
|
||||
<path
|
||||
d="M20.9499 14.2904C19.7436 13.0842 18.5449 11.8854 17.3499 10.6904C17.5634 10.4694 17.7844 10.2446 18.0054 10.0199C18.2639 9.76139 18.5261 9.50291 18.7884 9.24443C19.118 8.91852 19.5713 8.91852 19.8972 9.24443C20.7251 10.0611 21.5492 10.8815 22.3771 11.6981C22.6993 12.0165 22.7105 12.4698 22.3996 12.792C21.9238 13.2865 21.4443 13.7772 20.9686 14.2717C20.9648 14.2792 20.9536 14.2867 20.9499 14.2904Z"
|
||||
fill="white"
|
||||
/>
|
||||
</svg>
|
||||
<svg
|
||||
width="32"
|
||||
height="32"
|
||||
viewBox="0 0 32 32"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M16.5147 11.5C17.7284 12.7137 18.9234 13.9087 20.1296 15.115C19.9798 15.2611 19.8187 15.4109 19.6651 15.5683C17.4699 17.7635 15.271 19.9587 13.0758 22.1539C12.9334 22.2962 12.7948 22.4386 12.6524 22.5735C12.6187 22.6034 12.5663 22.6296 12.5213 22.6296C11.3788 22.6334 10.2362 22.6297 9.09365 22.6334C9.01498 22.6334 9 22.6034 9 22.536C9 21.4009 9 20.2621 9.00375 19.1271C9.00375 19.0746 9.02997 19.0109 9.06368 18.9772C10.4123 17.6249 11.7609 16.2763 13.1095 14.9277C14.2295 13.8076 15.3459 12.6913 16.466 11.5712C16.4884 11.5487 16.4997 11.5187 16.5147 11.5Z"
|
||||
fill="white"
|
||||
/>
|
||||
<path
|
||||
d="M20.9499 14.2904C19.7436 13.0842 18.5449 11.8854 17.3499 10.6904C17.5634 10.4694 17.7844 10.2446 18.0054 10.0199C18.2639 9.76139 18.5261 9.50291 18.7884 9.24443C19.118 8.91852 19.5713 8.91852 19.8972 9.24443C20.7251 10.0611 21.5492 10.8815 22.3771 11.6981C22.6993 12.0165 22.7105 12.4698 22.3996 12.792C21.9238 13.2865 21.4443 13.7772 20.9686 14.2717C20.9648 14.2792 20.9536 14.2867 20.9499 14.2904Z"
|
||||
fill="white"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{uploadStatus.message && !uploadStatus.loading && <p className={`text-center ${uploadStatus.status ? 'text-green-500':'text-red-500'}`}>{uploadStatus.message}</p>}
|
||||
{uploadStatus.loading && <p className="text-center">{uploadStatus.message}</p>}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* } */}
|
||||
</div>
|
||||
|
||||
<div className="content-footer w-full">
|
||||
|
||||
@@ -24,10 +24,12 @@ import {
|
||||
import RecipientAccountTab from "./Tabs/RecipientAccountTab";
|
||||
|
||||
export default function Settings({ faq }) {
|
||||
const apiCall = new usersService();
|
||||
const { userDetails } = useSelector((state) => state?.userDetails);
|
||||
const [profileImg, setProfileImg] = useState(
|
||||
userDetails?.profile_pic_url ? userDetails.profile_pic_url : profile
|
||||
);
|
||||
let [uploadStatus, setUploadStatus] = useState({loading: false, status: false, message:''}) // HOLDS STATE FOR UPLOAD PROFILE PICTURE STATUS
|
||||
const [coverImg, setCoverImg] = useState(cover);
|
||||
const [reloadCardList, setReloadCardList] = useState(false); // STATE TO DETERMINE WHEN CARD LIST RELOADS. EG: WHEN USER DELETES A CARD
|
||||
|
||||
@@ -36,12 +38,68 @@ export default function Settings({ faq }) {
|
||||
const browseProfileImg = () => {
|
||||
profileImgInput.current.click();
|
||||
};
|
||||
|
||||
const profileImgChangHandler = (e) => {
|
||||
// if (e.target.value !== "") {
|
||||
// const imgReader = new FileReader();
|
||||
// imgReader.onload = (event) => {
|
||||
// setProfileImg(event.target.result);
|
||||
// };
|
||||
// imgReader.readAsDataURL(e.target.files[0]);
|
||||
// }
|
||||
setUploadStatus({loading: false, status: false, message:''})
|
||||
let acceptedFormat = ["jpeg", "jpg", "png", "bmp", "gif"] // ARRAY OF SUPPORTED FORMATS
|
||||
let uploadedFile = e.target.files[0] //UPLOADED FILE
|
||||
|
||||
if(!acceptedFormat.includes(uploadedFile?.type?.split("/")[1]?.toLowerCase())){ //CHECKING FOR CORRECT UPLOAD FORMAT
|
||||
let msg = 'Please select '
|
||||
for(let i=0; i<=acceptedFormat.length-1; i++){
|
||||
if(i == acceptedFormat.length-1){
|
||||
msg+=`or ${acceptedFormat[i]}`
|
||||
}else{
|
||||
msg+=`${acceptedFormat[i]}, `
|
||||
}
|
||||
}
|
||||
setUploadStatus({loading: false, status: false, message:msg})
|
||||
return setTimeout(()=>{
|
||||
profileImgInput.current.value = '' // clear the input
|
||||
setUploadStatus({loading: false, status: false, message:''})
|
||||
},5000)
|
||||
}
|
||||
|
||||
if(uploadedFile.size > 5*1048576){ // CHECKING FOR CORRECT FILE SIZE
|
||||
setUploadStatus({loading: false, status: false, message:'File must not exceed 5MB'})
|
||||
return setTimeout(()=>{
|
||||
profileImgInput.current.value = '' // clear the input
|
||||
setUploadStatus({loading: false, status: false, message:''})
|
||||
},5000)
|
||||
}
|
||||
|
||||
if (e.target.value !== "") {
|
||||
const imgReader = new FileReader();
|
||||
imgReader.onload = (event) => {
|
||||
setProfileImg(event.target.result);
|
||||
let reqData = { // PAYLOAD FOR API CALL
|
||||
file_name: uploadedFile?.name,
|
||||
file_size: uploadedFile?.size,
|
||||
file_type: uploadedFile?.type?.split("/")[0]?.toLowerCase(),
|
||||
file_data: event?.target?.result,
|
||||
msg_type: 'FILE',
|
||||
action: 'WRENCHBOARD_PICTURE_PROFILE',
|
||||
// action: 11307
|
||||
}
|
||||
setUploadStatus({loading: true, status: false, message:'Loading...'})
|
||||
apiCall.sendFiles(reqData).then(res=>{
|
||||
if(res.status != 200 || res.data.internal_return < 0){
|
||||
return setUploadStatus({loading: false, status: false, message: 'Something went wrong, try again'})
|
||||
}
|
||||
setUploadStatus({loading: false, status: true, message: 'Uploaded successfully'})
|
||||
setProfileImg(event.target.result);
|
||||
}).catch(error=>{
|
||||
setUploadStatus({loading: false, status: false, message: 'Network error, try again'})
|
||||
}).finally(()=>{
|
||||
setTimeout(()=>{
|
||||
setUploadStatus({loading: false, status: false, message: ''})
|
||||
},5000)
|
||||
})
|
||||
};
|
||||
imgReader.readAsDataURL(e.target.files[0]);
|
||||
}
|
||||
@@ -61,7 +119,6 @@ export default function Settings({ faq }) {
|
||||
}
|
||||
};
|
||||
|
||||
const apiCall = useMemo(() => new usersService(), []);
|
||||
// Tabs Handling
|
||||
const tabs = [
|
||||
{
|
||||
@@ -113,7 +170,7 @@ export default function Settings({ faq }) {
|
||||
iconName: "page-right",
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
id: 9,
|
||||
name: "terms",
|
||||
title: "Terms and Conditions",
|
||||
iconName: "page-right",
|
||||
@@ -217,6 +274,7 @@ export default function Settings({ faq }) {
|
||||
coverImgChangHandler={coverImgChangHandler}
|
||||
browseCoverImg={browseCoverImg}
|
||||
coverImgInput={coverImgInput}
|
||||
uploadStatus={uploadStatus}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -351,7 +351,7 @@ const EditJobPopOut = ({
|
||||
className="w-[120px] h-[40px] 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'
|
||||
>
|
||||
Edit Job
|
||||
Save
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user