From 43e01c11d7f000727d96a5c08033c40fba0807e1 Mon Sep 17 00:00:00 2001 From: YasinShaikh123 <123150391+YasinShaikh123@users.noreply.github.com> Date: Thu, 27 Jun 2024 18:46:12 +0530 Subject: [PATCH 1/2] create oi form --- .../InvestmentCard/InvestmentCard.jsx | 110 +++--- src/Contexts/GlobalStateProvider.jsx | 335 ++++++++++++++++-- src/Pages/IO_Management/CreateIO.jsx | 11 +- src/Pages/IO_Management/ViewIO.jsx | 10 +- .../InvestmentType/AddInvestmentType.jsx | 11 + .../InvestmentType/EditInvestmentType.jsx | 22 ++ .../Master/InvestmentType/InvestmentType.jsx | 263 +++++++++++++- .../InvestmentType/ViewInvestmentType.jsx | 22 ++ src/Pages/Master/Sponser/AddSponser.jsx | 1 + src/Routes/Routes.js | 6 + 10 files changed, 685 insertions(+), 106 deletions(-) create mode 100644 src/Pages/Master/InvestmentType/AddInvestmentType.jsx create mode 100644 src/Pages/Master/InvestmentType/EditInvestmentType.jsx create mode 100644 src/Pages/Master/InvestmentType/ViewInvestmentType.jsx diff --git a/src/Components/InvestmentCard/InvestmentCard.jsx b/src/Components/InvestmentCard/InvestmentCard.jsx index 6b08414..13ed3af 100644 --- a/src/Components/InvestmentCard/InvestmentCard.jsx +++ b/src/Components/InvestmentCard/InvestmentCard.jsx @@ -16,7 +16,7 @@ import { OPACITY_ON_LOAD } from "../../Layout/animations"; const InvestmentCard = ({ investment }) => { return ( { mb={"20px"} boxShadow={"md"} border={"none"} - mt={2} + mt={2} > { objectFit="cover" w={"200px"} h={"140px"} - src={investment?.imgSrc} - alt={investment?.title} + src={investment?.banner_image} + alt={investment?.ioName} /> - {investment?.title} + {investment?.ioName} { ? "green" : "red" } - ps={2} pe={2} pt={0.5} pb={0.5} + ps={2} + pe={2} + pt={0.5} + pb={0.5} fontSize={"xs"} ms={3} > @@ -60,75 +63,88 @@ const InvestmentCard = ({ investment }) => { - Sponsor:{" "} + Sponsor: - {investment?.sponsor} - {" "} + {investment?.sponserName} + - Ann return:{" "} + Ann return: - {investment?.annReturn} - {" "} + {investment?.annualReturn} + - Ann Yield:{" "} + Ann Yield: - {investment?.annYield} - {" "} + {investment?.annualyield} + + + + Tenure: + + {investment?.tenure} + + + + Quaterly: + + {investment?.quaterly} + + + Destributed Amount: + + {investment?.destributedAmount} + + - Min.Invests:{" "} + Min.Invests: {investment?.minInvests} - {" "} + - Targ Close:{" "} + Targ Close: - {investment?.targClose} - {" "} + {new Date(investment?.targetClose).toLocaleDateString()} + - Holding per:{" "} + Year: - {investment?.holdingPer} - {" "} + {investment?.year} + - - - $ 500,000.450 - {investment?.progressValue} % Funded + + + $ 500,000.450 + + + 75 % Funded + - {/* */} - - {/* */} - - - + + + + + + + + + setDeleteAlert(false)} + isOpen={deleteAlert} + message={"Are you sure you want to delete Investment Type?"} + alertHandler={handleDelete} + isLoading={isLoading} + /> ); }; diff --git a/src/Pages/Master/InvestmentType/ViewInvestmentType.jsx b/src/Pages/Master/InvestmentType/ViewInvestmentType.jsx new file mode 100644 index 0000000..1c1b8fe --- /dev/null +++ b/src/Pages/Master/InvestmentType/ViewInvestmentType.jsx @@ -0,0 +1,22 @@ +import { Box, Image, Text } from "@chakra-ui/react" +// import error from "../assets/Error.svg" +import robot from "../../../assets/robot.png" +// import robot from "../assets/robot.png" +const ViewInvestmentType = () => { + return ( + + + + {/* The requested URL was not found on this server. */} + + ) +} + +export default ViewInvestmentType \ No newline at end of file diff --git a/src/Pages/Master/Sponser/AddSponser.jsx b/src/Pages/Master/Sponser/AddSponser.jsx index 06500dc..002aca2 100644 --- a/src/Pages/Master/Sponser/AddSponser.jsx +++ b/src/Pages/Master/Sponser/AddSponser.jsx @@ -51,6 +51,7 @@ export function debounce(func, delay) { debounceTimer = setTimeout(() => func.apply(this, args), delay); }; } + const AddSponser = () => { const navigate = useNavigate(); const { sponser, setSponser } = useContext(GlobalStateContext); diff --git a/src/Routes/Routes.js b/src/Routes/Routes.js index 3d73d16..c64e57a 100644 --- a/src/Routes/Routes.js +++ b/src/Routes/Routes.js @@ -17,7 +17,10 @@ import upgradeHistory from "../Pages/InvestorUpgrade/UpgradeHistory"; import InvestorDetails from "../Pages/Investor_Management/InvestorDetails"; import InvestorTransactions from "../Pages/Investor_Management/InvestorTransactions"; import ExchangeRate from "../Pages/Master/ExchangeRate/ExchangeRate"; +import AddInvestmentType from "../Pages/Master/InvestmentType/AddInvestmentType"; +import EditInvestmentType from "../Pages/Master/InvestmentType/EditInvestmentType"; import InvestmentType from "../Pages/Master/InvestmentType/InvestmentType"; +import ViewInvestmentType from "../Pages/Master/InvestmentType/ViewInvestmentType"; import AddSponser from "../Pages/Master/Sponser/AddSponser"; import EditSponser from "../Pages/Master/Sponser/EditSponser"; import Sponser from "../Pages/Master/Sponser/Sponsers"; @@ -39,6 +42,9 @@ export const RouteLink = [ { path: "/exchange-rate", Component: ExchangeRate }, { path: "/investment-type", Component: InvestmentType }, + { path: "/investment-type/add-investment", Component: AddInvestmentType }, + { path: "/investment-type/view-investment/:id", Component: ViewInvestmentType }, + { path: "/investment-type/edit-investment/:id", Component: EditInvestmentType }, // ===============[ IO Management]=============== { path: "/create-io", Component: CreateIO }, From 131652882e7f206f3c06391712c00f20a415c1c0 Mon Sep 17 00:00:00 2001 From: YasinShaikh123 <123150391+YasinShaikh123@users.noreply.github.com> Date: Fri, 28 Jun 2024 15:10:41 +0530 Subject: [PATCH 2/2] investment add --- src/Components/FormField.jsx | 2 +- src/Pages/IO_Management/ViewIO.jsx | 3 - .../InvestmentType/AddInvestmentType.jsx | 322 +++++++++++++++++- 3 files changed, 315 insertions(+), 12 deletions(-) diff --git a/src/Components/FormField.jsx b/src/Components/FormField.jsx index e11e1f3..af1ee46 100644 --- a/src/Components/FormField.jsx +++ b/src/Components/FormField.jsx @@ -19,7 +19,7 @@ const FormField = ({ handleImageChange, ...props }) => ( - + {label} { value={searchTerm} onChange={(e) => setSearchTerm(e.target.value)} /> - - - diff --git a/src/Pages/Master/InvestmentType/AddInvestmentType.jsx b/src/Pages/Master/InvestmentType/AddInvestmentType.jsx index 7a48652..d0669e1 100644 --- a/src/Pages/Master/InvestmentType/AddInvestmentType.jsx +++ b/src/Pages/Master/InvestmentType/AddInvestmentType.jsx @@ -1,11 +1,317 @@ -import React from 'react' +import React, { useContext, useState } from "react"; +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 { useNavigate } from "react-router-dom"; +import { v4 as uuidv4 } from "uuid"; +import { OPACITY_ON_LOAD } from "../../../Layout/animations"; +import GlobalStateContext from "../../../Contexts/GlobalStateContext"; +import FormField from "../../../Components/FormField"; -const AddInvestmentType = () => { - return ( -
- AddInvestmentType -
- ) +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"), + // .test( + // 'fileSize', + // 'File size is too large', + // value => value && value.size <= 10485760 // 10MB + // ) + // .test( + // 'fileType', + // 'Unsupported file format', + // value => value && ['image/jpg', 'image/jpeg', 'image/gif', 'image/png'].includes(value.type) + // ), + other_image: yup.mixed().required("Profile image is required"), + // .test( + // 'fileSize', + // 'File size is too large', + // value => value && value.size <= 10485760 // 10MB + // ) + // .test( + // 'fileType', + // 'Unsupported file format', + // value => value && ['image/jpg', 'image/jpeg', 'image/gif', 'image/png'].includes(value.type) + // ), +}); + +const startYear = 2024; +const endYear = 2124; +// const years = Array.from({ length: endYear - startYear + 1 }, (_, i) => startYear + i); +const years = Array.from({ length: 2124 - 2024 + 1 }, (_, i) => 2024 + i).map( + (year) => ({ value: year, label: year }) +); + +console.log(years); + +export function debounce(func, delay) { + let debounceTimer; + return function (...args) { + clearTimeout(debounceTimer); + debounceTimer = setTimeout(() => func.apply(this, args), delay); + }; } -export default AddInvestmentType + + + +const AddInvestmentType = () => { + 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 { + control, + handleSubmit, + reset, + setValue, + formState: { errors }, + } = useForm({ + resolver: yupResolver(schema), + // defaultValues: { + // destributedAmount: 0, + // tenure: 0, + // annualReturn: 0, + // miniInvest: 0, + // annualyield: 0, + // }, + }); + + console.log(errors); + + const onSubmit = (data) => { + + // setValue("banner_image", selectedBannerImageData); + data.banner_image = selectedBannerImageData; + const updatedData = { ...data, status: "Available"} + console.log(selectedBannerImageData); + 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 = [ + { + 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", + 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); +}; + return ( + +
+ + Investment Object Details + + + {investForm.map((field, index) => ( + + ))} + + + + + +
+ + {/* */} +
+ ); +}; + +export default AddInvestmentType;