diff --git a/src/Contexts/GlobalStateProvider.jsx b/src/Contexts/GlobalStateProvider.jsx index c260bf5..79090a1 100644 --- a/src/Contexts/GlobalStateProvider.jsx +++ b/src/Contexts/GlobalStateProvider.jsx @@ -411,58 +411,65 @@ const GlobalStateProvider = ({ children }) => { totalReturnOnInvestment: "73.0%", }, ]); - - const [create, setCreate] = useState([ + + const [caseDetails, setCaseDetails] = useState([ { id: 1, - Type: "PDF", - fileName: "Investment Private Company", - document: "Investment.pdf", - status: true, + date: "02-Jan-24", + particulars: "Cash Reserve- Initated", + amount: "50,000.00", + comments: " ", + updateBy: "Faisal", + updateOn: "02-Jan-24", }, { id: 2, - Type: "PDF", - fileName: "Investment Private", - document: "Investment.pdf", - status: true, + date: "12-Feb-24", + particulars: "Fees & Expense", + amount: "22,000.00", + comments: "Fees = $20,000 Expense = $2,000 ", + updateBy: "Faisal", + updateOn: "13-Feb-24", }, { id: 3, - Type: "PDF", - fileName: "Investment Private", - document: "Investment.pdf", - status: true, + date: "23-Mar-24", + particulars: "Distribution Received From Sponsor", + amount: "50,000.00", + comments: " ", + updateBy: "Nawab", + updateOn: "24-Mar-24", }, { id: 4, - Type: "PDF", - fileName: "Investment Private", - document: "Investment.pdf", - status: true, + date: "28-Mar-24", + particulars: "Distribution Paid To Investors", + amount: "40,000.00", + comments: " ", + updateBy: "Faisal", + updateOn: "28-Mar-24", }, { id: 5, - Type: "PDF", - fileName: "Investment Private", - document: "Investment.pdf", - status: true, + date: "26-Jun-24", + particulars: "Distribution Received From Sponsor", + amount: "70,000.00", + comments: " ", + updateBy: "Faisal", + updateOn: "27-Jun-24", }, { id: 6, - Type: "PDF", - fileName: "Investment Private", - document: "Investment.pdf", - status: true, - }, - { - id: 7, - Type: "PDF", - fileName: "Investment Private", - document: "Investment.pdf", - status: true, + date: "02-Jan-24", + particulars: "Distribution Paid To Investors", + amount: "60,000.00", + comments: " ", + updateBy: "Nawab", + updateOn: "28-Jun-24", }, ]); + + const [keyMerits, setKeyMerits] = useState([ { id: 1, @@ -1500,14 +1507,16 @@ const GlobalStateProvider = ({ children }) => { setDeleteRequest, viewIO, setViewIO, - create, - setCreate, + // create, + // setCreate, keyMerits, setKeyMerits, iOArtifacts, setIOArtifacts, investors, - setInvestors + setInvestors, + caseDetails, + setCaseDetails, }} > {children} diff --git a/src/Pages/IO_Management/CreateIO/IOArtifacts.jsx b/src/Pages/IO_Management/CreateIO/IOArtifacts.jsx index 8c55def..194b875 100644 --- a/src/Pages/IO_Management/CreateIO/IOArtifacts.jsx +++ b/src/Pages/IO_Management/CreateIO/IOArtifacts.jsx @@ -8,7 +8,6 @@ import { 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"; @@ -21,6 +20,7 @@ import { EditIcon, ViewIcon, } from "@chakra-ui/icons"; +import IOArtifactsAdd from "../IOArtifactsAdd"; const IOArtifacts = ({enableNextTab, index}) => { const { iOArtifacts, setIOArtifacts, slideFromRight } = @@ -218,7 +218,7 @@ const IOArtifacts = ({enableNextTab, index}) => { > Add - new Date(date).toLocaleDateString(); // Simple date formatter const IOCashDetails = () => { - return ( -
IOCashDetails
- ) -} + const toast = useToast(); + const { caseDetails, setCaseDetails, slideFromRight } = + useContext(GlobalStateContext); + 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(""); -export default IOCashDetails \ No newline at end of file + useEffect(() => { + // Simulate loading + const timer = setTimeout(() => { + setIsLoading(false); + }, 1500); + + // Cleanup the timer on component unmount + return () => clearTimeout(timer); + }, []); + + // Calculate totals + const totalAmount = caseDetails.reduce( + (acc, caseDetail) => acc + caseDetail.amount, + 0 + ); + + // Table setup + const tableHeadRow = [ + "Date", + "Particulars", + "Amount", + "Comments", + "Update by ", + "Update On", + ]; + + const handleUpdateStatus = debounce((id) => { + setCaseDetails((prevSponser) => + prevSponser.map((sponsor) => + sponsor.id === id ? { ...sponsor, status: !sponsor.status } : sponsor + ) + ); + toast({ + render: () => , + }); + }, 300); + + // Table filter + const filteredData = caseDetails.filter((item) => { + const name = item.date; + const searchLower = searchTerm.toLowerCase(); + const nameMatches = name.toLowerCase().includes(searchLower); + return nameMatches; + }); + + + const [ extractedArray, setExtractedArray ] = useState(filteredData?.map((item, index) => ({ + id: item?.id, + "Date": ( + + {item.date} + + ), + "Particulars": ( + + {item.particulars} + + ), + "Amount": ( + + {item.amount} + + ), + "Comments": ( + + {item.comments} + + ), + "Update by ": ( + + {item.updateBy} + + ), + "Update On": ( + + {item.updateOn} + + ), + }))); + + const handleDelete = () => { + const updatedSponsors = sponser.filter( + (sponsor) => sponsor.id !== actionId + ); + + setTimeout(() => { + setCaseDetails(updatedSponsors); + setDeleteAlert(false); + setIsLoading(false); + }, 100); + setIsLoading(true); + }; + + const Total = () => { + return ( + + + + + + + + + + + +
+ Total + + {" "} + + {/* {totalAmount} */} + {"5000"} + + {" "} + + {" "} + + {" "} +
+ ); + }; + + return ( + + + + setSearchTerm(e.target.value)} + /> + + + + + + + + } + setMouseEnteredId={setMouseEnteredId} + setMouseEntered={setMouseEntered} + /> + + setDeleteAlert(false)} + isOpen={deleteAlert} + message={"Are you sure you want to delete sponers?"} + alertHandler={handleDelete} + isLoading={isLoading} + /> + + ); +}; + +export default IOCashDetails; diff --git a/src/Pages/IO_Management/CreateIO/InvestmentDocument.jsx b/src/Pages/IO_Management/CreateIO/InvestmentDocument.jsx index 9101030..8b9f946 100644 --- a/src/Pages/IO_Management/CreateIO/InvestmentDocument.jsx +++ b/src/Pages/IO_Management/CreateIO/InvestmentDocument.jsx @@ -1,44 +1,71 @@ -import { Box, Button, HStack, Input, Text, Tooltip, useDisclosure, VStack } from "@chakra-ui/react"; +import { + Box, + Button, + HStack, + Input, + Text, + Tooltip, + useDisclosure, + VStack, + useToast, +} from "@chakra-ui/react"; import React, { useContext, useEffect, useRef, useState } from "react"; +import { useNavigate } from "react-router-dom"; 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"; +import { + AddIcon, + DeleteIcon, + DownloadIcon, + EditIcon, + ViewIcon, +} from "@chakra-ui/icons"; +import { GrDocumentPdf } from "react-icons/gr"; +import { AiOutlineFileGif } from "react-icons/ai"; const InvestmentDocument = ({ control, errors, enableNextTab, index }) => { - const { create, setCreate, sponser, setSponser,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(); + const { slideFromRight } = + useContext(GlobalStateContext); + const firstField = useRef(); + const [searchTerm, setSearchTerm] = useState(""); + const [isLoading, setIsLoading] = useState(true); + const [deleteAlert, setDeleteAlert] = useState(false); + const [actionId, setActionId] = useState(null); + const [mouseEntered, setMouseEntered] = useState(false); + const [mouseEnteredId, setMouseEnteredId] = useState(""); + const { isOpen, onOpen, onClose } = useDisclosure(); + const navigate = useNavigate(); + const toast = useToast(); - useEffect(() => { - // Simulate loading - const timer = setTimeout(() => { - setIsLoading(false); - }, 1500); - - // Cleanup the timer on component unmount - return () => clearTimeout(timer); - }, []); + const [create, setCreate] = useState([ + { + id: 1, + Type: , + fileName: "Investment Private Company", + document: "Investment.pdf", + status: true, + }, + { + id: 2, + Type: , + fileName: "Investment Private", + document: "Investment.pdf", + status: true, + }, + ]); + useEffect(() => { + const timer = setTimeout(() => { + setIsLoading(false); + }, 1500); - - const tableHeadRow = [ - "Sr.no", - "Type", - "File Name", - "Document", - "Action", - ]; + return () => clearTimeout(timer); + }, []); + + const tableHeadRow = ["Sr.no", "Type", "File Name", "Document", "Action"]; const handleUpdateStatus = debounce((id) => { setCreate((prevCreate) => @@ -47,148 +74,141 @@ const InvestmentDocument = ({ control, errors, enableNextTab, index }) => { ) ); toast({ - render: () => , + render: () => ( + + Status changed successfully! + + ), }); }, 300); - const filteredData = create?.filter((item) => { - // Filter by name (case insensitive) - const name = item.Type; - const searchLower = searchTerm.toLowerCase(); - const nameMatches = name.toLowerCase().includes(searchLower); - - return nameMatches; - }); + const filteredData = create.filter((item) => + item?.fileName?.toLowerCase().includes(searchTerm.toLowerCase()) + ); const handleDelete = () => { const updatedCreate = create.filter((create) => create.id !== actionId); - setTimeout(() => { - setSponser(updatedCreate); + setCreate(updatedCreate); setDeleteAlert(false); setIsLoading(false); }, 100); setIsLoading(true); }; - const extractedArray = filteredData?.map((item, index) => ({ + const extractedArray = filteredData.map((item, index) => ({ "Sr.no": ( {index + 1} ), - "Type": ( + Type: ( {item.Type} ), "File Name": ( - - + + {item.fileName} ), - "Document": ( + Document: ( {item.document} ), Action: ( - + @@ -197,10 +217,9 @@ const InvestmentDocument = ({ control, errors, enableNextTab, index }) => { ), })); - return ( - + { - - - + + setDeleteAlert(false)} isOpen={deleteAlert} - message={"Are you sure you want to delete sponers?"} + message="Are you sure you want to delete the sponsor?" alertHandler={handleDelete} isLoading={isLoading} /> diff --git a/src/Pages/IO_Management/CreateIO/Investors.jsx b/src/Pages/IO_Management/CreateIO/Investors.jsx index ebd3eb0..7d3d6ea 100644 --- a/src/Pages/IO_Management/CreateIO/Investors.jsx +++ b/src/Pages/IO_Management/CreateIO/Investors.jsx @@ -27,15 +27,6 @@ import { OPACITY_ON_LOAD } from "../../../Layout/animations"; import DataTable from "../../../Components/DataTable/DataTable"; import { HiDotsVertical } from "react-icons/hi"; import { Link, Link as RouterLink } from "react-router-dom"; -import { - AddIcon, - CheckIcon, - CloseIcon, - DeleteIcon, - EditIcon, - EmailIcon, - ViewIcon, -} from "@chakra-ui/icons"; import Pagination from "../../../Components/Pagination"; import GlobalStateContext from "../../../Contexts/GlobalStateContext"; import CustomAlertDialog from "../../../Components/CustomAlertDialog"; @@ -396,7 +387,7 @@ const Investors = () => { centered={true} emptyMessage={`We don't have any Sponers `} tableHeadRow={tableHeadRow} - data={extractedArray} + data={extractedArray} setData={setExtractedArray} isLoading={isLoading} viewActionId={actionId} diff --git a/src/Pages/IO_Management/CreateIO/KeyMerits.jsx b/src/Pages/IO_Management/CreateIO/KeyMerits.jsx index 9afe914..dbd7fd6 100644 --- a/src/Pages/IO_Management/CreateIO/KeyMerits.jsx +++ b/src/Pages/IO_Management/CreateIO/KeyMerits.jsx @@ -7,6 +7,7 @@ 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"; +import KeyMeritsAdd from "../KeyMeritsAdd"; const KeyMerits = ({enableNextTab, index}) => { const { keyMerits, setKeyMerits,slideFromRight} = @@ -19,6 +20,7 @@ const KeyMerits = ({enableNextTab, index}) => { const [mouseEntered, setMouseEntered] = useState(false); const [mouseEnteredId, setMouseEnteredId] = useState(""); const { isOpen, onOpen, onClose } = useDisclosure(); + useEffect(() => { // Simulate loading @@ -133,7 +135,7 @@ const KeyMerits = ({enableNextTab, index}) => { rounded={"sm"} size={"xs"} > - + { > Add - { + const [file, setFile] = useState(""); + const [fileName, setFileName] = useState(""); + const [alert, setAlert] = useState(false); + + const { + control, + handleSubmit, + formState: { errors }, + } = useForm({ + resolver: yupResolver(investmentDoct), + }); + + + + const onSubmit = (data) => { + console.log(data); + setSponser([ + { + ...data, + status: true, + id: uuidv4(), + createdAt: new Date().toISOString(), + }, + ...investmentDoct, + ]); + }; + + const handleSave = () => { + console.log({ + fileName: fileName, + file:file + }); + setAlert(false) + onClose() + + } + + return ( + <> + + + + + IO Artifacts + + + + + File Name + setFileName(e.target.value)} + fontSize={"sm"} + type="text" + size={"sm"} + /> + + + Document + setFile(e.target.value)} + fontSize={"sm"} + type="file" + className="form-control" + size={"sm"} + /> + + + + + + + + + + + setAlert(false)} + alertHandler={handleSave} + message={"Are you sure you want to add this document?"} + /> + + ); + }; + + export default IOArtifactsAdd; + \ No newline at end of file diff --git a/src/Pages/IO_Management/InvestmentDocuments.jsx b/src/Pages/IO_Management/InvestmentDocuments.jsx index e95146b..a2a5d6f 100644 --- a/src/Pages/IO_Management/InvestmentDocuments.jsx +++ b/src/Pages/IO_Management/InvestmentDocuments.jsx @@ -11,63 +11,110 @@ import { FormControl, FormLabel, Input, - InputGroup, - Stack, + Text, } from "@chakra-ui/react"; import * as yup from "yup"; -import React, { useContext, useEffect, useRef, useState } from "react"; -import FormInputMain from "../../Components/FormInputMain"; +import React, { useContext, useState } from "react"; import { useForm } from "react-hook-form"; import { yupResolver } from "@hookform/resolvers/yup"; import CustomAlertDialog from "../../Components/CustomAlertDialog"; +import { v4 as uuidv4 } from 'uuid'; +import { useNavigate } from 'react-router-dom'; +import { GrDocumentPdf } from "react-icons/gr"; +import { FaRegFileAlt } from "react-icons/fa"; +import { TbFileTypeDocx } from "react-icons/tb"; +import { AiOutlineFileGif } from "react-icons/ai"; +import GlobalStateContext from "../../Contexts/GlobalStateContext"; +import InvestmentDocument from "./CreateIO/InvestmentDocument"; -export const investmentDoct = yup.object().shape({ - type: yup.string().required("Sponser name is required"), - document: yup.string().required("Sponser name is required"), - fileName: yup.string().required("Mobile no is required"), +export const bytesToMB = (bytes) => { + if (bytes === 0) return "0 MB"; + const bytesInMB = 1024 * 1024; + return (bytes / bytesInMB).toFixed(2) + " MB"; +}; + +export const investmentDocSchema = yup.object().shape({ + document: yup.mixed().required("Document is required"), + fileName: yup.string().required("File name is required"), }); -const InvestmentDocuments = ({ id, isOpen, onClose, firstField }) => { - const [file, setFile] = useState(""); - const [fileName, setFileName] = useState(""); +const InvestmentDocuments = ({ id, isOpen, onClose, firstField, create, setCreate }) => { + const [file, setFile] = useState(null); const [alert, setAlert] = useState(false); + const navigate = useNavigate(); + const { - control, + register, handleSubmit, formState: { errors }, } = useForm({ - resolver: yupResolver(investmentDoct), + resolver: yupResolver(investmentDocSchema), }); - + // const onSubmit = (data) => { + // console.log(data); + // setFile(data.document[0]); + // // Additional code for handling form submission + // }; const onSubmit = (data) => { console.log(data); - setSponser([ - { - ...data, - status: true, - id: uuidv4(), - createdAt: new Date().toISOString(), - }, - ...investmentDoct, - ]); + setFile(data.document[0]); + + const newDocument = { + ...data, + document: data.document[0].name, // Store the document name + status: true, + id: uuidv4(), + createdAt: new Date().toISOString(), + Type:getFileIcon(file.type) + }; + + setCreate((prevCreate) => [...prevCreate, newDocument]); + navigate(" "); }; - const handleSave = () => { - console.log({ - fileName: fileName, - file:file - }); - setAlert(false) - onClose() + const handleFileChange = (event) => { + const selectedFile = event.target.files[0]; + setFile(selectedFile); + }; - } + const getFileIcon = (type) => { + switch (type) { + case 'application/pdf': + return ; + case 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': + case 'application/msword': + return ; + case 'image/jpeg': + case 'image/png': + case 'image/gif': + return ; + default: + return ; + } + }; + + const getFileTitle = (type) => { + switch (type) { + case 'application/pdf': + return "PDF"; + case 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': + case 'application/msword': + return "DOCX"; + case 'image/jpeg': + case 'image/png': + case 'image/gif': + return "JPG"; + default: + return "HH"; + } + }; return ( <> - { - Add Details - - - - - File Name - setFileName(e.target.value)} - fontSize={"sm"} - type="text" - size={"sm"} - /> - - - File Name - setFile(e.target.value)} - fontSize={"sm"} - type="file" - className="form-control" - size={"sm"} - /> - - - - - - - - + Add Details + + + + File Name + + {errors.fileName && ( + + {errors.fileName.message} + + )} + + + Document + + {errors.document && ( + + {errors.document.message} + + )} + + {file && ( + + + {getFileIcon(file.type)} + + {file.name} + + + {bytesToMB(file.size)} + + )} + + + + + + setAlert(false)} - alertHandler={handleSave} - message={"Are you sure you want to add this document?"} + message="Are you sure you want to add this document?" /> ); diff --git a/src/Pages/IO_Management/KeyMeritsAdd.jsx b/src/Pages/IO_Management/KeyMeritsAdd.jsx new file mode 100644 index 0000000..2de28e9 --- /dev/null +++ b/src/Pages/IO_Management/KeyMeritsAdd.jsx @@ -0,0 +1,150 @@ +import { + Box, + Button, + Drawer, + DrawerBody, + DrawerCloseButton, + DrawerContent, + DrawerFooter, + DrawerHeader, + DrawerOverlay, + FormControl, + FormLabel, + Input, + InputGroup, + Stack, + } from "@chakra-ui/react"; + import * as yup from "yup"; + import React, { useContext, useEffect, useRef, useState } from "react"; + import FormInputMain from "../../Components/FormInputMain"; + import { useForm } from "react-hook-form"; + import { yupResolver } from "@hookform/resolvers/yup"; + import CustomAlertDialog from "../../Components/CustomAlertDialog"; + + export const investmentDoct = yup.object().shape({ + type: yup.string().required("Sponser name is required"), + document: yup.string().required("Sponser name is required"), + fileName: yup.string().required("Mobile no is required"), + }); + + const KeyMeritsAdd = ({ id, isOpen, onClose, firstField }) => { + const [file, setFile] = useState(""); + const [fileName, setFileName] = useState(""); + const [alert, setAlert] = useState(false); + + const { + control, + handleSubmit, + formState: { errors }, + } = useForm({ + resolver: yupResolver(investmentDoct), + }); + + + + const onSubmit = (data) => { + console.log(data); + setSponser([ + { + ...data, + status: true, + id: uuidv4(), + createdAt: new Date().toISOString(), + }, + ...investmentDoct, + ]); + }; + + const handleSave = () => { + console.log({ + fileName: fileName, + file:file + }); + setAlert(false) + onClose() + + } + + return ( + <> + + + + + Key Merits + + + + + Title + setFileName(e.target.value)} + fontSize={"sm"} + type="text" + size={"sm"} + /> + + + Sub Title + setFileName(e.target.value)} + fontSize={"sm"} + type="textarea" + size={"sm"} + /> + + + Icon + setFile(e.target.value)} + fontSize={"sm"} + type="file" + className="form-control" + size={"sm"} + /> + + + + + + + + + + + setAlert(false)} + alertHandler={handleSave} + message={"Are you sure you want to add this document?"} + /> + + ); + }; + + export default KeyMeritsAdd; + \ No newline at end of file diff --git a/src/Pages/Master/Sponser/AddSponser.jsx b/src/Pages/Master/Sponser/AddSponser.jsx index 238d22c..850c175 100644 --- a/src/Pages/Master/Sponser/AddSponser.jsx +++ b/src/Pages/Master/Sponser/AddSponser.jsx @@ -257,7 +257,7 @@ const AddSponser = () => { createdAt: new Date().toISOString(), }, ...sponser, - ]); + ]); navigate("/sponser"); }; diff --git a/src/Pages/Master/Sponser/Sponsers.jsx b/src/Pages/Master/Sponser/Sponsers.jsx index 8fb996a..ba5dea9 100644 --- a/src/Pages/Master/Sponser/Sponsers.jsx +++ b/src/Pages/Master/Sponser/Sponsers.jsx @@ -1,16 +1,8 @@ import { - Avatar, - Badge, Box, Button, HStack, Input, - Menu, - MenuButton, - MenuItem, - MenuList, - Portal, - Select, Switch, Tag, Text, @@ -194,7 +186,7 @@ const Sponser = () => { - + { }, 100); setIsLoading(true); }; + return (