448 lines
19 KiB
React
448 lines
19 KiB
React
import React, { useEffect, useState } from "react";
|
|
import { useNavigate } from "react-router-dom";
|
|
import InputCom from "../../Helpers/Inputs/InputCom";
|
|
import ModalCom from "../../Helpers/ModalCom";
|
|
import LoadingSpinner from "../../Spinners/LoadingSpinner";
|
|
|
|
import usersService from "../../../services/UsersService";
|
|
|
|
import { Form, Formik } from "formik";
|
|
import * as Yup from "yup";
|
|
|
|
const validationSchema = Yup.object().shape({
|
|
amount: Yup.number()
|
|
.typeError("you must specify a number")
|
|
.min(1, "Amount must be greater than 0")
|
|
.required("Amount is required"),
|
|
recipientID: Yup.string()
|
|
.min(1, "Minimum 1 characters")
|
|
.max(50, "Maximum 50 characters")
|
|
.required("Recipient is required"),
|
|
});
|
|
|
|
const initialValues = {
|
|
amount: "",
|
|
recipientID: "",
|
|
comment: "",
|
|
};
|
|
|
|
function NairaWithdraw({
|
|
wallet,
|
|
action,
|
|
situation,
|
|
setShowConfirmNairaWithdraw,
|
|
}) {
|
|
const apiCall = new usersService(); // API CLASS CALL
|
|
const navigate = useNavigate();
|
|
const [tab, setTab] = useState("previous");
|
|
let [requestStatus, setRequestStatus] = useState(false);
|
|
|
|
let [recipients, setRecipients] = useState({
|
|
// FOR COUPON HISTORY
|
|
loading: true,
|
|
data: [],
|
|
error: false,
|
|
});
|
|
|
|
let [sendMoneyFee, setSendMoneyFee] = useState({
|
|
loading: false,
|
|
fee: 0,
|
|
total: 0,
|
|
}); // HOLD THE VALUE FOR walletSEND MONEY FEE
|
|
|
|
//FUNCTION TO GET RECIPIENT LIST
|
|
const getRecipients = () => {
|
|
apiCall
|
|
.getRecipient()
|
|
.then((res) => {
|
|
if (res.data.internal_return < 0) {
|
|
// success but no data
|
|
setRecipients((prev) => ({ ...prev, loading: false }));
|
|
return;
|
|
}
|
|
setRecipients((prev) => ({
|
|
...prev,
|
|
loading: false,
|
|
data: res.data.result_list,
|
|
}));
|
|
})
|
|
.catch((error) => {
|
|
setRecipients((prev) => ({ ...prev, loading: false, error: true }));
|
|
});
|
|
};
|
|
|
|
//FUNCTION TO GET SEND MONEY FEE
|
|
const getSendMoneyFee = ({ target: { value } }) => {
|
|
setSendMoneyFee({ loading: true, fee: 0, total: 0 });
|
|
let amount = value;
|
|
if (Number(amount) <= 0 || amount == "" || isNaN(amount)) {
|
|
setSendMoneyFee({ loading: false, fee: 0, total: 0 });
|
|
return;
|
|
}
|
|
apiCall
|
|
.getSendMoneyFee(Number(amount * 100))
|
|
.then((res) => {
|
|
setSendMoneyFee({
|
|
loading: false,
|
|
fee: res.data.processing_fee,
|
|
total: res.data.total_amount,
|
|
});
|
|
})
|
|
.catch((error) => {
|
|
setSendMoneyFee({ loading: false, fee: 0, total: 0 });
|
|
});
|
|
};
|
|
console.log("TESTING", sendMoneyFee);
|
|
//FUNCTION TO HANDLE SUBMIT
|
|
const handleSubmit = (values, helpers) => {
|
|
if (!values?.amount && !values.recipientID) return;
|
|
setRequestStatus(true);
|
|
let recipientDetails = recipients.data?.filter(
|
|
(item) => item.recipient_id == values.recipientID
|
|
);
|
|
let stateData = {
|
|
...values,
|
|
...sendMoneyFee,
|
|
details: { ...recipientDetails[0] },
|
|
};
|
|
|
|
setTimeout(() => {
|
|
setRequestStatus(false);
|
|
// navigate("confirm-withdraw-naira", { state: stateData });
|
|
action();
|
|
setShowConfirmNairaWithdraw({ show: true, state: stateData });
|
|
}, 1000);
|
|
};
|
|
|
|
useEffect(() => {
|
|
getRecipients();
|
|
}, []);
|
|
|
|
return (
|
|
<ModalCom action={action} situation={situation}>
|
|
<div className="content-wrapper w-[90%] md:w-[600px]">
|
|
<div className="w-full">
|
|
<div className="add-fund w-full md:p-8 p-4 bg-white dark:bg-dark-white rounded-2xl shadow">
|
|
<Formik
|
|
initialValues={initialValues}
|
|
validationSchema={validationSchema}
|
|
onSubmit={handleSubmit}
|
|
>
|
|
{(props) => {
|
|
return (
|
|
<Form className="transfer-fund-info">
|
|
<h2 className="py-2 text-slate-900 dark:text-white text-xl lg:text-2xl font-medium">
|
|
{`Withdraw from ${wallet.description} Wallet : ${
|
|
wallet.symbol
|
|
}${(wallet.amount * 0.01).toFixed(2)}`}
|
|
</h2>
|
|
{/* Amount Form */}
|
|
<div className="flex flex-col">
|
|
<div className="field w-full">
|
|
<InputCom
|
|
fieldClass="px-4"
|
|
parentClass="flex items-center gap-1 justify-between"
|
|
labelClass="flex-[0.2] mb-0"
|
|
inputClass="flex-[0.8] max-w-[12rem]"
|
|
label="Amount:"
|
|
type="number"
|
|
name="amount"
|
|
placeholder="0"
|
|
direction="rtl"
|
|
value={props.values.amount}
|
|
inputHandler={props.handleChange}
|
|
blurHandler={(e) => {
|
|
getSendMoneyFee(e);
|
|
}}
|
|
// props.handleBlur
|
|
// onMouseLeave={(e)=>{getSendMoneyFee(e)}}
|
|
/>
|
|
{props.errors.amount && props.touched.amount && (
|
|
<p className="sm:text-sm text-[12px] text-red-500 sm:text-left text-right sm:translate-y-0 translate-y-1">
|
|
{props.errors.amount}
|
|
</p>
|
|
)}
|
|
</div>
|
|
|
|
<div className="field w-full">
|
|
<InputCom
|
|
fieldClass="px-4 transfer-field"
|
|
parentClass="flex items-center gap-1 justify-between"
|
|
labelClass="flex-[0.2] mb-0"
|
|
inputClass="flex-[0.8] transfer-field max-w-[12rem]"
|
|
label="Fee:"
|
|
type="text"
|
|
name="fee"
|
|
direction="rtl"
|
|
value={
|
|
sendMoneyFee.loading
|
|
? "loading"
|
|
: (sendMoneyFee.fee * 0.01).toFixed(2)
|
|
}
|
|
disable={true}
|
|
/>
|
|
</div>
|
|
|
|
<div className="field w-full">
|
|
<InputCom
|
|
fieldClass="px-4 transfer-field"
|
|
parentClass="flex items-center gap-1 justify-between"
|
|
labelClass="flex-[0.2] mb-0"
|
|
inputClass="flex-[0.8] transfer-field max-w-[12rem]"
|
|
label="Total:"
|
|
type="text"
|
|
name="total"
|
|
direction="rtl"
|
|
value={
|
|
sendMoneyFee.loading
|
|
? "loading"
|
|
: (sendMoneyFee.total * 0.01).toFixed(2)
|
|
}
|
|
disable={true}
|
|
/>
|
|
</div>
|
|
|
|
<div className="field w-full mb-3 flex gap-1 justify-between">
|
|
<label className="text-[#181c32] dark:text-white text-base font-semibold flex flex-[0.2] mt-2.5">
|
|
Comment:
|
|
</label>
|
|
<textarea
|
|
style={{ resize: "none" }}
|
|
className="text-base px-4 py-2 rounded-md sm:max-w-[550px] max-w-[250px] text-dark-gray dark:text-white w-full bg-slate-100 dark:bg-[#11131F] focus:ring-0 focus:outline-none flex-[0.8]"
|
|
name="comment"
|
|
value={props.values.comment}
|
|
onChange={props.handleChange}
|
|
onBlur={props.handleBlur}
|
|
cols="30"
|
|
rows="2"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Account Selector */}
|
|
<div className=" flex items-center gap-[5rem]">
|
|
<h1 className="text-xl font-bold text-dark-gray dark:text-white tracking-tighter my-1">
|
|
To:
|
|
</h1>
|
|
<div className="my-1 flex items-center gap-2">
|
|
<label
|
|
onClick={() => setTab("previous")}
|
|
htmlFor="previous"
|
|
className="cursor-pointer flex items-center gap-1"
|
|
>
|
|
<input
|
|
type="radio"
|
|
id="previous"
|
|
name="card-option"
|
|
checked={tab === "previous"}
|
|
className={`p-2 text-lg font-bold text-slate-600 dark:text-white border pointer-events-none w-7 h-7 ${
|
|
tab == "previous" ? "" : ""
|
|
} tracking-wide transition duration-200`}
|
|
/>
|
|
Previous Account
|
|
</label>
|
|
<label
|
|
onClick={() => setTab("new")}
|
|
htmlFor="new"
|
|
className="cursor-pointer flex items-center gap-1"
|
|
>
|
|
<input
|
|
id="new"
|
|
type="radio"
|
|
name="card-option"
|
|
checked={tab === "new"}
|
|
className={`p-2 text-lg font-bold text-slate-600 dark:text-white border pointer-events-none w-7 h-7 ${
|
|
tab == "new" ? "" : ""
|
|
} tracking-wide transition duration-200`}
|
|
/>
|
|
New Account{" "}
|
|
</label>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="h[150px]">
|
|
{tab == "previous" && (
|
|
<div className="w-full">
|
|
<div className="relative my-3 md:flex items-center">
|
|
<div className="transfer-input w-full flex items-start gap-1 justify-between">
|
|
<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] sm:items-start items-end">
|
|
<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]"
|
|
value={props.values.recipientID}
|
|
name="recipientID"
|
|
onChange={props.handleChange}
|
|
onBlur={props.handleBlur}
|
|
>
|
|
{recipients.loading ? (
|
|
<option
|
|
className="text-slate-500 text-lg"
|
|
value=""
|
|
>
|
|
Loading...
|
|
</option>
|
|
) : recipients.data.length ? (
|
|
<>
|
|
<option
|
|
className="text-slate-500 text-lg"
|
|
value=""
|
|
>
|
|
Select...
|
|
</option>
|
|
{recipients.data.map((item, index) => (
|
|
<option
|
|
key={index}
|
|
value={item.recipient_id}
|
|
className="text-slate-500 text-lg"
|
|
>
|
|
{item.recipient}
|
|
</option>
|
|
))}
|
|
</>
|
|
) : recipients.error ? (
|
|
<option
|
|
className="text-slate-500 text-lg"
|
|
value=""
|
|
>
|
|
Could'nt load, try again!
|
|
</option>
|
|
) : (
|
|
<option
|
|
className="text-slate-500 text-lg"
|
|
value=""
|
|
>
|
|
No Recipient Found!
|
|
</option>
|
|
)}
|
|
</select>
|
|
<div className="flex justify-end relative w-full">
|
|
{props.errors.recipientID &&
|
|
props.touched.recipientID && (
|
|
<p className="sm:text-sm text-[12px] text-red-500 absolute sm:top-1 -top-20 sm:left-0 left-[160px]">
|
|
{props.errors.recipientID}
|
|
</p>
|
|
)}
|
|
{/* <Link
|
|
to="add-recipient"
|
|
className="mx-1 text-base text-white p-2 bg-[orange] rounded-md hover:opacity-80 max-w-[5rem]"
|
|
>
|
|
Add New
|
|
</Link> */}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
{tab == "new" && (
|
|
<div className="w-full">
|
|
<div className="relative my-3 md:flex items-center">
|
|
<div className="transfer-input w-full flex items-start gap-1 justify-between">
|
|
<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] sm:items-start items-end">
|
|
<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]"
|
|
value={props.values.recipientID}
|
|
name="recipientID"
|
|
onChange={props.handleChange}
|
|
onBlur={props.handleBlur}
|
|
>
|
|
{recipients.loading ? (
|
|
<option
|
|
className="text-slate-500 text-lg"
|
|
value=""
|
|
>
|
|
Loading...
|
|
</option>
|
|
) : recipients.data.length ? (
|
|
<>
|
|
<option
|
|
className="text-slate-500 text-lg"
|
|
value=""
|
|
>
|
|
Select...
|
|
</option>
|
|
{recipients.data.map((item, index) => (
|
|
<option
|
|
key={index}
|
|
value={item.recipient_id}
|
|
className="text-slate-500 text-lg"
|
|
>
|
|
{item.recipient}
|
|
</option>
|
|
))}
|
|
</>
|
|
) : recipients.error ? (
|
|
<option
|
|
className="text-slate-500 text-lg"
|
|
value=""
|
|
>
|
|
Could'nt load, try again!
|
|
</option>
|
|
) : (
|
|
<option
|
|
className="text-slate-500 text-lg"
|
|
value=""
|
|
>
|
|
No Recipient Found!
|
|
</option>
|
|
)}
|
|
</select>
|
|
<div className="flex justify-end relative w-full">
|
|
{props.errors.recipientID &&
|
|
props.touched.recipientID && (
|
|
<p className="sm:text-sm text-[12px] text-red-500 absolute sm:top-1 -top-20 sm:left-0 left-[160px]">
|
|
{props.errors.recipientID}
|
|
</p>
|
|
)}
|
|
{/* <Link
|
|
to="add-recipient"
|
|
className="mx-1 text-base text-white p-2 bg-[orange] rounded-md hover:opacity-80 max-w-[5rem]"
|
|
>
|
|
Add New
|
|
</Link> */}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
<div className="transfer-fund-btn flex justify-end items-center gap-2 py-4">
|
|
<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>
|
|
{requestStatus ? (
|
|
<LoadingSpinner size="8" color="sky-blue" />
|
|
) : (
|
|
<button
|
|
type="submit"
|
|
disabled={
|
|
props.isSubmitting || sendMoneyFee.loading
|
|
? true
|
|
: false
|
|
}
|
|
className="btn-gradient text-base tracking-wide px-4 py-2 rounded-full text-white cursor-pointer"
|
|
>
|
|
Continue
|
|
</button>
|
|
)}
|
|
</div>
|
|
</Form>
|
|
);
|
|
}}
|
|
</Formik>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</ModalCom>
|
|
);
|
|
}
|
|
|
|
export default NairaWithdraw;
|