update Io Cash Nav Transaction

This commit is contained in:
YasinShaikh123
2024-11-18 17:54:23 +05:30
parent 5fc16b58ea
commit 61e49393fe
28 changed files with 2350 additions and 1220 deletions

View File

@@ -12,7 +12,8 @@ const FullscreenLoaders = ({height}) => {
w={"100%"}
h={height ? height: "100vh"}
gap={4}
><div className="dot-spinner">
>
{/* <div className="dot-spinner">
<div className="dot-spinner__dot"></div>
<div className="dot-spinner__dot"></div>
<div className="dot-spinner__dot"></div>
@@ -21,8 +22,9 @@ const FullscreenLoaders = ({height}) => {
<div className="dot-spinner__dot"></div>
<div className="dot-spinner__dot"></div>
<div className="dot-spinner__dot"></div>
</div>
</div> */}
{/* <Text color='#004717' fontSize={'md'} fontWeight={500}>Loading...</Text> */}
<Spinner />
</Box>
);
};

View File

@@ -138,7 +138,7 @@ import RequestRejectModal from "./RequestRejectModal";
"Deposit Date",
"Deposit Amount (BHD)",
"Support Image",
"Action",
"Action",
];

View File

@@ -91,11 +91,11 @@ const AddCashDetails = ({ isOpen, onClose, firstField, actionId, setActionId, da
render: () => <ToastBox message={res?.error?.data?.message } status={"error"} />,
});
}
} catch (error) {
console.log(error);
setIsLoading(false);
}
};

View File

