drag and drop updated

This commit is contained in:
2024-07-08 12:22:27 +05:30
parent df2a12dff3
commit 5ceba1f8b9
16 changed files with 859 additions and 315 deletions

View File

@@ -21,6 +21,7 @@
"framer-motion": "^11.1.5",
"js-cookie": "^3.0.5",
"react": "^18.2.0",
"react-beautiful-dnd": "^13.1.1",
"react-dom": "^18.2.0",
"react-hook-form": "^7.51.3",
"react-icons": "^5.1.0",

View File

@@ -158,6 +158,11 @@
animation-iteration-count: 1;
}
.table-scroll::-webkit-scrollbar{
width: 2px !important;
height: 10px !important;
}
/* Total scrollbar width */
::-webkit-scrollbar {
width: 2px;
@@ -167,14 +172,13 @@
/* The track (background) of the scrollbar */
::-webkit-scrollbar-track {
background: transparent;
border-radius: 10px;
border-radius: 0px;
}
/* The draggable scrollbar handle */
::-webkit-scrollbar-thumb {
background: #0041184f;
border-radius: 10px;
border-radius: 0px;
cursor: grabbing;
}

View File

@@ -1,4 +1,4 @@
import React, { useContext } from "react";
import React, { useContext, useState } from "react";
import {
Table,
TableContainer,
@@ -10,6 +10,7 @@ import {
Skeleton,
TableCaption,
} from "@chakra-ui/react";
import { DragDropContext, Droppable, Draggable } from "react-beautiful-dnd";
import EmptySearchList from "../EmptySearchList";
import { useNavigate } from "react-router-dom";
@@ -17,88 +18,120 @@ import GlobalStateContext from "../../Contexts/GlobalStateContext";
const DataTable = ({
data,
setData,
isLoading,
tableHeadRow,
emptyMessage,
centered,
setMouseEntered,
setMouseEnteredId,
caption,
}) => {
const navigate = useNavigate();
const { slideFromRight } = useContext(GlobalStateContext);
const handleDragEnd = (result) => {
if (!result.destination) return;
const reorderedItems = Array.from(data);
const [removed] = reorderedItems.splice(result.source.index, 1);
reorderedItems.splice(result.destination.index, 0, removed);
setData(reorderedItems)
};
return (
<TableContainer overflowX={"hidden"} className="h-auto mb-3 w-100">
<TableContainer pb={8} overflowX={"scroll"} className="h-auto w-100 table-scroll">
{data?.length === 0 ? (
<EmptySearchList message={emptyMessage} />
) : (
<Table size="sm">
<TableCaption>Tanami v1.0</TableCaption>
<Thead backgroundColor="gray.50">
<Tr>
{tableHeadRow.map((heading, index) => (
<Th
textAlign={tableHeadRow.length - 1 === index ? "center" : "left"}
key={index}
p={3}
w={"auto"}
color={"#004118"}
>
<Skeleton isLoaded={!isLoading} fadeDuration={0.4} height="20px">
{heading}
</Skeleton>
</Th>
))}
</Tr>
</Thead>
<Tbody className="web-text-small">
{data?.map((item, index) => (
<Tr
// onMouseEnter={(e) => {
// e.currentTarget.style.backgroundColor = "transparent"; // Change the background color on hover
// e.currentTarget.style.transition = "0.1s";
// e.currentTarget.style.boxShadow =
// "rgba(0, 0, 0, 0.24) 0px 1px 8px";
// setMouseEntered(true);
// setMouseEnteredId(item.id);
// }}
// onMouseLeave={(e) => {
// e.currentTarget.style.backgroundColor = "transparent"; // Revert to default background color on hover out
// e.currentTarget.style.transition = "0.3s";
// e.currentTarget.style.boxShadow = "none";
// setMouseEntered(false);
// }}
transition={"0.5s all"}
_hover={{
bg: "green.50",
cursor: "pointer",
}}
key={index}
>
{tableHeadRow.map((heading, i) => (
<Td
textAlign={tableHeadRow.length - 1 === i ? "center" : "left"}
color={"gray.600"}
key={i}
style={{
whiteSpace: "nowrap",
textOverflow: "ellipsis",
}}
className="web-text-small"
// onClick={
// i === tableHeadRow.length - 1 || i === 0
// ? null
// : () => navigate(`edit-sponser/${item.id}`) // Define the onClick handler for other cells
// }
>
<Skeleton fadeDuration={index / 12} isLoaded={!isLoading}>
{item[heading]}
</Skeleton>
</Td>
))}
</Tr>
))}
</Tbody>
</Table>
<DragDropContext onDragEnd={handleDragEnd}>
<Droppable droppableId="table">
{(provided) => (
<Table size="sm" {...provided.droppableProps} ref={provided.innerRef}>
<TableCaption p={0}>{caption}</TableCaption>
<Thead backgroundColor="gray.50">
<Tr>
{tableHeadRow.map((heading, index) => (
<Th
textAlign={tableHeadRow.length - 1 === index || centered ? "center" : "left"}
key={index}
p={3}
width="100px" // Adjust width as needed
color={"#004118"}
whiteSpace="normal" // Allow text to wrap
wordBreak="normal" // Ensure long words break properly
overflowWrap="normal" // Break long words if necessary
>
{heading}
</Th>
))}
</Tr>
</Thead>
<Tbody className="web-text-small">
{data?.map((item, index) => (
item.id ? (
<Draggable key={item.id.toString()} draggableId={item.id.toString()} index={index}>
{(provided, snapshot) => (
<Tr
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
transition={"0s all"}
_hover={{
bg: "blue.50",
cursor: "grab",
}}
bg={snapshot.isDragging ? "blue.100" : "white"}
boxShadow={snapshot.isDragging ? "0 0 1em rgba(0, 0, 0, 0.2)" : "none"}
>
{tableHeadRow.map((heading, i) => (
<Td
textAlign={tableHeadRow.length - 1 === i || centered ? "center" : "left"}
color={"gray.600"}
key={i}
style={{
whiteSpace: "nowrap",
textOverflow: "ellipsis",
}}
className="web-text-small"
>
<Skeleton fadeDuration={index / 12} isLoaded={!isLoading}>
{item[heading]}
</Skeleton>
</Td>
))}
</Tr>
)}
</Draggable>
) : (
<Tr key={index}>
{tableHeadRow.map((heading, i) => (
<Td
textAlign={tableHeadRow.length - 1 === i || centered ? "center" : "left"}
color={"gray.600"}
key={i}
style={{
whiteSpace: "nowrap",
textOverflow: "ellipsis",
}}
className="web-text-small"
>
<Skeleton fadeDuration={index / 12} isLoaded={!isLoading}>
{item[heading]}
</Skeleton>
</Td>
))}
</Tr>
)
))}
{provided.placeholder}
</Tbody>
</Table>
)}
</Droppable>
</DragDropContext>
)}
</TableContainer>
);

View File

@@ -9,7 +9,9 @@ const FormInputMain = ({
control,
errors,
onSubmit,
children,
children,
onCancle,
submitTitle,
p,
w
}) => {
@@ -83,16 +85,17 @@ const FormInputMain = ({
{children}
<Box display={'flex'} justifyContent={'end'} mb={5}>
<Box display={"flex"} justifyContent={"space-around"} p={2} w={'49%'} gap={4}>
<Button
<Box display={"flex"} justifyContent={"end"} p={2} w={'49%'} gap={4}>
{onCancle && <Button
size={"sm"}
width={w?w:"44.5%"}
rounded={"sm"}
type="submit"
colorScheme='gray'
onClick={onCancle}
>
Cancel
</Button>
</Button>}
<Button
size={"sm"}
width={w?w:"44.5%"}
@@ -100,7 +103,7 @@ const FormInputMain = ({
type="submit"
colorScheme="green"
>
Submit
{submitTitle ? submitTitle : "Submit"}
</Button>
</Box>
</Box>

View File

@@ -33,7 +33,7 @@ const FormInputView = ({
<FormLabel key={id} color={"gray.500"} fontSize={"xs"}>
{label}
</FormLabel>
<FormLabel>{value}</FormLabel>
<FormLabel fontSize={'sm'}>{value}</FormLabel>
</Box>
))}
</Box>

View File

@@ -8,8 +8,6 @@ import { CiWallet } from "react-icons/ci";
import { HiOutlineReceiptPercent } from "react-icons/hi2";
import { IoMdQrScanner } from "react-icons/io";
const getRandomDate = (start, end) => {
const date = new Date(
start.getTime() + Math.random() * (end.getTime() - start.getTime())
@@ -25,9 +23,7 @@ const GlobalStateProvider = ({ children }) => {
const [memberIfo, setMemberInfo] = useState();
const [communityMembers, setCommityMembers] = useState();
const [slideFromRight, setSlideFormRight] = useState(false);
const { colorMode, toggleColorMode } = useColorMode();
const [sponser, setSponser] = useState([
{
id: 1,
@@ -282,121 +278,255 @@ const GlobalStateProvider = ({ children }) => {
createdAt: "6",
},
]);
const [investors, setInvestors] = useState([
{
id: 1,
clientId: "BH00000001",
firstName: "Faisal",
lastName: "Aljalahma",
investedAmount: 100000,
percentage: "10.0%",
marketValue: 114050,
returnOnInvestment: "14.1%",
distribution: 5000,
totalReturn: 62025,
totalReturnOnInvestment: "24.1%",
},
{
id: 2,
clientId: "BH00000002",
firstName: "Sara",
lastName: "Ahmed",
investedAmount: 150000,
percentage: "15.0%",
marketValue: 171075,
returnOnInvestment: "14.05%",
distribution: 7500,
totalReturn: 93038,
totalReturnOnInvestment: "25.5%",
},
{
id: 3,
clientId: "BH00000003",
firstName: "Ali",
lastName: "Khan",
investedAmount: 200000,
percentage: "20.0%",
marketValue: 228100,
returnOnInvestment: "14.05%",
distribution: 10000,
totalReturn: 124050,
totalReturnOnInvestment: "31.0%",
},
{
id: 4,
clientId: "BH00000004",
firstName: "Laila",
lastName: "Hassan",
investedAmount: 250000,
percentage: "25.0%",
marketValue: 285125,
returnOnInvestment: "14.05%",
distribution: 12500,
totalReturn: 155063,
totalReturnOnInvestment: "37.0%",
},
{
id: 5,
clientId: "BH00000005",
firstName: "Omar",
lastName: "Rahman",
investedAmount: 300000,
percentage: "30.0%",
marketValue: 342150,
returnOnInvestment: "14.05%",
distribution: 15000,
totalReturn: 186075,
totalReturnOnInvestment: "43.0%",
},
{
id: 6,
clientId: "BH00000006",
firstName: "Aisha",
lastName: "Saeed",
investedAmount: 350000,
percentage: "35.0%",
marketValue: 399175,
returnOnInvestment: "14.05%",
distribution: 17500,
totalReturn: 217088,
totalReturnOnInvestment: "49.0%",
},
{
id: 7,
clientId: "BH00000007",
firstName: "Mohammed",
lastName: "Yousef",
investedAmount: 400000,
percentage: "40.0%",
marketValue: 456200,
returnOnInvestment: "14.05%",
distribution: 20000,
totalReturn: 248100,
totalReturnOnInvestment: "55.0%",
},
{
id: 8,
clientId: "BH00000008",
firstName: "Fatima",
lastName: "Jaber",
investedAmount: 450000,
percentage: "45.0%",
marketValue: 513225,
returnOnInvestment: "14.05%",
distribution: 22500,
totalReturn: 279113,
totalReturnOnInvestment: "61.0%",
},
{
id: 9,
clientId: "BH00000009",
firstName: "Yasin",
lastName: "Abdullah",
investedAmount: 500000,
percentage: "50.0%",
marketValue: 570250,
returnOnInvestment: "14.05%",
distribution: 25000,
totalReturn: 310125,
totalReturnOnInvestment: "67.0%",
},
{
id: 10,
clientId: "BH00000010",
firstName: "Zara",
lastName: "Mustafa",
investedAmount: 550000,
percentage: "55.0%",
marketValue: 627275,
returnOnInvestment: "14.05%",
distribution: 27500,
totalReturn: 341138,
totalReturnOnInvestment: "73.0%",
},
]);
const [create, setCreate] = useState([
{
id: 1,
Type: "PDF",
fileName: "Investment Private Company",
document:"Investment.pdf",
document: "Investment.pdf",
status: true,
},
{
id: 2,
Type: "PDF",
fileName: "Investment Private",
document:"Investment.pdf",
document: "Investment.pdf",
status: true,
},
{
id: 3,
Type: "PDF",
fileName: "Investment Private",
document:"Investment.pdf",
document: "Investment.pdf",
status: true,
},
{
id: 4,
Type: "PDF",
fileName: "Investment Private",
document:"Investment.pdf",
document: "Investment.pdf",
status: true,
},
{
id: 5,
Type: "PDF",
fileName: "Investment Private",
document:"Investment.pdf",
document: "Investment.pdf",
status: true,
},
{
id: 6,
Type: "PDF",
fileName: "Investment Private",
document:"Investment.pdf",
document: "Investment.pdf",
status: true,
},
{
id: 7,
Type: "PDF",
fileName: "Investment Private",
document:"Investment.pdf",
document: "Investment.pdf",
status: true,
},
]);
const [keyMerits, setKeyMerits] = useState([
{
id: 1,
title: "Diversified Holdings",
subTitle: "Private equity portfolio of over 60 companies in various sectors and different countries around the world",
icon:<TbClock2 fontSize={'18px'} />,
subTitle:
"Private equity portfolio of over 60 companies in various sectors and different countries around the world",
icon: <TbClock2 fontSize={"18px"} />,
status: true,
},
{
id: 2,
title: "Top-Tier Manager",
subTitle: "KKR is a world-class global PE manager with over $570bn in assets under management",
icon:<CiWallet fontSize={'18px'} />,
subTitle:
"KKR is a world-class global PE manager with over $570bn in assets under management",
icon: <CiWallet fontSize={"18px"} />,
status: true,
},
{
id: 3,
title: "Strong performance",
subTitle: "Direct exposure to the KKRs best performing Buyout and Growth funds",
icon:<HiOutlineReceiptPercent fontSize={'18px'} />,
subTitle:
"Direct exposure to the KKRs best performing Buyout and Growth funds",
icon: <HiOutlineReceiptPercent fontSize={"18px"} />,
status: true,
},
{
id: 4,
title: "Leading Track Record",
subTitle: "Almost 50 year track record since 1977 of consistent, double-digit annual returns",
icon:<IoMdQrScanner fontSize={'18px'} />,
subTitle:
"Almost 50 year track record since 1977 of consistent, double-digit annual returns",
icon: <IoMdQrScanner fontSize={"18px"} />,
status: true,
},
]);
const [iOArtifacts, setIOArtifacts] = useState([
{
id: 1,
type: "JPG",
fileName: "Banner image",
document:"Banner.jpg",
document: "Banner.jpg",
status: true,
},
{
id: 2,
type: "JPG",
fileName: "Banner image",
document:"Banner.jpg",
document: "Banner.jpg",
status: true,
},
{
id: 3,
type: "JPG",
fileName: "Banner image",
document:"Banner.jpg",
document: "Banner.jpg",
status: true,
},
{
id: 4,
type: "JPG",
fileName: "Banner image",
document:"Banner.jpg",
document: "Banner.jpg",
status: true,
},
]);
const [investmentType, setInvestmentType] = useState([
{
id: 1,
@@ -441,7 +571,6 @@ const GlobalStateProvider = ({ children }) => {
status: true,
},
]);
const [investment, setInvestment] = useState([
// {
// banner_image:
@@ -495,7 +624,6 @@ const GlobalStateProvider = ({ children }) => {
// status: "Available"
// },
]);
const [rateExchange, setRateExchange] = useState([
{
id: uuidv4(),
@@ -596,7 +724,6 @@ const GlobalStateProvider = ({ children }) => {
rate: 2.66,
},
]);
const [InvestorDetails, setInvestorDetails] = useState([
{
id: 1,
@@ -613,7 +740,6 @@ const GlobalStateProvider = ({ children }) => {
Action: "Distribute",
},
]);
const [investorTransaction, setInvestorTransaction] = useState([
{
id: 1,
@@ -644,7 +770,6 @@ const GlobalStateProvider = ({ children }) => {
Action: "Distribute",
},
]);
const [pendingRequest, setPendingRequest] = useState([
{
id: uuidv4(),
@@ -755,7 +880,6 @@ const GlobalStateProvider = ({ children }) => {
amount: 1000,
},
]);
const [viewHistory, setViewHistory] = useState([
{
id: uuidv4(),
@@ -866,7 +990,6 @@ const GlobalStateProvider = ({ children }) => {
amount: 2200,
},
]);
const [upgradeHistory, setUpgradeHistory] = useState([
{
id: uuidv4(),
@@ -977,7 +1100,6 @@ const GlobalStateProvider = ({ children }) => {
amount: 2200,
},
]);
const [deleteHistory, setDeleteHistory] = useState([
{
id: uuidv4(),
@@ -1088,7 +1210,6 @@ const GlobalStateProvider = ({ children }) => {
amount: 2200,
},
]);
const [investorRequest, setInvestorRequest] = useState([
{
id: uuidv4(),
@@ -1199,7 +1320,6 @@ const GlobalStateProvider = ({ children }) => {
amount: 1000,
},
]);
const [deleteRequest, setDeleteRequest] = useState([
{
id: uuidv4(),
@@ -1310,7 +1430,6 @@ const GlobalStateProvider = ({ children }) => {
amount: 1000,
},
]);
const [viewIO, setViewIO] = useState([
{
id: 1,
@@ -1357,7 +1476,6 @@ const GlobalStateProvider = ({ children }) => {
toggleColorMode,
slideFromRight,
setSlideFormRight,
InvestorDetails,
setInvestorDetails,
investment,
@@ -1387,7 +1505,9 @@ const GlobalStateProvider = ({ children }) => {
keyMerits,
setKeyMerits,
iOArtifacts,
setIOArtifacts
setIOArtifacts,
investors,
setInvestors
}}
>
{children}

View File

@@ -324,7 +324,7 @@ const DashboardLayout = () => {
className="d-flex"
pe={0.5}
>
<Box
{/* <Box
bottom={4}
right={!slideFromRight ? 4 : "auto"}
left={slideFromRight ? 4 : "auto"}
@@ -349,7 +349,7 @@ const DashboardLayout = () => {
zIndex={999}
>
<IoMdSwap />
</Box>
</Box> */}
{slideFromRight ? null : (
<aside

View File

@@ -1,73 +1,45 @@
import React, { useContext, useEffect, useState } from "react";
import React, { useEffect, useState } from "react";
import { OPACITY_ON_LOAD } from "../../../Layout/animations";
import {
Box,
Divider,
FormControl,
FormLabel,
Heading,
Input,
Select,
Textarea,
Button,
Text,
Image,
Tabs,
TabList,
Tab,
TabPanel,
TabPanels,
Tooltip,
Switch,
useDisclosure,
} from "@chakra-ui/react";
import { useForm, Controller } from "react-hook-form";
import { useForm } from "react-hook-form";
import { yupResolver } from "@hookform/resolvers/yup";
import * as yup from "yup";
import {
AddIcon,
CloseIcon,
DeleteIcon,
EditIcon,
ViewIcon,
WarningTwoIcon,
} from "@chakra-ui/icons";
import { TiWarning } from "react-icons/ti";
import GlobalStateContext from "../../../Contexts/GlobalStateContext";
import { useNavigate } from "react-router-dom";
import FormField from "../../../Components/FormField";
import { v4 as uuidv4 } from "uuid";
import AddIOCharges from "../AddIOCharges";
import FormInputMain from "../../../Components/FormInputMain";
import DataTable from "../../../Components/DataTable/DataTable";
import { debounce } from "../../Master/Sponser/AddSponser";
import CustomAlertDialog from "../../../Components/CustomAlertDialog";
import { formatDate } from "../../../Components/Functions/UTCConvertor";
import IODetails from "./IODetails";
import KeyMerits from "./KeyMerits";
import IOArtifacts from "./IOArtifacts";
import Investors from "./Investors";
import IOCashDetails from "./IOCashDetails";
import IONAVDetails from "./IONAVDetails";
import Distribution from "./Destribution";
import InvestmentDocuments from "../InvestmentDocuments";
import InvestmentDocument from "./InvestmentDocument";
import InvestmentDocument from "./InvestmentDocument"; // Ensure this is the correct import
const schema = yup.object().shape({
ioName: yup.string().required("Arabic name is required"),
ioNameArabic: yup.string().required("Investment Object name is required"),
discription: yup.string().required("Sponser name is required"),
discriptionArabic: yup.string().required("Arabic name is required"),
typeName: yup.string().required("Investment Object name is required"),
typeNameArabic: yup.string().required("Sponser name is required"),
sponserName: yup.string().required("Arabic name is required"),
ioName: yup.string().required("IO name english is required"),
ioNameArabic: yup.string().required("IO name arabic is required"),
discription: yup.string().required("Discription in english is required"),
discriptionArabic: yup.string().required("Discription in Arabic is required"),
typeName: yup.string().required("Investment type in english is required"),
typeNameArabic: yup.string().required("Investment type in arabic is required"),
sponserName: yup.string().required("Sponser name is required"),
sponserNameArabic: yup
.string()
.required("Investment Object name is required"),
.required("Sponser name arabic is required"),
goalAmount: yup.string().required("Goal amount is required"),
holdingPeriod: yup.string().required("Sponser name is required"),
ioStartus: yup.string().required("Investment Object name is required"),
ioStatus: yup.string().required("Investment Object name is required"),
ioStartusArabic: yup.string().required("Sponser name is required"),
goalAmount: yup.string().required("Arabic name is required"),
closingDate: yup.string().required("Investment Object name is required"),
minInvestment: yup.string().required("Sponser name is required"),
maxInvestment: yup.string().required("Arabic name is required"),
@@ -108,66 +80,15 @@ const schema = yup.object().shape({
videos: yup.mixed().required("Profile image is required"),
});
const startYear = 2024;
const endYear = 2124;
const years = Array.from(
{ length: endYear - startYear + 1 },
(_, i) => startYear + i
).map((year) => ({ value: year, label: year }));
const CreateIO = () => {
const {
control,
handleSubmit,
reset,
watch,
setValue,
formState: { errors },
} = useForm({
resolver: yupResolver(schema),
});
const initialTabsState = [
{
label: "IO Details",
content: <IODetails control={control} errors={errors} />,
isDisabled: false,
},
{
label: "Investment documents",
content: <InvestmentDocument control={control} errors={errors} />,
isDisabled: true,
},
{
label: "Key merits",
content: <KeyMerits control={control} errors={errors} />,
isDisabled: false,
},
{
label: "IO artifacts",
content: <IOArtifacts control={control} errors={errors} />,
isDisabled: false,
},
{
label: "Investors",
content: <Investors control={control} errors={errors} />,
isDisabled: true,
},
{
label: "IO Cash Details",
content: <IOCashDetails control={control} errors={errors} />,
isDisabled: false,
},
{
label: "IO NAV Details",
content: <IONAVDetails control={control} errors={errors} />,
isDisabled: false,
},
];
const [tabs, setTabs] = useState(initialTabsState);
const [activeIndex, setActiveIndex] = useState(0);
const enableNextTab = (index) => {
setTabs((prevTabs) => {
const newTabs = [...prevTabs];
@@ -179,13 +100,48 @@ const CreateIO = () => {
});
};
useEffect(() => {
const timer = setTimeout(() => {
setIsLoading(false);
}, 1500);
const initialTabsState = [
{
label: "IO Details",
Content: IODetails,
isDisabled: false,
},
{
label: "Investment documents",
Content: InvestmentDocument,
isDisabled: true,
},
{
label: "Key merits",
Content: KeyMerits,
isDisabled: true,
},
{
label: "IO artifacts",
Content: IOArtifacts,
isDisabled: true,
},
{
label: "Investors",
Content: Investors,
isDisabled: false,
},
{
label: "IO Cash Details",
Content: IOCashDetails,
isDisabled: false,
},
{
label: "IO NAV Details",
Content: IONAVDetails,
isDisabled: false,
},
];
const [tabs, setTabs] = useState(initialTabsState);
const [activeIndex, setActiveIndex] = useState(0);
return () => clearTimeout(timer);
}, []);
const onSubmit = (data) => {
data.preventDefault();
@@ -194,11 +150,7 @@ const CreateIO = () => {
return (
<Box {...OPACITY_ON_LOAD} overflowY={"scroll"} height={"100vh"} pb={10}>
<Tabs
index={activeIndex }
onChange={(index) => setActiveIndex(index)}
mt={2}
>
<Tabs index={activeIndex} onChange={(index) => setActiveIndex(index)} mt={2}>
<TabList>
{tabs.map(({ label, isDisabled }, index) => (
<Tab
@@ -216,12 +168,9 @@ const CreateIO = () => {
</TabList>
<TabPanels>
{tabs.map((tab, index) => (
{tabs.map(({ Content }, index) => (
<TabPanel key={index}>
<Button onClick={() => enableNextTab(activeIndex)} size={"xs"}>
Next
</Button>
{tab.content}
<Content index={index} enableNextTab={enableNextTab} control={control} errors={errors} handleSubmit={handleSubmit} />
</TabPanel>
))}
</TabPanels>

View File

@@ -1,6 +1,7 @@
import {
Box,
Button,
HStack,
Input,
Text,
Tooltip,
@@ -21,7 +22,7 @@ import {
ViewIcon,
} from "@chakra-ui/icons";
const IOArtifacts = () => {
const IOArtifacts = ({enableNextTab, index}) => {
const { iOArtifacts, setIOArtifacts, slideFromRight } =
useContext(GlobalStateContext);
const firstField = useRef();
@@ -210,12 +211,9 @@ const IOArtifacts = () => {
<Button
leftIcon={<AddIcon />}
onClick={onOpen}
size={"xs"}
// width={"44.5%"}
size={"sm"}
fontSize={"xs"}
rounded={"sm"}
ps={3}
pe={4}
colorScheme="green"
>
Add
@@ -238,6 +236,10 @@ const IOArtifacts = () => {
setMouseEnteredId={setMouseEnteredId}
setMouseEntered={setMouseEntered}
/>
<HStack justifyContent={'flex-end'}>
<Button ps={8} pe={8} colorScheme="green" size={'sm'} rounded={'sm'} onClick={()=> enableNextTab(index)}>Next</Button>
</HStack>
<CustomAlertDialog
onClose={() => setDeleteAlert(false)}
isOpen={deleteAlert}

View File

@@ -1,14 +1,16 @@
import React from "react";
import FormInputMain from "../../../Components/FormInputMain";
import { useNavigate } from "react-router-dom";
const IODetails = ({ control, errors }) => {
const IODetails = ({ enableNextTab, control, errors, index, handleSubmit }) => {
const navigate = useNavigate()
const formFields = [
{
label: "IO Name (English)",
placeHolder: " ",
name: "ioName",
type: "text",
isRequired: true,
section: " ",
width: "49%",
},
@@ -17,7 +19,7 @@ const IODetails = ({ control, errors }) => {
placeHolder: " ",
name: "ioNameArabic",
type: "text",
isRequired: true,
section: " ",
width: "49%",
},
@@ -26,7 +28,7 @@ const IODetails = ({ control, errors }) => {
placeHolder: " ",
name: "discription",
type: "textarea",
isRequired: true,
section: " ",
width: "49%",
},
@@ -35,7 +37,7 @@ const IODetails = ({ control, errors }) => {
placeHolder: " ",
name: "discriptionArabic",
type: "textarea",
isRequired: true,
section: " ",
width: "49%",
},
@@ -44,7 +46,7 @@ const IODetails = ({ control, errors }) => {
placeHolder: " ",
name: "typeName",
type: "select",
isRequired: true,
section: " ",
width: "49%",
options: [
@@ -71,7 +73,7 @@ const IODetails = ({ control, errors }) => {
placeHolder: " ",
name: "typeNameArabic",
type: "select",
isRequired: true,
section: " ",
width: "49%",
options: [
@@ -98,7 +100,16 @@ const IODetails = ({ control, errors }) => {
placeHolder: " ",
name: "sponserName",
type: "text",
isRequired: true,
section: " ",
width: "49%",
},
{
label: "Sponser Name (Arabic)",
placeHolder: " ",
name: "sponserNameArabic",
type: "text",
section: " ",
width: "49%",
},
@@ -107,7 +118,7 @@ const IODetails = ({ control, errors }) => {
placeHolder: " ",
name: "goalAmount",
type: "Number",
isRequired: true,
section: " ",
width: "49%",
},
@@ -116,7 +127,7 @@ const IODetails = ({ control, errors }) => {
placeHolder: " ",
name: "minInvestment",
type: "number",
isRequired: true,
section: " ",
width: "32.3%",
},
@@ -125,7 +136,7 @@ const IODetails = ({ control, errors }) => {
placeHolder: " ",
name: "maxInvestment",
type: "number",
isRequired: true,
section: " ",
width: "32.3%",
},
@@ -134,7 +145,7 @@ const IODetails = ({ control, errors }) => {
placeHolder: " ",
name: "holdingPeriod",
type: "number",
isRequired: true,
section: " ",
width: "32.3%",
},
@@ -143,7 +154,7 @@ const IODetails = ({ control, errors }) => {
placeHolder: " ",
name: "expectedReturn",
type: "number",
isRequired: true,
section: " ",
width: "32.3%",
},
@@ -152,18 +163,36 @@ const IODetails = ({ control, errors }) => {
placeHolder: " ",
name: "closingDate",
type: "date",
isRequired: true,
section: " ",
width: "32.3%",
},
},
{
label: "IO Status (English)",
label: "IO status",
placeHolder: " ",
name: "minInvestment",
type: "text",
isRequired: true,
name: "ioStatus",
type: "select",
section: " ",
width: "32.3%",
options: [
{
label: "option 1",
value: "option 1",
},
{
label: "option 2",
value: "option 2",
},
{
label: "option 3",
value: "option 3",
},
{
label: "option 4",
value: "option 4",
},
],
},
];
@@ -176,13 +205,25 @@ const IODetails = ({ control, errors }) => {
return groups;
}, {});
const onSubmit = (e) =>{
e.preventDefault();
enableNextTab(index)
}
return (
<FormInputMain
p={0.1}
w={'auto'}
width={"23.8%"}
groupedFields={groupedFields}
control={control}
errors={errors}
// onSubmit={handleSubmit(onSubmit)}
onSubmit={onSubmit}
submitTitle={"Next"}
/>
);
};

View File

@@ -1,4 +1,4 @@
import { Box, Button, Input, Text, Tooltip, useDisclosure } from "@chakra-ui/react";
import { Box, Button, HStack, Input, Text, Tooltip, useDisclosure, VStack } from "@chakra-ui/react";
import React, { useContext, useEffect, useRef, useState } from "react";
import InvestmentDocuments from "../InvestmentDocuments";
import DataTable from "../../../Components/DataTable/DataTable";
@@ -8,7 +8,7 @@ import { debounce } from "../../Master/Sponser/AddSponser";
import { formatDate } from "../../../Components/Functions/UTCConvertor";
import { AddIcon, DeleteIcon, DownloadIcon, EditIcon, ViewIcon } from "@chakra-ui/icons";
const InvestmentDocument = ({ control, errors }) => {
const InvestmentDocument = ({ control, errors, enableNextTab, index }) => {
const { create, setCreate, sponser, setSponser,slideFromRight} =
useContext(GlobalStateContext);
const firstField = useRef();
@@ -214,12 +214,10 @@ const InvestmentDocument = ({ control, errors }) => {
<Button
leftIcon={<AddIcon />}
onClick={onOpen}
size={"xs"}
size={"sm"}
// width={"44.5%"}
fontSize={"xs"}
rounded={"sm"}
ps={3}
pe={4}
colorScheme="green"
>
@@ -243,6 +241,10 @@ const InvestmentDocument = ({ control, errors }) => {
setMouseEnteredId={setMouseEnteredId}
setMouseEntered={setMouseEntered}
/>
<HStack justifyContent={'flex-end'}>
<Button ps={8} pe={8} colorScheme="green" size={'sm'} rounded={'sm'} onClick={()=> enableNextTab(index)}>Next</Button>
</HStack>
<CustomAlertDialog
onClose={() => setDeleteAlert(false)}
isOpen={deleteAlert}

View File

@@ -1,9 +1,420 @@
import React from 'react'
import {
Avatar,
Badge,
Box,
Button,
HStack,
Input,
Menu,
MenuButton,
MenuItem,
MenuList,
Portal,
Select,
Switch,
Table,
Tag,
Tbody,
Text,
Th,
Thead,
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 { HiDotsVertical } from "react-icons/hi";
import { Link, Link as RouterLink } from "react-router-dom";
import {
AddIcon,
CheckIcon,
CloseIcon,
DeleteIcon,
EditIcon,
EmailIcon,
ViewIcon,
} from "@chakra-ui/icons";
import Pagination from "../../../Components/Pagination";
import GlobalStateContext from "../../../Contexts/GlobalStateContext";
import CustomAlertDialog from "../../../Components/CustomAlertDialog";
import ToastBox from "../../../Components/ToastBox";
import { debounce } from "../../Master/Sponser/AddSponser";
const formatDate = (date) => new Date(date).toLocaleDateString(); // Simple date formatter
const Investors = () => {
return (
<div>Investors</div>
)
}
const toast = useToast();
const { investors, setInvestors, slideFromRight } =
useContext(GlobalStateContext);
const [searchTerm, setSearchTerm] = useState("");
const [isLoading, setIsLoading] = useState(true);
const [deleteAlert, setDeleteAlert] = useState(false);
const [actionId, setActionId] = useState(false);
const [mouseEntered, setMouseEntered] = useState(false);
const [mouseEnteredId, setMouseEnteredId] = useState("");
export default Investors
useEffect(() => {
// Simulate loading
const timer = setTimeout(() => {
setIsLoading(false);
}, 1500);
// Cleanup the timer on component unmount
return () => clearTimeout(timer);
}, []);
// Calculate totals
const totalInvestedAmount = investors.reduce(
(acc, investor) => acc + investor.investedAmount,
0
);
const totalMarketValue = investors.reduce(
(acc, investor) => acc + investor.marketValue,
0
);
const totalDistribution = investors.reduce(
(acc, investor) => acc + investor.distribution,
0
);
const totalTotalReturn = investors.reduce(
(acc, investor) => acc + investor.totalReturn,
0
);
// Table setup
const tableHeadRow = [
"Client ID",
"First name",
"Last name",
"Investment amount",
"Percentage",
"Market Value",
"Return on Investment",
"Distribution",
"Total Return",
"Total return on Investment",
];
const handleUpdateStatus = debounce((id) => {
setInvestors((prevSponser) =>
prevSponser.map((sponsor) =>
sponsor.id === id ? { ...sponsor, status: !sponsor.status } : sponsor
)
);
toast({
render: () => <ToastBox message={"Status changed succesfully.!"} />,
});
}, 300);
// Table filter
const filteredData = investors.filter((item) => {
const name = item.firstName;
const searchLower = searchTerm.toLowerCase();
const nameMatches = name.toLowerCase().includes(searchLower);
return nameMatches;
});
const [ extractedArray, setExtractedArray ] = useState(filteredData?.map((item, index) => ({
id: item?.id,
"Client ID": (
<Text
justifyContent={slideFromRight ? "right" : "center"}
as={"span"}
color={"teal.900"}
fontWeight={"500"}
className="d-flex align-items-center web-text-small"
>
{item.clientId}
</Text>
),
"First name": (
<Text
justifyContent={slideFromRight ? "right" : "center"}
as={"span"}
color={"teal.900"}
fontWeight={"500"}
className="d-flex align-items-center web-text-small"
>
{item.firstName}
</Text>
),
"Last name": (
<Text
justifyContent={slideFromRight ? "right" : "center"}
as={"span"}
color={"teal.900"}
fontWeight={"500"}
className="d-flex align-items-center web-text-small"
>
{item.lastName}
</Text>
),
"Investment amount": (
<Text
justifyContent={slideFromRight ? "right" : "center"}
as={"span"}
color={"teal.900"}
fontWeight={"500"}
className="d-flex align-items-center web-text-small"
>
{`$${item.investedAmount}`}
</Text>
),
"Percentage": (
<Text
justifyContent={slideFromRight ? "right" : "center"}
as={"span"}
color={"teal.900"}
fontWeight={"500"}
className="d-flex align-items-center web-text-small"
>
{item.percentage}
</Text>
),
"Market Value": (
<Text
justifyContent={slideFromRight ? "right" : "center"}
as={"span"}
color={"teal.900"}
fontWeight={"500"}
className="d-flex align-items-center web-text-small"
>
{`$${item.marketValue}`}
</Text>
),
"Return on Investment": (
<Text
justifyContent={slideFromRight ? "right" : "center"}
as={"span"}
color={"teal.900"}
fontWeight={"500"}
h={6}
className="d-flex align-items-center web-text-small"
>
{item.returnOnInvestment}
</Text>
),
"Distribution": (
<Text
justifyContent={slideFromRight ? "right" : "center"}
as={"span"}
color={"teal.900"}
fontWeight={"500"}
className="d-flex align-items-center web-text-small"
>
{`$${item.distribution}`}
</Text>
),
"Total Return": (
<Text
justifyContent={slideFromRight ? "right" : "center"}
as={"span"}
color={"teal.900"}
fontWeight={"500"}
className="d-flex align-items-center web-text-small"
>
{`$${item.totalReturn}`}
</Text>
),
"Total return on Investment": (
<Text
justifyContent={slideFromRight ? "right" : "center"}
as={"span"}
color={"teal.900"}
fontWeight={"500"}
className="d-flex align-items-center web-text-small"
>
{item.totalReturnOnInvestment}
</Text>
),
})));
const handleDelete = () => {
const updatedSponsors = sponser.filter(
(sponsor) => sponsor.id !== actionId
);
setTimeout(() => {
setInvestors(updatedSponsors);
setDeleteAlert(false);
setIsLoading(false);
}, 100);
setIsLoading(true);
};
const Total = () => {
return (
<Table size="sm">
<Tbody backgroundColor="gray.50">
<Tr >
<Th
textAlign={"center"}
p={3}
width="100px"
color={"#004118"}
whiteSpace="normal"
wordBreak="normal"
overflowWrap="normal"
>
Total
</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"
>
{`$${totalInvestedAmount}`}
</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"
>
{`$${totalMarketValue}`}
</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"
>
{`$${totalDistribution}`}
</Th>
<Th
textAlign={"center"}
p={3}
width="100px"
color={"#004118"}
whiteSpace="normal"
wordBreak="normal"
overflowWrap="normal"
>
{`$${totalTotalReturn}`}
</Th>
<Th
textAlign={"center"}
p={3}
width="100px"
color={"#004118"}
whiteSpace="normal"
wordBreak="normal"
overflowWrap="normal"
>
{" "}
</Th>
</Tr>
</Tbody>
</Table>
);
};
return (
<Box {...OPACITY_ON_LOAD} pb={0}>
<Box bg="white.500">
<HStack
display={"flex"}
justifyContent={"space-between"}
pb={3}
spacing="24px"
>
<Input
type="search"
width={300}
placeholder="Search..."
size="sm"
rounded="sm"
focusBorderColor="green.500"
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
/>
<HStack display={"flex"} alignItems={"center"}>
<Pagination totalItems={10} />
</HStack>
</HStack>
</Box>
<DataTable
centered={true}
emptyMessage={`We don't have any Sponers `}
tableHeadRow={tableHeadRow}
data={extractedArray}
setData={setExtractedArray}
isLoading={isLoading}
viewActionId={actionId}
setViewActionId={setActionId}
caption={<Total />}
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 Investors;

View File

@@ -1,4 +1,4 @@
import { Box, Button, Input, Text, Tooltip, useDisclosure } from "@chakra-ui/react";
import { Box, Button, HStack, Input, Text, Tooltip, useDisclosure } from "@chakra-ui/react";
import React, { useContext, useEffect, useRef, useState } from "react";
import InvestmentDocuments from "../InvestmentDocuments";
import DataTable from "../../../Components/DataTable/DataTable";
@@ -8,7 +8,7 @@ import { debounce } from "../../Master/Sponser/AddSponser";
import { formatDate } from "../../../Components/Functions/UTCConvertor";
import { AddIcon, DeleteIcon, DownloadIcon, EditIcon, ViewIcon } from "@chakra-ui/icons";
const KeyMerits = () => {
const KeyMerits = ({enableNextTab, index}) => {
const { keyMerits, setKeyMerits,slideFromRight} =
useContext(GlobalStateContext);
const firstField = useRef();
@@ -71,7 +71,8 @@ const KeyMerits = () => {
setIsLoading(true);
};
const extractedArray = filteredData?.map((item, index) => ({
const [ extractedArray, setExtractedArray ] = useState(filteredData?.map((item, index) => ({
id: item.id,
"Sr.no": (
<Text
justifyContent={slideFromRight ? "right" : "left"}
@@ -177,7 +178,7 @@ const KeyMerits = () => {
</Tooltip>
</Box>
),
}));
})));
return (
@@ -196,12 +197,10 @@ const KeyMerits = () => {
<Button
leftIcon={<AddIcon />}
onClick={onOpen}
size={"xs"}
size={"sm"}
// width={"44.5%"}
fontSize={"xs"}
rounded={"sm"}
ps={3}
pe={4}
colorScheme="green"
>
@@ -217,6 +216,7 @@ const KeyMerits = () => {
emptyMessage={`We don't have any Sponers `}
tableHeadRow={tableHeadRow}
data={extractedArray}
setData={setExtractedArray}
isLoading={isLoading}
viewActionId={actionId}
setViewActionId={setActionId}
@@ -225,6 +225,10 @@ const KeyMerits = () => {
setMouseEnteredId={setMouseEnteredId}
setMouseEntered={setMouseEntered}
/>
<HStack justifyContent={'flex-end'}>
<Button ps={8} pe={8} colorScheme="green" size={'sm'} rounded={'sm'} onClick={()=> enableNextTab(index)}>Next</Button>
</HStack>
<CustomAlertDialog
onClose={() => setDeleteAlert(false)}
isOpen={deleteAlert}

View File

@@ -144,7 +144,6 @@ const ViewIOTable = () => {
"IO status": (
<Box w={"auto"} isTruncated={true}>
<Badge
as={"span"}
color={
item.IOstatus === "Open"
? "#00B69B"
@@ -159,11 +158,6 @@ const ViewIOTable = () => {
? "purple"
: "red"
}
fontWeight={"500"}
padding={"5px 15px"}
rounded={"10px"}
width={"100px"}
marginRight={"25px"}
>
{item.IOstatus}
</Badge>

View File

@@ -19,7 +19,6 @@ 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 { HiDotsVertical } from "react-icons/hi";
import { Link, Link as RouterLink, useNavigate } from "react-router-dom";
import {
@@ -36,6 +35,7 @@ import GlobalStateContext from "../../../Contexts/GlobalStateContext";
import CustomAlertDialog from "../../../Components/CustomAlertDialog";
import ToastBox from "../../../Components/ToastBox";
import { debounce } from "./AddInvestmentType";
import DataTable from "../../../Components/DataTable/DataTable";
const formatDate = (date) => new Date(date).toLocaleDateString(); // Simple date formatter
@@ -102,7 +102,8 @@ const InvestmentType = () => {
return nameMatches;
});
const extractedArray = filteredData?.map((item, index) => ({
const [ extractedArray, setExtractedArray ] = useState(filteredData?.map((item, index) => ({
id: item?.id,
"Sr.no": (
<Text
justifyContent={slideFromRight ? "right" : "left"}
@@ -277,7 +278,7 @@ const InvestmentType = () => {
// </Text>
// </Box>
// ),
}));
})));
const handleDelete = () => {
const IOtype = investmentType.filter(
@@ -333,8 +334,9 @@ const InvestmentType = () => {
</Box>
<DataTable
emptyMessage={`We don't have any Sponers `}
emptyMessage={`We don't have any Investment type `}
tableHeadRow={tableHeadRow}
setData={setExtractedArray}
data={extractedArray}
isLoading={isLoading}
viewActionId={actionId}

View File

@@ -100,7 +100,7 @@ const Sponser = () => {
return nameMatches;
});
const extractedArray = filteredData?.map((item) => ({
const [ extractedArray, setExtractedArray ] = useState(filteredData?.map((item) => ({
id: item?.id,
"Sponser name": (
<Text
@@ -147,35 +147,11 @@ const Sponser = () => {
// ),
"Created At": (
<span className="d-flex justify-content-between align-items-center">
<Box className="d-flex justify-content-between align-items-center">
<Text as={"span"} color={"gray.600"} fontWeight={"500"}>
{formatDate(item.createdAt)}
</Text>
{/* <Menu>
<MenuButton className="link p-1 rounded-1">
<HiDotsVertical className="rubix-text-dark fs-6" />
</MenuButton>
<Portal>
<MenuList minWidth="80px">
<RouterLink to={`edit-sponser/${item.id}`}>
<MenuItem className="web-text-medium">Edit</MenuItem>
</RouterLink>
<RouterLink to={`view-sponser/${item.id}`}>
<MenuItem className="web-text-medium">View</MenuItem>
</RouterLink>
<MenuItem
onClick={() => {
setActionId(item?.id);
setDeleteAlert(true);
}}
className="web-text-medium"
>
Delete
</MenuItem>
</MenuList>
</Portal>
</Menu> */}
</span>
</Box>
),
Action: (
<Box display={"flex"} justifyContent={"space-between"}>
@@ -270,7 +246,8 @@ const Sponser = () => {
// </Text>
// </Box>
// ),
}));
})))
const handleDelete = () => {
const updatedSponsors = sponser.filter(
@@ -329,6 +306,7 @@ const Sponser = () => {
emptyMessage={`We don't have any Sponers `}
tableHeadRow={tableHeadRow}
data={extractedArray}
setData={setExtractedArray}
isLoading={isLoading}
viewActionId={actionId}
setViewActionId={setActionId}