Merge branch 'main' of http://git.wdipl.com/Siddhesh.More/tanami-admin-panel into dev
This commit is contained in:
@@ -1,36 +1,32 @@
|
||||
import React, { forwardRef } from 'react';
|
||||
import { Input } from "@chakra-ui/react";
|
||||
|
||||
// export const formatCurrency = (value) => {
|
||||
// if (!value) return '';
|
||||
// const [integer, decimal] = value.split('.');
|
||||
// const formattedInteger = integer.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
|
||||
// return decimal ? `${formattedInteger}.${decimal}` : formattedInteger;
|
||||
// };
|
||||
|
||||
export const formatCurrency = (value) => {
|
||||
if (value === undefined || value === null) return ''; // Handle undefined or null values
|
||||
const [integer, decimal] = String(value).split('.'); // Convert value to string before splitting
|
||||
if (value === undefined || value === null) return '';
|
||||
const [integer, decimal] = String(value).split('.');
|
||||
const formattedInteger = integer.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
|
||||
return decimal ? `${formattedInteger}.${decimal}` : formattedInteger;
|
||||
return decimal !== undefined ? `${formattedInteger}.${decimal}` : formattedInteger;
|
||||
};
|
||||
const CurrencyInput = forwardRef(({ value, onChange, ...props }, ref) => {
|
||||
|
||||
|
||||
|
||||
const handleChange = (event) => {
|
||||
let { value } = event?.target;
|
||||
|
||||
// Remove non-numeric characters except decimal point
|
||||
value = value?.replace(/[^0-9.]/g, '');
|
||||
value = value.replace(/[^0-9.]/g, '');
|
||||
|
||||
// Ensure only one decimal point
|
||||
const parts = value?.split('.');
|
||||
const parts = value.split('.');
|
||||
if (parts.length > 2) {
|
||||
value = parts[0] + '.' + parts?.slice(1)?.join('');
|
||||
value = parts[0] + '.' + parts.slice(1).join('');
|
||||
}
|
||||
|
||||
onChange(value); // Pass the raw value to parent or use it directly
|
||||
// Restrict to two decimal places
|
||||
if (parts[1]?.length > 2) {
|
||||
value = parts[0] + '.' + parts[1].slice(0, 2);
|
||||
}
|
||||
|
||||
onChange(value); // Pass the raw value to parent
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -45,3 +41,50 @@ const CurrencyInput = forwardRef(({ value, onChange, ...props }, ref) => {
|
||||
});
|
||||
|
||||
export default CurrencyInput;
|
||||
|
||||
|
||||
|
||||
|
||||
// import React, { forwardRef } from 'react';
|
||||
// import { Input } from "@chakra-ui/react";
|
||||
|
||||
// export const formatCurrency = (value) => {
|
||||
// if (value === undefined || value === null) return ''; // Handle undefined or null values
|
||||
// const [integer, decimal] = String(value).split('.'); // Convert value to string before splitting
|
||||
// const formattedInteger = integer.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
|
||||
// return decimal ? `${formattedInteger}.${decimal}` : formattedInteger;
|
||||
// };
|
||||
|
||||
// const CurrencyInput = forwardRef(({ value, onChange, ...props }, ref) => {
|
||||
|
||||
// const handleChange = (event) => {
|
||||
// let { value } = event?.target;
|
||||
|
||||
// // Remove non-numeric characters except decimal point
|
||||
// value = value?.replace(/[^0-9.]/g, '');
|
||||
|
||||
// // Ensure only one decimal point and restrict to two decimal places
|
||||
// const parts = value?.split('.');
|
||||
// if (parts.length > 2) {
|
||||
// value = parts[0] + '.' + parts?.slice(1)?.join('');
|
||||
// }
|
||||
|
||||
// if (parts[1]?.length > 2) {
|
||||
// value = parts[0] + '.' + parts[1]?.slice(0, 2);
|
||||
// }
|
||||
|
||||
// onChange(value); // Pass the raw value to parent or use it directly
|
||||
// };
|
||||
|
||||
// return (
|
||||
// <Input
|
||||
// {...props}
|
||||
// ref={ref} // Forward ref here
|
||||
// type="text"
|
||||
// value={formatCurrency(value)}
|
||||
// onChange={handleChange}
|
||||
// />
|
||||
// );
|
||||
// });
|
||||
|
||||
// export default CurrencyInput;
|
||||
|
||||
@@ -477,8 +477,8 @@ const FormField = ({
|
||||
placeholder={placeHolder ? placeHolder : label}
|
||||
textAlign={arabic ? "right" : align ? align : "left"}
|
||||
_placeholder={{ fontSize: "sm" }}
|
||||
min={type === "date" ? today : undefined}
|
||||
maxLength={maxLength}
|
||||
// min={type === "date" ? today : undefined}
|
||||
// maxLength={maxLength}
|
||||
// defaultValue={type === "date" && "2023-07-26" : undefined}
|
||||
// defaultValue={value}
|
||||
// value={dateValue}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
|
||||
import dns from "node:dns"
|
||||
import * as XLSX from 'xlsx';
|
||||
|
||||
|
||||
export const generateSerialNumber = (index, currentPage, pageSize) => {
|
||||
@@ -145,4 +146,53 @@ export function calculatePercentage(part, total) {
|
||||
return 0; // To avoid division by zero
|
||||
}
|
||||
return (part / total) * 100;
|
||||
}
|
||||
}
|
||||
|
||||
export const exportToExcel = (data, customHeaders, fileName = 'exported-data.xlsx') => {
|
||||
// Map your data to include only the fields that match your custom headers
|
||||
const mappedData = data.map(item =>
|
||||
customHeaders.map(header => item[header.key] || '')
|
||||
);
|
||||
|
||||
// Prepend the headers row
|
||||
const sheetData = [customHeaders.map(header => header.label), ...mappedData];
|
||||
|
||||
// Create a worksheet from the data array
|
||||
const worksheet = XLSX.utils.aoa_to_sheet(sheetData);
|
||||
|
||||
// Apply styles to header cells
|
||||
customHeaders.forEach((header, index) => {
|
||||
const cellAddress = XLSX.utils.encode_cell({ r: 0, c: index }); // r: row, c: column
|
||||
if (!worksheet[cellAddress]) return; // Skip if cell doesn't exist
|
||||
|
||||
worksheet[cellAddress].s = {
|
||||
fill: {
|
||||
fgColor: { rgb: "FFFF00" } // Set header background color (Yellow in this case)
|
||||
},
|
||||
font: {
|
||||
bold: true, // Make header text bold
|
||||
color: { rgb: "000000" } // Set header text color (Black in this case)
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
// Create a new workbook and append the worksheet
|
||||
const workbook = XLSX.utils.book_new();
|
||||
XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1');
|
||||
|
||||
// Generate a buffer from the workbook
|
||||
const excelBuffer = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' });
|
||||
|
||||
// Create a Blob object from the buffer
|
||||
const dataBlob = new Blob([excelBuffer], { type: 'application/octet-stream' });
|
||||
|
||||
// Create a link element to trigger the download
|
||||
const link = document.createElement('a');
|
||||
link.href = URL.createObjectURL(dataBlob);
|
||||
link.download = fileName;
|
||||
|
||||
// Append the link to the document body, trigger the download, and remove the link
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
};
|
||||
|
||||
@@ -161,7 +161,7 @@ const DepositRequest = () => {
|
||||
</Text>
|
||||
),
|
||||
"First Name": (
|
||||
<Box isTruncated={true} w={"70px"}>
|
||||
<Box isTruncated={true} w={"170px"}>
|
||||
<Text as={"span"} color={"teal.900"} fontWeight={"500"}>
|
||||
{item?.firstName}
|
||||
</Text>
|
||||
|
||||
@@ -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";
|
||||
@@ -123,7 +126,15 @@ import { formatDatee } from "../../../Components/FormField";
|
||||
|
||||
|
||||
|
||||
const today = formatDatee(new Date(), 'yyyy-MM-dd');
|
||||
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));
|
||||
|
||||
|
||||
|
||||
@@ -162,7 +173,7 @@ const today = formatDatee(new Date(), 'yyyy-MM-dd');
|
||||
|
||||
|
||||
<FormControl isInvalid={errors.transactionAmount} isRequired>
|
||||
<FormLabel fontSize={"sm"}>Transaction Amount</FormLabel>
|
||||
<FormLabel fontSize={"sm"}>New NAV</FormLabel>
|
||||
<Controller
|
||||
name="transactionAmount"
|
||||
control={control}
|
||||
@@ -174,7 +185,24 @@ const today = formatDatee(new Date(), 'yyyy-MM-dd');
|
||||
{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}>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
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 } from '@chakra-ui/react';
|
||||
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';
|
||||
@@ -86,9 +86,7 @@ const Destribution = () => {
|
||||
fontWeight={"500"}
|
||||
className="d-flex align-items-center web-text-small"
|
||||
>
|
||||
{/* {`${item.transactionAmount}`} */}
|
||||
|
||||
{/* {`$${parseFloat(item.transactionAmount||0).toLocaleString()}`} */}
|
||||
<Badge ms={1} colorScheme="green" me={1}>$</Badge>
|
||||
{`${parseFloat(item.transactionAmount || 0).toLocaleString(undefined, {
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 2,
|
||||
|
||||
@@ -121,7 +121,7 @@ const IOCashDetails = () => {
|
||||
),
|
||||
Amount: (
|
||||
<Text
|
||||
justifyContent={"center"}
|
||||
justifyContent={"left"}
|
||||
as={"span"}
|
||||
color={"teal.900"}
|
||||
fontWeight={"500"}
|
||||
|
||||
@@ -69,7 +69,6 @@ const schema = yup.object().shape({
|
||||
.typeError("Goal Amount is must be number")
|
||||
.required('Goal amount is required')
|
||||
.positive('Goal amount must be a positive number'),
|
||||
|
||||
closingDate: yup
|
||||
.date()
|
||||
.notRequired("Closing date is required")
|
||||
@@ -98,6 +97,9 @@ const schema = yup.object().shape({
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const IODetails = ({ enableNextTab, index, data }) => {
|
||||
|
||||
|
||||
@@ -166,21 +168,90 @@ const IODetails = ({ enableNextTab, index, data }) => {
|
||||
}
|
||||
);
|
||||
|
||||
console.log(IObyID?.data?.minInvestmentAmt);
|
||||
|
||||
|
||||
const minInvestmentById = IObyID?.data?.minInvestmentAmt?.map(({minInvestmentAmt, country, country_xid,id })=>{
|
||||
|
||||
const minInvestmentById = IObyID?.data?.minInvestmentAmt?.map(({minInvestmentAmt, country, currencyCode, country_xid,id })=>{
|
||||
console.log(currencyCode);
|
||||
return{
|
||||
_id:id,
|
||||
id:country_xid,
|
||||
country: country?.countryName,
|
||||
value: removeTrailingZeros(minInvestmentAmt),
|
||||
logo: country?.flagIcon,
|
||||
curr: country?.countryCode,
|
||||
curr: currencyCode,
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
const schemaEdit = yup.object().shape({
|
||||
investmentNameEnglish: yup
|
||||
.string()
|
||||
.required("IO name in English is required")
|
||||
.min(3, "IO name in English must be at least 3 characters long")
|
||||
.max(150, "IO name in English must be at most 150 characters long"),
|
||||
|
||||
investmentNameArabic: yup
|
||||
.string()
|
||||
.required("IO name in Arabic is required")
|
||||
.min(3, "IO name in Arabic must be at least 3 characters long")
|
||||
.max(50, "IO name in Arabic must be at most 50 characters long"),
|
||||
|
||||
descriptionEnglish: yup
|
||||
.string()
|
||||
.required("Description in English is required")
|
||||
.min(10, "Description in English must be at least 10 characters long")
|
||||
.max(1000, "Description in English must be at most 1000 characters long"),
|
||||
|
||||
descriptionArabic: yup
|
||||
.string()
|
||||
.required("Description in Arabic is required")
|
||||
.min(10, "Description in Arabic must be at least 10 characters long")
|
||||
.max(2000, "Description in Arabic must be at most 500 characters long"),
|
||||
expectedReturnArabic: yup
|
||||
.string()
|
||||
.required("Expected return in Arabic is required"),
|
||||
|
||||
goalAmount: yup
|
||||
.number()
|
||||
.typeError("Goal Amount is must be number")
|
||||
.required('Goal amount is required')
|
||||
.positive('Goal amount must be a positive number')
|
||||
.min(IObyID?.data?.totalAmtInvestmentInUSD, `Goal amount should not be lesser then amount raised ${IObyID?.data?.totalAmtInvestmentInUSD}`),
|
||||
closingDate: yup
|
||||
.date()
|
||||
.notRequired("Closing date is required")
|
||||
.min(new Date(), "Closing date cannot be in the past"),
|
||||
|
||||
holdingPeriod: yup.string().required("Holding period is required"),
|
||||
holdingPeriodArabic: yup.string().required("Holding period is required"),
|
||||
|
||||
// minInvestmentAmount: yup
|
||||
// .number()
|
||||
// .required("Minimum investment is required")
|
||||
// .positive("Minimum investment must be a positive number")
|
||||
// .min(1, "Minimum investment must be at least 1"),
|
||||
|
||||
ISIN: yup.string().notRequired(),
|
||||
|
||||
InvestmentDetails: yup.string().notRequired(),
|
||||
|
||||
comment: yup.string().notRequired()
|
||||
.min(10, "Comment must be at least 10 characters long")
|
||||
.max(100, "Comment must be at most 100 characters long"),
|
||||
|
||||
expectedReturn: yup
|
||||
.string()
|
||||
.required("Expected return is required"),
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
const [values, setValues] = useState(id?minInvestmentById:miniValue);
|
||||
|
||||
console.log(values);
|
||||
|
||||
const formatNumber = (num) => {
|
||||
// Remove non-numeric characters and format with commas
|
||||
@@ -198,7 +269,7 @@ const IODetails = ({ enableNextTab, index, data }) => {
|
||||
handleSubmit,
|
||||
formState: { errors },
|
||||
} = useForm({
|
||||
resolver: yupResolver(schema),
|
||||
resolver: yupResolver(id ? schemaEdit : schema),
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@@ -22,6 +22,8 @@ import { formatDatee } from "../../../Components/FormField";
|
||||
import { AddIcon } from "@chakra-ui/icons";
|
||||
import AddIONav from "./AddIONav";
|
||||
import { formatDate } from "../../Master/Sponser/Sponsers";
|
||||
import { LuFileSpreadsheet } from "react-icons/lu";
|
||||
import { exportToExcel } from "../../../Constants/Constants";
|
||||
|
||||
const IONAVDetails = () => {
|
||||
const { navDetails, setNavDetails, IODetails } =
|
||||
@@ -80,7 +82,7 @@ const IONAVDetails = () => {
|
||||
fontWeight={"500"}
|
||||
className="d-flex align-items-center web-text-small"
|
||||
>
|
||||
{/* {formatDatee(item.transactionDate)} */}
|
||||
{/* {/ {formatDatee(item.transactionDate)} /} */}
|
||||
{formatDate(item?.transactionDate)}
|
||||
</Text>
|
||||
),
|
||||
@@ -90,17 +92,11 @@ const IONAVDetails = () => {
|
||||
as={"span"}
|
||||
color={"teal.900"}
|
||||
fontWeight={"500"}
|
||||
className="d-flex align-items-left web-text-small"
|
||||
className="d-flex align-items-center web-text-small"
|
||||
>
|
||||
{/* {`${item.transactionAmount}`} */}
|
||||
|
||||
<Badge ms={1} colorScheme="green" me={1}>
|
||||
$
|
||||
</Badge>
|
||||
{parseFloat(item.transactionAmount || 0).toLocaleString(undefined, {
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 2,
|
||||
})}
|
||||
{/* {/ {`${item.transactionAmount}`} /} */}
|
||||
<Badge ms={1} colorScheme="green" me={1}>$</Badge>
|
||||
{`${parseFloat(item.transactionAmount || 0).toLocaleString()}`}
|
||||
</Text>
|
||||
),
|
||||
"Last NAV update": (
|
||||
@@ -162,6 +158,23 @@ const IONAVDetails = () => {
|
||||
),
|
||||
}));
|
||||
|
||||
const customHeaders = [
|
||||
{ label: "ID", key: "id" },
|
||||
{ label: "Valuation Date", key: "transactionDate" },
|
||||
{ label: "NAV", key: "transactionAmount" },
|
||||
{ label: "Last NAV update", key: "previousNAVvalue" },
|
||||
|
||||
{ label: "Investment Closed", key: "initialNAVvalue" },
|
||||
{ label: "Comments", key: "comments" },
|
||||
|
||||
{ label: "Update by", key: "creator" },
|
||||
{ label: "Transaction Type", key: "transactionType" },
|
||||
{ label: "Comments", key: "comments" },
|
||||
// Add more headers as needed
|
||||
];
|
||||
|
||||
console.log(IODetails?.ioNAVHistory);
|
||||
|
||||
const handleDelete = () => {
|
||||
const updatedNav = navDetails.filter((sponsor) => sponsor.id !== actionId);
|
||||
|
||||
@@ -173,6 +186,8 @@ const IONAVDetails = () => {
|
||||
setIsLoading(true);
|
||||
};
|
||||
|
||||
const handleExport = () => {};
|
||||
|
||||
return (
|
||||
<Box {...OPACITY_ON_LOAD} pb={0}>
|
||||
<Box bg="white.500">
|
||||
@@ -193,24 +208,34 @@ const IONAVDetails = () => {
|
||||
onChange={(e) => setSearchTerm(e.target.value)}
|
||||
/>
|
||||
|
||||
{/* <HStack display={"flex"} alignItems={"center"}>
|
||||
<Pagination totalItems={10} />
|
||||
</HStack> */}
|
||||
|
||||
{/* {IODetails?.isInvestedAmount ? <Button onClick={onOpen} leftIcon={<AddIcon/>} colorScheme="forestGreen" size={'sm'} rounded={'sm'} fontSize={'xs'} >Add IO Cash</Button>:null} */}
|
||||
|
||||
{IODetails?.isInvestedAmount ? (
|
||||
<HStack display={"flex"} alignItems={"center"}>
|
||||
<Button
|
||||
onClick={onOpen}
|
||||
leftIcon={<AddIcon />}
|
||||
onClick={() =>
|
||||
exportToExcel(IODetails?.ioNAVHistory, customHeaders)
|
||||
}
|
||||
leftIcon={<LuFileSpreadsheet />}
|
||||
colorScheme="forestGreen"
|
||||
size={"sm"}
|
||||
variant={"outline"}
|
||||
rounded={"sm"}
|
||||
fontSize={"xs"}
|
||||
>
|
||||
Add IO Nav
|
||||
Export xls
|
||||
</Button>
|
||||
) : null}
|
||||
|
||||
{IODetails?.isInvestedAmount ? (
|
||||
<Button
|
||||
onClick={onOpen}
|
||||
leftIcon={<AddIcon />}
|
||||
colorScheme="forestGreen"
|
||||
size={"sm"}
|
||||
rounded={"sm"}
|
||||
fontSize={"xs"}
|
||||
>
|
||||
Add IO Nav
|
||||
</Button>
|
||||
) : null}
|
||||
</HStack>
|
||||
</HStack>
|
||||
</Box>
|
||||
|
||||
|
||||
@@ -39,8 +39,6 @@ import { FiRefreshCw } from "react-icons/fi";
|
||||
import { useGetIOByIdQuery } from "../../../Services/io.service";
|
||||
import { RepeatIcon } from "@chakra-ui/icons";
|
||||
|
||||
|
||||
|
||||
const rotate = keyframes`
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
@@ -52,21 +50,18 @@ const rotate = keyframes`
|
||||
|
||||
const formatDate = (date) => new Date(date).toLocaleDateString(); // Simple date formatter
|
||||
|
||||
const Investors = ({data}) => {
|
||||
const params = useParams()
|
||||
const id = params?.id
|
||||
const Investors = ({ data }) => {
|
||||
const params = useParams();
|
||||
const id = params?.id;
|
||||
const toast = useToast();
|
||||
const { investors, setInvestors, slideFromRight, IODetails } =
|
||||
useContext(GlobalStateContext);
|
||||
|
||||
const [ isRefetchLoading, setIsRefetchLoading ] = useState(false)
|
||||
|
||||
const {
|
||||
isLoading: IObyIDisLoading,
|
||||
refetch
|
||||
} = useGetIOByIdQuery(id, { skip: !id });
|
||||
|
||||
|
||||
const [isRefetchLoading, setIsRefetchLoading] = useState(false);
|
||||
|
||||
const { isLoading: IObyIDisLoading, refetch } = useGetIOByIdQuery(id, {
|
||||
skip: !id,
|
||||
});
|
||||
|
||||
const [searchTerm, setSearchTerm] = useState("");
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
@@ -137,9 +132,6 @@ const Investors = ({data}) => {
|
||||
return nameMatches;
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
const extractedArray = filteredData?.map((item, index) => ({
|
||||
id: item?.id,
|
||||
"Client ID": (
|
||||
@@ -177,17 +169,23 @@ const Investors = ({data}) => {
|
||||
),
|
||||
"Investment amount": (
|
||||
<Text
|
||||
justifyContent={slideFromRight ? "right" : "center"}
|
||||
justifyContent={slideFromRight ? "right" : "left"}
|
||||
as={"span"}
|
||||
color={"teal.900"}
|
||||
fontWeight={"500"}
|
||||
className="d-flex align-items-center web-text-small"
|
||||
>
|
||||
<Badge ms={1} colorScheme="green" me={1}>
|
||||
$
|
||||
</Badge>
|
||||
{/* {`$${formatCurrency(item.InvestedAmount_USD)}`} */}
|
||||
{`$${parseFloat(item.InvestedAmount_USD||0).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`}
|
||||
{`${parseFloat(item.InvestedAmount_USD || 0).toLocaleString(undefined, {
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 2,
|
||||
})}`}
|
||||
</Text>
|
||||
),
|
||||
"Percentage": (
|
||||
Percentage: (
|
||||
<Text
|
||||
justifyContent={slideFromRight ? "right" : "center"}
|
||||
as={"span"}
|
||||
@@ -200,13 +198,19 @@ const Investors = ({data}) => {
|
||||
),
|
||||
"Market Value": (
|
||||
<Text
|
||||
justifyContent={slideFromRight ? "right" : "center"}
|
||||
justifyContent={slideFromRight ? "right" : "left"}
|
||||
as={"span"}
|
||||
color={"teal.900"}
|
||||
fontWeight={"500"}
|
||||
className="d-flex align-items-center web-text-small"
|
||||
>
|
||||
{`$${parseFloat(item.Market_Value ||0).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`}
|
||||
<Badge ms={1} colorScheme="green" me={1}>
|
||||
$
|
||||
</Badge>
|
||||
{`${parseFloat(item.Market_Value || 0).toLocaleString(undefined, {
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 2,
|
||||
})}`}
|
||||
</Text>
|
||||
),
|
||||
"Return on Investment": (
|
||||
@@ -221,16 +225,20 @@ const Investors = ({data}) => {
|
||||
{item.Return_On_Investment || 0} %
|
||||
</Text>
|
||||
),
|
||||
"Distribution": (
|
||||
Distribution: (
|
||||
<Text
|
||||
justifyContent={slideFromRight ? "right" : "center"}
|
||||
justifyContent={slideFromRight ? "right" : "left"}
|
||||
as={"span"}
|
||||
color={"teal.900"}
|
||||
fontWeight={"500"}
|
||||
className="d-flex align-items-center web-text-small"
|
||||
>
|
||||
<Badge ms={1} colorScheme="green" me={1}>$</Badge>
|
||||
{/* {`$${item.Distribution_Amt}`} */}
|
||||
{`$${parseFloat(item.Distribution_Amt||0).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`}
|
||||
{`$${parseFloat(item.Distribution_Amt || 0).toLocaleString(undefined, {
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 2,
|
||||
})}`}
|
||||
</Text>
|
||||
),
|
||||
"Distribution Percent": (
|
||||
@@ -242,19 +250,26 @@ const Investors = ({data}) => {
|
||||
className="d-flex align-items-center web-text-small"
|
||||
>
|
||||
{/* {`$${item.Distribution_Amt}`} */}
|
||||
{`${parseFloat(item.Distribution_Per||0).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })} %`}
|
||||
{`${parseFloat(item.Distribution_Per || 0).toLocaleString(undefined, {
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 2,
|
||||
})} %`}
|
||||
</Text>
|
||||
),
|
||||
"Total Return": (
|
||||
<Text
|
||||
justifyContent={slideFromRight ? "right" : "center"}
|
||||
justifyContent={slideFromRight ? "right" : "left"}
|
||||
as={"span"}
|
||||
color={"teal.900"}
|
||||
fontWeight={"500"}
|
||||
className="d-flex align-items-center web-text-small"
|
||||
>
|
||||
<Badge ms={1} colorScheme="green" me={1}>$</Badge>
|
||||
{/* {`$${formatCurrency(item.Total_Return) || 0}`} */}
|
||||
{`$${parseFloat(item.Total_Return||0).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`}
|
||||
{`${parseFloat(item.Total_Return || 0).toLocaleString(undefined, {
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 2,
|
||||
})}`}
|
||||
</Text>
|
||||
),
|
||||
"Total return on Investment": (
|
||||
@@ -265,7 +280,7 @@ const Investors = ({data}) => {
|
||||
fontWeight={"500"}
|
||||
className="d-flex align-items-center web-text-small"
|
||||
>
|
||||
{item.Total_Return_On_Investment||0} %
|
||||
{item.Total_Return_On_Investment || 0} %
|
||||
</Text>
|
||||
),
|
||||
}));
|
||||
@@ -287,7 +302,7 @@ const Investors = ({data}) => {
|
||||
return (
|
||||
<Table size="sm">
|
||||
<Tbody backgroundColor="gray.50">
|
||||
<Tr >
|
||||
<Tr>
|
||||
<Th
|
||||
textAlign={"center"}
|
||||
p={3}
|
||||
@@ -404,12 +419,11 @@ const Investors = ({data}) => {
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
const handleRefresh = async() =>{
|
||||
setIsRefetchLoading(true)
|
||||
await refetch()
|
||||
setIsRefetchLoading(false)
|
||||
}
|
||||
const handleRefresh = async () => {
|
||||
setIsRefetchLoading(true);
|
||||
await refetch();
|
||||
setIsRefetchLoading(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<Box {...OPACITY_ON_LOAD} pb={0}>
|
||||
@@ -419,27 +433,60 @@ const Investors = ({data}) => {
|
||||
justifyContent={"space-between"}
|
||||
pb={3}
|
||||
spacing="24px"
|
||||
|
||||
>
|
||||
<span>
|
||||
<Input
|
||||
type="search"
|
||||
width={300}
|
||||
placeholder="Search..."
|
||||
size="sm"
|
||||
rounded="sm"
|
||||
focusBorderColor="green.500"
|
||||
value={searchTerm}
|
||||
onChange={(e) => setSearchTerm(e.target.value)}
|
||||
/>
|
||||
<Icon ms={3}
|
||||
animation={IObyIDisLoading ? `${rotate} 1s linear infinite` : "none"} bg={"gray.100"} onClick={handleRefresh} fontWeight={600} as={RepeatIcon} boxSize={8} p={2} rounded={'md'} _hover={{bg:'gray.100'}} cursor={'pointer'} />
|
||||
<Input
|
||||
type="search"
|
||||
width={300}
|
||||
placeholder="Search..."
|
||||
size="sm"
|
||||
rounded="sm"
|
||||
focusBorderColor="green.500"
|
||||
value={searchTerm}
|
||||
onChange={(e) => setSearchTerm(e.target.value)}
|
||||
/>
|
||||
<Icon
|
||||
ms={3}
|
||||
animation={
|
||||
IObyIDisLoading ? `${rotate} 1s linear infinite` : "none"
|
||||
}
|
||||
bg={"gray.100"}
|
||||
onClick={handleRefresh}
|
||||
fontWeight={600}
|
||||
as={RepeatIcon}
|
||||
boxSize={8}
|
||||
p={2}
|
||||
rounded={"md"}
|
||||
_hover={{ bg: "gray.100" }}
|
||||
cursor={"pointer"}
|
||||
/>
|
||||
</span>
|
||||
|
||||
<HStack bg={'#C6F6D5'} ps={4} pe={4} pt={1.5} pb={1.5} rounded={'md'} boxShadow={'sm'} display={"flex"} alignItems={"end"} flexDirection={'column'} >
|
||||
<Text fontWeight={600} fontSize={'sm'} as={'span'}>$ {parseFloat(IODetails?.totalAmtInvestmentInUSD).toLocaleString()}</Text>
|
||||
<Text fontWeight={600} color={'gray.500'} fontSize={'xs'} as={'span'}>Total Investment Amount ( USD )</Text>
|
||||
|
||||
<HStack
|
||||
bg={"#C6F6D5"}
|
||||
ps={4}
|
||||
pe={4}
|
||||
pt={1.5}
|
||||
pb={1.5}
|
||||
rounded={"md"}
|
||||
boxShadow={"sm"}
|
||||
display={"flex"}
|
||||
// alignItems={"end"}
|
||||
// flexDirection={"column"}
|
||||
alignItems={"center"}
|
||||
>
|
||||
<Text
|
||||
fontWeight={600}
|
||||
color={"gray.500"}
|
||||
fontSize={"xs"}
|
||||
as={"span"}
|
||||
>
|
||||
Total Investment Amount ( USD )
|
||||
</Text>
|
||||
<Badge ms={2} colorScheme="forestGreen" me={0}>$</Badge>
|
||||
<Text fontWeight={600} fontSize={"sm"} as={"span"} pt={"2px"}>
|
||||
{parseFloat(IODetails?.totalAmtInvestmentInUSD).toLocaleString()}
|
||||
</Text>
|
||||
</HStack>
|
||||
</HStack>
|
||||
</Box>
|
||||
@@ -448,7 +495,7 @@ const Investors = ({data}) => {
|
||||
centered={true}
|
||||
emptyMessage={`We don't have any Sponers `}
|
||||
tableHeadRow={tableHeadRow}
|
||||
data={extractedArray}
|
||||
data={extractedArray}
|
||||
isLoading={isLoading}
|
||||
viewActionId={actionId}
|
||||
setViewActionId={setActionId}
|
||||
|
||||
@@ -25,7 +25,7 @@ import {
|
||||
useToast,
|
||||
} from "@chakra-ui/react";
|
||||
import NormalData from "../../../../Components/DataTable/NormalTable";
|
||||
import { useState } from "react";
|
||||
import { useContext, useState } from "react";
|
||||
import { AddIcon } from "@chakra-ui/icons";
|
||||
import {
|
||||
useGetDistributedToInvestorMutation,
|
||||
@@ -41,19 +41,19 @@ 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";
|
||||
|
||||
|
||||
export const investor = yup.object().shape({
|
||||
amount: yup.string().required("Amount is required"),
|
||||
});
|
||||
|
||||
const DistributionInvestor = ({ isOpen, onClose, exit }) => {
|
||||
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 [ isCalculateLoading, setIsCalculateLoading ] = useState(false)
|
||||
const [ isFinalCalculateLoading, setIsFinalCalculateLoading ] = useState(false)
|
||||
const [ calcualtedData, setCalculatedDate ] = useState(null)
|
||||
const [ isCalcualtedData, setIsCalcualtedData ] = useState(false)
|
||||
const { IODetails } = useContext(GlobalStateContext);
|
||||
|
||||
// const {
|
||||
// data:IObyID,
|
||||
@@ -66,13 +66,35 @@ const DistributionInvestor = ({ isOpen, onClose, exit }) => {
|
||||
useGetDistributedToInvestorMutation();
|
||||
const [updateExitToInvestor] = useUpdateExitToInvestorMutation();
|
||||
|
||||
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 investor = yup.object().shape({
|
||||
amount: yup.string().required("Amount is required"),
|
||||
});
|
||||
|
||||
|
||||
const {
|
||||
control,
|
||||
handleSubmit,
|
||||
formState: { errors },
|
||||
reset,
|
||||
} = useForm({
|
||||
resolver: yupResolver(investor),
|
||||
resolver: yupResolver(!exit? investorExit: investor),
|
||||
});
|
||||
|
||||
// useEffect(()=>{
|
||||
@@ -391,13 +413,7 @@ const DistributionInvestor = ({ isOpen, onClose, exit }) => {
|
||||
Calculate
|
||||
</Button> */}
|
||||
</Box>
|
||||
<FormErrorMessage
|
||||
display={"flex"}
|
||||
justifyContent={"end"}
|
||||
pe={125}
|
||||
fontSize={"xs"}
|
||||
fontWeight={500}
|
||||
>
|
||||
<FormErrorMessage display={'flex'} justifyContent={'end'} pe={125} fontSize={"xs"} fontWeight={600}>
|
||||
{errors.amount?.message}
|
||||
</FormErrorMessage>
|
||||
</FormControl>
|
||||
|
||||
@@ -125,7 +125,7 @@ const ViewIOdetails = () => {
|
||||
country: country?.countryName,
|
||||
value: removeTrailingZeros(minInvestmentAmt),
|
||||
logo: country?.flagIcon,
|
||||
curr: country?.countryCode,
|
||||
curr: currencyCode,
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -1,365 +1,308 @@
|
||||
import {
|
||||
Avatar,
|
||||
Badge,
|
||||
Box,
|
||||
Button,
|
||||
HStack,
|
||||
Input,
|
||||
Menu,
|
||||
MenuButton,
|
||||
MenuItem,
|
||||
MenuList,
|
||||
Portal,
|
||||
Select,
|
||||
Switch,
|
||||
Table,
|
||||
Tag,
|
||||
Tbody,
|
||||
Text,
|
||||
Th,
|
||||
Tooltip,
|
||||
Tr,
|
||||
useToast,
|
||||
} from "@chakra-ui/react";
|
||||
import React, { useContext, useEffect, useState } from "react";
|
||||
import { OPACITY_ON_LOAD } from "../../../Layout/animations";
|
||||
import DataTable from "../../../Components/DataTable/DataTable";
|
||||
import Pagination from "../../../Components/Pagination";
|
||||
import GlobalStateContext from "../../../Contexts/GlobalStateContext";
|
||||
import CustomAlertDialog from "../../../Components/CustomAlertDialog";
|
||||
import ToastBox from "../../../Components/ToastBox";
|
||||
import { debounce } from "../../Master/Sponser/AddSponser";
|
||||
|
||||
const formatDate = (date) => new Date(date).toLocaleDateString(); // Simple date formatter
|
||||
|
||||
const Transaction = () => {
|
||||
const toast = useToast();
|
||||
const { transaction, setTransaction, slideFromRight, InvestorWallet, } =
|
||||
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 Setup]================================================================
|
||||
const tableHeadRow = [
|
||||
// "Sr N/O",
|
||||
"Date",
|
||||
"Transaction",
|
||||
"Amount in investors currency",
|
||||
// "Currency",
|
||||
"TO USD",
|
||||
"From USD",
|
||||
"USD amount",
|
||||
"IO Name",
|
||||
"Payment Method",
|
||||
];
|
||||
|
||||
console.log(transaction);
|
||||
Avatar,
|
||||
Badge,
|
||||
Box,
|
||||
Button,
|
||||
HStack,
|
||||
Input,
|
||||
Menu,
|
||||
MenuButton,
|
||||
MenuItem,
|
||||
MenuList,
|
||||
Portal,
|
||||
Select,
|
||||
Switch,
|
||||
Table,
|
||||
Tag,
|
||||
Tbody,
|
||||
Text,
|
||||
Th,
|
||||
Tooltip,
|
||||
Tr,
|
||||
useToast,
|
||||
} from "@chakra-ui/react";
|
||||
import React, { useContext, useEffect, useState } from "react";
|
||||
import { OPACITY_ON_LOAD } from "../../../Layout/animations";
|
||||
import NormalTable from "../../../Components/DataTable/NormalTable";
|
||||
import Pagination from "../../../Components/Pagination";
|
||||
import GlobalStateContext from "../../../Contexts/GlobalStateContext";
|
||||
import CustomAlertDialog from "../../../Components/CustomAlertDialog";
|
||||
import ToastBox from "../../../Components/ToastBox";
|
||||
import { debounce } from "../../Master/Sponser/AddSponser";
|
||||
|
||||
// ====================================================[Table Filter]================================================================
|
||||
const filteredData = transaction?.filter((item) => {
|
||||
// Filter by name (case insensitive)
|
||||
console.log(item?.investorTransaction?.transactionName);
|
||||
|
||||
const name = item?.investorTransaction?.transactionName;
|
||||
const searchLower = searchTerm?.toLowerCase();
|
||||
const nameMatches = name?.toLowerCase().includes(searchLower);
|
||||
|
||||
// Filter by status
|
||||
// const status = item.status;
|
||||
// const statusLower = status ? "active" : "inactive";
|
||||
|
||||
// const statusMatches =
|
||||
// statusFilter === "all" ||
|
||||
// (statusFilter === "active" && status === true) ||
|
||||
// (statusFilter === "inactive" && status === false);
|
||||
|
||||
return nameMatches;
|
||||
const formatDate = (date) => new Date(date).toLocaleDateString(); // Simple date formatter
|
||||
|
||||
const Transaction = () => {
|
||||
const toast = useToast();
|
||||
const { transaction, setTransaction, slideFromRight, InvestorWallet } =
|
||||
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",
|
||||
});
|
||||
};
|
||||
|
||||
console.log(filteredData);
|
||||
|
||||
|
||||
const extractedArray = filteredData?.map((item) => ({
|
||||
id: item?.id,
|
||||
"Sr N/O": (
|
||||
<Text w={'100px'}
|
||||
justifyContent={slideFromRight ? "right" : "left"}
|
||||
as={"span"}
|
||||
color={"gray.600"}
|
||||
className="d-flex align-items-center fw-bold web-text-small"
|
||||
>
|
||||
{item.id}
|
||||
console.log(transaction);
|
||||
|
||||
// ====================================================[Table Filter]================================================================
|
||||
const filteredData = transaction?.filter((item) => {
|
||||
// Filter by name (case insensitive)
|
||||
console.log(item?.investorTransaction?.transactionName);
|
||||
|
||||
const name = item?.investorTransaction?.transactionName;
|
||||
const searchLower = searchTerm?.toLowerCase();
|
||||
const nameMatches = name?.toLowerCase().includes(searchLower);
|
||||
|
||||
// Filter by status
|
||||
// const status = item.status;
|
||||
// const statusLower = status ? "active" : "inactive";
|
||||
|
||||
// const statusMatches =
|
||||
// statusFilter === "all" ||
|
||||
// (statusFilter === "active" && status === true) ||
|
||||
// (statusFilter === "inactive" && status === false);
|
||||
|
||||
return nameMatches;
|
||||
});
|
||||
|
||||
console.log(filteredData);
|
||||
|
||||
// ====================================================[Table Setup]================================================================
|
||||
const tableHeadRow = [
|
||||
// "Sr N/O",
|
||||
"Date",
|
||||
"Transaction",
|
||||
"Amount in investors currency",
|
||||
// "Currency",
|
||||
"TO USD",
|
||||
"From USD",
|
||||
"USD amount",
|
||||
"IO Name",
|
||||
"Payment Method",
|
||||
];
|
||||
const extractedArray = filteredData?.map((item) => ({
|
||||
id: item?.id,
|
||||
"Sr N/O": (
|
||||
<Text
|
||||
w={"100px"}
|
||||
justifyContent={slideFromRight ? "right" : "left"}
|
||||
as={"span"}
|
||||
color={"gray.600"}
|
||||
className="d-flex align-items-center fw-bold web-text-small"
|
||||
>
|
||||
{item.id}
|
||||
</Text>
|
||||
),
|
||||
Date: (
|
||||
<Box w={"80px"} isTruncated={true}>
|
||||
<Text as={"span"} color={"teal.900"}>
|
||||
{formatDate(item.transactionDate)}
|
||||
</Text>
|
||||
),
|
||||
"Date": (
|
||||
<Box w={"80px"} isTruncated={true}>
|
||||
<Text as={"span"} color={"teal.900"}>
|
||||
{formatDate(item.transactionDate)}
|
||||
</Text>
|
||||
</Box>
|
||||
),
|
||||
"Transaction": (
|
||||
<Box w={"80px"} isTruncated={true}>
|
||||
<Text as={"span"} color={"teal.900"}>
|
||||
{item.investorTransaction?.transactionName}
|
||||
</Text>
|
||||
</Box>
|
||||
),
|
||||
"Currency": (
|
||||
<Box w={"auto"} isTruncated={true}>
|
||||
<Text as={"span"} color={"teal.900"}>
|
||||
{item.investorCurrency}
|
||||
</Text>
|
||||
</Box>
|
||||
),
|
||||
"Amount in investors currency": (
|
||||
<Box w={"100px"} isTruncated={true} display={"flex"} justifyContent={"end"}>
|
||||
<Text as={"span"} color={"teal.900"}>
|
||||
{/* {item.investorAmount} */}
|
||||
{parseFloat(item?.investorAmount || 0).toLocaleString(undefined, {
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 2,
|
||||
})}
|
||||
<Badge ms={1} colorScheme="green">{item?.investorCurrency}</Badge>
|
||||
</Text>
|
||||
</Box>
|
||||
),
|
||||
"From USD": (
|
||||
<Box w={"100px"} isTruncated={true}>
|
||||
<Text as={"span"} color={"teal.900"}>
|
||||
{item.USDToInvCur_Rate}
|
||||
</Text>
|
||||
</Box>
|
||||
),
|
||||
"TO USD": (
|
||||
<Box w={"100px"} isTruncated={true}>
|
||||
<Text as={"span"} color={"teal.900"}>
|
||||
{item.invCurToUSD_Rate}
|
||||
</Text>
|
||||
</Box>
|
||||
),
|
||||
"USD amount": (
|
||||
<Box w={"100px"} isTruncated={true} display={"flex"} justifyContent={"end"}>
|
||||
<Text as={"span"} color={"teal.900"}>
|
||||
{/* {item.USDAmount} */}
|
||||
{parseFloat(item?.USDAmount || 0).toLocaleString(undefined, {
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 2,
|
||||
})}
|
||||
{/* <Badge ms={1} colorScheme="green">$</Badge> */}
|
||||
<Badge ms={1} colorScheme="green">USD</Badge>
|
||||
</Text>
|
||||
</Box>
|
||||
),
|
||||
"IO Name": (
|
||||
<Box w={"auto"} isTruncated={true}>
|
||||
<Text as={"span"} color={"teal.900"}>
|
||||
{item.io && item.io?.investmentNameEnglish}
|
||||
</Text>
|
||||
</Box>
|
||||
),
|
||||
"Payment Method": (
|
||||
<Box w={"auto"} isTruncated={true}>
|
||||
<Text as={"span"} color={"teal.900"}>
|
||||
{item.paymentMethod && item.paymentMethod?.paymentMethodName}
|
||||
</Text>
|
||||
</Box>
|
||||
),
|
||||
}));
|
||||
|
||||
const handleDelete = () => {
|
||||
const updatedInvestorDetails = InvestorDetails.filter(
|
||||
(sponsor) => sponsor.id !== actionId
|
||||
);
|
||||
|
||||
setTimeout(() => {
|
||||
setInvestorDetails(updatedInvestorDetails);
|
||||
setDeleteAlert(false);
|
||||
setIsLoading(false);
|
||||
}, 100);
|
||||
setIsLoading(true);
|
||||
};
|
||||
</Box>
|
||||
),
|
||||
Transaction: (
|
||||
<Box w={"80px"} isTruncated={true}>
|
||||
<Text as={"span"} color={"teal.900"}>
|
||||
{item.investorTransaction?.transactionName}
|
||||
</Text>
|
||||
</Box>
|
||||
),
|
||||
Currency: (
|
||||
<Box w={"auto"} isTruncated={true}>
|
||||
<Text as={"span"} color={"teal.900"}>
|
||||
{item.investorCurrency}
|
||||
</Text>
|
||||
</Box>
|
||||
),
|
||||
"Amount in investors currency": (
|
||||
<Box w={100} display={"flex"} justifyContent={"end"}>
|
||||
<Text as={"span"} textAlign={"end"} w={"100%"} color={"teal.900"}>
|
||||
{/* {item.investorAmount} */}
|
||||
{parseFloat(item?.investorAmount || 0).toLocaleString(undefined, {
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 2,
|
||||
})}
|
||||
<Badge ms={1} colorScheme="green">
|
||||
{item?.investorCurrency}
|
||||
</Badge>
|
||||
</Text>
|
||||
</Box>
|
||||
),
|
||||
"From USD": (
|
||||
<Text as={"span"} color={"teal.900"}>
|
||||
{item.USDToInvCur_Rate}
|
||||
</Text>
|
||||
),
|
||||
"TO USD": (
|
||||
<Text as={"span"} color={"teal.900"}>
|
||||
{item.invCurToUSD_Rate}
|
||||
</Text>
|
||||
),
|
||||
"USD amount": (
|
||||
<Box w={100} display={"flex"} justifyContent={"end"}>
|
||||
<Text as={"span"} textAlign={"end"} w={"100%"} color={"teal.900"}>
|
||||
{/* {item.USDAmount} */}
|
||||
{parseFloat(item?.USDAmount || 0).toLocaleString(undefined, {
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 2,
|
||||
})}
|
||||
<Badge ms={1} colorScheme="green" me={1}>
|
||||
$
|
||||
</Badge>
|
||||
</Text>
|
||||
</Box>
|
||||
),
|
||||
"IO Name": (
|
||||
<Box w={"auto"} isTruncated={true}>
|
||||
<Text as={"span"} color={"teal.900"}>
|
||||
{item.io && item.io?.investmentNameEnglish}
|
||||
</Text>
|
||||
</Box>
|
||||
),
|
||||
"Payment Method": (
|
||||
<Box w={"auto"} isTruncated={true}>
|
||||
<Text as={"span"} color={"teal.900"}>
|
||||
{item.paymentMethod && item.paymentMethod?.paymentMethodName}
|
||||
</Text>
|
||||
</Box>
|
||||
),
|
||||
}));
|
||||
|
||||
const Total = () => {
|
||||
return (
|
||||
<Table size="sm" >
|
||||
<Tbody backgroundColor="gray.50">
|
||||
<Tr >
|
||||
<Th
|
||||
textAlign={"left"}
|
||||
p={3}
|
||||
width="100px"
|
||||
color={"#004118"}
|
||||
whiteSpace="normal"
|
||||
wordBreak="normal"
|
||||
overflowWrap="normal"
|
||||
>
|
||||
Balance:
|
||||
</Th>
|
||||
<Th
|
||||
textAlign={"center"}
|
||||
p={3}
|
||||
width="120px"
|
||||
maxW={"120px"}
|
||||
color={"#004118"}
|
||||
whiteSpace="normal"
|
||||
wordBreak="normal"
|
||||
overflowWrap="normal"
|
||||
>
|
||||
{" "}
|
||||
</Th>
|
||||
<Th
|
||||
textAlign={"right"}
|
||||
p={3}
|
||||
width="100px"
|
||||
color={"#004118"}
|
||||
whiteSpace="normal"
|
||||
wordBreak="normal"
|
||||
overflowWrap="normal"
|
||||
>
|
||||
<Box display={"flex"} justifyContent={"end"}>
|
||||
{parseFloat(InvestorWallet?.WalletBalance_InInvCur).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
|
||||
<Badge ms={1} colorScheme="green">{InvestorWallet?.currencyCode_InCur}</Badge>
|
||||
</Box>
|
||||
</Th>
|
||||
<Th
|
||||
textAlign={"center"}
|
||||
p={3}
|
||||
width="100px"
|
||||
color={"#004118"}
|
||||
whiteSpace="normal"
|
||||
wordBreak="normal"
|
||||
overflowWrap="normal"
|
||||
>
|
||||
{" "}
|
||||
</Th>
|
||||
<Th
|
||||
textAlign={"center"}
|
||||
p={3}
|
||||
width="100px"
|
||||
color={"#004118"}
|
||||
whiteSpace="normal"
|
||||
wordBreak="normal"
|
||||
overflowWrap="normal"
|
||||
>
|
||||
{" "}
|
||||
</Th>
|
||||
<Th
|
||||
textAlign={"center"}
|
||||
p={3}
|
||||
width="100px"
|
||||
color={"#004118"}
|
||||
whiteSpace="normal"
|
||||
wordBreak="normal"
|
||||
overflowWrap="normal"
|
||||
>
|
||||
<Box display={"flex"} justifyContent={"end"}>
|
||||
{parseFloat(InvestorWallet?.WalletBalance_InUSD).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
|
||||
<Badge ms={1} colorScheme="green">USD</Badge>
|
||||
</Box>
|
||||
</Th>
|
||||
<Th
|
||||
textAlign={"center"}
|
||||
p={3}
|
||||
width="130px"
|
||||
color={"#004118"}
|
||||
whiteSpace="normal"
|
||||
wordBreak="normal"
|
||||
overflowWrap="normal"
|
||||
>
|
||||
{" "}
|
||||
</Th>
|
||||
<Th
|
||||
textAlign={"center"}
|
||||
p={3}
|
||||
width="130px"
|
||||
color={"#004118"}
|
||||
whiteSpace="normal"
|
||||
wordBreak="normal"
|
||||
overflowWrap="normal"
|
||||
>
|
||||
{" "}
|
||||
</Th>
|
||||
</Tr>
|
||||
</Tbody>
|
||||
</Table>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<Box {...OPACITY_ON_LOAD} overflowY={"scroll"} height={"100vh"} pb={38}>
|
||||
<Box bg="white.500">
|
||||
<HStack
|
||||
display={"flex"}
|
||||
justifyContent={"space-between"}
|
||||
ps={1}
|
||||
pe={1}
|
||||
pb={4}
|
||||
pt={4}
|
||||
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 display={"flex"} alignItems={"center"}>
|
||||
const totalRow = {
|
||||
// id: "total", // or any unique ID
|
||||
// "Sr N/O": (
|
||||
// <Text w={'100px'} color={"gray.600"} fontWeight={"bold"}>Total</Text>
|
||||
// ),
|
||||
Date: (
|
||||
<Text
|
||||
as={"span"}
|
||||
textAlign={"start"}
|
||||
w={"100%"}
|
||||
color={"teal.900"}
|
||||
fontWeight={"bold"}
|
||||
>
|
||||
<Badge ms={1} colorScheme="gray">
|
||||
Total
|
||||
</Badge>
|
||||
</Text>
|
||||
),
|
||||
Transaction: null,
|
||||
// "Currency": null,
|
||||
"Amount in investors currency": (
|
||||
<Box w={100} display={"flex"} justifyContent={"end"}>
|
||||
<Text as={"span"} textAlign={"end"} w={"100%"} color={"teal.900"}>
|
||||
{parseFloat(InvestorWallet?.WalletBalance_InInvCur).toLocaleString(
|
||||
undefined,
|
||||
{ minimumFractionDigits: 2, maximumFractionDigits: 2 }
|
||||
)}
|
||||
<Badge ms={1} colorScheme="green">
|
||||
{InvestorWallet?.currencyCode_InCur}
|
||||
</Badge>
|
||||
</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>
|
||||
),
|
||||
"IO Name": null,
|
||||
"Payment Method": null,
|
||||
};
|
||||
|
||||
extractedArray?.push(totalRow);
|
||||
|
||||
const handleDelete = () => {
|
||||
const updatedInvestorDetails = InvestorDetails.filter(
|
||||
(sponsor) => sponsor.id !== actionId
|
||||
);
|
||||
|
||||
setTimeout(() => {
|
||||
setInvestorDetails(updatedInvestorDetails);
|
||||
setDeleteAlert(false);
|
||||
setIsLoading(false);
|
||||
}, 100);
|
||||
setIsLoading(true);
|
||||
};
|
||||
|
||||
return (
|
||||
<Box {...OPACITY_ON_LOAD} overflowY={"scroll"} height={"100vh"} pb={38}>
|
||||
<Box bg="white.500">
|
||||
<HStack
|
||||
display={"flex"}
|
||||
justifyContent={"space-between"}
|
||||
ps={1}
|
||||
pe={1}
|
||||
pb={4}
|
||||
pt={4}
|
||||
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 display={"flex"} alignItems={"center"}>
|
||||
<Pagination totalItems={10} />
|
||||
</HStack> */}
|
||||
</HStack>
|
||||
</Box>
|
||||
|
||||
<DataTable
|
||||
emptyMessage={`We don't have any Sponers `}
|
||||
tableHeadRow={tableHeadRow}
|
||||
data={extractedArray}
|
||||
isLoading={isLoading}
|
||||
viewActionId={actionId}
|
||||
setViewActionId={setActionId}
|
||||
setMouseEnteredId={setMouseEnteredId}
|
||||
caption={<Total />}
|
||||
setMouseEntered={setMouseEntered}
|
||||
/>
|
||||
|
||||
<CustomAlertDialog
|
||||
onClose={() => setDeleteAlert(false)}
|
||||
isOpen={deleteAlert}
|
||||
message={"Are you sure you want to delete sponers?"}
|
||||
alertHandler={handleDelete}
|
||||
isLoading={isLoading}
|
||||
/>
|
||||
|
||||
</HStack>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default Transaction;
|
||||
|
||||
|
||||
<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}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default Transaction;
|
||||
|
||||
@@ -19,7 +19,7 @@ import {
|
||||
} from "@chakra-ui/react";
|
||||
import React, { useContext, useEffect, useState } from "react";
|
||||
import { OPACITY_ON_LOAD } from "../../../Layout/animations";
|
||||
import DataTable from "../../../Components/DataTable/DataTable";
|
||||
import NormalTable from "../../../Components/DataTable/NormalTable";
|
||||
import { HiDotsVertical } from "react-icons/hi";
|
||||
import { Link, Navigate, Link as RouterLink } from "react-router-dom";
|
||||
import {
|
||||
@@ -47,7 +47,7 @@ const ViewInvestorDetails = () => {
|
||||
const [actionId, setActionId] = useState(false);
|
||||
const [mouseEntered, setMouseEntered] = useState(false);
|
||||
const [mouseEnteredId, setMouseEnteredId] = useState("");
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
// Simulate loading
|
||||
const timer = setTimeout(() => {
|
||||
@@ -75,8 +75,7 @@ const ViewInvestorDetails = () => {
|
||||
// "Action",
|
||||
];
|
||||
|
||||
console.log(viewInvestor);
|
||||
|
||||
console.log(viewInvestor);
|
||||
|
||||
// ====================================================[Table Filter]================================================================
|
||||
const filteredData = viewInvestor?.filter((item) => {
|
||||
@@ -99,10 +98,11 @@ console.log(viewInvestor);
|
||||
|
||||
console.log(filteredData);
|
||||
|
||||
const extractedArray = filteredData?.map((item,index) => ({
|
||||
const extractedArray = filteredData?.map((item, index) => ({
|
||||
id: item?.id,
|
||||
"Sr N/O": (
|
||||
<Text w={'50px'}
|
||||
<Text
|
||||
w={"50px"}
|
||||
justifyContent={slideFromRight ? "right" : "left"}
|
||||
as={"span"}
|
||||
color={"gray.600"}
|
||||
@@ -119,7 +119,7 @@ console.log(viewInvestor);
|
||||
</Box>
|
||||
),
|
||||
"Sponsor Name": (
|
||||
<Box w={"auto"} isTruncated={true}>
|
||||
<Box w={"auto"} isTruncated={true}>
|
||||
<Text as={"span"} color={"teal.900"}>
|
||||
{item.sponsorName}
|
||||
</Text>
|
||||
@@ -128,15 +128,15 @@ console.log(viewInvestor);
|
||||
"Investment Amount": (
|
||||
<Box w={"auto"} isTruncated={true}>
|
||||
<Text as={"span"} color={"teal.900"}>
|
||||
{/* {item.investedAmount} */}
|
||||
$ {parseFloat(item?.investedAmount || 0).toLocaleString(undefined, {
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 2,
|
||||
})}
|
||||
<Badge ms={1} colorScheme="green" me={1}>$</Badge>
|
||||
{parseFloat(item?.investedAmount || 0).toLocaleString(undefined, {
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 2,
|
||||
})}
|
||||
</Text>
|
||||
</Box>
|
||||
),
|
||||
"Percentage": (
|
||||
Percentage: (
|
||||
<Box w={"auto"} isTruncated={true}>
|
||||
<Text as={"span"} color={"teal.900"}>
|
||||
{item?.Investor_Holidings} %
|
||||
@@ -145,11 +145,12 @@ console.log(viewInvestor);
|
||||
),
|
||||
"Market Value": (
|
||||
<Box w={"auto"} isTruncated={true}>
|
||||
<Text as={"span"} color={"teal.900"}>
|
||||
$ {parseFloat(item?.MarketValue || 0).toLocaleString(undefined, {
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 2,
|
||||
})}
|
||||
<Text as={"span"} color={"teal.900"}>
|
||||
<Badge ms={1} colorScheme="green" me={1}>$</Badge>
|
||||
{parseFloat(item?.MarketValue || 0).toLocaleString(undefined, {
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 2,
|
||||
})}
|
||||
</Text>
|
||||
</Box>
|
||||
),
|
||||
@@ -160,13 +161,17 @@ console.log(viewInvestor);
|
||||
</Text>
|
||||
</Box>
|
||||
),
|
||||
"Distribution": (
|
||||
Distribution: (
|
||||
<Box w={"auto"} isTruncated={true}>
|
||||
<Text as={"span"} color={"teal.900"}>
|
||||
$ {parseFloat(item?.DistributionAmountReceived || 0).toLocaleString(undefined, {
|
||||
<Badge ms={1} colorScheme="green" me={1}>$</Badge>
|
||||
{parseFloat(item?.DistributionAmountReceived || 0).toLocaleString(
|
||||
undefined,
|
||||
{
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 2,
|
||||
})}
|
||||
}
|
||||
)}
|
||||
</Text>
|
||||
</Box>
|
||||
),
|
||||
@@ -180,10 +185,11 @@ console.log(viewInvestor);
|
||||
"Total return": (
|
||||
<Box w={"auto"} isTruncated={true}>
|
||||
<Text as={"span"} color={"teal.900"}>
|
||||
$ {parseFloat(item?.TotalReturn || 0).toLocaleString(undefined, {
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 2,
|
||||
})}
|
||||
<Badge ms={1} colorScheme="green" me={1}>$</Badge>
|
||||
{parseFloat(item?.TotalReturn || 0).toLocaleString(undefined, {
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 2,
|
||||
})}
|
||||
</Text>
|
||||
</Box>
|
||||
),
|
||||
@@ -195,23 +201,35 @@ console.log(viewInvestor);
|
||||
</Box>
|
||||
),
|
||||
Status: (
|
||||
<Box w={"auto"} isTruncated={true}>
|
||||
<Badge
|
||||
fontWeight={"500"}
|
||||
textTransform={"none"}
|
||||
color={
|
||||
item.statusAdmin === "Open"
|
||||
? "green"
|
||||
: item.statusAdmin === "Pending"
|
||||
? "blue"
|
||||
: "red"
|
||||
}
|
||||
px={2}
|
||||
py={0.5}
|
||||
>
|
||||
{item.statusAdmin}
|
||||
</Badge>
|
||||
</Box>
|
||||
<Badge
|
||||
rounded={"full"}
|
||||
pt={1}
|
||||
pb={1}
|
||||
ps={4}
|
||||
pe={4}
|
||||
mt={1.5}
|
||||
mb={1.5}
|
||||
textTransform={"none"}
|
||||
// variant={"solid"}
|
||||
colorScheme={
|
||||
item?.statusAdmin === "Draft"
|
||||
? "gray"
|
||||
: item?.statusAdmin === "Processing"
|
||||
? "yellow"
|
||||
: item?.statusAdmin === "Open"
|
||||
? "blue"
|
||||
: item?.statusAdmin === "Closed"
|
||||
? "green"
|
||||
: item?.statusAdmin === "Exited"
|
||||
? "red"
|
||||
: item?.statusAdmin === "Canclled"
|
||||
? "orange"
|
||||
: "purple"
|
||||
}
|
||||
boxShadow={"0 4px 6px rgba(0, 0, 0, 0.1)"} // Adjusted shadow
|
||||
>
|
||||
{item?.statusAdmin}
|
||||
</Badge>
|
||||
),
|
||||
Action: (
|
||||
<Box display={"flex"} justifyContent={"space-between"}>
|
||||
@@ -279,7 +297,7 @@ console.log(viewInvestor);
|
||||
</HStack>
|
||||
</Box>
|
||||
|
||||
<DataTable
|
||||
<NormalTable
|
||||
emptyMessage={`We don't have any Sponers `}
|
||||
tableHeadRow={tableHeadRow}
|
||||
data={extractedArray}
|
||||
@@ -297,7 +315,6 @@ console.log(viewInvestor);
|
||||
alertHandler={handleDelete}
|
||||
isLoading={isLoading}
|
||||
/>
|
||||
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
import axios from "axios";
|
||||
|
||||
// Create an Axios instance for API calls
|
||||
export const api = axios.create({
|
||||
// baseURL: `https://tanami.betadelivery.com/api/v1`,
|
||||
baseURL: import.meta.env.VITE_BAS_URL, // Replace with your API base URL
|
||||
timeout: 10000, // Adjust timeout as needed
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
});
|
||||
|
||||
// Add Axios request interceptor to refresh token if expired
|
||||
api.interceptors.request.use(
|
||||
(config) => {
|
||||
console.log(config);
|
||||
// Modify headers or add tokens as needed
|
||||
// const token = localStorage.getItem("accessToken");
|
||||
// if (token) {
|
||||
// config.headers.Authorization = `Bearer ${token}`;
|
||||
// }
|
||||
return config;
|
||||
},
|
||||
(error) => {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
// // Add Axios response interceptor to handle token refreshing
|
||||
api.interceptors.response.use(
|
||||
(response) => {
|
||||
return response;
|
||||
},
|
||||
async (error) => {
|
||||
const originalRequest = error.config;
|
||||
|
||||
// Example logic for handling token expiration and refreshing
|
||||
if (
|
||||
error.response.status === 401 &&
|
||||
!originalRequest._retry &&
|
||||
localStorage.getItem("refreshToken")
|
||||
) {
|
||||
originalRequest._retry = true;
|
||||
|
||||
try {
|
||||
const response = await api.post("/refresh_token", {
|
||||
refreshToken: localStorage.getItem("refreshToken"),
|
||||
});
|
||||
|
||||
if (response.status === 200) {
|
||||
// Update tokens in local storage
|
||||
localStorage.setItem("accessTokenn", response.data.accessToken);
|
||||
localStorage.setItem("refreshTokenn", response.data.refreshToken);
|
||||
|
||||
// Retry the original request with the new tokens
|
||||
return api(originalRequest);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Failed to refresh token:", error);
|
||||
// Handle token refresh failure (e.g., redirect to login)
|
||||
}
|
||||
}
|
||||
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user