Files
tanami-admin-panel/src/Pages/IO_Management/InputComponents.jsx

545 lines
14 KiB
React
Raw Normal View History

2024-07-03 12:13:09 +05:30
import React, { useContext, useEffect, useState } from "react";
import { OPACITY_ON_LOAD } from "../../Layout/animations";
import {
Box,
Divider,
FormControl,
FormLabel,
Heading,
Input,
Select,
Textarea,
Button,
Text,
Image,
} from "@chakra-ui/react";
import { useForm, Controller } from "react-hook-form";
import { yupResolver } from "@hookform/resolvers/yup";
import * as yup from "yup";
import { AddIcon, CloseIcon, WarningTwoIcon } from "@chakra-ui/icons";
import { TiWarning } from "react-icons/ti";
import GlobalStateContext from "../../Contexts/GlobalStateContext";
import { useNavigate } from "react-router-dom";
import FormField from "../../Components/FormField";
import { v4 as uuidv4 } from "uuid";
import AddIOCharges from "./AddIOCharges";
import FormInputMain from "../../Components/FormInputMain";
const schema = yup.object().shape({
ioNameArabic: yup.string().required("Arabic name is required"),
ioName: yup.string().required("Investment Object name is required"),
sponserName: yup.string().required("Sponser name is required"),
destributedAmount: yup
.number()
.required("Distributed Amount is required")
.positive("Must be a positive number"),
year: yup.string().required("Year is required"),
tenure: yup
.number()
.required("Tenure is required")
.positive("Must be a positive number"),
annualReturn: yup
.number()
.required("Annual Return is required")
.positive("Must be a positive number"),
miniInvest: yup
.number()
.required("Minimum Invest is required")
.positive("Must be a positive number"),
quaterly: yup.string().required("Quaterly is required"),
targetClose: yup.date().required("Target close date is required"),
annualyield: yup
.number()
.required("Annual Yield is required")
.positive("Must be a positive number"),
banner_image: yup.mixed().required("Profile image is required"),
other_image: yup.mixed().required("Profile image is required"),
});
const startYear = 2024;
const endYear = 2124;
const years = Array.from(
{ length: endYear - startYear + 1 },
(_, i) => startYear + i
).map((year) => ({ value: year, label: year }));
const InputComponents = () => {
const navigate = useNavigate();
const { sponser, setSponser, investment, setInvestment } =
useContext(GlobalStateContext);
const [bannerImageData, setBannerImageData] = useState(null);
const [otherImageData, setOtherImageData] = useState(null);
const [selectedBannerImageData, setSelectedBannerImageData] = useState(null);
const [selectedOtherImageData, setSelectedOtherImageData] = useState(null);
const [charges, setCharges] = useState([]);
const [totalCharge, setTotalCharge] = useState(0.0);
const [totalAmount, setTotalAmount] = useState(0.0);
const {
control,
handleSubmit,
reset,
watch,
setValue,
formState: { errors },
} = useForm({
resolver: yupResolver(schema),
});
console.log(errors);
const destributedAmount = Number(watch().destributedAmount) || 0;
useEffect(() => {
const calculateTotalCharge = () => {
const totalChargeValue = charges.reduce(
(acc, { value }) => acc + Number(value),
0
);
setTotalCharge(totalChargeValue);
};
const calculateTotalAmount = () => {
const totalChargeValue = charges.reduce(
(acc, { value }) => acc + Number(value),
0
);
setTotalAmount(destributedAmount + totalChargeValue);
};
calculateTotalCharge();
calculateTotalAmount();
}, [charges, destributedAmount]);
const onSubmit = (data) => {
// setValue("banner_image", selectedBannerImageData);
data.banner_image = selectedBannerImageData;
const updatedData = { ...data, status: "Available" };
setInvestment([...investment, updatedData]);
navigate("/view-io");
reset();
};
// Extract options for the select input
const sponserOptions = sponser.map((item) => ({
value: item.sponserName,
label: item.sponserName,
}));
const [investForm, setInvestForm] = useState(
[
{
label: "Investment object name",
name: "ioName",
type: "text",
isRequired: true,
},
{
label: "Investment object",
name: "ioNameArabic",
placeHolder: "الرجاء إدخال القيمة",
arabic: true,
isRequired: true,
},
{
label: "Destributed Amount",
placeHolder: "$00.0",
helperText: "Please enter value in $",
name: "destributedAmount",
type: "number",
isRequired: true,
},
{
label: "Min Invest",
placeHolder: "$00.00",
helperText: "Please enter value in $",
name: "miniInvest",
type: "number",
isRequired: true,
},
{
label: "Year",
name: "year",
type: "select",
options: years,
isRequired: true,
},
{
label: "Quaterly",
name: "quaterly",
type: "select",
options: [
{ label: "Q1", value: "Q1" },
{ label: "Q2", value: "Q2" },
{ label: "Q3", value: "Q3" },
{ label: "Q4", value: "Q4" },
],
isRequired: true,
},
{
label: "Sponsers Name",
name: "sponserName",
type: "select",
options: sponserOptions,
isRequired: true,
},
{
label: "Target close",
name: "targetClose",
type: "date",
isRequired: true,
},
{
label: "Tenure",
name: "tenure",
type: "number",
isRequired: true,
},
{
label: "Annual yeild",
placeHolder: "00.00%",
helperText: "Please enter value in percentage",
name: "annualyield",
type: "number",
isRequired: true,
},
{
label: "Annual return",
placeHolder: "00.00%",
helperText: "Please enter value in percentage",
name: "annualReturn",
type: "number",
isRequired: true,
},
]
);
const handleBannerImageChange = (e) => {
const file = e.target.files[0];
setBannerImageData(file);
if (file) {
const reader = new FileReader();
reader.onloadend = () => {
setSelectedBannerImageData(reader.result);
};
reader.readAsDataURL(file);
}
};
// Handler for file input
const handleOtherImageChange = (e) => {
const files = Array.from(e.target.files);
const newImageData = [...(otherImageData || []), ...files]; // Ensure otherImageData is an array
setOtherImageData(newImageData);
const readers = files.map((file) => {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onloadend = () => {
resolve(reader.result);
};
reader.onerror = reject;
reader.readAsDataURL(file);
});
});
Promise.all(readers)
.then((results) => {
setSelectedOtherImageData([
...(selectedOtherImageData || []),
...results,
]); // Ensure selectedOtherImageData is an array
})
.catch((error) => {
console.error("Error reading files:", error);
});
};
// Function to remove a specific image
const removeOtherImage = (index) => {
const newImageData = otherImageData.filter((_, i) => i !== index);
const newSelectedImageData = selectedOtherImageData.filter(
(_, i) => i !== index
);
setOtherImageData(newImageData);
setSelectedOtherImageData(newSelectedImageData);
};
const formFields = [
{
label: "Investment object name",
name: "ioName",
type: "text",
isRequired: true,
section: "Investment Object Details",
},
{
label: "Investment object (Arabic)",
name: "ioNameArabic",
placeHolder: "الرجاء إدخال القيمة",
type: "text",
isRequired: true,
arabic: true,
section: "Investment Object Details",
},
{
label: "Destributed Amount",
name: "destributedAmount",
type: "number",
isRequired: true,
section: "Investment Object Details",
},
{
label: "Min Invest",
name: "miniInvest",
type: "number",
isRequired: true,
section: "Investment Object Details",
},
{
label: "Sponsers name",
name: "sponserName",
type: "text",
isRequired: true,
section: "Investment Object Details",
},
{
label: "Year",
name: "accountNumber",
type: "select",
options: years,
isRequired: true,
section: "Investment Object Details",
},
{
label: "Annual return",
name: "annualReturn",
type: "number",
isRequired: true,
section: "Investment Object Details",
},
{
label: "Annual yeild",
name: "annualyield",
type: "number",
helperText: "Please enter value in percentage",
isRequired: true,
section: "Investment Object Details",
},
{
label: "Quaterly",
name: "quaterly",
type: "select",
options: [
{
label: "Q1",
value: "Q1",
},
{
label: "Q2",
value: "Q2",
},
{
label: "Q3",
value: "Q3",
},
{
label: "Q4",
value: "Q4",
},
],
isRequired: true,
section: "Investment Object Details",
},
{
label: "Target close",
name: "targetClose",
type: "date",
isRequired: true,
section: "Investment Object Details",
},
{
label: "Banner image",
name: "banner_image",
id: "banner_image",
type: "fileNormal",
isRequired: true,
section: "Uplaod Banner Images",
multiple: false,
selectedImageData: selectedBannerImageData,
setSelectedImageData: setSelectedBannerImageData,
imageData: bannerImageData,
handleImageChange: handleBannerImageChange,
},
{
label: "Multi Image",
name: "OtherImage",
id: "OtherImage",
type: "fileNormal",
isRequired: true,
section: "Uplaod Banner Images",
multiple: true,
selectedImageData: selectedOtherImageData,
setSelectedImageData: setSelectedOtherImageData,
imageData: otherImageData,
handleImageChange: handleOtherImageChange,
removeImage: removeOtherImage,
},
];
const groupedFields = formFields.reduce((groups, field) => {
const { section } = field;
if (!groups[section]) {
groups[section] = [];
}
groups[section].push(field);
return groups;
}, {});
return (
<Box {...OPACITY_ON_LOAD} overflowY={"scroll"} height={"100vh"} pb={14}>
<FormInputMain
groupedFields={groupedFields}
control={control}
errors={errors}
onSubmit={handleSubmit(onSubmit)}
>
<Divider />
<Heading
w={"100%"}
display={"flex"}
justifyContent={"space-between"}
as="h6"
size="xs"
mb={5}
pe={6}
>
Final calculation
<AddIOCharges charges={charges} setCharges={setCharges} />
</Heading>
<Box
w={"40%"}
display={"flex"}
justifyContent={"center"}
flexDirection={"column"}
alignItems={"start"}
gap={1}
p={5}
m={1}
rounded={"lg"}
boxShadow={"lg"}
color={"#fff"}
bgGradient="linear(to-tr, #000000, #004118)"
>
{charges.map(({ title, value }, index) => (
<Box as={"span"} w={"100%"} display={"flex"}>
<Text
fontSize={"sm"}
fontWeight={"600"}
as={"span"}
w={"70%"}
bg={""}
>
{title}
</Text>
<Text
as={"span"}
fontSize={"sm"}
fontWeight={"600"}
w={"30%"}
bg={""}
>
$ {value}
</Text>
</Box>
))}
<Box
as={"span"}
w={"100%"}
display={"flex"}
flexDirection={"column"}
gap={2}
>
{totalCharge !== 0 ? (
<Box display={"flex"}>
<Text
fontSize={"sm"}
fontWeight={"500"}
as={"span"}
w={"70%"}
bg={""}
>
Total charges
</Text>
<Text
as={"span"}
fontSize={"sm"}
fontWeight={"600"}
w={"30%"}
bg={""}
>
$ {totalCharge.toFixed(4)}
</Text>
</Box>
) : (
""
)}
<Box display={"flex"}>
<Text
fontSize={"sm"}
fontWeight={"500"}
as={"span"}
w={"70%"}
bg={""}
>
Total distributed amount
</Text>
<Text
as={"span"}
fontSize={"sm"}
fontWeight={"600"}
w={"30%"}
bg={""}
>
$ {destributedAmount.toFixed(4)}
</Text>
</Box>
<Box pt={2} borderTop={"1px solid #fff"} as="span" display={"flex"}>
<Text
fontSize={"sm"}
fontWeight={"500"}
as={"span"}
w={"70%"}
bg={""}
>
Total Net Charges
</Text>
<Text
as={"span"}
fontSize={"sm"}
fontWeight={"600"}
w={"30%"}
bg={""}
>
$ {totalAmount.toFixed(4)}
</Text>
</Box>
</Box>
</Box>
</FormInputMain>
</Box>
);
};
export default InputComponents;