updated final fixes

This commit is contained in:
2024-08-30 16:09:07 +05:30
parent be451086b9
commit 68026ddd66
7 changed files with 427 additions and 187 deletions

View File

@@ -29,8 +29,7 @@ const investmentVideoSchema = yup.object().shape({
artifactName: yup.string().required("Artifact name is required"),
artifactStreamingURL: yup.string()
.required("Artifact streaming URL is required")
.url("Invalid URL format")
.matches(/\.mp4$/, "URL must end with .mp4"),
.url("Invalid URL format"),
});
const IOArtifactsAdd = ({ isOpen, onClose, firstField, actionId, setActionId, data }) => {

View File

@@ -24,6 +24,8 @@ import ToastBox from "../../../Components/ToastBox";
import { debounce } from "../../Master/Sponser/AddSponser";
import { AddIcon } from "@chakra-ui/icons";
import AddCashDetails from "./AddCashDetails";
import { LuFileSpreadsheet } from "react-icons/lu";
import { exportToExcel } from "../../../Constants/Constants";
const formatDate = (date) => new Date(date).toLocaleDateString(); // Simple date formatter
@@ -178,6 +180,18 @@ const IOCashDetails = () => {
),
}));
const customHeaders = [
{ label: "Date", key: "transactionDate" },
{ label: "Transaction type", key: "transactionType" },
{ label: "Amount", key: "transactionAmount" },
{ label: "Comments", key: "comments" },
// { label: "Update by", key: "creator" },
// { label: "Update On", key: "updateOn" },
// Add more headers as needed
];
const handleDelete = () => {
const updatedSponsors = sponser.filter(
(sponsor) => sponsor.id !== actionId
@@ -289,6 +303,22 @@ const IOCashDetails = () => {
onChange={(e) => setSearchTerm(e.target.value)}
/>
<HStack display={"flex"} alignItems={"center"}>
<Button
onClick={() =>
exportToExcel(IODetails?.ioCashHistory, customHeaders)
}
leftIcon={<LuFileSpreadsheet />}
colorScheme="forestGreen"
size={"sm"}
variant={"outline"}
rounded={"sm"}
fontSize={"xs"}
>
Export xls
</Button>
{IODetails?.isInvestedAmount ? (
<Button
onClick={onOpen}
@@ -302,6 +332,7 @@ const IOCashDetails = () => {
</Button>
) : null}
</HStack>
</HStack>
</Box>
<NormalTable

View File

@@ -167,9 +167,9 @@ const IONAVDetails = () => {
{ label: "Investment Closed", key: "initialNAVvalue" },
{ label: "Comments", key: "comments" },
{ label: "Update by", key: "creator" },
// { label: "Update by", key: "creator" },
{ label: "Transaction Type", key: "transactionType" },
{ label: "Comments", key: "comments" },
// { label: "Comments", key: "comments" },
// Add more headers as needed
];

View File

@@ -45,7 +45,7 @@ import GlobalStateContext from "../../../../Contexts/GlobalStateContext";
const DistributionInvestor = ({ isOpen, onClose, exit }) => {
const DistributionInvestor = ({ isOpen, onClose }) => {
const params = useParams();
const toast = useToast();
const id = params?.id;
@@ -55,6 +55,10 @@ const DistributionInvestor = ({ isOpen, onClose, exit }) => {
const [ isCalcualtedData, setIsCalcualtedData ] = useState(false)
const { IODetails } = useContext(GlobalStateContext);
// const {
// data:IObyID,
// error,
@@ -94,20 +98,10 @@ const DistributionInvestor = ({ isOpen, onClose, exit }) => {
formState: { errors },
reset,
} = useForm({
resolver: yupResolver(!exit? investorExit: investor),
resolver: yupResolver(investor),
});
// useEffect(()=>{
// try {
// const res = getDistributionInvestment({id,data})
// console.log(res);
// } catch (error) {
// }
// },[])
// console.log(IObyID);
// ====================================================[Table Setup]================================================================
const tableHeadRow = [
@@ -357,7 +351,9 @@ const DistributionInvestor = ({ isOpen, onClose, exit }) => {
const handleClose = () => {
onClose();
setIsFinalCalculateLoading(false);
reset();
reset({
amount:""
});
setCalculatedDate(null);
setIsCalcualtedData(false);
};
@@ -367,7 +363,7 @@ const DistributionInvestor = ({ isOpen, onClose, exit }) => {
<ModalOverlay />
<ModalContent maxW={1000}>
<ModalHeader fontSize={"md"}>
{exit ? "Enter Exit Amount" : " Distribution To Investor Transaction"}
Distribution To Investor Transaction
</ModalHeader>
<ModalCloseButton />
<ModalBody>
@@ -379,7 +375,7 @@ const DistributionInvestor = ({ isOpen, onClose, exit }) => {
<FormControl isInvalid={errors.amount} isRequired>
<FormLabel textAlign={"right"} fontSize={"sm"}>
{" "}
{exit ? "Enter Exit Amount" : "Amount to Distribute"}
Amount to Distribute
</FormLabel>
<Box
display={"flex"}
@@ -402,7 +398,7 @@ const DistributionInvestor = ({ isOpen, onClose, exit }) => {
/>
)}
/>
{/* <Button
<Button
leftIcon={<IoCalculator />}
size={"sm"}
rounded={0}
@@ -411,7 +407,7 @@ const DistributionInvestor = ({ isOpen, onClose, exit }) => {
isLoading={isCalculateLoading}
>
Calculate
</Button> */}
</Button>
</Box>
<FormErrorMessage display={'flex'} justifyContent={'end'} pe={125} fontSize={"xs"} fontWeight={600}>
{errors.amount?.message}

View File

@@ -1,7 +1,10 @@
import {
Alert,
AlertIcon,
Box,
Button,
FormControl,
FormErrorMessage,
FormLabel,
HStack,
Input,
@@ -19,115 +22,219 @@ import {
Textarea,
Th,
Tr,
useToast,
} from "@chakra-ui/react";
import DataTable from "../../../../Components/DataTable/DataTable";
import { useState } from "react";
import NormalData from "../../../../Components/DataTable/NormalTable";
import { useContext, useState } from "react";
import { AddIcon } from "@chakra-ui/icons";
import {
useGetDistributedToInvestorMutation,
useGetDistributionInvestorMutation,
useUpdateExitToInvestorMutation,
} from "../../../../Services/io.service";
import { useParams } from "react-router-dom";
import { useEffect } from "react";
import { Controller, useForm } from "react-hook-form";
import * as yup from "yup";
import { yupResolver } from "@hookform/resolvers/yup";
import ToastBox from "../../../../Components/ToastBox";
import CurrencyInput from "../../../../Components/CurrencyInput";
import { IoCalculator } from "react-icons/io5";
import { debounce } from "../../../Master/Sponser/AddSponser";
import GlobalStateContext from "../../../../Contexts/GlobalStateContext";
const Exit = ({ isOpen, onClose }) => {
const params = useParams();
const toast = useToast();
const id = params?.id;
const [isCalculateLoading, setIsCalculateLoading] = useState(false);
const [isFinalCalculateLoading, setIsFinalCalculateLoading] = useState(false);
const [calcualtedData, setCalculatedDate] = useState(null);
const [isCalcualtedData, setIsCalcualtedData] = useState(false);
const { IODetails } = useContext(GlobalStateContext);
const investorExit = yup.object().shape({
amount: yup
.string()
.required("Amount is required")
.test(
"max",
`Distribution amount should not be greater than IO cash amount ${IODetails?.ioCash}`,
function (value) {
const { ioCash } = IODetails || {}; // Safely get ioCash
if (value && ioCash) {
return parseFloat(value) <= parseFloat(ioCash); // Ensure both are compared as numbers
}
return true; // If ioCash is not available, skip validation
}
),
});
const {
control,
handleSubmit,
formState: { errors },
reset,
} = useForm({
resolver: yupResolver(investorExit),
});
useEffect(() => {
console.log("hiit useEffectc");
handleCalculate(id, {
amount: IODetails?.ioMVNAV,
});
reset({
amount: IODetails?.ioMVNAV,
});
}, [IODetails, id]);
const handleCalculate = async (id, data) => {
try {
const res = await getDistributionInvestment({ id, data });
console.log(res?.data?.data);
if (res?.error?.status === 401) {
// toast({
// render: () => (
// <ToastBox message={res?.error?.data?.message} status={"error"} />
// ),
// });
setIsCalculateLoading(false);
setIsCalcualtedData(false);
} else if (res?.data?.statusCode === 200) {
setCalculatedDate(res?.data?.data);
// toast({
// render: () => <ToastBox message={res?.data?.message} />,
// });
setIsCalculateLoading(false);
setIsCalcualtedData(true);
}
} catch (error) {}
};
// const {
// data:IObyID,
// error,
// isLoading,
// } = useGetDistributionInvestorMutation(id);
const [getDistributionInvestment] = useGetDistributionInvestorMutation();
const [getFinalDistributionInvestment] =
useGetDistributedToInvestorMutation();
const [updateExitToInvestor] = useUpdateExitToInvestorMutation();
const investor = yup.object().shape({
amount: yup.string().required("Amount is required"),
});
// useEffect(()=>{
// try {
// const res = getDistributionInvestment({id,data})
// console.log(res);
// } catch (error) {
// }
// },[])
// console.log(IObyID);
// ====================================================[Table Setup]================================================================
const tableHeadRow = [
"Sr No.",
"Client Id",
"First name",
"Last Name",
"Invested Amount",
"Distribution %",
"Exit Amount",
"Amount",
"Holding %",
"($)",
];
const filteredData = [
{
id: 1,
},
{
id: 1,
},
{
id: 1,
},
{
id: 1,
},
{
id: 1,
},
{
id: 1,
},
];
const [extractedArray, setExtractedArray] = useState(
filteredData?.map((item, index) => ({
id: item?.id,
"Sr No.": (
<Box
w={9}
display={"flex"}
alignItems={"center"}
isTruncated={true}
h={25}
const extractedArray = calcualtedData?.data?.map((item, index) => ({
id: item?.id,
"Sr No.": (
<Box
w={9}
display={"flex"}
alignItems={"center"}
isTruncated={true}
h={25}
>
<Text as={"span"} color={"teal.900"} fontWeight={"500"}>
{index + 1}
</Text>
</Box>
),
"Client Id": (
<Box w={100} isTruncated={true}>
<Text as={"span"} color={"teal.900"} fontWeight={"500"}>
{item?.clientId}
</Text>
</Box>
),
"First name": (
<Box minW={24} isTruncated={true}>
<Text as={"span"} color={"teal.900"} fontWeight={"500"}>
{item?.firstName}
</Text>
</Box>
),
"Last Name": (
<Box minW={24} isTruncated={true}>
<Text as={"span"} color={"teal.900"} fontWeight={"500"}>
{item?.lastName}
</Text>
</Box>
),
Amount: (
<Box minW={24} isTruncated={true}>
<Text as={"span"} color={"teal.900"} fontWeight={"500"}>
{item?.amount?.toLocaleString(undefined, {
minimumFractionDigits: 2,
maximumFractionDigits: 2,
})}
</Text>
</Box>
),
"Holding %": (
<Box minW={19} isTruncated={true}>
<Text
textAlign={"right"}
as={"span"}
color={"teal.900"}
fontWeight={"500"}
>
<Text as={"span"} color={"teal.900"} fontWeight={"500"}>
{index + 1}
</Text>
</Box>
),
"Client Id": (
<Box w={100} isTruncated={true}>
<Text as={"span"} color={"teal.900"} fontWeight={"500"}>
BH0000000
</Text>
</Box>
),
"First name": (
<Box minW={24} isTruncated={true}>
<Text as={"span"} color={"teal.900"} fontWeight={"500"}>
Faisal
</Text>
</Box>
),
"Last Name": (
<Box minW={24} isTruncated={true}>
<Text as={"span"} color={"teal.900"} fontWeight={"500"}>
Aljalahma
</Text>
</Box>
),
"Invested Amount": (
<Box minW={24} isTruncated={true}>
<Text as={"span"} color={"teal.900"} fontWeight={"500"}>
$100,000
</Text>
</Box>
),
"Distribution %": (
<Box minW={19} isTruncated={true}>
<Text
textAlign={"right"}
as={"span"}
color={"teal.900"}
fontWeight={"500"}
>
26.0 %
</Text>
</Box>
),
"Exit Amount": (
<Box minW={24} isTruncated={true}>
<Text as={"span"} color={"teal.900"} fontWeight={"500"}>
$100,000
</Text>
</Box>
),
}))
);
{parseFloat(item?.distribution_per).toFixed(2)}%
</Text>
</Box>
),
"($)": (
<Box minW={24} isTruncated={true}>
<Text as={"span"} color={"teal.900"} fontWeight={"500"}>
{item?.distribution_amt?.toLocaleString(undefined, {
minimumFractionDigits: 2,
maximumFractionDigits: 2,
})}
</Text>
</Box>
),
}));
const Total = () => {
return (
<Table size="sm">
<Tbody backgroundColor="gray.50">
<Tr>
<Tbody>
<Tr backgroundColor="gray.50">
<Th
textAlign={"left"}
p={3}
@@ -142,7 +249,7 @@ const Exit = ({ isOpen, onClose }) => {
<Th
textAlign={"center"}
p={3}
width="100px"
width="110px"
color={"#004118"}
whiteSpace="normal"
wordBreak="normal"
@@ -153,7 +260,7 @@ const Exit = ({ isOpen, onClose }) => {
<Th
textAlign={"center"}
p={3}
width="90px"
width="110px"
color={"#004118"}
whiteSpace="normal"
wordBreak="normal"
@@ -164,7 +271,7 @@ const Exit = ({ isOpen, onClose }) => {
<Th
textAlign={"center"}
p={3}
width="90px"
width="110px"
color={"#004118"}
whiteSpace="normal"
wordBreak="normal"
@@ -175,13 +282,16 @@ const Exit = ({ isOpen, onClose }) => {
<Th
textAlign={"left"}
p={3}
width="100px"
width="110px"
color={"#004118"}
whiteSpace="normal"
wordBreak="normal"
overflowWrap="normal"
>
$1,000,000
{calcualtedData?.totalInvestedAmt?.toLocaleString(undefined, {
minimumFractionDigits: 2,
maximumFractionDigits: 2,
})}
</Th>
<Th
textAlign={"left"}
@@ -191,8 +301,9 @@ const Exit = ({ isOpen, onClose }) => {
whiteSpace="normal"
wordBreak="normal"
overflowWrap="normal"
opacity={0}
>
100.0%
{calcualtedData?.distributed_per?.toFixed(2)}%
</Th>
<Th
textAlign={"center"}
@@ -203,7 +314,10 @@ const Exit = ({ isOpen, onClose }) => {
wordBreak="normal"
overflowWrap="normal"
>
$1,229,750
{calcualtedData?.distributed_amt?.toLocaleString(undefined, {
minimumFractionDigits: 2,
maximumFractionDigits: 2,
})}
</Th>
</Tr>
</Tbody>
@@ -211,52 +325,166 @@ const Exit = ({ isOpen, onClose }) => {
);
};
const onSubmit = async (data) => {
setIsCalculateLoading(true);
try {
const res = await getDistributionInvestment({ id, data });
console.log(res?.data?.data);
if (res?.error?.status === 401) {
toast({
render: () => (
<ToastBox message={res?.error?.data?.message} status={"error"} />
),
});
setIsCalculateLoading(false);
setIsCalcualtedData(false);
} else if (res?.data?.statusCode === 200) {
setCalculatedDate(res?.data?.data);
toast({
render: () => <ToastBox message={res?.data?.message} />,
});
setIsCalculateLoading(false);
setIsCalcualtedData(true);
}
} 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 exit)
? updateExitToInvestor({ id, data: finalData })
: 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 handleClose = () => {
onClose();
setIsFinalCalculateLoading(false);
setCalculatedDate(null);
setIsCalcualtedData(false);
};
return (
<Modal size={"xl"} isOpen={isOpen} onClose={onClose}>
<Modal size={"xl"} isOpen={isOpen} onClose={handleClose}>
<ModalOverlay />
<ModalContent maxW={1000}>
<ModalHeader fontSize={"md"}>Exit Transaction</ModalHeader>
<ModalHeader fontSize={"md"}>Enter Exit Amount</ModalHeader>
<ModalCloseButton />
<ModalBody>
<Text as="label" mb='5px' fontSize='sm' fontWeight={500}>Enter Exit Amount</Text>
<HStack mb={4}>
<Input focusBorderColor="forestGreen.400" placeholder="$00.00" size={"sm"} className="col" />
<Button
size={"sm"}
rounded={"sm"}
colorScheme="forestGreen"
>
Calculate
</Button>
{/* <Text as="label" mb="5px" fontSize="sm" fontWeight={500}>
Amount to Distribute
</Text> */}
<HStack onSubmit={handleSubmit(onSubmit)} as={"form"} mb={4}>
{/* <Input placeholder="$00.00" size={"sm"} className="col" /> */}
<FormControl isInvalid={errors.amount} isRequired>
<FormLabel textAlign={"right"} fontSize={"sm"}>
Enter Exit Amount
</FormLabel>
<Box
display={"flex"}
justifyContent={"end"}
alignItems={"end"}
gap={2}
>
<Controller
name="amount"
control={control}
render={({ field }) => (
<CurrencyInput
rounded={0}
w={"18%"}
{...field}
fontSize={"sm"}
type="number"
size={"sm"}
textAlign={"right"}
/>
)}
/>
</Box>
<FormErrorMessage
display={"flex"}
justifyContent={"end"}
pe={125}
fontSize={"xs"}
fontWeight={600}
>
{errors.amount?.message}
</FormErrorMessage>
</FormControl>
</HStack>
<DataTable
emptyMessage={`We don't have any Sponers `}
tableHeadRow={tableHeadRow}
data={extractedArray}
setData={setExtractedArray}
caption={<Total />}
// isLoading={isLoading}
/>
{/* {calcualtedData && ( */}
<NormalData
emptyMessage={`We don't have any Sponers `}
tableHeadRow={tableHeadRow}
data={extractedArray}
// total={<Total />}
// isLoading={isLoading}
/>
{/* ) } */}
</ModalBody>
<ModalFooter pt={0}>
<Button
bg={"hsla(139, 100%, 14%, 1)"}
mr={3}
color={"#fff"}
_hover={{
bg: "hsl(139deg 98.99% 26.59%)",
}}
size={'sm'}
rounded={"sm"}
>
Save
</Button>
<Button
size={'sm'}
rounded={"sm"} mr={3} onClick={onClose}>
Close
</Button>
{isCalcualtedData ? (
<>
<Button
bg={"hsla(139, 100%, 14%, 1)"}
mr={3}
color={"#fff"}
_hover={{
bg: "hsl(139deg 98.99% 26.59%)",
}}
size={"sm"}
rounded={"sm"}
onClick={handleSubmit(onFinalSubmit)}
isLoading={isFinalCalculateLoading}
>
Save
</Button>
<Button size={"sm"} rounded={"sm"} mr={3} onClick={onClose}>
Close
</Button>
</>
) : (
""
)}
</ModalFooter>
</ModalContent>
</Modal>

View File

@@ -481,24 +481,17 @@ const ViewIOdataHeader = ({ data, isLoading }) => {
{/* Modals */}
<AmountInvested isOpen={isInvestmentOpen} onClose={onInvestmentClose} />
<FeesExpenses isOpen={isFeesOpen} onClose={onFeesClose} />
{/* <Exit isOpen={isExitOpen} onClose={onExitClose} /> */}
<Exit isOpen={isExitOpen} onClose={onExitClose} />
<Cancle isOpen={isCancleOpen} onClose={onCancleClose} />
<DistributionSponsor
isOpen={isDistSponsorOpen}
onClose={onDistSponsorClose}
/>
<DistributionInvestor
exit={false}
isOpen={isDistInvestorOpen}
onClose={onDistInvestorClose}
/>
<DistributionInvestor
exit={true}
isOpen={isExitOpen}
onClose={onExitClose}
/>
<UpdateIONav isOpen={isUpdateNavOpen} onClose={onUpdateNavClose} />
<UpdateIOStatus
status={IODetails?.nextStatus}

View File

@@ -91,10 +91,10 @@ const Transaction = () => {
// "Sr N/O",
"Date",
"Transaction",
"Amount in investors currency",
"Amount",
// "Currency",
"TO USD",
"From USD",
// "TO USD",
// "From USD",
"USD amount",
"IO Name",
"Payment Method",
@@ -133,7 +133,7 @@ const Transaction = () => {
</Text>
</Box>
),
"Amount in investors currency": (
"Amount": (
<Box w={100} display={"flex"} justifyContent={"end"}>
<Text as={"span"} textAlign={"end"} w={"100%"} color={"teal.900"}>
{/* {item.investorAmount} */}
@@ -158,7 +158,10 @@ const Transaction = () => {
</Text>
),
"USD amount": (
<Box w={100} display={"flex"} justifyContent={"end"}>
{
item?.invCurToUSD_Rate === '0.0000' && (
<Text as={"span"} textAlign={"end"} w={"100%"} color={"teal.900"}>
{/* {item.USDAmount} */}
{parseFloat(item?.USDAmount || 0).toLocaleString(undefined, {
@@ -169,6 +172,8 @@ const Transaction = () => {
$
</Badge>
</Text>
)
}
</Box>
),
"IO Name": (
@@ -207,8 +212,8 @@ const Transaction = () => {
),
Transaction: null,
// "Currency": null,
"Amount in investors currency": (
<Box w={100} display={"flex"} justifyContent={"end"}>
"Amount": (
InvestorWallet?.currencyCode_InCur&&<Box w={100} display={"flex"} justifyContent={"end"}>
<Text as={"span"} textAlign={"end"} w={"100%"} color={"teal.900"}>
{parseFloat(InvestorWallet?.WalletBalance_InInvCur).toLocaleString(
undefined,
@@ -220,21 +225,9 @@ const Transaction = () => {
</Text>
</Box>
),
"TO USD": null,
"From USD": null,
"USD amount": (
<Box w={100} display={"flex"} justifyContent={"end"}>
<Text as={"span"} textAlign={"end"} w={"100%"} color={"teal.900"}>
{parseFloat(InvestorWallet?.WalletBalance_InUSD).toLocaleString(
undefined,
{ minimumFractionDigits: 2, maximumFractionDigits: 2 }
)}
<Badge ms={1} colorScheme="green">
$
</Badge>
</Text>
</Box>
),
// "TO USD": null,
// "From USD": null,
"USD amount": null,
"IO Name": null,
"Payment Method": null,
};