This commit is contained in:
2024-07-15 12:27:23 +05:30
parent 84afc0e4b2
commit 513e222a8f
21 changed files with 694 additions and 158 deletions

View File

@@ -0,0 +1,104 @@
import React from "react";
import {
Box,
Breadcrumb,
BreadcrumbItem,
BreadcrumbLink,
Text,
Button,
} from "@chakra-ui/react";
import { Link, useLocation } from "react-router-dom";
import { nav } from "../Routes/Nav";
const CustomBreadcrumb = () => {
const { pathname } = useLocation();
// Remove leading slash and split path into parts
const pathParts = pathname.replace(/^\//, "").split("/");
// Find the current menu item based on the provided path
const findMenuItem = (path) => {
let menuItem = null;
nav.forEach((menu) => {
if (menu.submenu) {
menu.submenu.forEach((item) => {
if (item.path === path) {
menuItem = item;
}
});
}
});
return menuItem;
};
// Generate breadcrumb items based on the current path
const generateBreadcrumbs = (pathParts) => {
const breadcrumbs = [];
let currentPath = "";
pathParts.forEach((part, index) => {
currentPath += `/${part}`;
const menuItem = findMenuItem(currentPath);
if (menuItem) {
breadcrumbs.push({ path: currentPath, title: menuItem.title });
} else {
// For nested paths without direct match, create a custom breadcrumb title
const customTitle = part.replace(/-/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
breadcrumbs.push({ path: currentPath, title: customTitle });
}
});
return breadcrumbs;
};
const breadcrumbs = generateBreadcrumbs(pathParts);
console.log(breadcrumbs);
return (
<Box
fontWeight="medium"
fontSize="xs"
color={"blue.700"}
display={"flex"}
alignItems={"center"}
p={1}
mt={2}
>
<Button
cursor={"pointer"}
variant="ghost"
pt={1.5}
pb={1.5}
ps={2}
pe={2}
rounded={"full"}
size={"xs"}
as={"span"}
>
Master
</Button>{" "}
{breadcrumbs.map((item, index) => (
<React.Fragment key={index}>
<Text size={"xs"} ps={1} pe={1} as={"span"}>
/
</Text>
<Link to={item.path}>
<Button
cursor={"pointer"}
variant="ghost"
pt={0.5}
pb={0.5}
ps={2}
pe={2}
rounded={"full"}
size={"xs"}
as={"span"}
>
{item.title}
</Button></Link>
</React.Fragment>
))}
</Box>
);
};
export default CustomBreadcrumb;

View File

@@ -8,9 +8,9 @@ const FullscreenLoaders = () => {
justifyContent={"center"}
alignItems={"center"}
w={"100%"}
h={"90%"}
h={"70vh"}
>
<Spinner color='teal.700' />
<Spinner color='green.700' />
</Box>
);
};

View File

@@ -0,0 +1,40 @@
import React from "react";
import { Link } from "react-router-dom"; // Adjust this based on your routing setup
import CustomBreadcrumb from "./CutomBreadcrumb";
const NavBreadcrumbs = ({ nav }) => {
// Function to recursively flatten submenu items and add parent titles
const flattenNav = (items, parentTitle = "") => {
let breadcrumbs = [];
items.forEach((item) => {
if (item.submenu) {
// Add parent title if present
breadcrumbs.push({
label: parentTitle ? `${parentTitle} / ${item.title}` : item.title,
link: null, // Adjust link as per your routing setup
});
// Recursively flatten submenu items
breadcrumbs = [
...breadcrumbs,
...flattenNav(item.submenu, `${parentTitle} / ${item.title}`),
];
} else {
// If no submenu, add current item as breadcrumb
breadcrumbs.push({
label: parentTitle ? `${parentTitle} / ${item.title}` : item.title,
link: item.path, // Adjust link as per your routing setup
});
}
});
return breadcrumbs;
};
// Flatten nav array into breadcrumbs
const flattenedNav = flattenNav(nav);
console.log(nav);
return <CustomBreadcrumb items={flattenedNav} />;
};
export default NavBreadcrumbs;

View File

@@ -49,6 +49,7 @@ import {
Image,
Alert,
AlertIcon,
Breadcrumb,
} from "@chakra-ui/react";
import GlobalStateContext from "../Contexts/GlobalStateContext";
import Cookies from "js-cookie"; // Import the Cookies library
@@ -68,6 +69,8 @@ import { GrManual } from "react-icons/gr";
import { LuContact } from "react-icons/lu";
import shield from "../assets/shield.png";
import SplashScreen from "../Pages/SplashScreen";
import CutomBreadcrumb from "../Components/CutomBreadcrumb";
import CustomBreadcrumb from "../Components/CutomBreadcrumb";
const DashboardLayout = ({ isOnline }) => {
const navigate = useNavigate();
@@ -120,8 +123,6 @@ const DashboardLayout = ({ isOnline }) => {
navigate("/login");
};
console.log();
// // Function to get the title based on the route
const getTitle = () => {
switch (true) {
@@ -623,10 +624,11 @@ const DashboardLayout = ({ isOnline }) => {
)}
<main
className={`h-100 ${slideFromRight ? "pe-3" : "ps-3"} `}
className={`h-100 ${slideFromRight ? "pe-3" : "ps-3"} d-flex flex-column gap-0`}
style={{
width: `calc(100% - ${isDrawerOpen || openDrawerClick ? 232 : 74}px)`,
transition: "width 0.3s ease-in-out",
}}
>
{/* <header className="p-2 ps-0 pt-3 fw-400 border-bottom">
@@ -639,6 +641,8 @@ const DashboardLayout = ({ isOnline }) => {
icon
title={getTitle()}
/>
<CustomBreadcrumb />
<AppContent />
</main>

View File

@@ -97,12 +97,7 @@ const schema = yup.object().shape({
.min(new Date(), "Closing date cannot be in the past"),
ioStatus: yup
.string()
.required("Investment Object status is required")
.oneOf(
["open", "pending", "closed"],
"Investment Object status must be one of 'open', 'pending', or 'closed'"
),
.string(),
});
const IODetails = ({ enableNextTab, index, isLoading, setIsLoading }) => {
@@ -153,6 +148,8 @@ const IODetails = ({ enableNextTab, index, isLoading, setIsLoading }) => {
resolver: yupResolver(schema),
});
console.log(errors);
useEffect(() => {
const found = IODetails?.find(
(item) => item?.id.toString() === id?.toString()
@@ -515,8 +512,10 @@ const IODetails = ({ enableNextTab, index, isLoading, setIsLoading }) => {
return enableNextTab(index);
}
const id = generateUniqueId();
setValue("id", id)
const updatedData = { ...data, id };
const status = "Draft"
// setValue("id", id)
console.log(data);
const updatedData = { ...data, id, ioStatus : status };
console.log(data);
// Add the updated data to the IODetails array

View File

@@ -43,19 +43,32 @@ const AmountInvested = ({ isOpen, onClose }) => {
size="sm"
rounded={'sm'}
textAlign={'end'}
readOnly
value={"$ 100000"}
focusBorderColor="forestGreen.300"
fontSize={"sm"} placeholder="$00.00" />
</FormControl>
<FormControl mb={"15px"} >
<FormLabel as={"label"} fontSize={"sm"} fontWeight={500}>Amount to invest</FormLabel>
<Input
size="sm"
rounded={'sm'}
textAlign={'end'}
focusBorderColor="forestGreen.300"
fontSize={"sm"} placeholder="$00.00" />
</FormControl>
<FormControl mb={"15px"}>
<FormLabel as={"label"} fontSize={"sm"} fontWeight={500}>
Comments
IO Cash
</FormLabel>
<Textarea
<Input
size="sm"
rounded={'sm'}
placeholder="$00.00"
focusBorderColor="forestGreen.300"
fontSize={"sm"} placeholder="Write Comments" />
fontSize={"sm"} />
</FormControl>
</ModalBody>
<ModalFooter>

View File

@@ -0,0 +1,63 @@
import {
Box,
Button,
FormControl,
FormLabel,
Input,
Modal,
ModalBody,
ModalCloseButton,
ModalContent,
ModalFooter,
ModalHeader,
ModalOverlay,
Text,
Textarea,
} from "@chakra-ui/react";
const Cancle = ({ isOpen, onClose }) => {
return (
<Modal isCentered isOpen={isOpen} onClose={onClose}>
<ModalOverlay />
<ModalContent>
<ModalHeader fontSize={'md'}>Cancel</ModalHeader>
<ModalCloseButton />
<ModalBody>
<FormControl mb={"15px"} >
<FormLabel as={"label"} fontSize={"sm"} fontWeight={500}>Comment</FormLabel>
<Textarea
size="sm"
rounded={'sm'}
textAlign={'start'}
rows={3}
focusBorderColor="forestGreen.300"
fontSize={"sm"} placeholder="Enter comments here..." />
</FormControl>
</ModalBody>
<ModalFooter>
<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>
</ModalFooter>
</ModalContent>
</Modal>
);
};
export default Cancle;

View File

@@ -3,6 +3,7 @@ import {
Button,
FormControl,
FormLabel,
HStack,
Input,
Modal,
ModalBody,
@@ -11,54 +12,218 @@ import {
ModalFooter,
ModalHeader,
ModalOverlay,
Switch,
Table,
Tbody,
Text,
Textarea,
Th,
Tr,
} from "@chakra-ui/react";
import DataTable from "../../../../Components/DataTable/DataTable";
import { useState } from "react";
import { AddIcon } from "@chakra-ui/icons";
const DistributionInvestor = ({ isOpen, onClose }) => {
// ====================================================[Table Setup]================================================================
const tableHeadRow = [
"Sr No.",
"Client Id",
"First name",
"Last Name",
"Amount",
"%",
"($)",
];
const filteredData = [
{
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}>
<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"}>
BH00000001
</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>
),
"Amount": (
<Box minW={24} isTruncated={true}>
<Text as={"span"} color={"teal.900"} fontWeight={"500"}>
$100,000 /-
</Text>
</Box>
),
"%": (
<Box minW={19} isTruncated={true}>
<Text textAlign={'right'} as={"span"} color={"teal.900"} fontWeight={"500"}>
26.0 %
</Text>
</Box>
),
"($)": (
<Box minW={24} isTruncated={true}>
<Text as={"span"} color={"teal.900"} fontWeight={"500"}>
$100,000 /-
</Text>
</Box>
),
}))
);
const Total = () => {
return (
<Table size="sm">
<Tbody backgroundColor="gray.50">
<Tr >
<Th
textAlign={"left"}
p={3}
width="90px"
color={"#004118"}
whiteSpace="normal"
wordBreak="normal"
overflowWrap="normal"
>
Total
</Th>
<Th
textAlign={"center"}
p={3}
width="110px"
color={"#004118"}
whiteSpace="normal"
wordBreak="normal"
overflowWrap="normal"
>
{" "}
</Th>
<Th
textAlign={"center"}
p={3}
width="110px"
color={"#004118"}
whiteSpace="normal"
wordBreak="normal"
overflowWrap="normal"
>
{" "}
</Th>
<Th
textAlign={"center"}
p={3}
width="110px"
color={"#004118"}
whiteSpace="normal"
wordBreak="normal"
overflowWrap="normal"
>
{" "}
</Th>
<Th
textAlign={"left"}
p={3}
width="110px"
color={"#004118"}
whiteSpace="normal"
wordBreak="normal"
overflowWrap="normal"
>
$100200
</Th>
<Th
textAlign={"left"}
p={3}
width="90px"
color={"#004118"}
whiteSpace="normal"
wordBreak="normal"
overflowWrap="normal"
>
{" "}
</Th>
<Th
textAlign={"center"}
p={3}
width="100px"
color={"#004118"}
whiteSpace="normal"
wordBreak="normal"
overflowWrap="normal"
>
$100230
</Th>
</Tr>
</Tbody>
</Table>
);
};
return (
<Modal isOpen={isOpen} onClose={onClose}>
<Modal size={'xl'} isOpen={isOpen} onClose={onClose}>
<ModalOverlay />
<ModalContent>
<ModalContent maxW={1000} >
<ModalHeader fontSize={"md"}>Distribution To investors</ModalHeader>
<ModalCloseButton />
<ModalBody>
<FormControl mb={"15px"}>
<FormLabel as={"label"} fontSize={"sm"} fontWeight={500}>
Date
</FormLabel>
<Input
placeholder="Select Date"
size="sm"
rounded={'sm'}
focusBorderColor="forestGreen.300"
fontSize={"sm"}
type="date"
/>
</FormControl>
<ModalBody >
<FormControl mb={"15px"} >
<FormLabel as={"label"} fontSize={"sm"} fontWeight={500}>Amount</FormLabel>
<Input
size="sm"
rounded={'sm'}
focusBorderColor="forestGreen.300"
textAlign={'end'}
fontSize={"sm"} placeholder="$00.00" />
</FormControl>
<HStack mb={4} >
<Input placeholder="$00.00" size={'sm'} className="col" />
<Input placeholder="$00.00" size={'sm'} className="col" />
<Button leftIcon={<AddIcon />} size={'sm'} rounded={'sm'} colorScheme="green">Add</Button>
</HStack>
<FormControl mb={"15px"}>
<FormLabel as={"label"} fontSize={"sm"} fontWeight={500}>
Comments
</FormLabel>
<Textarea
size="sm"
rounded={'sm'}
focusBorderColor="forestGreen.300"
fontSize={"sm"} placeholder="Write Comments" />
</FormControl>
<DataTable
emptyMessage={`We don't have any Sponers `}
tableHeadRow={tableHeadRow}
data={extractedArray}
setData={setExtractedArray}
caption={<Total/>}
// isLoading={isLoading}
/>
</ModalBody>
<ModalFooter>
{/* <ModalFooter>
<Button
bg={"hsla(139, 100%, 14%, 1)"}
mr={3}
@@ -76,7 +241,10 @@ const DistributionInvestor = ({ isOpen, onClose }) => {
rounded={"sm"} mr={3} onClick={onClose}>
Close
</Button>
</ModalFooter>
</ModalFooter> */}
</ModalContent>
</Modal>
);

View File

@@ -0,0 +1,86 @@
import {
Box,
Button,
FormControl,
FormLabel,
Input,
Modal,
ModalBody,
ModalCloseButton,
ModalContent,
ModalFooter,
ModalHeader,
ModalOverlay,
Text,
Textarea,
} from "@chakra-ui/react";
const Exit = ({ isOpen, onClose }) => {
return (
<Modal isOpen={isOpen} onClose={onClose}>
<ModalOverlay />
<ModalContent>
<ModalHeader fontSize={'md'}>Amount Invested</ModalHeader>
<ModalCloseButton />
<ModalBody>
<FormControl mb={"15px"}>
<FormLabel as={"label"} fontSize={"sm"} fontWeight={500}>
Date
</FormLabel>
<Input
placeholder="Select Date"
size="sm"
rounded={'sm'}
fontSize={"sm"}
focusBorderColor="forestGreen.300"
type="date"
/>
</FormControl>
<FormControl mb={"15px"} >
<FormLabel as={"label"} fontSize={"sm"} fontWeight={500}>IO NAV</FormLabel>
<Input
size="sm"
rounded={'sm'}
textAlign={'end'}
focusBorderColor="forestGreen.300"
fontSize={"sm"} placeholder="$00.00" />
</FormControl>
<FormControl mb={"15px"} >
<FormLabel as={"label"} fontSize={"sm"} fontWeight={500}>Distribution</FormLabel>
<Input
size="sm"
rounded={'sm'}
textAlign={'end'}
focusBorderColor="forestGreen.300"
fontSize={"sm"} placeholder="$00.00" />
</FormControl>
</ModalBody>
<ModalFooter>
<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>
</ModalFooter>
</ModalContent>
</Modal>
);
};
export default Exit;

View File

@@ -54,7 +54,7 @@ const UpdateIOStatus = ({ isOpen, onClose }) => {
<Textarea
size="sm"
rounded={'sm'}
colorScheme={'green'}
focusBorderColor="forestGreen.300"
fontSize={"sm"} placeholder="Write Comments" />
</FormControl>
</ModalBody>

View File

@@ -22,6 +22,7 @@ import {
MenuDivider,
Badge,
Box,
Icon,
} from "@chakra-ui/react";
import header from "../../../assets/IOheader.png";
import { HiDotsVertical } from "react-icons/hi";
@@ -34,9 +35,13 @@ import UpdateIONav from "./HeaderModal/UpdateIONav";
import UpdateIOStatus from "./HeaderModal/UpdateIOStatus";
import { useContext, useRef } from "react";
import GlobalStateContext from "../../../Contexts/GlobalStateContext";
import Exit from "./HeaderModal/Exit";
import Cancle from "./HeaderModal/Cancle";
import { AddIcon } from "@chakra-ui/icons";
import { GrGallery } from "react-icons/gr";
const ViewIOdataHeader = () => {
const params = useParams()
const params = useParams();
const id = params?.id;
const { isOpen, onOpen, onClose } = useDisclosure();
const btnRef = useRef();
@@ -45,7 +50,6 @@ const ViewIOdataHeader = () => {
(item) => item?.id.toString() === id?.toString()
);
const {
isOpen: isInvestmentOpen,
onOpen: onInvestmentOpen,
@@ -76,6 +80,17 @@ const ViewIOdataHeader = () => {
onOpen: onUpdateStatusOpen,
onClose: onUpdateStatusClose,
} = useDisclosure();
const {
isOpen: isExitOpen,
onOpen: onExitOpen,
onClose: onExitClose,
} = useDisclosure();
const {
isOpen: isCancleOpen,
onOpen: onCancleOpen,
onClose: onCancleClose,
} = useDisclosure();
const bg = {
bg: "#fff",
@@ -109,8 +124,11 @@ const ViewIOdataHeader = () => {
borderRadius={"10px"}
position={"relative"}
>
<Box p={1}>
<Image h={82} src={header} />
<Box h={100} w={200} p={1.5} >
{/* <Image rounded={'md'} h={"100%"} src={foundObject?.ioName} alt={foundObject?.ioName}/> */}
<Box w={'100%'} h={'100%'} display={'flex'} justifyContent={'center'} alignItems={'center'} bg={"#fff"} rounded={'md'}>
<Icon color={'gray.700'} as={GrGallery} />
</Box>
</Box>
{/* <Box display={"flex"} flexDirection={"column"} gap={2}>
<Text as={"span"} fontSize={"sm"} fontWeight={"500"}>
@@ -121,37 +139,35 @@ const ViewIOdataHeader = () => {
</Text>
</Box> */}
<Box display={"flex"} flexDirection={"column"} gap={2}>
<Box display={"flex"} flexDirection={"column"} gap={2}>
<Text as={"span"} fontSize={"xs"} color={"gray.500"} fontWeight={"500"}>
IO Name
</Text>
<Text as={"span"} fontSize={"sm"} fontWeight={"500"}>
{id ? foundObject?.ioName : "N/A"}
{id ? foundObject?.ioName : "---"}
</Text>
</Box>
<Box display={"flex"} flexDirection={"column"} gap={2}>
<Text as={"span"} fontSize={"xs"} color={"gray.500"} fontWeight={"500"}>
Sponsorer Name
</Text>
<Text as={"span"} fontSize={"sm"} fontWeight={"500"}>
{id ? foundObject?.sponserName : "N/A"}
{id ? foundObject?.sponserName : "---"}
</Text>
</Box>
<Box display={"flex"} flexDirection={"column"} gap={2}>
<Text as={"span"} fontSize={"xs"} color={"gray.500"} fontWeight={"500"}>
IO Status
</Text>
<Badge
rounded={'md'}
rounded={"md"}
pt={0.5}
pb={0.5}
ps={4}
pe={4}
textTransform={'none'}
textTransform={"none"}
color={
foundObject?.ioStatus === "Open"
? "#00B69B"
@@ -167,7 +183,7 @@ const ViewIOdataHeader = () => {
: "red"
}
>
{id ? foundObject?.ioStatus : "N/A"}
{id ? foundObject?.ioStatus : "---"}
</Badge>
</Box>
<Box display={"flex"} flexDirection={"column"} gap={2}>
@@ -175,8 +191,7 @@ const ViewIOdataHeader = () => {
IO MV NAV
</Text>
<Text as={"span"} fontSize={"sm"} fontWeight={"500"}>
{id? "$42012.00" : "N/A"}
{id ? "$42012.00" : "---"}
</Text>
</Box>
<Box display={"flex"} flexDirection={"column"} gap={2}>
@@ -184,7 +199,7 @@ const ViewIOdataHeader = () => {
IO cash
</Text>
<Text as={"span"} fontSize={"sm"} fontWeight={"500"}>
{id ?"$48,000" : "N/A"}
{id ? "$48,000" : "---"}
</Text>
</Box>
<Box display={"flex"} flexDirection={"column"} gap={2}>
@@ -192,7 +207,7 @@ const ViewIOdataHeader = () => {
IO NAV
</Text>
<Text as={"span"} fontSize={"sm"} fontWeight={"500"}>
{id ? "$1,140,500" : "N/A"}
{id ? "$1,140,500" : "---"}
</Text>
</Box>
@@ -215,24 +230,34 @@ const ViewIOdataHeader = () => {
<HiDotsVertical className="rubix-text-dark fs-6" />
</MenuButton>
<MenuList fontSize={"sm"}>
<MenuItem _hover={{
bg:"#fff"
}} as={'span'} fontWeight={600} className="border-bottom">
<MenuItem
_hover={{
bg: "#fff",
}}
as={"span"}
fontWeight={600}
className="border-bottom"
>
Tansaction
</MenuItem>
<MenuItem onClick={onInvestmentOpen} className="border-bottom">Amount Invested</MenuItem>
<MenuItem onClick={onFeesOpen} className="border-bottom">Fees & Expenses</MenuItem>
<MenuItem onClick={onInvestmentOpen} className="border-bottom">
Amount Invested
</MenuItem>
<MenuItem onClick={onFeesOpen} className="border-bottom">
Fees & Expenses
</MenuItem>
<MenuItem onClick={onDistSponsorOpen} className="border-bottom">
Distribution from Sponsors
</MenuItem>
<MenuItem onClick={onDistInvestorOpen}
className="border-bottom">
<MenuItem onClick={onDistInvestorOpen} className="border-bottom">
Distribution To investors
</MenuItem>
<MenuItem onClick={onUpdateNavOpen} className="border-bottom">Update iO NAV</MenuItem>
<MenuItem className="border-bottom">Exit</MenuItem>
<MenuItem className="border-bottom">Cancel</MenuItem>
<MenuItem onClick={onUpdateStatusOpen}>Update iO status</MenuItem>
<MenuItem onClick={onUpdateNavOpen} className="border-bottom">
Update iO NAV
</MenuItem>
<MenuItem onClick={onExitOpen} className="border-bottom">Exit</MenuItem>
<MenuItem onClick={onCancleOpen} className="border-bottom">Cancel</MenuItem>
<MenuItem onClick={onUpdateStatusOpen}>Update iO status</MenuItem>
</MenuList>
</Menu>
@@ -322,6 +347,8 @@ const ViewIOdataHeader = () => {
{/* Modals */}
<AmountInvested isOpen={isInvestmentOpen} onClose={onInvestmentClose} />
<FeesExpenses isOpen={isFeesOpen} onClose={onFeesClose} />
<Exit isOpen={isExitOpen} onClose={onExitClose} />
<Cancle isOpen={isCancleOpen} onClose={onCancleClose} />
<DistributionSponsor
isOpen={isDistSponsorOpen}
onClose={onDistSponsorClose}

View File

@@ -6,6 +6,7 @@ import { useForm } from "react-hook-form";
import GlobalStateContext from "../../../Contexts/GlobalStateContext";
import DataTable from "../../../Components/DataTable/DataTable";
import FormInputView from "../../../Components/FormInputView";
import FullscreenLoaders from "../../../Components/Loaders/FullscreenLoaders";
const ViewIOdetails = () => {
const navigate = useNavigate()
@@ -117,7 +118,7 @@ const ViewIOdetails = () => {
}, {});
if (!foundObject) {
return <Box>Loading...</Box>;
return <FullscreenLoaders/>;
}
return <Box position={'relative'}>

View File

@@ -296,6 +296,20 @@ const InvestorDetails = () => {
<Select focusBorderColor="green.500" size={'sm'} fontSize={'xs'} cursor={'pointer'}>
<option value="" selected disabled hidden>Status</option>
<option value="all">All</option>
<option value="ban">Ban</option>
<option value="unban">UnBan</option>
</Select>
<Select focusBorderColor="green.500" size={'sm'} fontSize={'xs'} cursor={'pointer'}>
<option value="" selected disabled hidden>Status</option>
<option value="all">All</option>
<option value="ban">Ban</option>
<option value="unban">UnBan</option>
</Select>
<Select focusBorderColor="green.500" size={'sm'} fontSize={'xs'} cursor={'pointer'}>
<option value="" selected disabled hidden>Status</option>
<option value="all">All</option>
<option value="ban">Ban</option>
<option value="unban">UnBan</option>

View File

@@ -143,7 +143,7 @@ const Login = () => {
type="text"
name="name"
variant="filled"
placeholder="Owner name"
placeholder="Email"
size="lg"
className="web-text-medium"
/>

View File

@@ -294,7 +294,7 @@ const InvestmentType = () => {
};
return (
<Box {...OPACITY_ON_LOAD} overflowY={"scroll"} height={"100vh"} pb={38}>
<Box {...OPACITY_ON_LOAD} overflowY={"scroll"} height={"100vh"} pb={38}>
<Box bg="white.500">
<HStack
display={"flex"}

View File

@@ -28,11 +28,16 @@ import GlobalStateContext from "../../../Contexts/GlobalStateContext";
import CustomAlertDialog from "../../../Components/CustomAlertDialog";
import ToastBox from "../../../Components/ToastBox";
import { debounce } from "./AddSponser";
import { useGetSponserMasterQuery } from "../../../Services/sponser.service";
const formatDate = (date) => new Date(date).toLocaleDateString(); // Simple date formatter
const Sponser = () => {
const toast = useToast();
const { data: sponsors, error, isLoading: isSponserLoading } = useGetSponserMasterQuery();
console.log(isSponserLoading);
console.log(sponsors);
const { sponser, setSponser, slideFromRight } =
useContext(GlobalStateContext);
const [searchTerm, setSearchTerm] = useState("");

View File

@@ -0,0 +1,68 @@
import axios from "axios";
// Create an Axios instance for API calls
export const api = axios.create({
baseURL: "https://fakestoreapi.com", // 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("accessToken", response.data.accessToken);
localStorage.setItem(
"refreshToken",
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);
}
);

View File

@@ -1,23 +1,25 @@
//sponser.service
// Need to use the React-specific entry point to import createApi
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
import { api } from "./api.service";
const baseUrl = import.meta.env.VITE_API_BASE_URL + "/api";
const baseUrl = api?.defaults.baseURL;
// Define a service using a base URL and expected endpoints
export const sponserMaster = createApi({
reducerPath: "sponserMaster",
baseQuery: fetchBaseQuery({ baseUrl }),
baseQuery: fetchBaseQuery({ baseUrl: baseUrl }),
tagTypes: [],
endpoints: (builder) => ({
getSponserMaster: builder.query({
query: () => '/getUsers',
query: () => '/products/1',
}),
getsponserMasterById: builder.query({
getSponserMasterById: builder.query({
query: (id) => `/getUser/${id}`,
}),
}),
});
// Export hooks for usage in functional components
export const { useSponserMasterQuery, useGetsponserMasterByIdQuery } = sponserMaster;
export const { useGetSponserMasterQuery, useGetSponserMasterByIdQuery } = sponserMaster;

View File

@@ -1,4 +1,3 @@
import axios from "axios";
import { configureStore } from "@reduxjs/toolkit";
import { setupListeners } from "@reduxjs/toolkit/query";
import { sponserMaster } from "../Services/sponser.service";
@@ -7,72 +6,7 @@ import { exchangeRate } from "../Services/exchange.rate.service";
import { ioService } from "../Services/io.service";
import { investorDetails } from "../Services/investor.details.service";
import { investorTransaction } from "../Services/investor.transaction.service";
// Create an Axios instance for API calls
const api = axios.create({
baseURL: "https://api.example.com", // 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) => {
// 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("accessToken", response.data.accessToken);
localStorage.setItem(
"refreshToken",
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);
}
);
import { api } from "../Services/api.service";
export const store = configureStore({
reducer: {
@@ -89,7 +23,14 @@ export const store = configureStore({
thunk: {
extraArgument: api, // Pass Axios instance as extra argument
},
}),
}).concat(
sponserMaster.middleware,
investmentType.middleware,
exchangeRate.middleware,
ioService.middleware,
investorDetails.middleware,
investorTransaction.middleware
),
});
setupListeners(store.dispatch);

BIN
src/assets/pro1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 532 KiB

View File

@@ -7,8 +7,9 @@ import { Provider } from "react-redux";
import { PersistGate } from "redux-persist/integration/react";
import { ChakraProvider } from "@chakra-ui/react";
import GlobalStateProvider from "./Contexts/GlobalStateProvider";
import { store } from "./Store/Store.js";
// import { store } from "./Store/Store.js";
import customTheme from "./Theme/Theme.js";
import store from "./Store/Store.js";
ReactDOM.createRoot(document.getElementById("root")).render(
<ChakraProvider theme={customTheme} >