From 744dd7f9e97c1b1a7101c2fdeff92b116ee9852a Mon Sep 17 00:00:00 2001 From: rockyeverlast Date: Fri, 5 Jul 2024 20:02:10 +0530 Subject: [PATCH 1/2] Resturctured ViewIOdata page --- src/Components/FormInputView.jsx | 3 +- src/Pages/IO_Management/CreateIO/CreateIO.jsx | 45 +- src/Pages/IO_Management/EditViewIO.jsx | 456 ++++++++++++++++++ .../IO_Management/ViewIO/ViewDistribution.jsx | 7 + .../IO_Management/{ => ViewIO}/ViewIO.jsx | 48 +- .../{ => ViewIO}/ViewIOTable.jsx | 14 +- .../IO_Management/ViewIO/ViewIOartifacts.jsx | 9 + src/Pages/IO_Management/ViewIO/ViewIOcash.jsx | 9 + src/Pages/IO_Management/ViewIO/ViewIOdata.jsx | 84 ++++ .../{ => ViewIO}/ViewIOdataHeader.jsx | 2 +- .../IO_Management/ViewIO/ViewIOdetails.jsx | 124 +++++ src/Pages/IO_Management/ViewIO/ViewIOdocs.jsx | 7 + src/Pages/IO_Management/ViewIO/ViewIOnav.jsx | 9 + .../IO_Management/ViewIO/ViewInvestors.jsx | 9 + .../IO_Management/ViewIO/ViewKeyMerits.jsx | 9 + src/Pages/IO_Management/ViewIOdata.jsx | 225 --------- src/Routes/Routes.js | 8 +- 17 files changed, 766 insertions(+), 302 deletions(-) create mode 100644 src/Pages/IO_Management/EditViewIO.jsx create mode 100644 src/Pages/IO_Management/ViewIO/ViewDistribution.jsx rename src/Pages/IO_Management/{ => ViewIO}/ViewIO.jsx (83%) rename src/Pages/IO_Management/{ => ViewIO}/ViewIOTable.jsx (94%) create mode 100644 src/Pages/IO_Management/ViewIO/ViewIOartifacts.jsx create mode 100644 src/Pages/IO_Management/ViewIO/ViewIOcash.jsx create mode 100644 src/Pages/IO_Management/ViewIO/ViewIOdata.jsx rename src/Pages/IO_Management/{ => ViewIO}/ViewIOdataHeader.jsx (94%) create mode 100644 src/Pages/IO_Management/ViewIO/ViewIOdetails.jsx create mode 100644 src/Pages/IO_Management/ViewIO/ViewIOdocs.jsx create mode 100644 src/Pages/IO_Management/ViewIO/ViewIOnav.jsx create mode 100644 src/Pages/IO_Management/ViewIO/ViewInvestors.jsx create mode 100644 src/Pages/IO_Management/ViewIO/ViewKeyMerits.jsx delete mode 100644 src/Pages/IO_Management/ViewIOdata.jsx diff --git a/src/Components/FormInputView.jsx b/src/Components/FormInputView.jsx index 922101b..d3c7394 100644 --- a/src/Components/FormInputView.jsx +++ b/src/Components/FormInputView.jsx @@ -16,6 +16,7 @@ const FormInputView = ({ {Object?.entries(groupedFields, groupedFieldsTwo).map( ([section, fields], index) => ( + {console.log(fields)} {section} @@ -27,7 +28,7 @@ const FormInputView = ({ flexWrap={"wrap"} gap={4} > - {fields.map(({ value, label, id, width }, key) => ( + {fields.map(({ value, label, id, width, btn }, key) => ( {label} diff --git a/src/Pages/IO_Management/CreateIO/CreateIO.jsx b/src/Pages/IO_Management/CreateIO/CreateIO.jsx index feaca28..a71369e 100644 --- a/src/Pages/IO_Management/CreateIO/CreateIO.jsx +++ b/src/Pages/IO_Management/CreateIO/CreateIO.jsx @@ -421,54 +421,13 @@ const CreateIO = () => { > {label} ))} - {/* - Investment Documents - - - Key Merits - - - IO artifacts - - - Investors - - - IO Cash detail - - - IO NAV detail - - - Distribution - */} + {tabs.map(({content}, index) => ( - + {content} ))} diff --git a/src/Pages/IO_Management/EditViewIO.jsx b/src/Pages/IO_Management/EditViewIO.jsx new file mode 100644 index 0000000..ad45014 --- /dev/null +++ b/src/Pages/IO_Management/EditViewIO.jsx @@ -0,0 +1,456 @@ +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, + Tabs, + TabList, + Tab, + TabPanel, + TabPanels, + Tooltip, + Switch, + useDisclosure, +} 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, + DeleteIcon, + EditIcon, + ViewIcon, + 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"; +import DataTable from "../../../Components/DataTable/DataTable"; +import { debounce } from "../../Master/Sponser/AddSponser"; +import CustomAlertDialog from "../../../Components/CustomAlertDialog"; +import { formatDate } from "../../../Components/Functions/UTCConvertor"; +import IODetails from "./IODetails"; +import KeyMerits from "./KeyMerits"; +import IOArtifacts from "./IOArtifacts"; +import Investors from "./Investors"; +import IOCashDetails from "./IOCashDetails"; +import IONAVDetails from "./IONAVDetails"; +import Distribution from "./Destribution"; +import InvestmentDocuments from "../InvestmentDocuments"; +import InvestmentDocument from "./InvestmentDocument"; + +const schema = yup.object().shape({ + ioName: yup.string().required("Arabic name is required"), + ioNameArabic: yup.string().required("Investment Object name is required"), + discription: yup.string().required("Sponser name is required"), + discriptionArabic: yup.string().required("Arabic name is required"), + typeName: yup.string().required("Investment Object name is required"), + typeNameArabic: yup.string().required("Sponser name is required"), + sponserName: yup.string().required("Arabic name is required"), + sponserNameArabic: yup + .string() + .required("Investment Object name is required"), + holdingPeriod: yup.string().required("Sponser name is required"), + ioStartus: yup.string().required("Investment Object name is required"), + ioStartusArabic: yup.string().required("Sponser name is required"), + goalAmount: yup.string().required("Arabic name is required"), + closingDate: yup.string().required("Investment Object name is required"), + minInvestment: yup.string().required("Sponser name is required"), + maxInvestment: yup.string().required("Arabic name is required"), + expectedReturn: yup.string().required("Investment Object name is required"), + originalValue: yup.string().required("Sponser name is required"), + keyname: yup.string().required("Arabic name is required"), + keyNameArabic: yup.string().required("Investment Object name is required"), + keyDescription: yup.string().required("Sponser name is required"), + keyDescriptionArabic: yup.string().required("Sponser name is required"), + docType: 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"), + iconUpload: yup.mixed().required("Profile image is required"), + bannerImages: yup.mixed().required("Profile image is required"), + otherImage: yup.mixed().required("Profile image is required"), + docAttach: yup.mixed().required("Profile image is required"), + videos: 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 EditViewIO = () => { + const navigate = useNavigate(); + const { create, setCreate, 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 [searchTerm, setSearchTerm] = useState(""); + const [isLoading, setIsLoading] = useState(true); + const [deleteAlert, setDeleteAlert] = useState(false); + const [actionId, setActionId] = useState(false); + const [mouseEntered, setMouseEntered] = useState(false); + const [mouseEnteredId, setMouseEnteredId] = useState(""); + + const { + control, + handleSubmit, + reset, + watch, + setValue, + formState: { errors }, + } = useForm({ + resolver: yupResolver(schema), + }); + + const tabs = [ + { + label: "IO Details", + content: , + }, + { + label: "Investment documents", + content: , + }, + { + label: "Key merits", + content: , + }, + { + label: "IO artifacts", + content: , + }, + { + label: "Investors", + content: , + }, + { + label: "IO Cash Details", + content: , + }, + { + label: "IO NAV Details", + content: , + }, + { + label: "Distribution", + content: , + }, + ]; + + useEffect(() => { + // Simulate loading + const timer = setTimeout(() => { + setIsLoading(false); + }, 1500); + + // Cleanup the timer on component unmount + return () => clearTimeout(timer); + }, []); + + 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" }; + console.log(selectedBannerImageData); + setInvestment([...investment, updatedData]); + navigate("/view-io"); + reset(); + }; + + // Extract options for the select input + const createOptions = create.map((item) => ({ + value: item.sponserName, + label: item.sponserName, + })); + + 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); + } + }; + + const { isOpen, onOpen, onClose } = useDisclosure(); + const firstField = React.useRef(); + + // 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 keyMerits = [ + { + label: "Name (English)", + placeHolder: " ", + name: "keyname", + type: "text", + isRequired: true, + section: " ", + width: "32.3%", + }, + { + label: "Name (Arabic)", + placeHolder: " ", + name: "keyNameArabic", + type: "text", + isRequired: true, + section: " ", + width: "32.3%", + }, + { + label: "Icon", + placeHolder: " ", + name: "iconUpload", + type: "fileNormal", + isRequired: true, + section: " ", + width: "32.3%", + }, + { + label: "Description (English)", + placeHolder: " ", + name: "keyDescription", + type: "textarea", + isRequired: true, + section: " ", + width: "32.3%", + }, + { + label: "Description (Arabic)", + placeHolder: " ", + name: "keyDescriptionArabic", + type: "textarea", + isRequired: true, + section: " ", + width: "32.3%", + }, + ]; + + const images = [ + { + label: "Banner Images ", + placeHolder: " ", + name: "bannerImages", + type: "fileNormal", + isRequired: true, + section: " ", + width: "32.3%", + }, + + { + label: "Other Images", + placeHolder: " ", + name: "otherImage", + type: "fileNormal", + isRequired: true, + section: " ", + width: "32.3%", + }, + ]; + + const documents = [ + { + label: "Type", + placeHolder: " ", + name: "docType", + type: "text", + isRequired: true, + section: " ", + width: "32.3%", + }, + { + label: "Attachment", + placeHolder: " ", + name: "type", + type: "docAttach", + isRequired: true, + section: " ", + width: "32.3%", + }, + ]; + + const Videos = [ + { + label: "Videos", + placeHolder: " ", + name: "videos", + type: "fileNormal", + isRequired: true, + section: " ", + width: "32.3%", + }, + ]; + + const groupedFieldsTwo = keyMerits.reduce((groups, field) => { + const { section } = field; + if (!groups[section]) { + groups[section] = []; + } + groups[section].push(field); + return groups; + }, {}); + + const groupedFieldsThree = images.reduce((groups, field) => { + const { section } = field; + if (!groups[section]) { + groups[section] = []; + } + groups[section].push(field); + return groups; + }, {}); + + const groupedFieldsFour = documents.reduce((groups, field) => { + const { section } = field; + if (!groups[section]) { + groups[section] = []; + } + groups[section].push(field); + return groups; + }, {}); + + const groupedFieldsFive = Videos.reduce((groups, field) => { + const { section } = field; + if (!groups[section]) { + groups[section] = []; + } + groups[section].push(field); + return groups; + }, {}); + + return ( + + + + {tabs.map(({ label }, index) => ( + + {label} + + ))} + + + + {tabs.map(({ content }, index) => ( + {content} + ))} + + + + ); +}; + +export default EditViewIO; diff --git a/src/Pages/IO_Management/ViewIO/ViewDistribution.jsx b/src/Pages/IO_Management/ViewIO/ViewDistribution.jsx new file mode 100644 index 0000000..2f0c529 --- /dev/null +++ b/src/Pages/IO_Management/ViewIO/ViewDistribution.jsx @@ -0,0 +1,7 @@ +import React from "react"; + +const ViewDistribution = () => { + return
ViewDistribution
; +}; + +export default ViewDistribution; diff --git a/src/Pages/IO_Management/ViewIO.jsx b/src/Pages/IO_Management/ViewIO/ViewIO.jsx similarity index 83% rename from src/Pages/IO_Management/ViewIO.jsx rename to src/Pages/IO_Management/ViewIO/ViewIO.jsx index 3561caf..87c7c40 100644 --- a/src/Pages/IO_Management/ViewIO.jsx +++ b/src/Pages/IO_Management/ViewIO/ViewIO.jsx @@ -15,11 +15,11 @@ import { // import error from "../assets/Error.svg" // import robot from "../../../assets/robot.png" import { useContext, useEffect, useState } from "react"; -import { OPACITY_ON_LOAD } from "../../Layout/animations"; -import InvestmentCard from "../../Components/InvestmentCard/InvestmentCard"; -import GlobalStateContext from "../../Contexts/GlobalStateContext"; -import Pagination from "../../Components/Pagination"; -import EmptySearchList from "../../Components/EmptySearchList"; +import { OPACITY_ON_LOAD } from "../../../Layout/animations"; +import InvestmentCard from "../../../Components/InvestmentCard/InvestmentCard"; +import Pagination from "../../../Components/Pagination"; +import EmptySearchList from "../../../Components/EmptySearchList"; +import GlobalStateContext from "../../../Contexts/GlobalStateContext"; const ExchangeRate = () => { const [searchTerm, setSearchTerm] = useState(""); @@ -27,6 +27,9 @@ const ExchangeRate = () => { const [isLoading, setIsLoading] = useState(true); const [statusFilter, setStatusFilter] = useState("all"); + + console.log(investment); + useEffect(() => { // Simulate loading const timer = setTimeout(() => { @@ -53,7 +56,7 @@ const ExchangeRate = () => { (statusFilter === "Upcomming" && status === "Upcomming") || (statusFilter === "Closed" && status === "Closed"); - return nameMatches && statusMatches; + return nameMatches && statusMatches; }); const availableInvestments = filteredData.filter( @@ -68,7 +71,7 @@ const ExchangeRate = () => { return ( - + {/* All */} {/* Available @@ -94,21 +97,22 @@ const ExchangeRate = () => { value={searchTerm} onChange={(e) => setSearchTerm(e.target.value)} /> - - - + + + {filteredData?.length === 0 ? ( diff --git a/src/Pages/IO_Management/ViewIOTable.jsx b/src/Pages/IO_Management/ViewIO/ViewIOTable.jsx similarity index 94% rename from src/Pages/IO_Management/ViewIOTable.jsx rename to src/Pages/IO_Management/ViewIO/ViewIOTable.jsx index 28d700a..5b5bd95 100644 --- a/src/Pages/IO_Management/ViewIOTable.jsx +++ b/src/Pages/IO_Management/ViewIO/ViewIOTable.jsx @@ -18,8 +18,8 @@ import { useToast, } from "@chakra-ui/react"; import React, { useContext, useEffect, useState } from "react"; -import { OPACITY_ON_LOAD } from "../../Layout/animations"; -import DataTable from "../../Components/DataTable/DataTable"; +import { OPACITY_ON_LOAD } from "../../../Layout/animations"; +import DataTable from "../../../Components/DataTable/DataTable"; import { HiDotsVertical } from "react-icons/hi"; import { Link, Link as RouterLink, useNavigate } from "react-router-dom"; import { @@ -31,10 +31,10 @@ import { EmailIcon, ViewIcon, } from "@chakra-ui/icons"; -import Pagination from "../../Components/Pagination"; -import GlobalStateContext from "../../Contexts/GlobalStateContext"; -import CustomAlertDialog from "../../Components/CustomAlertDialog"; -import ToastBox from "../../Components/ToastBox"; +import Pagination from "../../../Components/Pagination"; +import GlobalStateContext from "../../../Contexts/GlobalStateContext"; +import CustomAlertDialog from "../../../Components/CustomAlertDialog"; +import ToastBox from "../../../Components/ToastBox"; // import { debounce } from "./AddIOCharges"; const formatDate = (date) => new Date(date).toLocaleDateString(); // Simple date formatter @@ -50,6 +50,8 @@ const ViewIOTable = () => { const [mouseEntered, setMouseEntered] = useState(false); const [mouseEnteredId, setMouseEnteredId] = useState(""); + + console.log(viewIO); useEffect(() => { // Simulate loading const timer = setTimeout(() => { diff --git a/src/Pages/IO_Management/ViewIO/ViewIOartifacts.jsx b/src/Pages/IO_Management/ViewIO/ViewIOartifacts.jsx new file mode 100644 index 0000000..41b81de --- /dev/null +++ b/src/Pages/IO_Management/ViewIO/ViewIOartifacts.jsx @@ -0,0 +1,9 @@ +import React from 'react' + +const ViewIOartifacts = () => { + return ( +
ViewIOartifacts
+ ) +} + +export default ViewIOartifacts \ No newline at end of file diff --git a/src/Pages/IO_Management/ViewIO/ViewIOcash.jsx b/src/Pages/IO_Management/ViewIO/ViewIOcash.jsx new file mode 100644 index 0000000..48c4270 --- /dev/null +++ b/src/Pages/IO_Management/ViewIO/ViewIOcash.jsx @@ -0,0 +1,9 @@ +import React from 'react' + +const ViewIOcash = () => { + return ( +
ViewIOcash
+ ) +} + +export default ViewIOcash \ No newline at end of file diff --git a/src/Pages/IO_Management/ViewIO/ViewIOdata.jsx b/src/Pages/IO_Management/ViewIO/ViewIOdata.jsx new file mode 100644 index 0000000..a9fe68e --- /dev/null +++ b/src/Pages/IO_Management/ViewIO/ViewIOdata.jsx @@ -0,0 +1,84 @@ +import { + Box, + Button, + Input, + Tab, + TabList, + TabPanel, + TabPanels, + Tabs, + Text, +} from "@chakra-ui/react"; +import { useNavigate, useParams } from "react-router-dom"; +import GlobalStateContext from "../../../Contexts/GlobalStateContext"; +import { useContext, useEffect, useState } from "react"; +import FormInputView from "../../../Components/FormInputView"; +import { useForm } from "react-hook-form"; // assuming react-hook-form is used +import { OPACITY_ON_LOAD } from "../../../Layout/animations"; +import { ArrowBackIcon } from "@chakra-ui/icons"; +import CustomAlertDialog from "../../../Components/CustomAlertDialog"; +import ViewIOdataHeader from "./ViewIOdataHeader"; +import ViewIOdetails from "./ViewIOdetails"; +import ViewIOdocs from "./ViewIOdocs"; +import ViewKeyMerits from "./ViewKeyMerits"; +import ViewIOartifacts from "./ViewIOartifacts"; +import ViewInvestors from "./ViewInvestors"; +import ViewIOcash from "./ViewIOcash"; +import ViewIOnav from "./ViewIOnav"; +import ViewDistribution from "./ViewDistribution"; + +const ViewIOdata = () => { + const [isEditing, setIsEditing] = useState(false); + const navigate = useNavigate(); + + const tabs = [ + { label: "IO Details", content: }, + { label: "Investment documents", content: }, + { label: "Key merits", content: }, + { label: "IO artifacts", content: }, + { label: "Investors", content: }, + { label: "IO Cash Details", content: }, + { label: "IO NAV Details", content: }, + { label: "Distribution", content: }, + ]; + + return ( + + + navigate(-1)} + style={{ fontSize: "15px", cursor: "pointer" }} + > + Back + + + + + + + {tabs.map(({ label }, index) => ( + + {label} + + ))} + + + + {tabs.map(({ content }, index) => ( + {content} + ))} + + + + ); +}; + +export default ViewIOdata; diff --git a/src/Pages/IO_Management/ViewIOdataHeader.jsx b/src/Pages/IO_Management/ViewIO/ViewIOdataHeader.jsx similarity index 94% rename from src/Pages/IO_Management/ViewIOdataHeader.jsx rename to src/Pages/IO_Management/ViewIO/ViewIOdataHeader.jsx index 54f5369..c476aaf 100644 --- a/src/Pages/IO_Management/ViewIOdataHeader.jsx +++ b/src/Pages/IO_Management/ViewIO/ViewIOdataHeader.jsx @@ -1,5 +1,5 @@ import { Box, Image, Text } from "@chakra-ui/react"; -import header from "../../../src/assets/IOheader.png"; +import header from "../../../assets/IOheader.png"; const ViewIOdataHeader = () => { return ( diff --git a/src/Pages/IO_Management/ViewIO/ViewIOdetails.jsx b/src/Pages/IO_Management/ViewIO/ViewIOdetails.jsx new file mode 100644 index 0000000..640dcb0 --- /dev/null +++ b/src/Pages/IO_Management/ViewIO/ViewIOdetails.jsx @@ -0,0 +1,124 @@ +import { Box } from "@chakra-ui/react"; +import React, { useContext } from "react"; + +import { useNavigate, useParams } from "react-router-dom"; +import { useForm } from "react-hook-form"; +import GlobalStateContext from "../../../Contexts/GlobalStateContext"; +import DataTable from "../../../Components/DataTable/DataTable"; +import FormInputView from "../../../Components/FormInputView"; + +const ViewIOdetails = () => { + const params = useParams(); + const { viewIO } = useContext(GlobalStateContext); + console.log(viewIO); + const { reset } = useForm(); // assuming react-hook-form + + const id = params?.id; + const foundObject = viewIO?.find( + (item) => item?.id.toString() === id.toString() + ); + + const formFields = [ + { + label: "IO Name (English)", + value: foundObject.DealName, + width: "49%", + section: "", + }, + { + label: "IO Name (Arabic)", + value: foundObject.SponsorName, + width: "49%", + section: "", + }, + { + label: "Description (English)", + value: foundObject.IOstatus, + width: "49%", + section: "", + }, + { + label: "Description (Arabic)", + value: foundObject.IOstatus, + width: "49%", + section: "", + }, + { + label: "Investment Type (English)", + value: foundObject.DealName, + width: "49%", + section: "", + }, + { + label: "Investment Type (Arabic)", + value: foundObject.DealID, + width: "49%", + section: "", + }, + { + label: "Sponser Name (English)", + value: foundObject.IOstatus, + width: "49%", + section: "", + }, + { + label: "Goal Amount (English)", + value: foundObject.IOstatus, + width: "49%", + section: "", + }, + { + label: "Minimum Investment Amount (English)", + value: foundObject.IOstatus, + width: "32.3%", + section: "", + }, + { + label: "Maximum Investment Amount (English)", + value: foundObject.IOstatus, + width: "32.3%", + section: "", + }, + { + label: "Holding Period (English)", + value: foundObject.IOstatus, + width: "32.3%", + section: "", + }, + { + label: "Expected Return Estimated (English)", + value: foundObject.IOstatus, + width: "32.3%", + section: "", + }, + { + label: "Closing Date (English)", + value: foundObject.IOstatus, + width: "32.3%", + section: "", + }, + { + label: "IO Status (English)", + value: foundObject.IOstatus, + width: "32.3%", + section: "", + }, + ]; + + const groupedFields = formFields.reduce((groups, field) => { + const { section } = field; + if (!groups[section]) { + groups[section] = []; + } + groups[section].push(field); + return groups; + }, {}); + + if (!foundObject) { + return Loading...; + } + + return ; +}; + +export default ViewIOdetails; diff --git a/src/Pages/IO_Management/ViewIO/ViewIOdocs.jsx b/src/Pages/IO_Management/ViewIO/ViewIOdocs.jsx new file mode 100644 index 0000000..b43fce2 --- /dev/null +++ b/src/Pages/IO_Management/ViewIO/ViewIOdocs.jsx @@ -0,0 +1,7 @@ +import React from "react"; + +const ViewIOdocs = () => { + return
ViewIOdocs
; +}; + +export default ViewIOdocs; diff --git a/src/Pages/IO_Management/ViewIO/ViewIOnav.jsx b/src/Pages/IO_Management/ViewIO/ViewIOnav.jsx new file mode 100644 index 0000000..cfd68b6 --- /dev/null +++ b/src/Pages/IO_Management/ViewIO/ViewIOnav.jsx @@ -0,0 +1,9 @@ +import React from 'react' + +const ViewIOnav = () => { + return ( +
ViewIOnav
+ ) +} + +export default ViewIOnav \ No newline at end of file diff --git a/src/Pages/IO_Management/ViewIO/ViewInvestors.jsx b/src/Pages/IO_Management/ViewIO/ViewInvestors.jsx new file mode 100644 index 0000000..04b9123 --- /dev/null +++ b/src/Pages/IO_Management/ViewIO/ViewInvestors.jsx @@ -0,0 +1,9 @@ +import React from 'react' + +const ViewInvestors = () => { + return ( +
ViewInvestors
+ ) +} + +export default ViewInvestors \ No newline at end of file diff --git a/src/Pages/IO_Management/ViewIO/ViewKeyMerits.jsx b/src/Pages/IO_Management/ViewIO/ViewKeyMerits.jsx new file mode 100644 index 0000000..6f7c7db --- /dev/null +++ b/src/Pages/IO_Management/ViewIO/ViewKeyMerits.jsx @@ -0,0 +1,9 @@ +import React from 'react' + +const ViewKeyMerits = () => { + return ( +
ViewKeyMerits
+ ) +} + +export default ViewKeyMerits \ No newline at end of file diff --git a/src/Pages/IO_Management/ViewIOdata.jsx b/src/Pages/IO_Management/ViewIOdata.jsx deleted file mode 100644 index afd6d10..0000000 --- a/src/Pages/IO_Management/ViewIOdata.jsx +++ /dev/null @@ -1,225 +0,0 @@ -import { - Box, - Button, - Input, - Tab, - TabList, - TabPanel, - TabPanels, - Tabs, - Text, -} from "@chakra-ui/react"; -import { useNavigate, useParams } from "react-router-dom"; -import GlobalStateContext from "../../Contexts/GlobalStateContext"; -import { useContext, useEffect, useState } from "react"; -import FormInputView from "../../Components/FormInputView"; -import { useForm } from "react-hook-form"; // assuming react-hook-form is used -import { OPACITY_ON_LOAD } from "../../Layout/animations"; -import { ArrowBackIcon } from "@chakra-ui/icons"; -import DataTable from "../../Components/DataTable/DataTable"; -import CustomAlertDialog from "../../Components/CustomAlertDialog"; -import FormInputMain from "../../Components/FormInputMain"; -import InvestmentDocuments from "./InvestmentDocuments"; -import ViewIOdataHeader from "./ViewIOdataHeader"; - -const ViewIOdata = () => { - const navigate = useNavigate(); - const params = useParams(); - const { viewIO } = useContext(GlobalStateContext); - const { reset } = useForm(); // assuming react-hook-form - - - - const id = params?.id; - const foundObject = viewIO.find( - (item) => item?.id.toString() === id.toString() - ); - - if (!foundObject) { - return Loading...; - } - - const formFields = [ - { - label: "IO Name (English)", - value: foundObject.DealName, - width: "49%", - section: "", - }, - { - label: "IO Name (Arabic)", - value: foundObject.SponsorName, - width: "49%", - section: "", - }, - { - label: "Description (English)", - value: foundObject.IOstatus, - width: "49%", - section: "", - }, - { - label: "Description (Arabic)", - value: foundObject.IOstatus, - width: "49%", - section: "", - }, - { - label: "Investment Type (English)", - value: foundObject.DealName, - width: "49%", - section: "", - }, - { - label: "Investment Type (Arabic)", - value: foundObject.DealID, - width: "49%", - section: "", - }, - { - label: "Sponser Name (English)", - value: foundObject.IOstatus, - width: "49%", - section: "", - }, - { - label: "Goal Amount (English)", - value: foundObject.IOstatus, - width: "49%", - section: "", - }, - { - label: "Minimum Investment Amount (English)", - value: foundObject.IOstatus, - width: "32.3%", - section: "", - }, - { - label: "Maximum Investment Amount (English)", - value: foundObject.IOstatus, - width: "32.3%", - section: "", - }, - { - label: "Holding Period (English)", - value: foundObject.IOstatus, - width: "32.3%", - section: "", - }, - { - label: "Expected Return Estimated (English)", - value: foundObject.IOstatus, - width: "32.3%", - section: "", - }, - { - label: "Closing Date (English)", - value: foundObject.IOstatus, - width: "32.3%", - section: "", - }, - { - label: "IO Status (English)", - value: foundObject.IOstatus, - width: "32.3%", - section: "", - }, - ]; - - const groupedFields = formFields.reduce((groups, field) => { - const { section } = field; - if (!groups[section]) { - groups[section] = []; - } - groups[section].push(field); - return groups; - }, {}); - - return ( - - - navigate(-1)} - style={{ fontSize: "15px", cursor: "pointer" }} - > - Back - - - - - - - - IO Details - - - Investment Documents - - - Key Merits - - - IO artifacts - - - Investors - - - IO Cash detail - - - IO NAV detail - - - Distribution - - - - - - - - - - - - - - - - - - - - - - - - ); -}; - -export default ViewIOdata; diff --git a/src/Routes/Routes.js b/src/Routes/Routes.js index fed20c5..e405292 100644 --- a/src/Routes/Routes.js +++ b/src/Routes/Routes.js @@ -10,10 +10,10 @@ import Users from "../Pages/Admin/Users"; import CreateIO from "../Pages/IO_Management/CreateIO/CreateIO"; // import CreateIO from "../Pages/IO_Management/InputComponents"; import Create from "../Pages/IO_Management/InputComponents"; -import ViewIO from "../Pages/IO_Management/ViewIO"; -import View from "../Pages/IO_Management/ViewIO"; -import ViewIOTable from "../Pages/IO_Management/ViewIOTable"; -import ViewIOdata from "../Pages/IO_Management/ViewIOdata"; +import ViewIO from "../Pages/IO_Management/ViewIO/ViewIO"; +import View from "../Pages/IO_Management/ViewIO/ViewIO"; +import ViewIOTable from "../Pages/IO_Management/ViewIO/ViewIOTable"; +import ViewIOdata from "../Pages/IO_Management/ViewIO/ViewIOdata"; import InvestorPendingRequest from "../Pages/InvestorUpgrade/InvestorRequest"; import UpgradeHistory from "../Pages/InvestorUpgrade/UpgradeHistory"; import upgradeHistory from "../Pages/InvestorUpgrade/UpgradeHistory"; From d314f9f3931d41aecf4d0fbdfaced896414ad3e9 Mon Sep 17 00:00:00 2001 From: YasinShaikh123 <123150391+YasinShaikh123@users.noreply.github.com> Date: Fri, 5 Jul 2024 20:04:32 +0530 Subject: [PATCH 2/2] artifacts tabs --- src/Components/CreateIOld.jsx | 779 ++++++++++++++++++ src/Contexts/GlobalStateProvider.jsx | 133 ++- src/Pages/IO_Management/CreateIO/CreateIO.jsx | 4 +- .../IO_Management/CreateIO/IOArtifacts.jsx | 255 +++++- .../CreateIO/InvestmentDocument.jsx | 149 +++- .../IO_Management/CreateIO/KeyMerits.jsx | 242 +++++- 6 files changed, 1489 insertions(+), 73 deletions(-) create mode 100644 src/Components/CreateIOld.jsx diff --git a/src/Components/CreateIOld.jsx b/src/Components/CreateIOld.jsx new file mode 100644 index 0000000..5cad274 --- /dev/null +++ b/src/Components/CreateIOld.jsx @@ -0,0 +1,779 @@ +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, + Tabs, + TabList, + Tab, + TabPanel, + TabPanels, + Tooltip, + Switch, + useDisclosure, +} 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, + DeleteIcon, + EditIcon, + ViewIcon, + 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"; +import DataTable from "../../Components/DataTable/DataTable"; +import { debounce } from "../Master/Sponser/AddSponser"; +import CustomAlertDialog from "../../Components/CustomAlertDialog"; +import { formatDate } from "../../Components/Functions/UTCConvertor"; +import InvestmentDocuments from "./InvestmentDocuments"; + +const schema = yup.object().shape({ + ioName: yup.string().required("Arabic name is required"), + ioNameArabic: yup.string().required("Investment Object name is required"), + discription: yup.string().required("Sponser name is required"), + discriptionArabic: yup.string().required("Arabic name is required"), + typeName: yup.string().required("Investment Object name is required"), + typeNameArabic: yup.string().required("Sponser name is required"), + sponserName: yup.string().required("Arabic name is required"), + sponserNameArabic: yup + .string() + .required("Investment Object name is required"), + holdingPeriod: yup.string().required("Sponser name is required"), + ioStartus: yup.string().required("Investment Object name is required"), + ioStartusArabic: yup.string().required("Sponser name is required"), + goalAmount: yup.string().required("Arabic name is required"), + closingDate: yup.string().required("Investment Object name is required"), + minInvestment: yup.string().required("Sponser name is required"), + maxInvestment: yup.string().required("Arabic name is required"), + expectedReturn: yup.string().required("Investment Object name is required"), + originalValue: yup.string().required("Sponser name is required"), + keyname: yup.string().required("Arabic name is required"), + keyNameArabic: yup.string().required("Investment Object name is required"), + keyDescription: yup.string().required("Sponser name is required"), + keyDescriptionArabic: yup.string().required("Sponser name is required"), + docType: 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"), + iconUpload: yup.mixed().required("Profile image is required"), + bannerImages: yup.mixed().required("Profile image is required"), + otherImage: yup.mixed().required("Profile image is required"), + docAttach: yup.mixed().required("Profile image is required"), + videos: 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 CreateIO = () => { + const navigate = useNavigate(); + const { create, setCreate, 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 [searchTerm, setSearchTerm] = useState(""); + const [isLoading, setIsLoading] = useState(true); + const [deleteAlert, setDeleteAlert] = useState(false); + const [actionId, setActionId] = useState(false); + const [mouseEntered, setMouseEntered] = useState(false); + const [mouseEnteredId, setMouseEnteredId] = useState(""); + + const { + control, + handleSubmit, + reset, + watch, + setValue, + formState: { errors }, + } = useForm({ + resolver: yupResolver(schema), + }); + + console.log(errors); + + useEffect(() => { + // Simulate loading + const timer = setTimeout(() => { + setIsLoading(false); + }, 1500); + + // Cleanup the timer on component unmount + return () => clearTimeout(timer); + }, []); + + const tableHeadRow = [ + "Sponser name", + "Address", + "Mobile no", + "Created At", + "Action", + ]; + + const handleUpdateStatus = debounce((id) => { + setCreate((prevCreate) => + prevCreate.map((create) => + create.id === id ? { ...create, status: !create.status } : create + ) + ); + toast({ + render: () => , + }); + }, 300); + + const filteredData = create?.filter((item) => { + // Filter by name (case insensitive) + const name = item.sponserName; + const searchLower = searchTerm.toLowerCase(); + const nameMatches = name.toLowerCase().includes(searchLower); + + return nameMatches; + }); + + const handleDelete = () => { + const updatedCreate = create.filter((create) => create.id !== actionId); + + setTimeout(() => { + setSponser(updatedCreate); + setDeleteAlert(false); + setIsLoading(false); + }, 100); + setIsLoading(true); + }; + + const extractedArray = filteredData?.map((item) => ({ + id: item?.id, + "Sponser name": ( + + "{item.sponserName}" + + ), + Address: ( + + + " {item.sponserAddress}" + + + ), + "Mobile no": ( + + + "{item.mobileNo}" + + + ), + + "Created At": ( + + + {formatDate(item.createdAt)} + + + ), + Action: , + })); + + console.log(extractedArray); + + 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" }; + console.log(selectedBannerImageData); + setInvestment([...investment, updatedData]); + navigate("/view-io"); + reset(); + }; + + // Extract options for the select input + const createOptions = create.map((item) => ({ + value: item.sponserName, + label: item.sponserName, + })); + + 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); + } + }; + + const { isOpen, onOpen, onClose } = useDisclosure(); + const firstField = React.useRef(); + + // 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: "IO Name (English)", + placeHolder: " ", + name: "ioName", + type: "text", + isRequired: true, + section: " ", + width: "49%", + }, + { + label: "IO Name (Arabic)", + placeHolder: " ", + name: "ioNameArabic", + type: "text", + isRequired: true, + section: " ", + width: "49%", + }, + { + label: "Description (English)", + placeHolder: " ", + name: "discription", + type: "textarea", + isRequired: true, + section: " ", + width: "49%", + }, + { + label: "Description (Arabic)", + placeHolder: " ", + name: "discriptionArabic", + type: "textarea", + isRequired: true, + section: " ", + width: "49%", + }, + { + label: "Investment Type (English)", + placeHolder: " ", + name: "typeName", + type: "select", + isRequired: true, + section: " ", + width: "49%", + options: [ + { + label: "option 1", + value: "option 1", + }, + { + label: "option 2", + value: "option 2", + }, + { + label: "option 3", + value: "option 3", + }, + { + label: "option 4", + value: "option 4", + }, + ], + }, + { + label: "Investment Type (Arabic)", + placeHolder: " ", + name: "typeNameArabic", + type: "select", + isRequired: true, + section: " ", + width: "49%", + options: [ + { + label: "option 1", + value: "option 1", + }, + { + label: "option 2", + value: "option 2", + }, + { + label: "option 3", + value: "option 3", + }, + { + label: "option 4", + value: "option 4", + }, + ], + }, + { + label: "Sponser Name (English)", + placeHolder: " ", + name: "sponserName", + type: "text", + isRequired: true, + section: " ", + width: "49%", + }, + { + label: "Goal Amount (English)", + placeHolder: " ", + name: "goalAmount", + type: "Number", + isRequired: true, + section: " ", + width: "49%", + }, + { + label: "Minimum Investment Amount (English)", + placeHolder: " ", + name: "minInvestment", + type: "number", + isRequired: true, + section: " ", + width: "32.3%", + }, + { + label: "Maximum Investment Amount (English)", + placeHolder: " ", + name: "maxInvestment", + type: "number", + isRequired: true, + section: " ", + width: "32.3%", + }, + { + label: "Holding Period (English)", + placeHolder: " ", + name: "holdingPeriod", + type: "number", + isRequired: true, + section: " ", + width: "32.3%", + }, + { + label: "Expected Return Estimated (English)", + placeHolder: " ", + name: "expectedReturn", + type: "number", + isRequired: true, + section: " ", + width: "32.3%", + }, + { + label: "Closing Date (English)", + placeHolder: " ", + name: "closingDate", + type: "date", + isRequired: true, + section: " ", + width: "32.3%", + }, + { + label: "IO Status (English)", + placeHolder: " ", + name: "minInvestment", + type: "text", + isRequired: true, + section: " ", + width: "32.3%", + }, + ]; + + const keyMerits = [ + { + label: "Name (English)", + placeHolder: " ", + name: "keyname", + type: "text", + isRequired: true, + section: " ", + width: "32.3%", + }, + { + label: "Name (Arabic)", + placeHolder: " ", + name: "keyNameArabic", + type: "text", + isRequired: true, + section: " ", + width: "32.3%", + }, + { + label: "Icon", + placeHolder: " ", + name: "iconUpload", + type: "fileNormal", + isRequired: true, + section: " ", + width: "32.3%", + }, + { + label: "Description (English)", + placeHolder: " ", + name: "keyDescription", + type: "textarea", + isRequired: true, + section: " ", + width: "32.3%", + }, + { + label: "Description (Arabic)", + placeHolder: " ", + name: "keyDescriptionArabic", + type: "textarea", + isRequired: true, + section: " ", + width: "32.3%", + }, + ]; + + const images = [ + { + label: "Banner Images ", + placeHolder: " ", + name: "bannerImages", + type: "fileNormal", + isRequired: true, + section: " ", + width: "32.3%", + }, + + { + label: "Other Images", + placeHolder: " ", + name: "otherImage", + type: "fileNormal", + isRequired: true, + section: " ", + width: "32.3%", + }, + ]; + + const documents = [ + { + label: "Type", + placeHolder: " ", + name: "docType", + type: "text", + isRequired: true, + section: " ", + width: "32.3%", + }, + { + label: "Attachment", + placeHolder: " ", + name: "type", + type: "docAttach", + isRequired: true, + section: " ", + width: "32.3%", + }, + ]; + + const Videos = [ + { + label: "Videos", + placeHolder: " ", + name: "videos", + type: "fileNormal", + isRequired: true, + section: " ", + width: "32.3%", + }, + ]; + + const groupedFields = formFields.reduce((groups, field) => { + const { section } = field; + if (!groups[section]) { + groups[section] = []; + } + groups[section].push(field); + return groups; + }, {}); + + const groupedFieldsTwo = keyMerits.reduce((groups, field) => { + const { section } = field; + if (!groups[section]) { + groups[section] = []; + } + groups[section].push(field); + return groups; + }, {}); + + const groupedFieldsThree = images.reduce((groups, field) => { + const { section } = field; + if (!groups[section]) { + groups[section] = []; + } + groups[section].push(field); + return groups; + }, {}); + + const groupedFieldsFour = documents.reduce((groups, field) => { + const { section } = field; + if (!groups[section]) { + groups[section] = []; + } + groups[section].push(field); + return groups; + }, {}); + + const groupedFieldsFive = Videos.reduce((groups, field) => { + const { section } = field; + if (!groups[section]) { + groups[section] = []; + } + groups[section].push(field); + return groups; + }, {}); + + return ( + + + + + IO Details + + + Investment Documents + + + Key Merits + + + IO artifacts + + + Investors + + + IO Cash detail + + + IO NAV detail + + + Distribution + + + + + + + + + + setSearchTerm(e.target.value)} + /> + + + + + setDeleteAlert(false)} + isOpen={deleteAlert} + message={"Are you sure you want to delete sponers?"} + alertHandler={handleDelete} + isLoading={isLoading} + /> + + + + + + + + + + + + + + + ); +}; + +export default CreateIO; diff --git a/src/Contexts/GlobalStateProvider.jsx b/src/Contexts/GlobalStateProvider.jsx index 19f1736..26be72f 100644 --- a/src/Contexts/GlobalStateProvider.jsx +++ b/src/Contexts/GlobalStateProvider.jsx @@ -3,6 +3,12 @@ import React, { useState } from "react"; import GlobalStateContext from "./GlobalStateContext"; import { effect, useColorMode } from "@chakra-ui/react"; import { v4 as uuidv4 } from "uuid"; +import { TbClock2 } from "react-icons/tb"; +import { CiWallet } from "react-icons/ci"; +import { HiOutlineReceiptPercent } from "react-icons/hi2"; +import { IoMdQrScanner } from "react-icons/io"; + + const getRandomDate = (start, end) => { const date = new Date( @@ -280,51 +286,118 @@ const GlobalStateProvider = ({ children }) => { const [create, setCreate] = useState([ { id: 1, - sponserName: "Commercial", - description: "Investment Private Company", + Type: "PDF", + fileName: "Investment Private Company", + document:"Investment.pdf", status: true, }, { id: 2, - sponserName: "Commercial", - description: "Investment Private", + Type: "PDF", + fileName: "Investment Private", + document:"Investment.pdf", status: true, }, { id: 3, - sponserName: "Commercial", - description: "Investment Private", + Type: "PDF", + fileName: "Investment Private", + document:"Investment.pdf", status: true, }, { id: 4, - sponserName: "Commercial", - description: "Investment Private", + Type: "PDF", + fileName: "Investment Private", + document:"Investment.pdf", + status: true, + }, + { + id: 5, + Type: "PDF", + fileName: "Investment Private", + document:"Investment.pdf", + status: true, + }, + { + id: 6, + Type: "PDF", + fileName: "Investment Private", + document:"Investment.pdf", + status: true, + }, + { + id: 7, + Type: "PDF", + fileName: "Investment Private", + document:"Investment.pdf", + status: true, + }, + ]); + + const [keyMerits, setKeyMerits] = useState([ + { + id: 1, + title: "Diversified Holdings", + subTitle: "Private equity portfolio of over 60 companies in various sectors and different countries around the world", + icon:, + status: true, + }, + { + id: 2, + title: "Top-Tier Manager", + subTitle: "KKR is a world-class global PE manager with over $570bn in assets under management", + icon:, + status: true, + }, + { + id: 3, + title: "Strong performance", + subTitle: "Direct exposure to the KKR’s best performing Buyout and Growth funds", + icon:, + status: true, + }, + { + id: 4, + title: "Leading Track Record", + subTitle: "Almost 50 year track record since 1977 of consistent, double-digit annual returns", + icon:, + status: true, + }, + ]); + + const [iOArtifacts, setIOArtifacts] = useState([ + { + id: 1, + type: "JPG", + fileName: "Banner image", + document:"Banner.jpg", + status: true, + }, + { + id: 2, + type: "JPG", + fileName: "Banner image", + document:"Banner.jpg", + status: true, + }, + { + id: 3, + type: "JPG", + fileName: "Banner image", + document:"Banner.jpg", + status: true, + }, + { + id: 4, + type: "JPG", + fileName: "Banner image", + document:"Banner.jpg", status: true, }, ]); const [investmentType, setInvestmentType] = useState([ - // { - // id: 1, - // investmentName: "Commercial", - // mobileNo: "0987654321", - // investmentAddress: "1725 Slough Ave, Scranton, USA", - // accountHolderName: "Michael Scott", - // bankName: "Dunder Mifflin Bank", - // accountNumber: "1111222233", - // bankBranch: "Scranton Branch", - // branchAddress: "101 Paper St, Scranton, USA", - // ifscCode: "IFSC11111", - // swiftCode: "SWIFT12345", - // routingNumber: "123450987", - // iban: "IBAN1111222233", - // accountType: "checking", - // bankPhoneNumber: "0987654321", - // bankEmail: "michael.scott@example.com", - // status: true, - // createdAt: "45", - // }, { id: 1, investmentName: "Commercial", @@ -1311,6 +1384,10 @@ const GlobalStateProvider = ({ children }) => { setViewIO, create, setCreate, + keyMerits, + setKeyMerits, + iOArtifacts, + setIOArtifacts }} > {children} diff --git a/src/Pages/IO_Management/CreateIO/CreateIO.jsx b/src/Pages/IO_Management/CreateIO/CreateIO.jsx index 6bada19..170656f 100644 --- a/src/Pages/IO_Management/CreateIO/CreateIO.jsx +++ b/src/Pages/IO_Management/CreateIO/CreateIO.jsx @@ -160,12 +160,12 @@ const CreateIO = () => { { label: "Key merits", content: , - isDisabled: true, + isDisabled: false, }, { label: "IO artifacts", content: , - isDisabled: true, + isDisabled: false, }, { label: "Investors", diff --git a/src/Pages/IO_Management/CreateIO/IOArtifacts.jsx b/src/Pages/IO_Management/CreateIO/IOArtifacts.jsx index 4069e31..938afff 100644 --- a/src/Pages/IO_Management/CreateIO/IOArtifacts.jsx +++ b/src/Pages/IO_Management/CreateIO/IOArtifacts.jsx @@ -1,9 +1,252 @@ -import React from 'react' +import { + Box, + Button, + Input, + Text, + Tooltip, + useDisclosure, +} from "@chakra-ui/react"; +import React, { useContext, useEffect, useRef, useState } from "react"; +import InvestmentDocuments from "../InvestmentDocuments"; +import DataTable from "../../../Components/DataTable/DataTable"; +import CustomAlertDialog from "../../../Components/CustomAlertDialog"; +import GlobalStateContext from "../../../Contexts/GlobalStateContext"; +import { debounce } from "../../Master/Sponser/AddSponser"; +import { formatDate } from "../../../Components/Functions/UTCConvertor"; +import { + AddIcon, + DeleteIcon, + DownloadIcon, + EditIcon, + ViewIcon, +} from "@chakra-ui/icons"; const IOArtifacts = () => { - return ( -
IOArtifacts
- ) -} + const { iOArtifacts, setIOArtifacts, slideFromRight } = + useContext(GlobalStateContext); + const firstField = useRef(); + const [searchTerm, setSearchTerm] = useState(""); + const [isLoading, setIsLoading] = useState(true); + const [deleteAlert, setDeleteAlert] = useState(false); + const [actionId, setActionId] = useState(false); + const [mouseEntered, setMouseEntered] = useState(false); + const [mouseEnteredId, setMouseEnteredId] = useState(""); + const { isOpen, onOpen, onClose } = useDisclosure(); -export default IOArtifacts \ No newline at end of file + useEffect(() => { + // Simulate loading + const timer = setTimeout(() => { + setIsLoading(false); + }, 1500); + + // Cleanup the timer on component unmount + return () => clearTimeout(timer); + }, []); + + const tableHeadRow = [ + "Sr.no", + "Type", + "File Name", + "Document", + "Action" + ]; + + const handleUpdateStatus = debounce((id) => { + setIOArtifacts((prevIOArtifacts) => + prevIOArtifacts.map((iOArtifacts) => + iOArtifacts.id === id + ? { ...iOArtifacts, status: !iOArtifacts.status } + : iOArtifacts + ) + ); + toast({ + render: () => , + }); + }, 300); + + const filteredData = iOArtifacts?.filter((item) => { + // Filter by name (case insensitive) + const name = item.type; + const searchLower = searchTerm.toLowerCase(); + const nameMatches = name.toLowerCase().includes(searchLower); + + return nameMatches; + }); + + const handleDelete = () => { + const updatedIOArtifacts = iOArtifacts.filter( + (iOArtifacts) => iOArtifacts.id !== actionId + ); + + setTimeout(() => { + setSponser(updatedIOArtifacts); + setDeleteAlert(false); + setIsLoading(false); + }, 100); + setIsLoading(true); + }; + + const extractedArray = filteredData?.map((item, index) => ({ + "Sr.no": ( + + {index + 1} + + ), + Type: ( + + {item.type} + + ), + "File Name": ( + + + {item.fileName} + + + ), + "Document": ( + + {item.document} + + ), + Action: ( + + + + + + + + + + + + ), + })); + + return ( + + + setSearchTerm(e.target.value)} + /> + + + + + setDeleteAlert(false)} + isOpen={deleteAlert} + message={"Are you sure you want to delete sponers?"} + alertHandler={handleDelete} + isLoading={isLoading} + /> + + ); +}; + +export default IOArtifacts; diff --git a/src/Pages/IO_Management/CreateIO/InvestmentDocument.jsx b/src/Pages/IO_Management/CreateIO/InvestmentDocument.jsx index 6ada9a6..5023f4f 100644 --- a/src/Pages/IO_Management/CreateIO/InvestmentDocument.jsx +++ b/src/Pages/IO_Management/CreateIO/InvestmentDocument.jsx @@ -1,4 +1,4 @@ -import { Box, Button, Input, Text, useDisclosure } from "@chakra-ui/react"; +import { Box, Button, Input, Text, Tooltip, useDisclosure } from "@chakra-ui/react"; import React, { useContext, useEffect, useRef, useState } from "react"; import InvestmentDocuments from "../InvestmentDocuments"; import DataTable from "../../../Components/DataTable/DataTable"; @@ -6,10 +6,10 @@ import CustomAlertDialog from "../../../Components/CustomAlertDialog"; import GlobalStateContext from "../../../Contexts/GlobalStateContext"; import { debounce } from "../../Master/Sponser/AddSponser"; import { formatDate } from "../../../Components/Functions/UTCConvertor"; -import { AddIcon } from "@chakra-ui/icons"; +import { AddIcon, DeleteIcon, DownloadIcon, EditIcon, ViewIcon } from "@chakra-ui/icons"; const InvestmentDocument = ({ control, errors }) => { - const { create, setCreate, sponser, setSponser, investment, setInvestment } = + const { create, setCreate, sponser, setSponser,slideFromRight} = useContext(GlobalStateContext); const firstField = useRef(); const [searchTerm, setSearchTerm] = useState(""); @@ -33,10 +33,10 @@ const InvestmentDocument = ({ control, errors }) => { const tableHeadRow = [ - "Sponser name", - "Address", - "Mobile no", - "Created At", + "Sr.no", + "Type", + "File Name", + "Document", "Action", ]; @@ -53,7 +53,7 @@ const InvestmentDocument = ({ control, errors }) => { const filteredData = create?.filter((item) => { // Filter by name (case insensitive) - const name = item.sponserName; + const name = item.Type; const searchLower = searchTerm.toLowerCase(); const nameMatches = name.toLowerCase().includes(searchLower); @@ -71,43 +71,130 @@ const InvestmentDocument = ({ control, errors }) => { setIsLoading(true); }; - const extractedArray = filteredData?.map((item) => ({ - id: item?.id, - "Sponser name": ( + const extractedArray = filteredData?.map((item, index) => ({ + "Sr.no": ( - "{item.sponserName}" + {index + 1} ), - Address: ( - + "Type": ( + + {item.Type} + + ), + "File Name": ( + - " {item.sponserAddress}" + {item.fileName} ), - "Mobile no": ( - - - "{item.mobileNo}" - + "Document": ( + + {item.document} + + ), + Action: ( + + + + + + + + + + + + + ), - - "Created At": ( - - - {formatDate(item.createdAt)} - - - ), - Action: , })); diff --git a/src/Pages/IO_Management/CreateIO/KeyMerits.jsx b/src/Pages/IO_Management/CreateIO/KeyMerits.jsx index c739fff..7110a56 100644 --- a/src/Pages/IO_Management/CreateIO/KeyMerits.jsx +++ b/src/Pages/IO_Management/CreateIO/KeyMerits.jsx @@ -1,9 +1,239 @@ -import React from 'react' +import { Box, Button, Input, Text, Tooltip, useDisclosure } from "@chakra-ui/react"; +import React, { useContext, useEffect, useRef, useState } from "react"; +import InvestmentDocuments from "../InvestmentDocuments"; +import DataTable from "../../../Components/DataTable/DataTable"; +import CustomAlertDialog from "../../../Components/CustomAlertDialog"; +import GlobalStateContext from "../../../Contexts/GlobalStateContext"; +import { debounce } from "../../Master/Sponser/AddSponser"; +import { formatDate } from "../../../Components/Functions/UTCConvertor"; +import { AddIcon, DeleteIcon, DownloadIcon, EditIcon, ViewIcon } from "@chakra-ui/icons"; const KeyMerits = () => { - return ( -
KeyMerits
- ) -} + const { keyMerits, setKeyMerits,slideFromRight} = + useContext(GlobalStateContext); + const firstField = useRef(); + const [searchTerm, setSearchTerm] = useState(""); + const [isLoading, setIsLoading] = useState(true); + const [deleteAlert, setDeleteAlert] = useState(false); + const [actionId, setActionId] = useState(false); + const [mouseEntered, setMouseEntered] = useState(false); + const [mouseEnteredId, setMouseEnteredId] = useState(""); + const { isOpen, onOpen, onClose } = useDisclosure(); -export default KeyMerits \ No newline at end of file + useEffect(() => { + // Simulate loading + const timer = setTimeout(() => { + setIsLoading(false); + }, 1500); + + // Cleanup the timer on component unmount + return () => clearTimeout(timer); + }, []); + + + + const tableHeadRow = [ + "Sr.no", + "Title", + "Sub title", + "Icon", + "Action", + ]; + + const handleUpdateStatus = debounce((id) => { + setKeyMerits((prevKeyMerits) => + prevKeyMerits.map((keyMerits) => + keyMerits.id === id ? { ...keyMerits, status: !keyMerits.status } : keyMerits + ) + ); + toast({ + render: () => , + }); + }, 300); + + const filteredData = keyMerits?.filter((item) => { + // Filter by name (case insensitive) + const name = item.title; + const searchLower = searchTerm.toLowerCase(); + const nameMatches = name.toLowerCase().includes(searchLower); + + return nameMatches; + }); + + const handleDelete = () => { + const updatedKeyMerits = keyMerits.filter((keyMerits) => keyMerits.id !== actionId); + + setTimeout(() => { + setSponser(updatedKeyMerits); + setDeleteAlert(false); + setIsLoading(false); + }, 100); + setIsLoading(true); + }; + + const extractedArray = filteredData?.map((item, index) => ({ + "Sr.no": ( + + {index + 1} + + ), + "Title": ( + + {item.title} + + ), + "Sub title": ( + + + {item.subTitle} + + + ), + "Icon": ( + + {item.icon} + + ), + Action: ( + + + + + + + + + + + + ), + })); + + + return ( + + + setSearchTerm(e.target.value)} + /> + + + + + setDeleteAlert(false)} + isOpen={deleteAlert} + message={"Are you sure you want to delete sponers?"} + alertHandler={handleDelete} + isLoading={isLoading} + /> + + ); +}; + +export default KeyMerits;