@@ -1,37 +1,49 @@
import React, { useContext, useEffect, useRef, useState } from 'react'
import GlobalStateContext from '../../../Contexts/GlobalStateContext';
import { Box, HStack, Input,Text, Table, Tbody, Th, Tr, Avatar, useDisclosure,Button, Badge } from '@chakra-ui/react';
import { OPACITY_ON_LOAD } from '../../../Layout/animations';
import Pagination from '../../../Components/Pagination';
import NormalTable from '../../../Components/DataTable/NormalTable';
import CustomAlertDialog from '../../../Components/CustomAlertDialog';
import { formatDatee } from '../../../Components/FormField';
import { AddIcon } from '@chakra-ui/icons';
import AddIONav from './AddIONav';
import React, { useContext, useEffect, useRef, useState } from "react";
import GlobalStateContext from "../../../Contexts/GlobalStateContext";
import {
Box,
HStack,
Input,
Text,
Table,
Tbody,
Th,
Tr,
Avatar,
useDisclosure,
Button,
Badge,
} from "@chakra-ui/react";
import { OPACITY_ON_LOAD } from "../../../Layout/animations";
import Pagination from "../../../Components/Pagination";
import NormalTable from "../../../Components/DataTable/NormalTable";
import CustomAlertDialog from "../../../Components/CustomAlertDialog";
import { formatDatee } from "../../../Components/FormField";
import { AddIcon } from "@chakra-ui/icons";
import AddIONav from "./AddIONav";
const Destribution = () => {
const { navDetails, setNavDetails, IODetails } =
useContext(GlobalStateContext);
const firstField = useRef();
const { isOpen, onOpen, onClose } = useDisclosure();
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 firstField = useRef();
const { isOpen, onOpen, onClose } = useDisclosure();
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("");
console.log(IODetails?.ioNAVHistory);
const formatDate = (date) => {
return new Date(date).toLocaleDateString("en-GB", {
day: "2-digit",
month: "2-digit",
year: "numeric",
});
};
console.log(IODetails?.ioNAVHistory);
const formatDate = (date) => {
return new Date(date).toLocaleDateString('en-GB', {
day: '2-digit',
month: '2-digit',
year: 'numeric',
});
};
useEffect(() => {
// Simulate loading
const timer = setTimeout(() => {
@@ -42,32 +54,38 @@ const Destribution = () => {
return () => clearTimeout(timer);
}, []);
// Table setup
const tableHeadRow = [
// "Sr.No",
"Date",
"Amount",
"% of Investment"
];
// Table setup
const tableHeadRow = [
// "Sr.No",
"Date",
"Amount",
"% of Investment",
];
// Table filter
const filteredData = IODetails?.distributionToInvestor?.filter((item) => {
const name = item?.transactionAmount;
const searchLower = searchTerm.toLowerCase();
const nameMatches = name.toLowerCase().includes(searchLower);
return nameMatches;
}).sort((b, a) => new Date(a.transactionDate) - new Date(b.transactionDate));
// Table filter
const filteredData = IODetails?.distributionToInvestor
?.filter((item) => {
const name = item?.transactionAmount;
const searchLower = searchTerm.toLowerCase();
const nameMatches = name.toLowerCase().includes(searchLower);
return nameMatches;
})
.sort((b, a) => new Date(a.transactionDate) - new Date(b.transactionDate));
const extractedArray=filteredData?.map((item, index) => ({
const extractedArray = filteredData?.map((item, index) => ({
id: item?.id,
"Sr.No": <Text
justifyContent={"start"}
as={"span"}
color={"teal.900"}
fontWeight={"500"}
className="d-flex align-items-start web-text-small"
>{item?.id}</Text>,
"Date": (
"Sr.No": (
<Text
justifyContent={"start"}
as={"span"}
color={"teal.900"}
fontWeight={"500"}
className="d-flex align-items-start web-text-small"
>
{item?.id}
</Text>
),
Date: (
<Text
justifyContent={"center"}
as={"span"}
@@ -78,7 +96,7 @@ const Destribution = () => {
{formatDate(item.transactionDate)}
</Text>
),
"Amount": (
Amount: (
<Text
justifyContent={"center"}
as={"span"}
@@ -86,11 +104,13 @@ const Destribution = () => {
fontWeight={"500"}
className="d-flex align-items-center web-text-small"
>
<Badge ms={1} colorScheme="green" me={1}>$</Badge>
<Badge ms={1} colorScheme="green" me={1}>
$
</Badge>
{`${parseFloat(item.transactionAmount || 0).toLocaleString(undefined, {
minimumFractionDigits: 2,
maximumFractionDigits: 2,
})}`}
minimumFractionDigits: 2,
maximumFractionDigits: 2,
})}`}
</Text>
),
"% of Investment": (
@@ -106,12 +126,8 @@ const Destribution = () => {
),
}));
const handleDelete = () => {
const updatedNav = navDetails.filter(
(sponsor) => sponsor.id !== actionId
);
const updatedNav = navDetails.filter((sponsor) => sponsor.id !== actionId);
setTimeout(() => {
setNavDetails(updatedNav);
@@ -121,12 +137,11 @@ const Destribution = () => {
setIsLoading(true);
};
const Total = () => {
return (
<Table size="sm">
<Tbody>
<Tr backgroundColor="gray.50">
<Tr backgroundColor="gray.50">
<Th
textAlign={"center"}
p={3}
@@ -147,8 +162,13 @@ const Destribution = () => {
wordBreak="normal"
overflowWrap="normal"
>
<Badge ms={1} colorScheme="green" me={1}>$</Badge>{IODetails?.total_distributeToInvestor_amt?.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
<Badge ms={1} colorScheme="green" me={1}>
$
</Badge>
{IODetails?.total_distributeToInvestor_amt?.toLocaleString(
undefined,
{ minimumFractionDigits: 2, maximumFractionDigits: 2 }
)}
</Th>
<Th
textAlign={"center"}
@@ -167,62 +187,52 @@ const Destribution = () => {
);
};
return (
<Box {...OPACITY_ON_LOAD} pb={0}>
<Box bg="white.500">
<HStack
display={"flex"}
justifyContent={"space-between"}
pb={3}
spacing="24px"
>
<Input
type="search"
width={300}
placeholder="Search..."
size="sm"
rounded="sm"
focusBorderColor="green.500"
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
/>
</HStack>
</Box>
<NormalTable
centered={true}
emptyMessage={`We don't have any Sponers`}
tableHeadRow={tableHeadRow}
data={extractedArray}
isLoading={isLoading}
viewActionId={actionId}
setViewActionId={setActionId}
total={<Total />}
setMouseEnteredId={setMouseEnteredId}
setMouseEntered={setMouseEntered}
/>
<CustomAlertDialog
onClose={() => setDeleteAlert(false)}
isOpen={deleteAlert}
message={"Are you sure you want to delete sponers?"}
alertHandler={handleDelete}
isLoading={isLoading}
/>
return (<Box {...OPACITY_ON_LOAD} pb={0}>
<Box bg="white.500">
<HStack
display={"flex"}
justifyContent={"space-between"}
pb={3}
spacing="24px"
>
<Input
type="search"
width={300}
placeholder="Search..."
size="sm"
rounded="sm"
focusBorderColor="green.500"
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
/>
</HStack>
<AddIONav isOpen={isOpen} onClose={onClose} firstField={firstField} />
</Box>
);
};
<NormalTable
centered={true}
emptyMessage={`We don't have any Sponers`}
tableHeadRow={tableHeadRow}
data={extractedArray}
isLoading={isLoading}
viewActionId={actionId}
setViewActionId={setActionId}
total={<Total/>}
setMouseEnteredId={setMouseEnteredId}
setMouseEntered={setMouseEntered}
/>
<CustomAlertDialog
onClose={() => setDeleteAlert(false)}
isOpen={deleteAlert}
message={"Are you sure you want to delete sponers?"}
alertHandler={handleDelete}
isLoading={isLoading}
/>
<AddIONav
isOpen={isOpen}
onClose={onClose}
firstField={firstField} />
</Box>
)
}
export default Destribution
export default Destribution;

View File

@@ -36,7 +36,7 @@ const cashDetails = yup.object().shape({
comments: yup.string().notRequired(),
});
const AddApproved = ({ isOpen, onClose, firstField, actionId, setActionId, data }) => {
const AddCaseDetails = ({ isOpen, onClose, firstField, actionId, setActionId, data }) => {
const params = useParams()
const id = params?.id
const [file, setFile] = useState("");
@@ -79,13 +79,13 @@ const AddApproved = ({ isOpen, onClose, firstField, actionId, setActionId, data
try {
const res = await createIoCash({ data, id })
if (res?.data?.statusCode === 200) {
if (res?.data) {
setIsLoading(false);
toast({
render: () => <ToastBox message={res?.data?.message} />,
});
handleClose()
}else if(res?.error?.status === 400){
}else if(res?.error){
setIsLoading(false);
toast({
render: () => <ToastBox message={res?.error?.data?.message } status={"error"} />,
@@ -94,6 +94,7 @@ const AddApproved = ({ isOpen, onClose, firstField, actionId, setActionId, data
} catch (error) {
console.log(error);
setIsLoading(false);
}
};
@@ -248,4 +249,4 @@ const AddApproved = ({ isOpen, onClose, firstField, actionId, setActionId, data
);
};
export default AddApproved;
export default AddCaseDetails;

View File

@@ -26,20 +26,20 @@ import CustomAlertDialog from "../../../../Components/CustomAlertDialog";
import ToastBox from "../../../../Components/ToastBox";
import AddCashDetails from "../AddCashDetails";
import { debounce } from "../../../Admin/Contact";
import AddApproved from "./addApproved";
import AddApproved from "./AddCaseDetails";
import { useUpdateIOCaseMutation } from "../../../../Services/io.service";
import { useParams } from "react-router-dom";
import AddCaseDetails from "./AddCaseDetails";
const formatDate = (date) => new Date(date).toLocaleDateString();
const Approved = () => {
const firstField = useRef();
const params = useParams()
const params = useParams();
const toast = useToast();
const id = params?.id
const id = params?.id;
const { isOpen, onOpen, onClose } = useDisclosure();
const { IODetails, approved, setApproved } =
useContext(GlobalStateContext);
const { IODetails, approved, setApproved } = useContext(GlobalStateContext);
const [searchTerm, setSearchTerm] = useState("");
const [isLoading, setIsLoading] = useState(true);
const [deleteAlert, setDeleteAlert] = useState(false);
@@ -65,69 +65,59 @@ const Approved = () => {
});
};
console.log("==============",IODetails?.ioCashStatusHistory?.Approved);
console.log("==============", IODetails?.ioCashStatusHistory?.Approved);
// Table filter
const filteredData = IODetails?.ioCashStatusHistory?.Approved?.filter((item) => {
// Filter by name (case insensitive)
const name = item.transactionDate;
const searchLower = searchTerm.toLowerCase();
const nameMatches = name.toLowerCase().includes(searchLower);
return nameMatches;
});
const filteredData = IODetails?.ioCashStatusHistory?.Approved?.filter(
(item) => {
// Filter by name (case insensitive)
const name = item.transactionDate;
const searchLower = searchTerm.toLowerCase();
const nameMatches = name.toLowerCase().includes(searchLower);
return nameMatches;
}
);
const [updateIOCase] = useUpdateIOCaseMutation()
const [updateIOCase] = useUpdateIOCaseMutation();
const tableHeadRow = [
"Sr No.",
"Transaction date",
"Transaction Type",
"Amount",
"Comments",
"Update by",
// "Update by",
"Update On",
];
const extractedArray = filteredData?.map((item, index) => ({
id: item?.id,
"Sr No.": (
<Text
as={"span"}
color={"gray.800"}
fontWeight={"500"}
>
<Text as={"span"} color={"gray.800"} fontWeight={"500"}>
{index + 1}.
</Text>
),
"Transaction date": (
<Text
as={"span"}
color={"gray.600"}
fontWeight={"500"}
>
<Text as={"span"} color={"gray.600"} fontWeight={"500"}>
{formatDate(item?.transactionDate)}
</Text>
),
"Amount": (
<Text
as={"span"}
color={"gray.800"}
fontWeight={"500"}
>
"Transaction Type": (
<Text as={"span"} color={"gray.600"} fontWeight={"500"}>
{item?.transactionType}
</Text>
),
Amount: (
<Text as={"span"} color={"gray.800"} fontWeight={"500"}>
<Badge ms={1} colorScheme="green" me={1}>
$
</Badge>
{item?.transactionAmount}
</Text>
),
"Comments": (
<Text
w={"100px"}
as={"span"}
color={"gray.800"}
fontWeight={"500"}
>
{item?.comments ? item?.comments : "---" }
Comments: (
<Text w={"100px"} as={"span"} color={"gray.800"} fontWeight={"500"}>
{item?.comments ? item?.comments : "---"}
</Text>
),
"Update by": (
@@ -140,7 +130,7 @@ const Approved = () => {
alignItems={"center"}
>
<Avatar
mr={2}
mr={2}
size="sm"
name={item.creator?.firstName}
src={item.creator?.profilePhoto}
@@ -149,12 +139,7 @@ const Approved = () => {
</Text>
),
"Update On": (
<Text
w={"100px"}
as={"span"}
color={"gray.800"}
fontWeight={"500"}
>
<Text w={"100px"} as={"span"} color={"gray.800"} fontWeight={"500"}>
{formatDate(item.updatedAt)}
</Text>
),
@@ -173,13 +158,15 @@ const Approved = () => {
setIsLoading(true);
};
const ioCashExporteDetails = IODetails?.ioCashStatusHistory?.Approved?.map((item, index) => ({
"Transaction date": item?.transactionDate,
"Transaction type": item?.transactionType,
Amount: parseFloat(item?.transactionAmount) || 0,
Comments: item?.comments,
}));
const ioCashExporteDetails = IODetails?.ioCashStatusHistory?.Approved?.map(
(item, index) => ({
"Transaction date": item?.transactionDate,
"Transaction type": item?.transactionType,
Amount: parseFloat(item?.transactionAmount) || 0,
Comments: item?.comments,
})
);
const exportToExcelNew = (data, fileName) => {
const worksheet = XLSX.utils.json_to_sheet(data);
const workbook = XLSX.utils.book_new();
@@ -273,9 +260,9 @@ const Approved = () => {
);
};
const handleAdd = async () =>{
try {
const res = await updateIOCase(id)
const handleAdd = async () => {
try {
const res = await updateIOCase(id);
if (res?.data) {
toast({
render: () => (
@@ -283,8 +270,7 @@ const Approved = () => {
),
});
setIsLoading(false);
onOpen()
onOpen();
} else if (res?.error) {
toast({
render: () => (
@@ -293,10 +279,8 @@ const Approved = () => {
});
setIsLoading(false);
}
} catch (error) {
}
}
} catch (error) {}
};
return (
<Box {...OPACITY_ON_LOAD} pb={0}>
@@ -345,7 +329,7 @@ const Approved = () => {
Add
</Button> */}
{IODetails?.isInvestedAmount ? (
<Button
localStorage?.getItem('role') ==="Maker"&& <Button
onClick={handleAdd}
leftIcon={<AddIcon />}
colorScheme="forestGreen"
@@ -367,7 +351,7 @@ const Approved = () => {
isLoading={isLoading}
viewActionId={actionId}
setViewActionId={setActionId}
total={<Total/>}
total={<Total />}
setMouseEnteredId={setMouseEnteredId}
setMouseEntered={setMouseEntered}
/>
@@ -380,7 +364,7 @@ const Approved = () => {
isLoading={isLoading}
/> */}
<AddApproved
<AddCaseDetails
isOpen={isOpen}
onClose={onClose}
firstField={firstField}

View File

@@ -35,17 +35,19 @@ import { debounce } from "../../../Admin/Contact";
import AddPending from "./AddPending";
import { useParams } from "react-router-dom";
import { useUpdateIOCaseMutation } from "../../../../Services/io.service";
import RequestApproveModal from "./RequestApproveModal";
import RequestRejectModal from "./RequestRejectModal";
import AddCaseDetails from "./AddCaseDetails";
const formatDate = (date) => new Date(date).toLocaleDateString();
const Pending = () => {
const toast = useToast();
const params = useParams()
const id = params?.id
const params = useParams();
const id = params?.id;
const firstField = useRef();
const { isOpen, onOpen, onClose } = useDisclosure();
const { IODetails, approved, setApproved } =
useContext(GlobalStateContext);
const { IODetails, approved, setApproved } = useContext(GlobalStateContext);
const [searchTerm, setSearchTerm] = useState("");
const [isLoading, setIsLoading] = useState(true);
const [deleteAlert, setDeleteAlert] = useState(false);
@@ -53,7 +55,17 @@ const Pending = () => {
const [mouseEntered, setMouseEntered] = useState(false);
const [mouseEnteredId, setMouseEnteredId] = useState("");
const [updateIOCase] = useUpdateIOCaseMutation()
const [updateIOCase] = useUpdateIOCaseMutation();
const {
isOpen: isConfirmOpen,
onOpen: onConfirmOpen,
onClose: onConfirmClose,
} = useDisclosure();
const {
isOpen: isRejectOpen,
onOpen: onRejectOpen,
onClose: onRejectClose,
} = useDisclosure();
useEffect(() => {
// Simulate loading
@@ -74,22 +86,25 @@ const Pending = () => {
};
// Table filter
const filteredData = IODetails?.ioCashStatusHistory?.Pending?.filter((item) => {
// Filter by name (case insensitive)
const name = item.transactionDate;
const searchLower = searchTerm.toLowerCase();
const nameMatches = name.toLowerCase().includes(searchLower);
return nameMatches;
});
const filteredData = IODetails?.ioCashStatusHistory?.Pending?.filter(
(item) => {
// Filter by name (case insensitive)
const name = item?.transactionDate;
const searchLower = searchTerm?.toLowerCase();
const nameMatches = name?.toLowerCase().includes(searchLower);
return nameMatches;
}
);
const tableHeadRow = [
"Sr No.",
"Transaction date",
"Transaction Type",
"Amount",
"Comments",
"Update by",
// "Update by",
"Update On",
"Status",
...(localStorage?.getItem('role')!=="Maker" ? ["Status"] : []),
];
const extractedArray = filteredData?.map((item, index) => ({
@@ -104,6 +119,11 @@ const Pending = () => {
{formatDate(item?.transactionDate)}
</Text>
),
"Transaction Type": (
<Text as={"span"} color={"gray.600"} fontWeight={"500"}>
{item?.transactionType}
</Text>
),
Amount: (
<Text as={"span"} color={"gray.800"} fontWeight={"500"}>
<Badge ms={1} colorScheme="green" me={1}>
@@ -129,8 +149,8 @@ const Pending = () => {
<Avatar
mr={2}
size="sm"
name={item.creator?.firstName}
src={item.creator?.profilePhoto}
name={item?.creator?.firstName}
src={item?.creator?.profilePhoto}
/>
{item?.creator?.firstName}
</Text>
@@ -213,6 +233,15 @@ const Pending = () => {
setIsLoading(true);
};
const ioCashExporteDetails = IODetails?.ioCashStatusHistory?.Approved?.map(
(item, index) => ({
"Transaction date": item?.transactionDate,
"Transaction type": item?.transactionType,
Amount: parseFloat(item?.transactionAmount) || 0,
Comments: item?.comments,
})
);
const Total = () => {
return (
<Table size="sm">
@@ -306,30 +335,27 @@ const Pending = () => {
);
};
const handleAdd = async () =>{
const handleAdd = async () => {
try {
const res = await updateIOCase(id)
if (res?.data) {
toast({
render: () => (
<ToastBox status={"success"} message={res?.data?.message} />
),
});
setIsLoading(false);
onOpen()
} else if (res?.error) {
toast({
render: () => (
<ToastBox status={"error"} message={res?.error?.data?.message} />
),
});
setIsLoading(false);
}
} catch (error) {
}
}
const res = await updateIOCase(id);
if (res?.data) {
toast({
render: () => (
<ToastBox status={"success"} message={res?.data?.message} />
),
});
setIsLoading(false);
onOpen();
} else if (res?.error) {
toast({
render: () => (
<ToastBox status={"error"} message={res?.error?.data?.message} />
),
});
setIsLoading(false);
}
} catch (error) {}
};
return (
<Box {...OPACITY_ON_LOAD} pb={0}>
@@ -352,17 +378,18 @@ const Pending = () => {
/>
<HStack display={"flex"} alignItems={"center"}>
<Button
onClick={handleAdd}
leftIcon={<AddIcon />}
colorScheme={"forestGreen"}
rounded={"sm"}
fontSize={"xs"}
size={"sm"}
fontWeight={500}
>
Add
</Button>
{IODetails?.isInvestedAmount ? (
localStorage?.getItem('role') ==="Maker"&& <Button
onClick={handleAdd}
leftIcon={<AddIcon />}
colorScheme="forestGreen"
size={"sm"}
rounded={"sm"}
fontSize={"xs"}
>
Add
</Button>
) : null}
</HStack>
</HStack>
</Box>
@@ -387,7 +414,24 @@ const Pending = () => {
isLoading={isLoading}
/>
<AddPending isOpen={isOpen} onClose={onClose} firstField={firstField} />
<AddCaseDetails
isOpen={isOpen}
onClose={onClose}
firstField={firstField}
/>
<RequestApproveModal
// data={data?.data?.rows}
isOpen={isConfirmOpen}
onClose={onConfirmClose}
id={actionId}
// firstField={firstField}
/>
<RequestRejectModal
isOpen={isRejectOpen}
onClose={onRejectClose}
id={actionId}
/>
</Box>
);
};

View File

@@ -26,6 +26,7 @@ import AddRejected from "./AddRejected";
import { useUpdateIOCaseMutation } from "../../../../Services/io.service";
import { useParams } from "react-router-dom";
import ToastBox from "../../../../Components/ToastBox";
import AddCaseDetails from "./AddCaseDetails";
const formatDate = (date) => new Date(date).toLocaleDateString();
@@ -77,9 +78,10 @@ import ToastBox from "../../../../Components/ToastBox";
const tableHeadRow = [
"Sr No.",
"Transaction date",
"Transaction Type",
"Amount",
"Comments",
"Update by",
// "Update by",
"Update On",
];
@@ -103,6 +105,11 @@ import ToastBox from "../../../../Components/ToastBox";
{formatDate(item?.transactionDate)}
</Text>
),
"Transaction Type": (
<Text as={"span"} color={"gray.600"} fontWeight={"500"}>
{item?.transactionType}
</Text>
),
"Amount": (
<Text
as={"span"}
@@ -298,8 +305,8 @@ import ToastBox from "../../../../Components/ToastBox";
/>
<HStack display={"flex"} alignItems={"center"}>
{IODetails?.isInvestedAmount ? (
<Button
{IODetails?.isInvestedAmount ? (
localStorage?.getItem('role') ==="Maker"&& <Button
onClick={handleAdd}
leftIcon={<AddIcon />}
colorScheme="forestGreen"
@@ -334,7 +341,7 @@ import ToastBox from "../../../../Components/ToastBox";
isLoading={isLoading}
/>
<AddRejected
<AddCaseDetails
isOpen={isOpen}
onClose={onClose}
firstField={firstField}

View File

@@ -0,0 +1,176 @@
import {
Box,
Button,
FormControl,
FormHelperText,
FormLabel,
Input,
Modal,
ModalBody,
ModalCloseButton,
ModalContent,
ModalFooter,
ModalHeader,
ModalOverlay,
Text,
Textarea,
useDisclosure,
useToast,
} from "@chakra-ui/react";
import React, { useEffect, useState } from "react";
import * as yup from "yup";
import { yupResolver } from "@hookform/resolvers/yup";
import { useForm } from "react-hook-form";
import ToastBox from "../../../../Components/ToastBox";
import { useApproveIOCaseMutation } from "../../../../Services/io.service";
export const conformModalSchema = yup.object().shape({
// checkerComment: yup.string().required("Comment is required")
// .max(50, "Investment name cannot be more than 50 characters"),
checkerComment: yup
.string()
.required("Comment is required")
.max(200, "Approve Comment cannot be more than 200 characters"),
});
const RequestApproveModal = ({ isOpen, onClose, firstField ,id}) => {
const [isBtnLoading , setIsBtnLoading] = useState(false)
const toast = useToast()
const {
register,
reset,
watch,
handleSubmit,
formState: { errors },
} = useForm({
resolver: yupResolver(conformModalSchema),
});
const [ approveIOCase ] = useApproveIOCaseMutation()
const onSubmit = async(data) => {
console.log(data, "tewxttttt");
setIsBtnLoading(true)
try {
const res = await approveIOCase({data,id})
if (res?.error) {
toast({
render: () => (
<ToastBox status={"error"} message={res?.error?.data?.message} />
),
});
setIsBtnLoading(false)
}else if(res?.data){
toast({
render: () => (
<ToastBox message={res?.data?.message} />
),
});
onClose()
setIsBtnLoading(false)
}else{
toast({
render: () => (
<ToastBox status={'error'} message={"Something went wrong"} />
),
});
setIsBtnLoading(false)
}
} catch (error) {
}
};
const handleFileChange = (event) => {
const selectedFile = event.target.files[0];
setFile(selectedFile);
};
const { data, isLoading } =
(id, {
skip: !id,
});
useEffect(() => {
if (data) {
reset({
investorAmount: data?.data?.investorAmount,
});
}
}, [data, reset]);
const heandleOnClose = () =>{
reset()
onClose()
}
return (
<Modal isCentered isOpen={isOpen} onClose={heandleOnClose} initialFocusRef={firstField}>
<ModalOverlay />
<ModalContent pb={4}>
<ModalHeader fontSize={"md"}>Approve Comment</ModalHeader>
<ModalCloseButton />
{isLoading ? (
<FullscreenLoaders height={"50vh"} />
) : (
<Box as="form" onSubmit={handleSubmit(onSubmit)}>
<ModalBody>
<FormControl mb={4} isRequired>
<FormLabel fontSize="sm">Comment</FormLabel>
<Textarea
rows={6}
focusBorderColor="green.400"
name="checkerComment"
{...register("checkerComment")}
fontSize="sm"
type="textarea"
size="md"
placeholder={"Enter your checkerComment...."}
rounded={"md"}
resize={"none"}
maxLength={200}
/>
{errors.checkerComment && (
<Text fontSize="xs" color="red">
{errors.checkerComment.message}
</Text>
)}
<FormHelperText fontSize="xs" color="gray.500">
Maximum length should be 200 characters. You have entered
{watch("checkerComment")?.length || 0} characters.
</FormHelperText>
</FormControl>
</ModalBody>
<ModalFooter>
<Button
colorScheme="gray"
mr={3}
onClick={onClose}
size={"sm"}
rounded={"sm"}
>
Cancel
</Button>
<Button
colorScheme="forestGreen"
variant="solid"
size={"sm"}
rounded={"sm"}
isLoading={isBtnLoading}
type="submit"
>
Send
</Button>
</ModalFooter>
</Box>
)}
</ModalContent>
</Modal>
);
};
export default RequestApproveModal;

View File

@@ -0,0 +1,164 @@
import {
Box,
Button,
FormControl,
FormLabel,
Input,
Modal,
ModalBody,
ModalCloseButton,
ModalContent,
ModalFooter,
ModalHeader,
ModalOverlay,
Text,
Textarea,
useDisclosure,
useToast,
} from "@chakra-ui/react";
import React, { useEffect, useState } from "react";
import * as yup from "yup";
import { yupResolver } from "@hookform/resolvers/yup";
import { useForm } from "react-hook-form";
import ToastBox from "../../../../Components/ToastBox";
import { useRejectIOCaseMutation } from "../../../../Services/io.service";
export const conformModalSchema = yup.object().shape({
comments: yup.string().required("Comment is required"),
});
const RequestRejectModal = ({ isOpen, onClose, firstField ,id}) => {
const [isBtnLoading , setIsBtnLoading] = useState(false)
const toast = useToast()
const {
register,
reset,
handleSubmit,
formState: { errors },
} = useForm({
resolver: yupResolver(conformModalSchema),
});
const [ rejectIOCase ] = useRejectIOCaseMutation()
const onSubmit = async(data) => {
console.log(data, "tewxttttt");
setIsBtnLoading(true)
try {
const res = await rejectIOCase({data,id})
if (res?.error) {
toast({
render: () => (
<ToastBox status={"error"} message={res?.error?.data?.message} />
),
});
setIsBtnLoading(false)
}else if(res?.data){
toast({
render: () => (
<ToastBox message={res?.data?.message} />
),
});
onClose()
setIsBtnLoading(false)
}else{
toast({
render: () => (
<ToastBox status={'error'} message={"Something went wrong"} />
),
});
setIsBtnLoading(false)
}
} catch (error) {
}
};
const handleFileChange = (event) => {
const selectedFile = event.target.files[0];
setFile(selectedFile);
};
const { data, isLoading } =
(id, {
skip: !id,
});
useEffect(() => {
if (data) {
reset({
investorAmount: data?.data?.investorAmount,
});
}
}, [data, reset]);
const heandleOnClose = () =>{
reset()
onClose()
}
return (
<Modal isCentered isOpen={isOpen} onClose={heandleOnClose} initialFocusRef={firstField}>
<ModalOverlay />
<ModalContent pb={4}>
<ModalHeader fontSize={"md"}>Reject Comment</ModalHeader>
<ModalCloseButton />
{isLoading ? (
<FullscreenLoaders height={"50vh"} />
) : (
<Box as="form" onSubmit={handleSubmit(onSubmit)}>
<ModalBody>
<FormControl mb={4} isRequired>
<FormLabel fontSize="sm">Comment</FormLabel>
<Textarea
rows={6}
focusBorderColor="green.400"
name="comments"
{...register("comments")}
fontSize="sm"
type="textarea"
size="md"
placeholder={"Enter your comments...."}
rounded={"md"}
resize={"none"}
/>
{errors.comments && (
<Text fontSize="xs" color="red">
{errors.comments.message}
</Text>
)}
</FormControl>
</ModalBody>
<ModalFooter>
<Button
colorScheme="gray"
mr={3}
onClick={onClose}
size={"sm"}
rounded={"sm"}
>
Cancel
</Button>
<Button
colorScheme="forestGreen"
variant="solid"
size={"sm"}
rounded={"sm"}
isLoading={isBtnLoading}
type="submit"
>
Send
</Button>
</ModalFooter>
</Box>
)}
</ModalContent>
</Modal>
);
};
export default RequestRejectModal;

View File

@@ -1,251 +0,0 @@
import {
Box,
Button,
Drawer,
DrawerBody,
DrawerCloseButton,
DrawerContent,
DrawerFooter,
DrawerHeader,
DrawerOverlay,
FormControl,
FormErrorMessage,
FormLabel,
Input,
Select,
Stack,
Textarea,
useToast,
} from "@chakra-ui/react";
import * as yup from "yup";
import React, { useState, useEffect, useContext } from "react";
import { useForm, Controller } from "react-hook-form";
import { yupResolver } from "@hookform/resolvers/yup";
import { v4 as uuidv4 } from "uuid";
import { useParams } from "react-router-dom";
import CustomAlertDialog from "../../../../Components/CustomAlertDialog";
import { useCreateIoCashMutation, useCreateVideoArtifactsMutation, useUpdateVideoArtifactsMutation } from "../../../../Services/io.service";
import ToastBox from "../../../../Components/ToastBox";
import GlobalStateContext from "../../../../Contexts/GlobalStateContext";
import CurrencyInput from "../../../../Components/CurrencyInput";
const cashDetails = yup.object().shape({
transactionDate: yup.string().required("Date is required"),
ioTransType_xid: yup.number().required("Cash transaction is required"),
transactionAmount: yup.number().required("Transaction Amount is required"),
comments: yup.string().notRequired(),
});
const AddApproved = ({ isOpen, onClose, firstField, actionId, setActionId, data }) => {
const params = useParams()
const id = params?.id
const [file, setFile] = useState("");
const [fileName, setFileName] = useState("");
const [isLoading, setIsLoading] = useState(false)
const [alert, setAlert] = useState(false);
const toast = useToast();
// ======================[ Cotext Api ]
const { IODetails } = useContext(GlobalStateContext);
const found = data?.find((item) => item?.id === actionId);
const [createArtifactsVideo] = useCreateVideoArtifactsMutation()
const [updateVideoArtifacts] = useUpdateVideoArtifactsMutation()
// const {
// data
// } = useGetArtifactsQuery(id)
const {
control,
handleSubmit,
watch,
reset,
formState: { errors },
} = useForm({
resolver: yupResolver(cashDetails),
});
const [createIoCash] = useCreateIoCashMutation()
const onSubmit = async (data) => {
setIsLoading(true)
try {
const res = await createIoCash({ data, id })
if (res?.data?.statusCode === 200) {
setIsLoading(false);
toast({
render: () => <ToastBox message={res?.data?.message} />,
});
handleClose()
}else if(res?.error?.status === 400){
setIsLoading(false);
toast({
render: () => <ToastBox message={res?.error?.data?.message } status={"error"} />,
});
}
} catch (error) {
console.log(error);
}
};
const handleConfirm = () => {
handleSubmit(onSubmit)();
};
const handleSave = () => {
handleSubmit(onSubmit)();
};
const handleClose = () => {
setAlert(false)
onClose()
reset({
transactionAmount:""
})
}
return (
<>
<Drawer
size={"md"}
isOpen={isOpen}
placement="right"
initialFocusRef={firstField}
onClose={handleClose}
>
<DrawerOverlay />
<DrawerContent>
<DrawerCloseButton />
<DrawerHeader fontSize={"sm"}>IO Nav Details</DrawerHeader>
<DrawerBody>
<Stack spacing={4}>
<FormControl isInvalid={errors.transactionDate} isRequired>
<FormLabel fontSize={"sm"}>Date Selection</FormLabel>
<Controller
name="transactionDate"
control={control}
render={({ field }) => (
<Input
focusBorderColor="forestGreen.300" {...field} fontSize={"sm"} type="date" size={"sm"} />
)}
/>
<FormErrorMessage fontSize={"xs"} fontWeight={500}>
{errors.transactionDate?.message}
</FormErrorMessage>
</FormControl>
<FormControl isInvalid={errors.ioTransType_xid} isRequired>
<FormLabel fontSize={"sm"}>Cash transaction</FormLabel>
<Controller
name="ioTransType_xid"
control={control}
render={({ field }) => (
<Select
{...field}
placeholder="Select an option"
fontSize={"sm"}
size={"sm"}
focusBorderColor="forestGreen.300"
>
{IODetails?.ioCashTransaction?.map(({ id, transactionName }) => (
<option key={id} value={id}>
{transactionName}
</option>
))}
</Select>
)}
/>
<FormErrorMessage fontSize={"xs"} fontWeight={500}>
{errors.ioTransType_xid?.message}
</FormErrorMessage>
</FormControl>
<FormControl isInvalid={errors.transactionAmount} isRequired>
<FormLabel fontSize={"sm"}>Transaction Amount</FormLabel>
<Controller
name="transactionAmount"
control={control}
render={({ field }) => (
<CurrencyInput {...field} textAlign={'right'} fontSize={"sm"} type="number" size={"sm"} />
)}
/>
<FormErrorMessage fontSize={"xs"} fontWeight={500}>
{errors.transactionAmount?.message}
</FormErrorMessage>
</FormControl>
<FormControl isInvalid={errors.comments}>
<FormLabel fontSize={"sm"}>Comments</FormLabel>
<Controller
name="comments"
control={control}
render={({ field }) => (
<Textarea {...field} textAlign={'left'}
focusBorderColor="forestGreen.300" fontSize={"sm"} type="text" size={"sm"} />
)}
/>
<FormErrorMessage fontSize={"xs"} fontWeight={500}>
{errors.comments?.message}
</FormErrorMessage>
</FormControl>
</Stack>
</DrawerBody>
<DrawerFooter>
<Button
variant="outline"
colorScheme={"forestGreen"}
rounded={"sm"}
size={"sm"}
mr={3}
onClick={handleClose}
>
Cancel
</Button>
<Button
colorScheme={"forestGreen"}
rounded={"sm"}
size={"sm"}
onClick={() => setAlert(true)}
>
Save
</Button>
</DrawerFooter>
</DrawerContent>
</Drawer>
<CustomAlertDialog
isOpen={alert}
onClose={() => setAlert(false)}
alertHandler={handleSave}
message={"Are you sure you want to add cash details?"}
isLoading={isLoading}
/>
</>
);
};
export default AddApproved;

View File

@@ -11,10 +11,13 @@ import {
FormControl,
FormErrorMessage,
FormLabel,
HStack,
Input,
Select,
Stack,
Text,
Textarea,
VStack,
useToast,
} from "@chakra-ui/react";
import * as yup from "yup";
@@ -24,20 +27,20 @@ import { yupResolver } from "@hookform/resolvers/yup";
import { v4 as uuidv4 } from "uuid";
import { useParams } from "react-router-dom";
import CustomAlertDialog from "../../../../Components/CustomAlertDialog";
import { useCreateIoCashMutation, useCreateVideoArtifactsMutation, useUpdateVideoArtifactsMutation } from "../../../../Services/io.service";
import ToastBox from "../../../../Components/ToastBox";
import GlobalStateContext from "../../../../Contexts/GlobalStateContext";
import CurrencyInput from "../../../../Components/CurrencyInput";
import { useAddNavDetailsMutation } from "../../../../Services/io.service";
import { formatDatee } from "../../../../Components/FormField";
const cashDetails = yup.object().shape({
const ioNav = yup.object().shape({
transactionDate: yup.string().required("Date is required"),
ioTransType_xid: yup.number().required("Cash transaction is required"),
transactionAmount: yup.number().required("Transaction Amount is required"),
transactionAmount: yup.number().required("New NAV is required"),
comments: yup.string().notRequired(),
});
const AddPending = ({ isOpen, onClose, firstField, actionId, setActionId, data }) => {
const params = useParams()
const AddNavDetails = ({ isOpen, onClose, firstField, actionId, setActionId, data }) => {
const params = useParams()
const id = params?.id
const [file, setFile] = useState("");
const [fileName, setFileName] = useState("");
@@ -52,11 +55,10 @@ const AddPending = ({ isOpen, onClose, firstField, actionId, setActionId, data }
const found = data?.find((item) => item?.id === actionId);
const [createArtifactsVideo] = useCreateVideoArtifactsMutation()
const [updateVideoArtifacts] = useUpdateVideoArtifactsMutation()
const [addNavDetails] = useAddNavDetailsMutation()
// const {
// data
// } = useGetArtifactsQuery(id)
// } = useGetArtifactsQuery(id)
const {
control,
@@ -65,35 +67,34 @@ const AddPending = ({ isOpen, onClose, firstField, actionId, setActionId, data }
reset,
formState: { errors },
} = useForm({
resolver: yupResolver(cashDetails),
resolver: yupResolver(ioNav),
});
const [createIoCash] = useCreateIoCashMutation()
const onSubmit = async (data) => {
setIsLoading(true)
try {
const res = await createIoCash({ data, id })
if (res?.data?.statusCode === 200) {
const res = await addNavDetails({ data, id })
if (res?.data?.statusCode === 201) {
setIsLoading(false);
toast({
render: () => <ToastBox message={res?.data?.message} />,
});
handleClose()
}else if(res?.error?.status === 400){
setIsLoading(false);
toast({
render: () => <ToastBox message={res?.error?.data?.message } status={"error"} />,
});
handleClose()
}
} catch (error) {
console.log(error);
}
};
@@ -109,13 +110,31 @@ const AddPending = ({ isOpen, onClose, firstField, actionId, setActionId, data }
};
const handleClose = () => {
setIsLoading(false);
setAlert(false)
onClose()
reset({
transactionAmount:""
transactionDate:"",
transactionAmount:"",
comments:""
})
}
const today = formatDatee(new Date(), 'yyyy-MM-dd');
function calculatePercentage(newNav, currNav) {
const per = (newNav - currNav) / currNav * 100
return per.toFixed(2)
}
console.log(calculatePercentage(1092500, 976070));
return (
<>
<Drawer
@@ -132,14 +151,15 @@ const AddPending = ({ isOpen, onClose, firstField, actionId, setActionId, data }
<DrawerBody>
<Stack spacing={4}>
<FormControl isInvalid={errors.transactionDate} isRequired>
<FormControl isInvalid={errors.transactionDate} isRequired>
<FormLabel fontSize={"sm"}>Date Selection</FormLabel>
<Controller
name="transactionDate"
control={control}
render={({ field }) => (
<Input
focusBorderColor="forestGreen.300" {...field} fontSize={"sm"} type="date" size={"sm"} />
<Input {...field}
max={today} // Set max attribute to todays date
fontSize={"sm"} type="date" size={"sm"} />
)}
/>
<FormErrorMessage fontSize={"xs"} fontWeight={500}>
@@ -148,37 +168,9 @@ const AddPending = ({ isOpen, onClose, firstField, actionId, setActionId, data }
</FormControl>
<FormControl isInvalid={errors.ioTransType_xid} isRequired>
<FormLabel fontSize={"sm"}>Cash transaction</FormLabel>
<Controller
name="ioTransType_xid"
control={control}
render={({ field }) => (
<Select
{...field}
placeholder="Select an option"
fontSize={"sm"}
size={"sm"}
focusBorderColor="forestGreen.300"
>
{IODetails?.ioCashTransaction?.map(({ id, transactionName }) => (
<option key={id} value={id}>
{transactionName}
</option>
))}
</Select>
)}
/>
<FormErrorMessage fontSize={"xs"} fontWeight={500}>
{errors.ioTransType_xid?.message}
</FormErrorMessage>
</FormControl>
<FormControl isInvalid={errors.transactionAmount} isRequired>
<FormLabel fontSize={"sm"}>Transaction Amount</FormLabel>
<FormLabel fontSize={"sm"}>New NAV</FormLabel>
<Controller
name="transactionAmount"
control={control}
@@ -190,7 +182,26 @@ const AddPending = ({ isOpen, onClose, firstField, actionId, setActionId, data }
{errors.transactionAmount?.message}
</FormErrorMessage>
</FormControl>
<HStack justify={'start'} gap={10} bg={'green.100'} p={3} rounded={'md'} shadow={'md'}>
<VStack align={'start'}>
<Text as={'span'} fontSize={'sm'} fontWeight={500}>Current nav</Text>
<Text as={'span'} fontSize={'sm'}>
{parseFloat(IODetails?.ioNAV || 0).toLocaleString(undefined, {
minimumFractionDigits: 2,
maximumFractionDigits: 2,
})}
</Text>
</VStack>
<VStack align={'start'}>
<Text as={'span'} fontSize={'sm'} fontWeight={500}>Live return %</Text>
<Text as={'span'} fontSize={'sm'}>{calculatePercentage(watch()?.transactionAmount||IODetails?.ioNAV,IODetails?.ioNAV)}</Text>
</VStack>
</HStack>
<FormControl isInvalid={errors.comments}>
@@ -199,8 +210,7 @@ const AddPending = ({ isOpen, onClose, firstField, actionId, setActionId, data }
name="comments"
control={control}
render={({ field }) => (
<Textarea {...field} textAlign={'left'}
focusBorderColor="forestGreen.300" fontSize={"sm"} type="text" size={"sm"} />
<Textarea {...field} fontSize={"sm"} type="text" size={"sm"} />
)}
/>
<FormErrorMessage fontSize={"xs"} fontWeight={500}>
@@ -241,11 +251,11 @@ const AddPending = ({ isOpen, onClose, firstField, actionId, setActionId, data }
isOpen={alert}
onClose={() => setAlert(false)}
alertHandler={handleSave}
message={"Are you sure you want to add cash details?"}
message={"Are you sure you want to add NAV details?"}
isLoading={isLoading}
/>
</>
);
};
export default AddPending;
export default AddNavDetails;

View File

@@ -1,251 +0,0 @@
import {
Box,
Button,
Drawer,
DrawerBody,
DrawerCloseButton,
DrawerContent,
DrawerFooter,
DrawerHeader,
DrawerOverlay,
FormControl,
FormErrorMessage,
FormLabel,
Input,
Select,
Stack,
Textarea,
useToast,
} from "@chakra-ui/react";
import * as yup from "yup";
import React, { useState, useEffect, useContext } from "react";
import { useForm, Controller } from "react-hook-form";
import { yupResolver } from "@hookform/resolvers/yup";
import { v4 as uuidv4 } from "uuid";
import { useParams } from "react-router-dom";
import CustomAlertDialog from "../../../../Components/CustomAlertDialog";
import { useCreateIoCashMutation, useCreateVideoArtifactsMutation, useUpdateVideoArtifactsMutation } from "../../../../Services/io.service";
import ToastBox from "../../../../Components/ToastBox";
import GlobalStateContext from "../../../../Contexts/GlobalStateContext";
import CurrencyInput from "../../../../Components/CurrencyInput";
const cashDetails = yup.object().shape({
transactionDate: yup.string().required("Date is required"),
ioTransType_xid: yup.number().required("Cash transaction is required"),
transactionAmount: yup.number().required("Transaction Amount is required"),
comments: yup.string().notRequired(),
});
const AddRejected = ({ isOpen, onClose, firstField, actionId, setActionId, data }) => {
const params = useParams()
const id = params?.id
const [file, setFile] = useState("");
const [fileName, setFileName] = useState("");
const [isLoading, setIsLoading] = useState(false)
const [alert, setAlert] = useState(false);
const toast = useToast();
// ======================[ Cotext Api ]
const { IODetails } = useContext(GlobalStateContext);
const found = data?.find((item) => item?.id === actionId);
const [createArtifactsVideo] = useCreateVideoArtifactsMutation()
const [updateVideoArtifacts] = useUpdateVideoArtifactsMutation()
// const {
// data
// } = useGetArtifactsQuery(id)
const {
control,
handleSubmit,
watch,
reset,
formState: { errors },
} = useForm({
resolver: yupResolver(cashDetails),
});
const [createIoCash] = useCreateIoCashMutation()
const onSubmit = async (data) => {
setIsLoading(true)
try {
const res = await createIoCash({ data, id })
if (res?.data?.statusCode === 200) {
setIsLoading(false);
toast({
render: () => <ToastBox message={res?.data?.message} />,
});
handleClose()
}else if(res?.error?.status === 400){
setIsLoading(false);
toast({
render: () => <ToastBox message={res?.error?.data?.message } status={"error"} />,
});
}
} catch (error) {
console.log(error);
}
};
const handleConfirm = () => {
handleSubmit(onSubmit)();
};
const handleSave = () => {
handleSubmit(onSubmit)();
};
const handleClose = () => {
setAlert(false)
onClose()
reset({
transactionAmount:""
})
}
return (
<>
<Drawer
size={"md"}
isOpen={isOpen}
placement="right"
initialFocusRef={firstField}
onClose={handleClose}
>
<DrawerOverlay />
<DrawerContent>
<DrawerCloseButton />
<DrawerHeader fontSize={"sm"}>IO Nav Details</DrawerHeader>
<DrawerBody>
<Stack spacing={4}>
<FormControl isInvalid={errors.transactionDate} isRequired>
<FormLabel fontSize={"sm"}>Date Selection</FormLabel>
<Controller
name="transactionDate"
control={control}
render={({ field }) => (
<Input
focusBorderColor="forestGreen.300" {...field} fontSize={"sm"} type="date" size={"sm"} />
)}
/>
<FormErrorMessage fontSize={"xs"} fontWeight={500}>
{errors.transactionDate?.message}
</FormErrorMessage>
</FormControl>
<FormControl isInvalid={errors.ioTransType_xid} isRequired>
<FormLabel fontSize={"sm"}>Cash transaction</FormLabel>
<Controller
name="ioTransType_xid"
control={control}
render={({ field }) => (
<Select
{...field}
placeholder="Select an option"
fontSize={"sm"}
size={"sm"}
focusBorderColor="forestGreen.300"
>
{IODetails?.ioCashTransaction?.map(({ id, transactionName }) => (
<option key={id} value={id}>
{transactionName}
</option>
))}
</Select>
)}
/>
<FormErrorMessage fontSize={"xs"} fontWeight={500}>
{errors.ioTransType_xid?.message}
</FormErrorMessage>
</FormControl>
<FormControl isInvalid={errors.transactionAmount} isRequired>
<FormLabel fontSize={"sm"}>Transaction Amount</FormLabel>
<Controller
name="transactionAmount"
control={control}
render={({ field }) => (
<CurrencyInput {...field} textAlign={'right'} fontSize={"sm"} type="number" size={"sm"} />
)}
/>
<FormErrorMessage fontSize={"xs"} fontWeight={500}>
{errors.transactionAmount?.message}
</FormErrorMessage>
</FormControl>
<FormControl isInvalid={errors.comments}>
<FormLabel fontSize={"sm"}>Comments</FormLabel>
<Controller
name="comments"
control={control}
render={({ field }) => (
<Textarea {...field} textAlign={'left'}
focusBorderColor="forestGreen.300" fontSize={"sm"} type="text" size={"sm"} />
)}
/>
<FormErrorMessage fontSize={"xs"} fontWeight={500}>
{errors.comments?.message}
</FormErrorMessage>
</FormControl>
</Stack>
</DrawerBody>
<DrawerFooter>
<Button
variant="outline"
colorScheme={"forestGreen"}
rounded={"sm"}
size={"sm"}
mr={3}
onClick={handleClose}
>
Cancel
</Button>
<Button
colorScheme={"forestGreen"}
rounded={"sm"}
size={"sm"}
onClick={() => setAlert(true)}
>
Save
</Button>
</DrawerFooter>
</DrawerContent>
</Drawer>
<CustomAlertDialog
isOpen={alert}
onClose={() => setAlert(false)}
alertHandler={handleSave}
message={"Are you sure you want to add cash details?"}
isLoading={isLoading}
/>
</>
);
};
export default AddRejected;

View File

@@ -28,12 +28,13 @@ import {
import { debounce } from "../../../Admin/Contact";
import { useParams } from "react-router-dom";
import { useUpdateIOCaseMutation } from "../../../../Services/io.service";
import AddApproved from "./AddApproved";
import AddApproved from "./AddNavDetails";
import AddNavDetails from "./AddNavDetails";
const formatDate = (date) => new Date(date).toLocaleDateString();
const Approved = () => {
const params = useParams()
const params = useParams()
const toast = useToast();
const id = params?.id
const firstField = useRef();
@@ -71,8 +72,8 @@ import AddApproved from "./AddApproved";
const filteredData = IODetails?.ioNAVStatusHistory?.Approved?.filter((item) => {
// Filter by name (case insensitive)
const name = item.transactionAmount;
const searchLower = searchTerm.toLowerCase();
const nameMatches = name.toLowerCase().includes(searchLower);
const searchLower = searchTerm?.toLowerCase();
const nameMatches = name?.toLowerCase().includes(searchLower);
return nameMatches;
});
@@ -83,7 +84,7 @@ import AddApproved from "./AddApproved";
"Last Nav Update",
"Investment Closed",
"Comments",
"Updated By",
// "Updated By",
];
const extractedArray = filteredData?.map((item, index) => ({
@@ -171,30 +172,30 @@ import AddApproved from "./AddApproved";
}));
const handleAdd = async () =>{
try {
const res = await updateIOCase(id)
if (res?.data) {
toast({
render: () => (
<ToastBox status={"success"} message={res?.data?.message} />
),
});
setIsLoading(false);
onOpen()
} else if (res?.error) {
toast({
render: () => (
<ToastBox status={"error"} message={res?.error?.data?.message} />
),
});
setIsLoading(false);
}
} catch (error) {
}
}
const handleAdd = async () =>{
try {
const res = await updateIOCase(id)
if (res?.data) {
toast({
render: () => (
<ToastBox status={"success"} message={res?.data?.message} />
),
});
setIsLoading(false);
onOpen()
} else if (res?.error) {
toast({
render: () => (
<ToastBox status={"error"} message={res?.error?.data?.message} />
),
});
setIsLoading(false);
}
} catch (error) {
}
}
const handleDelete = () => {
const updatedSponsors = sponser.filter(
@@ -266,7 +267,7 @@ import AddApproved from "./AddApproved";
Export xls
</Button>
{IODetails?.isInvestedAmount ? (
<Button
localStorage?.getItem('role') ==="Maker"&& <Button
onClick={handleAdd}
leftIcon={<AddIcon />}
colorScheme="forestGreen"
@@ -278,7 +279,7 @@ import AddApproved from "./AddApproved";
</Button>
) : null}
</HStack>
</HStack>
</HStack>
</Box>
<NormalTable
@@ -300,7 +301,7 @@ import AddApproved from "./AddApproved";
isLoading={isLoading}
/>
<AddApproved
<AddNavDetails
isOpen={isOpen}
onClose={onClose}
firstField={firstField}

View File

@@ -1,119 +1,131 @@
import {
Badge,
Box,
Button,
HStack,
Input,
Text,
Tooltip,
useDisclosure,
useToast,
} from "@chakra-ui/react";
import React, { useContext, useEffect, useRef, useState } from "react";
import { OPACITY_ON_LOAD } from "../../../../Layout/animations";
import NormalTable from "../../../../Components/DataTable/NormalTable";
import GlobalStateContext from "../../../../Contexts/GlobalStateContext";
import CustomAlertDialog from "../../../../Components/CustomAlertDialog";
import { CheckIcon, CloseIcon } from "@chakra-ui/icons";
const formatDate = (date) => new Date(date).toLocaleDateString();
const Pending = () => {
const toast = useToast();
const firstField = useRef();
const { isOpen, onOpen, onClose } = useDisclosure();
const { IODetails, iONAVDetail, setIONAVDetail } =
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("");
useEffect(() => {
// Simulate loading
const timer = setTimeout(() => {
setIsLoading(false);
}, 1500);
// Cleanup the timer on component unmount
return () => clearTimeout(timer);
}, []);
const formatDate = (date) => {
return new Date(date).toLocaleDateString("en-GB", {
day: "2-digit",
month: "2-digit",
year: "numeric",
});
};
// Table filter
const filteredData = IODetails?.ioNAVStatusHistory?.Pending?.filter((item) => {
// Filter by name (case insensitive)
const name = item.transactionDate;
const searchLower = searchTerm.toLowerCase();
const nameMatches = name.toLowerCase().includes(searchLower);
return nameMatches;
Avatar,
Badge,
Box,
Button,
HStack,
Input,
Text,
Tooltip,
useDisclosure,
useToast,
} from "@chakra-ui/react";
import React, { useContext, useEffect, useRef, useState } from "react";
import { OPACITY_ON_LOAD } from "../../../../Layout/animations";
import NormalTable from "../../../../Components/DataTable/NormalTable";
import GlobalStateContext from "../../../../Contexts/GlobalStateContext";
import CustomAlertDialog from "../../../../Components/CustomAlertDialog";
import { AddIcon, CheckIcon, CloseIcon } from "@chakra-ui/icons";
import { useParams } from "react-router-dom";
import { useUpdateIOCaseMutation } from "../../../../Services/io.service";
import ToastBox from "../../../../Components/ToastBox";
import AddNavDetails from "./AddNavDetails";
import RequestApproveModal from "./RequestApproveModal";
import RequestRejectModal from "./RequestRejectModal";
const formatDate = (date) => new Date(date).toLocaleDateString();
const Pending = () => {
const params = useParams();
const toast = useToast();
const id = params?.id;
const firstField = useRef();
const { isOpen, onOpen, onClose } = useDisclosure();
const { IODetails, iONAVDetail, setIONAVDetail } =
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("");
const [updateIOCase] = useUpdateIOCaseMutation();
const {
isOpen: isConfirmOpen,
onOpen: onConfirmOpen,
onClose: onConfirmClose,
} = useDisclosure();
const {
isOpen: isRejectOpen,
onOpen: onRejectOpen,
onClose: onRejectClose,
} = useDisclosure();
useEffect(() => {
// Simulate loading
const timer = setTimeout(() => {
setIsLoading(false);
}, 1500);
// Cleanup the timer on component unmount
return () => clearTimeout(timer);
}, []);
const formatDate = (date) => {
return new Date(date).toLocaleDateString("en-GB", {
day: "2-digit",
month: "2-digit",
year: "numeric",
});
const tableHeadRow = [
"Sr No.",
"Valuation date",
"NAV",
"Last Nav Update",
"Investment Closed",
"Comments",
"Updated By",
"Status",
];
const extractedArray = filteredData?.map((item, index) => ({
id: item?.id,
"Sr No.": (
<Text
as={"span"}
color={"gray.800"}
fontWeight={"500"}
>
{index + 1}.
</Text>
),
"Valuation date": (
<Text
as={"span"}
color={"gray.600"}
fontWeight={"500"}
>
{formatDate(item?.transactionDate)}
</Text>
),
"NAV": (
<Text
as={"span"}
color={"gray.600"}
fontWeight={"500"}
>
<Badge ms={1} colorScheme="green" me={1}>
$
</Badge>
{item?.transactionAmount}
</Text>
),
"Last Nav Update": (
<Text
justifyContent={"center"}
as={"span"}
color={"teal.900"}
fontWeight={"500"}
className="d-flex align-items-center web-text-small"
>
{item.previousNAVvalue && `${item.previousNAVvalue}`}
</Text>
),
"Investment Closed": (
};
// Table filter
const filteredData = IODetails?.ioNAVStatusHistory?.Pending?.filter(
(item) => {
// Filter by name (case insensitive)
const name = item?.transactionDate;
const searchLower = searchTerm?.toLowerCase();
const nameMatches = name?.toLowerCase().includes(searchLower);
return nameMatches;
}
);
const tableHeadRow = [
"Sr No.",
"Valuation date",
"NAV",
"Last Nav Update",
"Investment Closed",
"Comments",
// "Updated By",
...(localStorage?.getItem('role')!=="Maker" ? ["Status"] : []),
];
const extractedArray = filteredData?.map((item, index) => ({
id: item?.id,
"Sr No.": (
<Text as={"span"} color={"gray.800"} fontWeight={"500"}>
{index + 1}.
</Text>
),
"Valuation date": (
<Text as={"span"} color={"gray.600"} fontWeight={"500"}>
{formatDate(item?.transactionDate)}
</Text>
),
NAV: (
<Text as={"span"} color={"gray.600"} fontWeight={"500"}>
<Badge ms={1} colorScheme="green" me={1}>
$
</Badge>
{item?.transactionAmount}
</Text>
),
"Last Nav Update": (
<Text
justifyContent={"center"}
as={"span"}
color={"teal.900"}
fontWeight={"500"}
className="d-flex align-items-center web-text-small"
>
{item.previousNAVvalue && `${item.previousNAVvalue}`}
</Text>
),
"Investment Closed": (
<Text
justifyContent={"center"}
as={"span"}
@@ -124,150 +136,195 @@ import { CheckIcon, CloseIcon } from "@chakra-ui/icons";
{item?.initialNAVvalue && `${item?.initialNAVvalue}`}
</Text>
),
"Comments": (
<Text
w={"100px"}
as={"span"}
color={"gray.800"}
fontWeight={"500"}
>
{item?.comments ? item?.comments : "---" }
</Text>
),
"Updated By": (
<Text
w={"100px"}
as={"span"}
color={"gray.800"}
fontWeight={"500"}
display={"flex"}
Comments: (
<Text w={"100px"} as={"span"} color={"gray.800"} fontWeight={"500"}>
{item?.comments ? item?.comments : "---"}
</Text>
),
"Updated By": (
<Text
w={"100px"}
as={"span"}
color={"gray.800"}
fontWeight={"500"}
display={"flex"}
alignItems={"center"}
>
<Avatar
mr={2}
>
<Avatar
mr={2}
size="sm"
name={item.creator?.firstName}
src={item.creator?.profilePhoto}
/>
{item?.creator?.firstName}
</Text>
),
"Status": (
<Box display={"flex"} justifyContent={"center"} gap={2}>
<Tooltip
{item?.creator?.firstName}
</Text>
),
Status: (
<Box display={"flex"} justifyContent={"center"} gap={2}>
<Tooltip
rounded={"sm"}
fontSize={"xs"}
label="Approve"
bg="#fff"
color={"green.500"}
placement="left-start"
>
<Button
// colorScheme="forestGreen"
// color="green.500"
rounded={"sm"}
fontSize={"xs"}
label="Approve"
bg="#fff"
color={"green.500"}
placement="left-start"
size={"xs"}
textTransform={"inherit"}
fontWeight={500}
px={2}
py={1}
onClick={() => {
setActionId(item.id);
onConfirmOpen();
}}
colorScheme="green"
variant={"solid"}
cursor={"pointer"}
>
<Button
// colorScheme="forestGreen"
// color="green.500"
rounded={"sm"}
size={"xs"}
textTransform={"inherit"}
fontWeight={500}
px={2}
py={1}
onClick={() => {
setActionId(item.id);
onConfirmOpen();
}}
colorScheme="green"
variant={"solid"}
cursor={"pointer"}
>
<CheckIcon fontSize={"12px"} />
</Button>
</Tooltip>
<Tooltip
<CheckIcon fontSize={"12px"} />
</Button>
</Tooltip>
<Tooltip
rounded={"sm"}
fontSize={"xs"}
label="Reject"
bg="#fff"
color={"red.500"}
placement="left-start"
>
<Button
colorScheme="red"
// color="red.500"
rounded={"sm"}
fontSize={"xs"}
label="Reject"
bg="#fff"
color={"red.500"}
placement="left-start"
>
<Button
colorScheme="red"
// color="red.500"
rounded={"sm"}
size={"xs"}
textTransform={"inherit"}
fontWeight={500}
px={2}
onClick={() => {
setActionId(item.id);
onRejectOpen();
}}
py={1}
size={"xs"}
textTransform={"inherit"}
fontWeight={500}
px={2}
onClick={() => {
setActionId(item.id);
onRejectOpen();
}}
py={1}
// variant={"solid"}
>
<CloseIcon fontSize={"10px"} />
</Button>
</Tooltip>
</Box>
),
}));
const handleDelete = () => {
const updatedSponsors = sponser.filter(
(sponsor) => sponsor.id !== actionId
);
setTimeout(() => {
setCaseDetails(updatedSponsors);
setDeleteAlert(false);
setIsLoading(false);
}, 100);
setIsLoading(true);
};
return (
<Box {...OPACITY_ON_LOAD} pb={0}>
<Box bg="white.500">
<HStack
display={"flex"}
justifyContent={"space-between"}
pb={3}
spacing="24px"
>
<Input
type="search"
width={300}
placeholder="Search..."
size="sm"
rounded="sm"
focusBorderColor="green.500"
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
/>
</HStack>
</Box>
<NormalTable
emptyMessage={`We don't have any Sponers`}
tableHeadRow={tableHeadRow}
data={extractedArray}
isLoading={isLoading}
viewActionId={actionId}
setViewActionId={setActionId}
setMouseEnteredId={setMouseEnteredId}
setMouseEntered={setMouseEntered}
/>
<CustomAlertDialog
onClose={() => setDeleteAlert(false)}
isOpen={deleteAlert}
message={"Are you sure you want to delete sponers?"}
alertHandler={handleDelete}
isLoading={isLoading}
/>
<CloseIcon fontSize={"10px"} />
</Button>
</Tooltip>
</Box>
),
}));
const handleDelete = () => {
const updatedSponsors = sponser.filter(
(sponsor) => sponsor.id !== actionId
);
setTimeout(() => {
setCaseDetails(updatedSponsors);
setDeleteAlert(false);
setIsLoading(false);
}, 100);
setIsLoading(true);
};
export default Pending;
const handleAdd = async () => {
try {
const res = await updateIOCase(id);
if (res?.data) {
toast({
render: () => (
<ToastBox status={"success"} message={res?.data?.message} />
),
});
setIsLoading(false);
onOpen();
} else if (res?.error) {
toast({
render: () => (
<ToastBox status={"error"} message={res?.error?.data?.message} />
),
});
setIsLoading(false);
}
} catch (error) {}
};
return (
<Box {...OPACITY_ON_LOAD} pb={0}>
<Box bg="white.500">
<HStack
display={"flex"}
justifyContent={"space-between"}
pb={3}
spacing="24px"
>
<Input
type="search"
width={300}
placeholder="Search..."
size="sm"
rounded="sm"
focusBorderColor="green.500"
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
/>
{IODetails?.isInvestedAmount ? (
localStorage?.getItem('role') ==="Maker"&& <Button
onClick={handleAdd}
leftIcon={<AddIcon />}
colorScheme="forestGreen"
size={"sm"}
rounded={"sm"}
fontSize={"xs"}
>
Add
</Button>
) : null}
</HStack>
</Box>
<NormalTable
emptyMessage={`We don't have any Sponers`}
tableHeadRow={tableHeadRow}
data={extractedArray}
isLoading={isLoading}
viewActionId={actionId}
setViewActionId={setActionId}
setMouseEnteredId={setMouseEnteredId}
setMouseEntered={setMouseEntered}
/>
<CustomAlertDialog
onClose={() => setDeleteAlert(false)}
isOpen={deleteAlert}
message={"Are you sure you want to delete sponers?"}
alertHandler={handleDelete}
isLoading={isLoading}
/>
<AddNavDetails
isOpen={isOpen}
onClose={onClose}
firstField={firstField}
/>
<RequestApproveModal
// data={data?.data?.rows}
isOpen={isConfirmOpen}
onClose={onConfirmClose}
id={actionId}
// firstField={firstField}
/>
<RequestRejectModal
isOpen={isRejectOpen}
onClose={onRejectClose}
id={actionId}
/>
</Box>
);
};
export default Pending;

View File

@@ -25,11 +25,16 @@ import {
import ToastBox from "../../../../Components/ToastBox";
import AddCashDetails from "../AddCashDetails";
import { debounce } from "../../../Admin/Contact";
import { useUpdateIOCaseMutation } from "../../../../Services/io.service";
import { useParams } from "react-router-dom";
import AddNavDetails from "./AddNavDetails";
const formatDate = (date) => new Date(date).toLocaleDateString();
const Rejected = () => {
const params = useParams()
const toast = useToast();
const id = params?.id
const firstField = useRef();
const { isOpen, onOpen, onClose } = useDisclosure();
const { IODetails, iONAVDetail, setIONAVDetail } =
@@ -40,6 +45,7 @@ import {
const [actionId, setActionId] = useState(false);
const [mouseEntered, setMouseEntered] = useState(false);
const [mouseEnteredId, setMouseEnteredId] = useState("");
const [updateIOCase] = useUpdateIOCaseMutation()
useEffect(() => {
// Simulate loading
@@ -76,7 +82,7 @@ import {
"Last Nav Update",
"Investment Closed",
"Comments",
"Updated By",
// "Updated By",
];
const extractedArray = filteredData?.map((item, index) => ({
@@ -176,6 +182,31 @@ import {
setIsLoading(true);
};
const handleAdd = async () =>{
try {
const res = await updateIOCase(id)
if (res?.data) {
toast({
render: () => (
<ToastBox status={"success"} message={res?.data?.message} />
),
});
setIsLoading(false);
onOpen()
} else if (res?.error) {
toast({
render: () => (
<ToastBox status={"error"} message={res?.error?.data?.message} />
),
});
setIsLoading(false);
}
} catch (error) {
}
}
return (
<Box {...OPACITY_ON_LOAD} pb={0}>
<Box bg="white.500">
@@ -195,6 +226,19 @@ import {
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
/>
{IODetails?.isInvestedAmount ? (
localStorage?.getItem('role') ==="Maker"&& <Button
onClick={handleAdd}
leftIcon={<AddIcon />}
colorScheme="forestGreen"
size={"sm"}
rounded={"sm"}
fontSize={"xs"}
>
Add
</Button>
) : null}
</HStack>
</Box>
@@ -216,6 +260,13 @@ import {
alertHandler={handleDelete}
isLoading={isLoading}
/>
<AddNavDetails
isOpen={isOpen}
onClose={onClose}
firstField={firstField}
/>
</Box>
);
};

View File

@@ -0,0 +1,176 @@
import {
Box,
Button,
FormControl,
FormHelperText,
FormLabel,
Input,
Modal,
ModalBody,
ModalCloseButton,
ModalContent,
ModalFooter,
ModalHeader,
ModalOverlay,
Text,
Textarea,
useDisclosure,
useToast,
} from "@chakra-ui/react";
import React, { useEffect, useState } from "react";
import * as yup from "yup";
import { yupResolver } from "@hookform/resolvers/yup";
import { useForm } from "react-hook-form";
import ToastBox from "../../../../Components/ToastBox";
import { useApproveIOCaseMutation, useApproveIONavMutation } from "../../../../Services/io.service";
export const conformModalSchema = yup.object().shape({
// checkerComment: yup.string().required("Comment is required")
// .max(50, "Investment name cannot be more than 50 characters"),
checkerComment: yup
.string()
.required("Comment is required")
.max(200, "Approve Comment cannot be more than 200 characters"),
});
const RequestApproveModal = ({ isOpen, onClose, firstField ,id}) => {
const [isBtnLoading , setIsBtnLoading] = useState(false)
const toast = useToast()
const {
register,
reset,
watch,
handleSubmit,
formState: { errors },
} = useForm({
resolver: yupResolver(conformModalSchema),
});
const [ approveIONav ] = useApproveIONavMutation()
const onSubmit = async(data) => {
console.log(data, "tewxttttt");
setIsBtnLoading(true)
try {
const res = await approveIONav({data,id})
if (res?.error) {
toast({
render: () => (
<ToastBox status={"error"} message={res?.error?.data?.message} />
),
});
setIsBtnLoading(false)
}else if(res?.data){
toast({
render: () => (
<ToastBox message={res?.data?.message} />
),
});
onClose()
setIsBtnLoading(false)
}else{
toast({
render: () => (
<ToastBox status={'error'} message={"Something went wrong"} />
),
});
setIsBtnLoading(false)
}
} catch (error) {
}
};
const handleFileChange = (event) => {
const selectedFile = event.target.files[0];
setFile(selectedFile);
};
const { data, isLoading } =
(id, {
skip: !id,
});
useEffect(() => {
if (data) {
reset({
investorAmount: data?.data?.investorAmount,
});
}
}, [data, reset]);
const heandleOnClose = () =>{
reset()
onClose()
}
return (
<Modal isCentered isOpen={isOpen} onClose={heandleOnClose} initialFocusRef={firstField}>
<ModalOverlay />
<ModalContent pb={4}>
<ModalHeader fontSize={"md"}>Approve Comment</ModalHeader>
<ModalCloseButton />
{isLoading ? (
<FullscreenLoaders height={"50vh"} />
) : (
<Box as="form" onSubmit={handleSubmit(onSubmit)}>
<ModalBody>
<FormControl mb={4} isRequired>
<FormLabel fontSize="sm">Comment</FormLabel>
<Textarea
rows={6}
focusBorderColor="green.400"
name="checkerComment"
{...register("checkerComment")}
fontSize="sm"
type="textarea"
size="md"
placeholder={"Enter your checkerComment...."}
rounded={"md"}
resize={"none"}
maxLength={200}
/>
{errors.checkerComment && (
<Text fontSize="xs" color="red">
{errors.checkerComment.message}
</Text>
)}
<FormHelperText fontSize="xs" color="gray.500">
Maximum length should be 200 characters. You have entered
{watch("checkerComment")?.length || 0} characters.
</FormHelperText>
</FormControl>
</ModalBody>
<ModalFooter>
<Button
colorScheme="gray"
mr={3}
onClick={onClose}
size={"sm"}
rounded={"sm"}
>
Cancel
</Button>
<Button
colorScheme="forestGreen"
variant="solid"
size={"sm"}
rounded={"sm"}
isLoading={isBtnLoading}
type="submit"
>
Send
</Button>
</ModalFooter>
</Box>
)}
</ModalContent>
</Modal>
);
};
export default RequestApproveModal;

View File

@@ -0,0 +1,164 @@
import {
Box,
Button,
FormControl,
FormLabel,
Input,
Modal,
ModalBody,
ModalCloseButton,
ModalContent,
ModalFooter,
ModalHeader,
ModalOverlay,
Text,
Textarea,
useDisclosure,
useToast,
} from "@chakra-ui/react";
import React, { useEffect, useState } from "react";
import * as yup from "yup";
import { yupResolver } from "@hookform/resolvers/yup";
import { useForm } from "react-hook-form";
import ToastBox from "../../../../Components/ToastBox";
import { useRejectIOCaseMutation } from "../../../../Services/io.service";
export const conformModalSchema = yup.object().shape({
comments: yup.string().required("Comment is required"),
});
const RequestRejectModal = ({ isOpen, onClose, firstField ,id}) => {
const [isBtnLoading , setIsBtnLoading] = useState(false)
const toast = useToast()
const {
register,
reset,
handleSubmit,
formState: { errors },
} = useForm({
resolver: yupResolver(conformModalSchema),
});
const [ rejectIOCase ] = useRejectIOCaseMutation()
const onSubmit = async(data) => {
console.log(data, "tewxttttt");
setIsBtnLoading(true)
try {
const res = await rejectIOCase({data,id})
if (res?.error) {
toast({
render: () => (
<ToastBox status={"error"} message={res?.error?.data?.message} />
),
});
setIsBtnLoading(false)
}else if(res?.data){
toast({
render: () => (
<ToastBox message={res?.data?.message} />
),
});
onClose()
setIsBtnLoading(false)
}else{
toast({
render: () => (
<ToastBox status={'error'} message={"Something went wrong"} />
),
});
setIsBtnLoading(false)
}
} catch (error) {
}
};
const handleFileChange = (event) => {
const selectedFile = event.target.files[0];
setFile(selectedFile);
};
const { data, isLoading } =
(id, {
skip: !id,
});
useEffect(() => {
if (data) {
reset({
investorAmount: data?.data?.investorAmount,
});
}
}, [data, reset]);
const heandleOnClose = () =>{
reset()
onClose()
}
return (
<Modal isCentered isOpen={isOpen} onClose={heandleOnClose} initialFocusRef={firstField}>
<ModalOverlay />
<ModalContent pb={4}>
<ModalHeader fontSize={"md"}>Reject Comment</ModalHeader>
<ModalCloseButton />
{isLoading ? (
<FullscreenLoaders height={"50vh"} />
) : (
<Box as="form" onSubmit={handleSubmit(onSubmit)}>
<ModalBody>
<FormControl mb={4} isRequired>
<FormLabel fontSize="sm">Comment</FormLabel>
<Textarea
rows={6}
focusBorderColor="green.400"
name="comments"
{...register("comments")}
fontSize="sm"
type="textarea"
size="md"
placeholder={"Enter your comments...."}
rounded={"md"}
resize={"none"}
/>
{errors.comments && (
<Text fontSize="xs" color="red">
{errors.comments.message}
</Text>
)}
</FormControl>
</ModalBody>
<ModalFooter>
<Button
colorScheme="gray"
mr={3}
onClick={onClose}
size={"sm"}
rounded={"sm"}
>
Cancel
</Button>
<Button
colorScheme="forestGreen"
variant="solid"
size={"sm"}
rounded={"sm"}
isLoading={isBtnLoading}
type="submit"
>
Send
</Button>
</ModalFooter>
</Box>
)}
</ModalContent>
</Modal>
);
};
export default RequestRejectModal;

View File

@@ -63,9 +63,9 @@ import {
// Table filter
const filteredData = IODetails?.ioTransactionRecords?.Approved?.filter((item) => {
// Filter by name (case insensitive)
const name = item.transactionAmount;
const searchLower = searchTerm.toLowerCase();
const nameMatches = name.toLowerCase().includes(searchLower);
const name = item?.transactionAmount;
const searchLower = searchTerm?.toLowerCase();
const nameMatches = name?.toLowerCase().includes(searchLower);
return nameMatches;
});
@@ -75,7 +75,7 @@ import {
"Amount",
"Created By",
"Created On",
"Approved By",
// "Approved By",
"Approved On",
];

View File

@@ -21,6 +21,8 @@ import {
import GlobalStateContext from "../../../../Contexts/GlobalStateContext";
import CustomAlertDialog from "../../../../Components/CustomAlertDialog";
import { CheckIcon, CloseIcon } from "@chakra-ui/icons";
import RequestApproveModal from "./RequestApproveModal";
import RequestRejectModal from "./RequestRejectModal";
const formatDate = (date) => new Date(date).toLocaleDateString();
@@ -36,6 +38,17 @@ import { CheckIcon, CloseIcon } from "@chakra-ui/icons";
const [actionId, setActionId] = useState(false);
const [mouseEntered, setMouseEntered] = useState(false);
const [mouseEnteredId, setMouseEnteredId] = useState("");
const {
isOpen: isConfirmOpen,
onOpen: onConfirmOpen,
onClose: onConfirmClose,
} = useDisclosure();
const {
isOpen: isRejectOpen,
onOpen: onRejectOpen,
onClose: onRejectClose,
} = useDisclosure();
useEffect(() => {
// Simulate loading
@@ -55,15 +68,17 @@ import { CheckIcon, CloseIcon } from "@chakra-ui/icons";
});
};
console.log("==============panding",IODetails?.ioTransactionRecords?.Pending);
// Table filter
const filteredData = IODetails?.ioTransactionRecords?.Pending?.filter((item) => {
// Filter by name (case insensitive)
const name = item.transactionName;
const searchLower = searchTerm.toLowerCase();
const nameMatches = name.toLowerCase().includes(searchLower);
return nameMatches;
});
// const filteredData = IODetails?.ioTransactionRecords?.Pending?.filter((item) => {
// // Filter by name (case insensitive)
// const name = item.transactionName;
// const searchLower = searchTerm?.toLowerCase();
// const nameMatches = name?.toLowerCase().includes(searchLower);
// return nameMatches;
// });
const tableHeadRow = [
"Sr No.",
@@ -71,12 +86,12 @@ import { CheckIcon, CloseIcon } from "@chakra-ui/icons";
"Amount",
"Created By",
"Created On",
"Approved By",
// "Approved By",
"Approved On",
"Status"
];
const extractedArray = filteredData?.map((item, index) => ({
const extractedArray = IODetails?.ioTransactionRecords?.Pending?.map((item, index) => ({
id: item?.id,
"Sr No.": (
<Text
@@ -139,13 +154,14 @@ import { CheckIcon, CloseIcon } from "@chakra-ui/icons";
</Text>
),
"Approved On": (
<Text
<Text
w={"100px"}
as={"span"}
color={"gray.800"}
fontWeight={"500"}
>
{formatDate(item?.updatedAt)}
>
{item?.modifier ? formatDate(item?.updatedAt) : "---" }
{}
</Text>
),
"Status": (
@@ -178,7 +194,7 @@ import { CheckIcon, CloseIcon } from "@chakra-ui/icons";
<CheckIcon fontSize={"12px"} />
</Button>
</Tooltip>
<Tooltip
<Tooltip
rounded={"sm"}
fontSize={"xs"}
label="Reject"
@@ -199,7 +215,7 @@ import { CheckIcon, CloseIcon } from "@chakra-ui/icons";
onRejectOpen();
}}
py={1}
// variant={"solid"}
// variant={"solid"}
>
<CloseIcon fontSize={"10px"} />
</Button>
@@ -261,6 +277,19 @@ import { CheckIcon, CloseIcon } from "@chakra-ui/icons";
alertHandler={handleDelete}
isLoading={isLoading}
/>
<RequestApproveModal
// data={data?.data?.rows}
isOpen={isConfirmOpen}
onClose={onConfirmClose}
id={actionId}
// firstField={firstField}
/>
<RequestRejectModal
isOpen={isRejectOpen}
onClose={onRejectClose}
id={actionId}
/>
</Box>
);
};

View File

@@ -61,13 +61,13 @@ import {
// Table filter
const filteredData = IODetails?.ioTransactionRecords?.Reject?.filter((item) => {
// Filter by name (case insensitive)
const name = item.transactionName;
const searchLower = searchTerm.toLowerCase();
const nameMatches = name.toLowerCase().includes(searchLower);
return nameMatches;
});
// const filteredData = IODetails?.ioTransactionRecords?.Reject?.filter((item) => {
// // Filter by name (case insensitive)
// const name = item.transactionName;
// const searchLower = searchTerm.toLowerCase();
// const nameMatches = name.toLowerCase().includes(searchLower);
// return nameMatches;
// });
const tableHeadRow = [
"Sr No.",
@@ -75,11 +75,11 @@ import {
"Amount",
"Created By",
"Created On",
"Approved By",
// "Approved By",
"Approved On",
];
const extractedArray = filteredData?.map((item, index) => ({
const extractedArray = IODetails?.ioTransactionRecords?.Reject?.map((item, index) => ({
id: item?.id,
"Sr No.": (
<Text

View File

@@ -0,0 +1,175 @@
import {
Box,
Button,
FormControl,
FormHelperText,
FormLabel,
Input,
Modal,
ModalBody,
ModalCloseButton,
ModalContent,
ModalFooter,
ModalHeader,
ModalOverlay,
Text,
Textarea,
useDisclosure,
useToast,
} from "@chakra-ui/react";
import React, { useEffect, useState } from "react";
import * as yup from "yup";
import { yupResolver } from "@hookform/resolvers/yup";
import { useForm } from "react-hook-form";
import ToastBox from "../../../../Components/ToastBox";
import { useApproveDistributionMutation, useApproveIOCaseMutation, useApproveIONavMutation } from "../../../../Services/io.service";
export const conformModalSchema = yup.object().shape({
// checkerComment: yup.string().required("Comment is required")
// .max(50, "Investment name cannot be more than 50 characters"),
checkerComment: yup
.string()
.required("Comment is required")
.max(200, "Approve Comment cannot be more than 200 characters"),
});
const RequestApproveModal = ({ isOpen, onClose, firstField ,id}) => {
const [isBtnLoading , setIsBtnLoading] = useState(false)
const toast = useToast()
const {
register,
reset,
watch,
handleSubmit,
formState: { errors },
} = useForm({
resolver: yupResolver(conformModalSchema),
});
const [ approveDistribution ] = useApproveDistributionMutation()
const onSubmit = async(data) => {
setIsBtnLoading(true)
try {
const res = await approveDistribution({data,id})
if (res?.error) {
toast({
render: () => (
<ToastBox status={"error"} message={res?.error?.data?.message} />
),
});
setIsBtnLoading(false)
}else if(res?.data){
toast({
render: () => (
<ToastBox message={res?.data?.message} />
),
});
onClose()
setIsBtnLoading(false)
}else{
toast({
render: () => (
<ToastBox status={'error'} message={"Something went wrong"} />
),
});
setIsBtnLoading(false)
}
} catch (error) {
}
};
const handleFileChange = (event) => {
const selectedFile = event.target.files[0];
setFile(selectedFile);
};
const { data, isLoading } =
(id, {
skip: !id,
});
useEffect(() => {
if (data) {
reset({
investorAmount: data?.data?.investorAmount,
});
}
}, [data, reset]);
const heandleOnClose = () =>{
reset()
onClose()
}
return (
<Modal isCentered isOpen={isOpen} onClose={heandleOnClose} initialFocusRef={firstField}>
<ModalOverlay />
<ModalContent pb={4}>
<ModalHeader fontSize={"md"}>Approve Comment</ModalHeader>
<ModalCloseButton />
{isLoading ? (
<FullscreenLoaders height={"50vh"} />
) : (
<Box as="form" onSubmit={handleSubmit(onSubmit)}>
<ModalBody>
<FormControl mb={4} isRequired>
<FormLabel fontSize="sm">Comment</FormLabel>
<Textarea
rows={6}
focusBorderColor="green.400"
name="checkerComment"
{...register("checkerComment")}
fontSize="sm"
type="textarea"
size="md"
placeholder={"Enter your checkerComment...."}
rounded={"md"}
resize={"none"}
maxLength={200}
/>
{errors.checkerComment && (
<Text fontSize="xs" color="red">
{errors.checkerComment.message}
</Text>
)}
<FormHelperText fontSize="xs" color="gray.500">
Maximum length should be 200 characters. You have entered
{watch("checkerComment")?.length || 0} characters.
</FormHelperText>
</FormControl>
</ModalBody>
<ModalFooter>
<Button
colorScheme="gray"
mr={3}
onClick={onClose}
size={"sm"}
rounded={"sm"}
>
Cancel
</Button>
<Button
colorScheme="forestGreen"
variant="solid"
size={"sm"}
rounded={"sm"}
isLoading={isBtnLoading}
type="submit"
>
Send
</Button>
</ModalFooter>
</Box>
)}
</ModalContent>
</Modal>
);
};
export default RequestApproveModal;

View File

@@ -0,0 +1,176 @@
import {
Box,
Button,
FormControl,
FormHelperText,
FormLabel,
Input,
Modal,
ModalBody,
ModalCloseButton,
ModalContent,
ModalFooter,
ModalHeader,
ModalOverlay,
Text,
Textarea,
useDisclosure,
useToast,
} from "@chakra-ui/react";
import React, { useEffect, useState } from "react";
import * as yup from "yup";
import { yupResolver } from "@hookform/resolvers/yup";
import { useForm } from "react-hook-form";
import ToastBox from "../../../../Components/ToastBox";
import { useApproveDistributionMutation, useApproveExitMutation, useApproveIOCaseMutation, useApproveIONavMutation } from "../../../../Services/io.service";
export const conformModalSchema = yup.object().shape({
// checkerComment: yup.string().required("Comment is required")
// .max(50, "Investment name cannot be more than 50 characters"),
checkerComment: yup
.string()
.required("Comment is required")
.max(200, "Approve Comment cannot be more than 200 characters"),
});
const RequestApproveModal = ({ isOpen, onClose, firstField ,id}) => {
const [isBtnLoading , setIsBtnLoading] = useState(false)
const toast = useToast()
const {
register,
reset,
watch,
handleSubmit,
formState: { errors },
} = useForm({
resolver: yupResolver(conformModalSchema),
});
const [ approveExit ] = useApproveExitMutation()
const onSubmit = async(data) => {
setIsBtnLoading(true)
try {
const res = await approveExit({data,id})
if (res?.error) {
toast({
render: () => (
<ToastBox status={"error"} message={res?.error?.data?.message} />
),
});
setIsBtnLoading(false)
}else if(res?.data){
toast({
render: () => (
<ToastBox message={res?.data?.message} />
),
});
onClose()
setIsBtnLoading(false)
}else{
toast({
render: () => (
<ToastBox status={'error'} message={"Something went wrong"} />
),
});
setIsBtnLoading(false)
}
} catch (error) {
}
};
const handleFileChange = (event) => {
const selectedFile = event.target.files[0];
setFile(selectedFile);
};
const { data, isLoading } =
(id, {
skip: !id,
});
useEffect(() => {
if (data) {
reset({
investorAmount: data?.data?.investorAmount,
});
}
}, [data, reset]);
const heandleOnClose = () =>{
reset()
onClose()
}
return (
<Modal isCentered isOpen={isOpen} onClose={heandleOnClose} initialFocusRef={firstField}>
<ModalOverlay />
<ModalContent pb={4}>
<ModalHeader fontSize={"md"}>Approve Comment</ModalHeader>
<ModalCloseButton />
{isLoading ? (
<FullscreenLoaders height={"50vh"} />
) : (
<Box as="form" onSubmit={handleSubmit(onSubmit)}>
<ModalBody>
<FormControl mb={4} isRequired>
<FormLabel fontSize="sm">Comment</FormLabel>
<Textarea
rows={6}
focusBorderColor="green.400"
name="checkerComment"
{...register("checkerComment")}
fontSize="sm"
type="textarea"
size="md"
placeholder={"Enter your checkerComment...."}
rounded={"md"}
resize={"none"}
maxLength={200}
/>
{errors.checkerComment && (
<Text fontSize="xs" color="red">
{errors.checkerComment.message}
</Text>
)}
<FormHelperText fontSize="xs" color="gray.500">
Maximum length should be 200 characters. You have entered
{watch("checkerComment")?.length || 0} characters.
</FormHelperText>
</FormControl>
</ModalBody>
<ModalFooter>
<Button
colorScheme="gray"
mr={3}
onClick={onClose}
size={"sm"}
rounded={"sm"}
>
Cancel
</Button>
<Button
colorScheme="forestGreen"
variant="solid"
size={"sm"}
rounded={"sm"}
isLoading={isBtnLoading}
type="submit"
>
Send
</Button>
</ModalFooter>
</Box>
)}
</ModalContent>
</Modal>
);
};
export default RequestApproveModal;

View File

@@ -0,0 +1,164 @@
import {
Box,
Button,
FormControl,
FormLabel,
Input,
Modal,
ModalBody,
ModalCloseButton,
ModalContent,
ModalFooter,
ModalHeader,
ModalOverlay,
Text,
Textarea,
useDisclosure,
useToast,
} from "@chakra-ui/react";
import React, { useEffect, useState } from "react";
import * as yup from "yup";
import { yupResolver } from "@hookform/resolvers/yup";
import { useForm } from "react-hook-form";
import ToastBox from "../../../../Components/ToastBox";
import { useRejectIOCaseMutation } from "../../../../Services/io.service";
export const conformModalSchema = yup.object().shape({
comments: yup.string().required("Comment is required"),
});
const RequestRejectModal = ({ isOpen, onClose, firstField ,id}) => {
const [isBtnLoading , setIsBtnLoading] = useState(false)
const toast = useToast()
const {
register,
reset,
handleSubmit,
formState: { errors },
} = useForm({
resolver: yupResolver(conformModalSchema),
});
const [ rejectIOCase ] = useRejectIOCaseMutation()
const onSubmit = async(data) => {
console.log(data, "tewxttttt");
setIsBtnLoading(true)
try {
const res = await rejectIOCase({data,id})
if (res?.error) {
toast({
render: () => (
<ToastBox status={"error"} message={res?.error?.data?.message} />
),
});
setIsBtnLoading(false)
}else if(res?.data){
toast({
render: () => (
<ToastBox message={res?.data?.message} />
),
});
onClose()
setIsBtnLoading(false)
}else{
toast({
render: () => (
<ToastBox status={'error'} message={"Something went wrong"} />
),
});
setIsBtnLoading(false)
}
} catch (error) {
}
};
const handleFileChange = (event) => {
const selectedFile = event.target.files[0];
setFile(selectedFile);
};
const { data, isLoading } =
(id, {
skip: !id,
});
useEffect(() => {
if (data) {
reset({
investorAmount: data?.data?.investorAmount,
});
}
}, [data, reset]);
const heandleOnClose = () =>{
reset()
onClose()
}
return (
<Modal isCentered isOpen={isOpen} onClose={heandleOnClose} initialFocusRef={firstField}>
<ModalOverlay />
<ModalContent pb={4}>
<ModalHeader fontSize={"md"}>Reject Comment</ModalHeader>
<ModalCloseButton />
{isLoading ? (
<FullscreenLoaders height={"50vh"} />
) : (
<Box as="form" onSubmit={handleSubmit(onSubmit)}>
<ModalBody>
<FormControl mb={4} isRequired>
<FormLabel fontSize="sm">Comment</FormLabel>
<Textarea
rows={6}
focusBorderColor="green.400"
name="comments"
{...register("comments")}
fontSize="sm"
type="textarea"
size="md"
placeholder={"Enter your comments...."}
rounded={"md"}
resize={"none"}
/>
{errors.comments && (
<Text fontSize="xs" color="red">
{errors.comments.message}
</Text>
)}
</FormControl>
</ModalBody>
<ModalFooter>
<Button
colorScheme="gray"
mr={3}
onClick={onClose}
size={"sm"}
rounded={"sm"}
>
Cancel
</Button>
<Button
colorScheme="forestGreen"
variant="solid"
size={"sm"}
rounded={"sm"}
isLoading={isBtnLoading}
type="submit"
>
Send
</Button>
</ModalFooter>
</Box>
)}
</ModalContent>
</Modal>
);
};
export default RequestRejectModal;

View File

@@ -28,8 +28,10 @@ import NormalData from "../../../../Components/DataTable/NormalTable";
import { useContext, useState } from "react";
import { AddIcon } from "@chakra-ui/icons";
import {
useAddIOTransactionMutation,
useGetDistributedToInvestorMutation,
useGetDistributionInvestorMutation,
useSaveIOTransactionMutation,
useUpdateExitToInvestorMutation,
} from "../../../../Services/io.service";
import { useParams } from "react-router-dom";
@@ -42,6 +44,7 @@ import CurrencyInput from "../../../../Components/CurrencyInput";
import { IoCalculator } from "react-icons/io5";
import { debounce } from "../../../Master/Sponser/AddSponser";
import GlobalStateContext from "../../../../Contexts/GlobalStateContext";
import { validate } from "uuid";
@@ -101,6 +104,8 @@ const DistributionInvestor = ({ isOpen, onClose }) => {
resolver: yupResolver(investorExit),
});
const [saveIOTransaction] = useSaveIOTransactionMutation();
// ====================================================[Table Setup]================================================================
@@ -314,45 +319,81 @@ const DistributionInvestor = ({ isOpen, onClose }) => {
} catch (error) {}
};
// const onFinalSubmit = async (data) => {
// setIsFinalCalculateLoading(true);
// if (!isCalcualtedData) {
// setIsFinalCalculateLoading(false);
// return toast({
// render: () => (
// <ToastBox
// message={"Please calculate investment first."}
// status="warn"
// />
// ),
// });
// }
// const finalData = {
// transactionAmount: data?.amount,
// };
// try {
// const res = await getFinalDistributionInvestment({ id, data: finalData });
// console.log(finalData);
// if (res?.error?.status === 401) {
// toast({
// render: () => (
// <ToastBox message={res?.error?.data?.message} status="error" />
// ),
// });
// } else if (res?.data?.statusCode === 200) {
// toast({
// render: () => <ToastBox message={res?.data?.message} />,
// });
// handleClose();
// }
// } catch (error) {
// console.error("An error occurred:", error);
// } finally {
// handleClose();
// }
// };
const onFinalSubmit = async (data) => {
setIsFinalCalculateLoading(true);
if (!isCalcualtedData) {
setIsFinalCalculateLoading(false);
return toast({
render: () => (
<ToastBox
message={"Please calculate investment first."}
status="warn"
/>
),
});
}
const finalData = {
const currentDate = new Date();
const dataToSend = {
transactionDate: currentDate,
transactionAmount: data?.amount,
};
}
console.log("dataaaaaaa",dataToSend);
try {
const res = await getFinalDistributionInvestment({ id, data: finalData });
console.log(finalData);
if (res?.error?.status === 401) {
const res = await saveIOTransaction({ id,data: dataToSend });
console.log(res?.data?.data);
onClose();
if (!isCalcualtedData) {
setIsFinalCalculateLoading(false);
return toast({
render: () => (
<ToastBox
message={"Please calculate investment first."}
status="warn"
/>
),
});
} else if (res?.error) {
toast({
render: () => (
<ToastBox message={res?.error?.data?.message} status="error" />
<ToastBox status={"error"} message={res?.error?.data?.message} />
),
});
} else if (res?.data?.statusCode === 200) {
toast({
render: () => <ToastBox message={res?.data?.message} />,
});
handleClose();
// setIsLoading(false);
}
} catch (error) {
console.error("An error occurred:", error);
} finally {
handleClose();
}
} catch (error) {}
};
const handleClose = () => {

View File

@@ -28,6 +28,7 @@ import NormalData from "../../../../Components/DataTable/NormalTable";
import { useContext, useState } from "react";
import { AddIcon } from "@chakra-ui/icons";
import {
useExitIOTransactionMutation,
useGetDistributedToInvestorMutation,
useGetDistributionInvestorMutation,
useUpdateExitToInvestorMutation,
@@ -122,7 +123,7 @@ const Exit = ({ isOpen, onClose }) => {
const [getDistributionInvestment] = useGetDistributionInvestorMutation();
const [getFinalDistributionInvestment] =
useGetDistributedToInvestorMutation();
const [updateExitToInvestor] = useUpdateExitToInvestorMutation();
const [exitIOTransaction] = useExitIOTransactionMutation();
const investor = yup.object().shape({
amount: yup.string().required("Amount is required"),
@@ -340,46 +341,69 @@ const Exit = ({ isOpen, onClose }) => {
} catch (error) {}
};
const onFinalSubmit = async (data) => {
console.log("hit");
setIsFinalCalculateLoading(true);
// if (!isCalcualtedData) {
// setIsFinalCalculateLoading(false);
// return toast({
// render: () => (
// <ToastBox
// message={"Please calculate investment first."}
// status="warn"
// />
// ),
// });
// }
// const onFinalSubmit = async (data) => {
// console.log("hit");
// setIsFinalCalculateLoading(true);
// const finalData = {
// transactionAmount: IODetails?.ioMVNAV,
// };
const finalData = {
// try {
// const res = await exitIOTransaction({ id, data: finalData });
// console.log(finalData);
// if (res?.error?.status === 401) {
// toast({
// render: () => (
// <ToastBox message={res?.error?.data?.message} status="error" />
// ),
// });
// } else if (res?.data?.statusCode === 200) {
// toast({
// render: () => <ToastBox message={res?.data?.message} />,
// });
// handleClose();
// }
// } catch (error) {
// console.error("An error occurred:", error);
// } finally {
// handleClose();
// }
// };
const onFinalSubmit = async () => {
setIsCalculateLoading(true);
const currentDate = new Date();
const dataToSend = {
transactionDate: currentDate,
transactionAmount: IODetails?.ioMVNAV,
};
}
try {
const res = await updateExitToInvestor({ id, data: finalData });
console.log(finalData);
const res = await exitIOTransaction({ id,data: dataToSend });
console.log(res?.data?.data);
if (res?.error?.status === 401) {
toast({
onClose();
if (!isCalcualtedData) {
setIsFinalCalculateLoading(false);
return toast({
render: () => (
<ToastBox message={res?.error?.data?.message} status="error" />
<ToastBox
message={"Please calculate investment first."}
status="warn"
/>
),
});
} else if (res?.data?.statusCode === 200) {
} else if (res?.error) {
toast({
render: () => <ToastBox message={res?.data?.message} />,
render: () => (
<ToastBox status={"error"} message={res?.error?.data?.message} />
),
});
handleClose();
setIsLoading(false);
}
} catch (error) {
console.error("An error occurred:", error);
} finally {
handleClose();
}
} catch (error) {}
};
const handleClose = () => {
@@ -389,7 +413,7 @@ const Exit = ({ isOpen, onClose }) => {
};
return (
<Modal size={"xl"} isOpen={isOpen} onClose={handleClose}>
<Modal size={"xl"} isOpen={isOpen} onClose={handleClose} >
<ModalOverlay />
<ModalContent maxW={1000}>
<ModalHeader fontSize={"md"}>Exit Transaction</ModalHeader>
@@ -435,7 +459,7 @@ const Exit = ({ isOpen, onClose }) => {
{/* ) } */}
</ModalBody>
<ModalFooter pt={0}>
{isCalcualtedData ? (
{/* {isCalcualtedData ? ( */}
<>
<Button
bg={"hsla(139, 100%, 14%, 1)"}
@@ -455,9 +479,9 @@ const Exit = ({ isOpen, onClose }) => {
Close
</Button>
</>
) : (
{/* ) : (
""
)}
)} */}
</ModalFooter>
</ModalContent>
</Modal>

View File

@@ -24,6 +24,7 @@ import {
Box,
Icon,
HStack,
useToast,
} from "@chakra-ui/react";
import header from "../../../assets/IOheader.png";
import { HiDotsVertical } from "react-icons/hi";
@@ -41,12 +42,15 @@ import Cancle from "./HeaderModal/Cancle";
import { AddIcon } from "@chakra-ui/icons";
import { GrGallery } from "react-icons/gr";
import Loader01 from "../../../Components/Loaders/Loader01";
import { useUpdateTransactionMutation } from "../../../Services/io.service";
import ToastBox from "../../../Components/ToastBox";
// import { formatCurrency } from "../../../Components/CurrencyInput";
// import { removeTrailingZeros } from "../../../Constants/Constants";
const ViewIOdataHeader = ({ data, isLoading }) => {
const params = useParams();
const id = params?.id;
const params = useParams()
const toast = useToast();
const id = params?.id
const { isOpen, onOpen, onClose } = useDisclosure();
const btnRef = useRef();
const { IODetails, isIOloading } = useContext(GlobalStateContext);
@@ -108,6 +112,63 @@ const ViewIOdataHeader = ({ data, isLoading }) => {
IODetails?.artifactsImage?.[0]?.artifactPathName
);
const [updateTransaction] = useUpdateTransactionMutation()
const handleDistributionInvestors = async () =>{
try {
const res = await updateTransaction(id)
if (res?.data) {
toast({
render: () => (
<ToastBox status={"success"} message={res?.data?.message} />
),
});
// setIsLoading(false);
onDistInvestorOpen()
} else if (res?.error) {
toast({
render: () => (
<ToastBox status={"error"} message={res?.error?.data?.message} />
),
});
// setIsLoading(false);
}
} catch (error) {
}
}
const handleExit = async () =>{
try {
const res = await updateTransaction(id)
if (res?.data) {
toast({
render: () => (
<ToastBox status={"success"} message={res?.data?.message} />
),
});
// setIsLoading(false);
onExitOpen()
} else if (res?.error) {
toast({
render: () => (
<ToastBox status={"error"} message={res?.error?.data?.message} />
),
});
// setIsLoading(false);
}
} catch (error) {
}
}
const menu = [
{
id: 1,
@@ -127,8 +188,8 @@ const ViewIOdataHeader = ({ data, isLoading }) => {
{
id: 6,
title: "Distribution To Investors",
onClickFunction: onDistInvestorOpen,
},
onClickFunction: handleDistributionInvestors,
},
{
id: 5,
title: "Update IO NAV",
@@ -137,7 +198,7 @@ const ViewIOdataHeader = ({ data, isLoading }) => {
{
id: 8,
title: "Exit",
onClickFunction: onExitOpen,
onClickFunction: handleExit,
},
{
id: 9,

View File

@@ -15,9 +15,9 @@ export const ioService = createApi({
"getArtifactsVideo",
"getInvestmentDocuments",
"getIOById",
"getSponser",
"getInvestmentType",
"getInvestmentTypeID"
"getSponser",
"getInvestmentType",
"getInvestmentTypeID",
],
endpoints: (builder) => ({
// =====[get prepopulate data]
@@ -28,7 +28,8 @@ export const ioService = createApi({
// =====[get]
getIOs: builder.query({
query: ({ page, size, ioStatus_xid, search }) => `/io/admin?page=${page}&size=${size}&ioStatus_xid=${ioStatus_xid}&search=${search}`,
query: ({ page, size, ioStatus_xid, search }) =>
`/io/admin?page=${page}&size=${size}&ioStatus_xid=${ioStatus_xid}&search=${search}`,
providesTags: ["getIO"],
}),
@@ -261,9 +262,7 @@ export const ioService = createApi({
invalidatesTags: ["getIOById"],
}),
// ==============[ Displaye Orders ]===============
// ==============[ Displaye Orders ]===============
setDisplayOrder: builder.mutation({
query: ({ data }) => ({
@@ -309,7 +308,7 @@ export const ioService = createApi({
method: "POST",
body: data,
}),
invalidatesTags: ["getSponser","prePopulate"],
invalidatesTags: ["getSponser", "prePopulate"],
}),
// ========[Update Sponser]========
@@ -320,12 +319,11 @@ export const ioService = createApi({
method: "PATCH",
body: data,
}),
invalidatesTags: ["getSponser","prePopulate"],
invalidatesTags: ["getSponser", "prePopulate"],
}),
// ======[Get All]=====
getSponserMaster: builder.query({
query: ({ page, size, searchTerm }) => {
let baseURL = `/sponsor/admin/?search=${searchTerm || ""}`;
@@ -336,10 +334,10 @@ export const ioService = createApi({
},
providesTags: ["getSponser"],
}),
// ========[Delete Sponser]========
deleteSponser: builder.mutation({
deleteSponser: builder.mutation({
query: (id) => ({
url: `/sponsor/admin/delete/${id}`,
method: "DELETE",
@@ -356,7 +354,7 @@ export const ioService = createApi({
getSponserMasterActive: builder.query({
query: () => "/sponsor/admin/active",
}),
// ======[Get ID]=====
getSponserById: builder.query({
@@ -369,12 +367,8 @@ export const ioService = createApi({
query: () => `/sponsor/admin/active`,
}),
// ===============================[ Investment Type ]===================================
// ===============================[ Investment Type ]===================================
// ========[Get All]=========
getInvestmentTypes: builder.query({
@@ -405,11 +399,15 @@ export const ioService = createApi({
updateInvestmentType: builder.mutation({
query: ({ data, id }) => ({
url: `/investmentType/admin/${id}`,
url: `/investmentType/admin/${id}`,
method: "PATCH",
body: data,
}),
invalidatesTags: ["getInvestmentTypeID", "getInvestmentType", "prePopulate"],
invalidatesTags: [
"getInvestmentTypeID",
"getInvestmentType",
"prePopulate",
],
}),
// ========[Delete Investment]=======
@@ -419,30 +417,142 @@ export const ioService = createApi({
url: `/investmentType/admin/delete/${id}`,
method: "DELETE",
}),
invalidatesTags: ["getInvestmentType", 'prePopulate'],
invalidatesTags: ["getInvestmentType", "prePopulate"],
}),
profile: builder.query({
query: (id) => `/auth/admin/profile`,
}),
// ========Add Io Details========
updateIOCase: builder.mutation({
query: (id) => ({
url: `/io/admin/maker-transaction/${id}/verify-pending-transaction-for-cash-and-nav`,
method: "POST",
}),
invalidatesTags: ["getIOById"],
updateIOCase: builder.mutation({
query: (id) => ({
url: `/io/admin/maker-transaction/${id}/verify-pending-transaction-for-cash-and-nav`,
method: "POST",
}),
invalidatesTags: ["getIOById"],
}),
updateTransaction: builder.mutation({
query: (id) => ({
// url: `/io/admin/maker-transaction/${id}/verify-pending-transaction-for-cash-and-nav`,
url: `/io/admin/maker-transaction/${id}/verify-pending-transaction`,
method: "POST",
}),
invalidatesTags: ["getIOById"],
}),
addNavDetails: builder.mutation({
query: ({id,data}) => ({
url: `/io/admin/maker-transaction/${id}/io-nav`,
method: "POST",
body:data,
}),
invalidatesTags: ["getIOById"],
}),
addIOTransaction: builder.mutation({
query: ({id,data}) => ({
url: `/io/admin/maker-transaction/${id}/io-nav`,
method: "POST",
body:data,
}),
invalidatesTags: ["getIOById"],
}),
saveIOTransaction: builder.mutation({
query: ({id,data}) => ({
url: `/io/admin/maker-transaction/${id}/io-yeild`,
method: "POST",
body:data,
}),
invalidatesTags: ["getIOById"],
}),
exitIOTransaction: builder.mutation({
query: ({id,data}) => ({
url: `/io/admin/maker-transaction/${id}/io-exit`,
method: "POST",
body:data,
}),
invalidatesTags: ["getIOById"],
}),
addIoCase: builder.mutation({
query: (id) => ({
url: `/io/admin/maker-transaction/${id}/verify-pending-transaction`,
method: "POST",
}),
invalidatesTags: ["getIOById"],
}),
approveIOCase: builder.mutation({
query: ({id,data}) => ({
url: `/io/admin/checker-transaction/approved/io-cash/${id}`,
method: "PATCH",
body:data,
}),
invalidatesTags: ["getIOById"],
}),
approveIONav: builder.mutation({
query: ({id,data}) => ({
url: `/io/admin/checker-transaction/approved/io-nav/${id}`,
method: "PATCH",
body:data,
}),
invalidatesTags: ["getIOById"],
}),
approveDistribution: builder.mutation({
query: ({id,data}) => ({
url: `/io/admin/checker-transaction/approved/distributed-to-investor/${id}`,
method: "PATCH",
body:data,
}),
invalidatesTags: ["getIOById"],
}),
approveExit: builder.mutation({
query: ({id,data}) => ({
url: `/io/admin/checker-transaction/approved/exit/${id}`,
method: "PATCH",
body:data,
}),
invalidatesTags: ["getIOById"],
}),
rejectIOCase: builder.mutation({
query: ({id,data}) => ({
url: `/io/admin/checker-transaction/reject/${id}`,
method: "PATCH",
body:data,
}),
invalidatesTags: ["getIOById"],
}),
}),
});
@@ -475,7 +585,6 @@ export const {
useDeleteVideoArtifactsMutation,
useDeleteImageArtifactsMutation,
useSetDisplayOrderMutation,
useSetDisplayOrderIODocumentsMutation,
useSetDisplayOrderIOArtifactsImageMutation,
@@ -493,11 +602,9 @@ export const {
useGetDistributedToInvestorMutation,
useUpdateExitToInvestorMutation,
useUpdateCancleStatusMutation,
// ==============[ Sponser ]===============
// ==============[ Sponser ]===============
useGetSponserMasterQuery,
useGetSponserMasterActiveQuery,
useCreateSponserMutation,
@@ -506,7 +613,6 @@ export const {
useDeleteSponserMutation,
useGetActiveSponserMasterQuery,
// ============[ Investment Type ]========
useGetInvestmentTypesQuery,
@@ -516,9 +622,18 @@ export const {
useDeleteInvestmentTypeMutation,
useProfileQuery,
// ========[ Add Io Details ]========
useUpdateIOCaseMutation
useUpdateIOCaseMutation,
useUpdateTransactionMutation,
useApproveIOCaseMutation,
useRejectIOCaseMutation,
useAddNavDetailsMutation,
useApproveIONavMutation,
useAddIOTransactionMutation,
useSaveIOTransactionMutation,
useApproveDistributionMutation,
useExitIOTransactionMutation,
useApproveExitMutation
} = ioService;