Compare commits
79 Commits
v1.0.0
...
feature-de
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d7012f2692 | ||
|
|
e07a92ba03 | ||
|
|
adb4bd5d27 | ||
| cfda3264fc | |||
|
|
1569afe4f0 | ||
|
|
4a3072b4d3 | ||
| 4516c70406 | |||
| 50f87869be | |||
| d69e4a203f | |||
| 6e4c794d2b | |||
| dfbc1ad338 | |||
| aa1c0c994a | |||
| cecd8dd5e0 | |||
| 620b365437 | |||
| 2e5ecb967f | |||
| 3df4ed8df3 | |||
| 6f514fe121 | |||
| 125d6e6ae3 | |||
|
|
68d6bd7c9e | ||
| e7aef39fa7 | |||
| 71f8c8a98d | |||
| 08559eb833 | |||
| fc7d8ac0e9 | |||
|
|
692e08abd6 | ||
| a0b722bd12 | |||
|
|
34c51c4c4c | ||
|
|
b5a960f7df | ||
| 1f97c841f7 | |||
| ba9efdd48b | |||
|
|
e103258995 | ||
|
|
9d404a58f2 | ||
|
|
24d4926f75 | ||
|
|
ee8f905d3a | ||
| 568b2f716a | |||
| 27a975fe8a | |||
|
|
395d60fd2f | ||
| 78c7f55673 | |||
|
|
b308e22b6d | ||
| c9ad4a4377 | |||
| 2d641a9748 | |||
| 83aa170c60 | |||
|
|
54e37a3703 | ||
| 8dae36daaf | |||
| 84fb0d77cf | |||
| 94d3e25cce | |||
|
|
f17f77d409 | ||
|
|
51a4bc7917 | ||
|
|
78d573037d | ||
| 5b1f89efc9 | |||
|
|
7de0a679e0 | ||
| 8cc16ddc8a | |||
| 60b0263133 | |||
| fd45d6aeef | |||
| f7a8da789c | |||
|
|
e0765514f5 | ||
| 0393a18762 | |||
| e8b9a4af40 | |||
| dce1a09f98 | |||
| 1de2710cd1 | |||
|
|
66afc30a14 | ||
| e657409edb | |||
| 9f6136935d | |||
| 26363e2b0c | |||
|
|
0e7f954d20 | ||
| 9da83b8297 | |||
| 591e0c92a0 | |||
|
|
e234ce3181 | ||
|
|
4c6df2cc2f | ||
| 2a11fed4f0 | |||
| 2b4896fa9b | |||
|
|
2202305d28 | ||
| 059275b310 | |||
|
|
d42cdf0a50 | ||
|
|
5ca4dad151 | ||
| eaf6394a4f | |||
| 6b9dc86a5e | |||
| 60a6a053b3 | |||
|
|
8d5788ce02 | ||
|
|
3e3c47149a |
@@ -22,7 +22,7 @@ const craftedMsg = "Crafted with ❤️ by WDI Team for a better web.";
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
<script type="text/javascript">
|
<!-- <script type="text/javascript">
|
||||||
function googleTranslateElementInit() {
|
function googleTranslateElementInit() {
|
||||||
new google.translate.TranslateElement({
|
new google.translate.TranslateElement({
|
||||||
pageLanguage: 'en',
|
pageLanguage: 'en',
|
||||||
@@ -30,7 +30,10 @@ const craftedMsg = "Crafted with ❤️ by WDI Team for a better web.";
|
|||||||
layout: google.translate.TranslateElement.InlineLayout.SIMPLE
|
layout: google.translate.TranslateElement.InlineLayout.SIMPLE
|
||||||
}, 'google_translate_element');
|
}, 'google_translate_element');
|
||||||
}
|
}
|
||||||
</script>
|
</script> -->
|
||||||
<script type="text/javascript" src="//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit"></script>
|
<!-- <script type="text/javascript" src="//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit"></script> -->
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
|
||||||
|
<script src="https://stackpath.bootstrapcdn.com/bootstrap/5.3.0/js/bootstrap.bundle.min.js"></script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
2363
package-lock.json
generated
@@ -16,17 +16,21 @@
|
|||||||
"@emotion/styled": "^11.11.5",
|
"@emotion/styled": "^11.11.5",
|
||||||
"@hookform/resolvers": "^3.3.4",
|
"@hookform/resolvers": "^3.3.4",
|
||||||
"@reduxjs/toolkit": "^2.2.3",
|
"@reduxjs/toolkit": "^2.2.3",
|
||||||
|
"apexcharts": "^3.52.0",
|
||||||
"axios": "^1.7.2",
|
"axios": "^1.7.2",
|
||||||
"bootstrap": "5.3.3",
|
"bootstrap": "5.3.3",
|
||||||
|
"chart.js": "^4.4.3",
|
||||||
"dotenv": "^16.4.5",
|
"dotenv": "^16.4.5",
|
||||||
"framer-motion": "^11.1.5",
|
"framer-motion": "^11.1.5",
|
||||||
"js-cookie": "^3.0.5",
|
"js-cookie": "^3.0.5",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
|
"react-apexcharts": "^1.4.1",
|
||||||
"react-beautiful-dnd": "^13.1.1",
|
"react-beautiful-dnd": "^13.1.1",
|
||||||
|
"react-chartjs-2": "^5.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-hook-form": "^7.51.3",
|
"react-hook-form": "^7.51.3",
|
||||||
"react-icons": "^5.1.0",
|
"react-icons": "^5.1.0",
|
||||||
"react-quill": "^2.0.0",
|
"react-quill": "^0.0.2",
|
||||||
"react-redux": "^9.1.1",
|
"react-redux": "^9.1.1",
|
||||||
"react-router-dom": "^6.22.3",
|
"react-router-dom": "^6.22.3",
|
||||||
"redux-persist": "^6.0.0",
|
"redux-persist": "^6.0.0",
|
||||||
|
|||||||
153
src/App.css
@@ -14,6 +14,11 @@
|
|||||||
/* font-family: "Lato", sans-serif !important; */
|
/* font-family: "Lato", sans-serif !important; */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
::selection {
|
||||||
|
background-color: #004717; /* Change this to your desired color */
|
||||||
|
color: white; /* Optional: Change the text color */
|
||||||
|
}
|
||||||
|
|
||||||
.pointer {
|
.pointer {
|
||||||
cursor: pointer !important;
|
cursor: pointer !important;
|
||||||
}
|
}
|
||||||
@@ -336,3 +341,151 @@
|
|||||||
font-size: 22px !important;
|
font-size: 22px !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ========= [ switch BTN ============ */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* From Uiverse.io by Nawsome */
|
||||||
|
.switch {
|
||||||
|
display: block;
|
||||||
|
background-color: black;
|
||||||
|
width: 85px;
|
||||||
|
height: 115px;
|
||||||
|
box-shadow: 0 0 10px 2px rgba(0, 0, 0, 0.2), 0 0 1px 2px black, inset 0 2px 2px -2px white, inset 0 0 2px 15px #47434c, inset 0 0 2px 22px black;
|
||||||
|
border-radius: 5px;
|
||||||
|
padding: 20px;
|
||||||
|
perspective: 700px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch input {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch input:checked + .button {
|
||||||
|
transform: translateZ(20px) rotateX(25deg);
|
||||||
|
box-shadow: 0 -10px 20px #ff1818;
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch input:checked + .button .light {
|
||||||
|
animation: flicker 0.2s infinite 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch input:checked + .button .shine {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch input:checked + .button .shadow {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch .button {
|
||||||
|
display: block;
|
||||||
|
transition: all 0.3s cubic-bezier(1, 0, 1, 1);
|
||||||
|
transform-origin: center center -20px;
|
||||||
|
transform: translateZ(20px) rotateX(-25deg);
|
||||||
|
transform-style: preserve-3d;
|
||||||
|
background-color: #9b0621;
|
||||||
|
height: 100%;
|
||||||
|
position: relative;
|
||||||
|
cursor: pointer;
|
||||||
|
background: linear-gradient(#980000 0%, #6f0000 30%, #6f0000 70%, #980000 100%);
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch .button::before {
|
||||||
|
content: "";
|
||||||
|
background: linear-gradient(rgba(255, 255, 255, 0.8) 10%, rgba(255, 255, 255, 0.3) 30%, #650000 75%, #320000) 50% 50%/97% 97%, #b10000;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
width: 100%;
|
||||||
|
height: 50px;
|
||||||
|
transform-origin: top;
|
||||||
|
transform: rotateX(-90deg);
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch .button::after {
|
||||||
|
content: "";
|
||||||
|
background-image: linear-gradient(#650000, #320000);
|
||||||
|
width: 100%;
|
||||||
|
height: 58px;
|
||||||
|
transform-origin: top;
|
||||||
|
transform: translateY(50px) rotateX(-90deg);
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
box-shadow: 0 50px 8px 0px black, 0 80px 20px 0px rgba(0, 0, 0, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch .light {
|
||||||
|
opacity: 0;
|
||||||
|
animation: light-off 1s;
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-image: radial-gradient(#ffc97e, #ff1818 40%, transparent 70%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch .dots {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-image: radial-gradient(transparent 30%, rgba(101, 0, 0, 0.7) 70%);
|
||||||
|
background-size: 10px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch .characters {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: linear-gradient(white, white) 50% 20%/5% 20%, radial-gradient(circle, transparent 50%, white 52%, white 70%, transparent 72%) 50% 80%/33% 25%;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch .shine {
|
||||||
|
transition: all 0.3s cubic-bezier(1, 0, 1, 1);
|
||||||
|
opacity: 0.3;
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: linear-gradient(white, transparent 3%) 50% 50%/97% 97%, linear-gradient(rgba(255, 255, 255, 0.5), transparent 50%, transparent 80%, rgba(255, 255, 255, 0.5)) 50% 50%/97% 97%;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch .shadow {
|
||||||
|
transition: all 0.3s cubic-bezier(1, 0, 1, 1);
|
||||||
|
opacity: 1;
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: linear-gradient(transparent 70%, rgba(0, 0, 0, 0.8));
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes flicker {
|
||||||
|
0% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
80% {
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes light-off {
|
||||||
|
0% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
80% {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
19
src/App.jsx
@@ -37,12 +37,16 @@ const App = () => {
|
|||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const PrivateRoute = ({ children }) => {
|
// const token = localStorage.getItem('accessToken')
|
||||||
if (!isAuthenticate && isAuthenticatedInCookie !== "true") {
|
// console.log(token);
|
||||||
return <Navigate to="/login" replace />;
|
|
||||||
}
|
|
||||||
return children;
|
// const PrivateRoute = ({ children }) => {
|
||||||
};
|
// if (!isAuthenticate && isAuthenticatedInCookie !== "true") {
|
||||||
|
// return <Navigate to="/login" replace />;
|
||||||
|
// }
|
||||||
|
// return children;
|
||||||
|
// };
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Router>
|
<Router>
|
||||||
@@ -52,7 +56,8 @@ const App = () => {
|
|||||||
path="/*"
|
path="/*"
|
||||||
element={
|
element={
|
||||||
// isOnline ? (
|
// isOnline ? (
|
||||||
isAuthenticate || isAuthenticatedInCookie === "true" ? (
|
// isAuthenticate || isAuthenticatedInCookie === "true" ? (
|
||||||
|
localStorage.getItem('accessToken') && localStorage.getItem('refreshToken') ? (
|
||||||
<DefaultLayout isOnline={isOnline} />
|
<DefaultLayout isOnline={isOnline} />
|
||||||
) : (
|
) : (
|
||||||
<Login />
|
<Login />
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ const CreateIO = () => {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const tableHeadRow = [
|
const tableHeadRow = [
|
||||||
"Sponsorer name",
|
"Sponsor name",
|
||||||
"Address",
|
"Address",
|
||||||
"Mobile no",
|
"Mobile no",
|
||||||
"Created At",
|
"Created At",
|
||||||
@@ -191,7 +191,7 @@ const CreateIO = () => {
|
|||||||
|
|
||||||
const extractedArray = filteredData?.map((item) => ({
|
const extractedArray = filteredData?.map((item) => ({
|
||||||
id: item?.id,
|
id: item?.id,
|
||||||
"Sponsorer name": (
|
"Sponsor name": (
|
||||||
<Text
|
<Text
|
||||||
justifyContent={"left"}
|
justifyContent={"left"}
|
||||||
as={"span"}
|
as={"span"}
|
||||||
@@ -413,7 +413,7 @@ const CreateIO = () => {
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Sponsorer Name (English)",
|
label: "Sponsor Name (English)",
|
||||||
placeHolder: " ",
|
placeHolder: " ",
|
||||||
name: "sponserName",
|
name: "sponserName",
|
||||||
type: "text",
|
type: "text",
|
||||||
|
|||||||
47
src/Components/CurrencyInput.jsx
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
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
|
||||||
|
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
|
||||||
|
const parts = value?.split('.');
|
||||||
|
if (parts.length > 2) {
|
||||||
|
value = parts[0] + '.' + parts?.slice(1)?.join('');
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
@@ -50,7 +50,7 @@ const DataTable = ({
|
|||||||
const [removed] = reorderedItems.splice(result.source.index, 1);
|
const [removed] = reorderedItems.splice(result.source.index, 1);
|
||||||
reorderedItems.splice(result.destination.index, 0, removed);
|
reorderedItems.splice(result.destination.index, 0, removed);
|
||||||
setData(reorderedItems)
|
setData(reorderedItems)
|
||||||
console.log("New Order:", reorderedItems.map((item, index) => ({ index, item })));
|
// console.log("New Order:", reorderedItems.map((item, index) => ({ index, item })));
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import {
|
|||||||
Tfoot,
|
Tfoot,
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import EmptySearchList from "../EmptySearchList";
|
import EmptySearchList from "../EmptySearchList";
|
||||||
|
import { TABLE_PAGINATION } from "../../Constants/Paginations";
|
||||||
|
|
||||||
const DataTable = ({
|
const DataTable = ({
|
||||||
data,
|
data,
|
||||||
@@ -20,6 +21,9 @@ const DataTable = ({
|
|||||||
emptyMessage,
|
emptyMessage,
|
||||||
centered,
|
centered,
|
||||||
}) => {
|
}) => {
|
||||||
|
|
||||||
|
console.log(data);
|
||||||
|
|
||||||
const columnWidth =
|
const columnWidth =
|
||||||
data && data[0]
|
data && data[0]
|
||||||
? `${(100 / Object.keys(data[0]).length).toFixed(2)}%`
|
? `${(100 / Object.keys(data[0]).length).toFixed(2)}%`
|
||||||
@@ -35,7 +39,6 @@ const DataTable = ({
|
|||||||
<Tr>
|
<Tr>
|
||||||
{tableHeadRow.map((heading, index) => (
|
{tableHeadRow.map((heading, index) => (
|
||||||
<Th
|
<Th
|
||||||
width={'fit-content'}
|
|
||||||
textAlign={
|
textAlign={
|
||||||
tableHeadRow.length - 1 === index || centered
|
tableHeadRow.length - 1 === index || centered
|
||||||
? "center"
|
? "center"
|
||||||
@@ -43,7 +46,13 @@ const DataTable = ({
|
|||||||
}
|
}
|
||||||
key={index}
|
key={index}
|
||||||
p={3}
|
p={3}
|
||||||
w={columnWidth}
|
width="20px" // 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
|
||||||
|
textTransform={'none'}
|
||||||
|
|
||||||
>
|
>
|
||||||
{isLoading ? <Skeleton height="20px" /> : heading}
|
{isLoading ? <Skeleton height="20px" /> : heading}
|
||||||
{/* {heading} */}
|
{/* {heading} */}
|
||||||
@@ -53,7 +62,7 @@ const DataTable = ({
|
|||||||
</Thead>
|
</Thead>
|
||||||
<Tbody className="web-text-small">
|
<Tbody className="web-text-small">
|
||||||
{isLoading
|
{isLoading
|
||||||
? Array.from({ length: 12 }).map((_, index) => (
|
? Array.from({ length: TABLE_PAGINATION?.size }).map((_, index) => (
|
||||||
<Tr key={index}>
|
<Tr key={index}>
|
||||||
{tableHeadRow.map((_, i) => (
|
{tableHeadRow.map((_, i) => (
|
||||||
<Td
|
<Td
|
||||||
|
|||||||
55
src/Components/Doughnut/ApexDonut.jsx
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
import React, { useState } from 'react';
|
||||||
|
import ApexCharts from 'react-apexcharts';
|
||||||
|
|
||||||
|
const ApexChart = ({ data }) => {
|
||||||
|
|
||||||
|
// Customize colors and series titles here
|
||||||
|
const [options] = useState({
|
||||||
|
chart: {
|
||||||
|
width: 600,
|
||||||
|
type: 'donut',
|
||||||
|
},
|
||||||
|
plotOptions: {
|
||||||
|
pie: {
|
||||||
|
startAngle: -90,
|
||||||
|
endAngle: 270,
|
||||||
|
donut: {
|
||||||
|
size: '45%' // Adjust the donut size here (percentage of chart size)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
labels:data?.labels,
|
||||||
|
dataLabels: {
|
||||||
|
enabled: false
|
||||||
|
},
|
||||||
|
fill: {
|
||||||
|
type: 'gradient',
|
||||||
|
},
|
||||||
|
colors: data?.backgroundColor,
|
||||||
|
legend: {
|
||||||
|
show: false,
|
||||||
|
position: 'right',
|
||||||
|
labels: {
|
||||||
|
colors: ['#000'], // Customize the color of the legend labels
|
||||||
|
useSeriesColors: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
responsive: [{
|
||||||
|
breakpoint: 480,
|
||||||
|
options: {
|
||||||
|
chart: {
|
||||||
|
width: 500
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
position: 'center'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ApexCharts options={options} series={data?.values} type="donut" width={300} />
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ApexChart;
|
||||||
66
src/Components/Doughnut/ApexLine.jsx
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
import React, { useState } from 'react';
|
||||||
|
import ReactApexChart from 'react-apexcharts';
|
||||||
|
|
||||||
|
function ApexLine() {
|
||||||
|
const [chartOptions, setChartOptions] = useState({
|
||||||
|
series: [{
|
||||||
|
name: 'Rate',
|
||||||
|
data: [45, 23, 70, 65, 5, 34, 32],
|
||||||
|
gradientToColors: ['#004017'],
|
||||||
|
}],
|
||||||
|
options: {
|
||||||
|
chart: {
|
||||||
|
height: 350,
|
||||||
|
type: 'line',
|
||||||
|
toolbar: {
|
||||||
|
show: false // Hide the action icons
|
||||||
|
}
|
||||||
|
},
|
||||||
|
stroke: {
|
||||||
|
width: 5,
|
||||||
|
curve: 'smooth',
|
||||||
|
colors: ['#598369'], // Customize the line color here
|
||||||
|
},
|
||||||
|
markers: {
|
||||||
|
size: 6, // Size of markers
|
||||||
|
colors: ['#004118'], // Marker (dot) color
|
||||||
|
strokeColor: '#fff', // Stroke color of the marker
|
||||||
|
strokeWidth: 2
|
||||||
|
},
|
||||||
|
xaxis: {
|
||||||
|
type: 'category', // Change from 'datetime' to 'category'
|
||||||
|
categories: ['BH', 'KW', 'OM', 'QA', 'SA', 'UAE', 'IND'],
|
||||||
|
tickAmount: 7
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
text: 'Exchange Rate Currency', // Adjust the title if needed
|
||||||
|
align: 'left',
|
||||||
|
style: {
|
||||||
|
fontSize: '15px',
|
||||||
|
color: '#000',
|
||||||
|
fontWeight: 400
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fill: {
|
||||||
|
type: 'gradient',
|
||||||
|
gradient: {
|
||||||
|
shade: 'dark',
|
||||||
|
gradientToColors: ['#004017'],
|
||||||
|
shadeIntensity: 4,
|
||||||
|
type: 'horizontal',
|
||||||
|
opacityFrom: 1,
|
||||||
|
opacityTo: 1,
|
||||||
|
stops: [0, 100] // Gradient stops
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<ReactApexChart options={chartOptions.options} series={chartOptions.series} type="line" height={"100%"} width={"600"} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ApexLine;
|
||||||
39
src/Components/Doughnut/DonutChart.jsx
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
// DonutChart.jsx
|
||||||
|
import React from 'react';
|
||||||
|
import { Doughnut } from 'react-chartjs-2';
|
||||||
|
import { Chart as ChartJS, Title, Tooltip, Legend, ArcElement } from 'chart.js';
|
||||||
|
|
||||||
|
ChartJS.register(Title, Tooltip, Legend, ArcElement);
|
||||||
|
|
||||||
|
const DonutChart = ({ data, width = 300, height = 250 }) => {
|
||||||
|
const chartData = {
|
||||||
|
labels: data.labels,
|
||||||
|
datasets: [
|
||||||
|
{
|
||||||
|
label: 'My Dataset',
|
||||||
|
data: data.values,
|
||||||
|
backgroundColor: [ '#3182ce', '#004118', '#D69E2E', '#E53E3E' ],
|
||||||
|
borderColor: ['#FFF'],
|
||||||
|
borderWidth: 2,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
const options = {
|
||||||
|
responsive: true,
|
||||||
|
plugins: {
|
||||||
|
legend: {
|
||||||
|
display: false, // Hide the legend
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
callbacks: {
|
||||||
|
label: (tooltipItem) => `${tooltipItem.label}: ${tooltipItem.raw}`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
return <Doughnut data={chartData} options={options} width={'100%'} />;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default DonutChart;
|
||||||
80
src/Components/Doughnut/LineChart.jsx
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
// LineChart.jsx
|
||||||
|
import React from 'react';
|
||||||
|
import { Line } from 'react-chartjs-2';
|
||||||
|
import { Chart as ChartJS, Title, Tooltip, Legend, LineElement, PointElement, LinearScale, CategoryScale } from 'chart.js';
|
||||||
|
|
||||||
|
// Register the necessary components
|
||||||
|
ChartJS.register( Title, Tooltip, Legend, LineElement, PointElement, LinearScale, CategoryScale );
|
||||||
|
|
||||||
|
// Sample options for the chart
|
||||||
|
// Sample options for the chart
|
||||||
|
const options = {
|
||||||
|
responsive: true,
|
||||||
|
plugins: {
|
||||||
|
legend: {
|
||||||
|
position: 'top',
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
callbacks: {
|
||||||
|
label: function (context) {
|
||||||
|
let label = context.dataset.label || '';
|
||||||
|
if (label) {
|
||||||
|
label += ': ';
|
||||||
|
}
|
||||||
|
if (context.parsed.y !== null) {
|
||||||
|
label += `${context.parsed.y}`;
|
||||||
|
}
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
animation: {
|
||||||
|
tension: {
|
||||||
|
duration: 2000,
|
||||||
|
easing: 'linear',
|
||||||
|
from: 1,
|
||||||
|
to: 0,
|
||||||
|
loop: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const Utils = {
|
||||||
|
numbers: ({ count, min, max }) => Array.from({ length: count }, () => Math.floor(Math.random() * (max - min + 1)) + min),
|
||||||
|
CHART_COLORS: {
|
||||||
|
red: 'rgba(255, 99, 132, 1)',
|
||||||
|
darkGreen: 'rgba(0, 65, 24, 1)' // Added color related to #004118
|
||||||
|
},
|
||||||
|
transparentize: (color, opacity) => {
|
||||||
|
// Use regex to replace the alpha value
|
||||||
|
return color.replace(/(rgba\(\d+, \d+, \d+, )\d+(\))/, `$1${opacity}$2`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const LineChart = ({ width = 300, height = 250 }) => {
|
||||||
|
const data = {
|
||||||
|
labels: ['Bahrain', 'Kuwait', 'Oman', 'Qatar', 'Saudi Arabia', 'UAE', 'India'],
|
||||||
|
datasets: [
|
||||||
|
{
|
||||||
|
label: 'Exchange rate',
|
||||||
|
data: [45.9087, 23.8798, 99.9809, 65.8987, 65.8987, 34.9898, 32.8987],
|
||||||
|
borderColor: Utils.CHART_COLORS.darkGreen,
|
||||||
|
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.darkGreen, 0.5),
|
||||||
|
pointStyle: 'rectRounded',
|
||||||
|
pointRadius: 10,
|
||||||
|
pointHoverRadius: 15
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Line data={data} options={options} />
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default LineChart;
|
||||||
41
src/Components/DummyComponent.jsx
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
import { Box, Input } from "@chakra-ui/react";
|
||||||
|
import React, { useRef, useState } from "react";
|
||||||
|
import audioClick from "../assets/click-151673.mp3";
|
||||||
|
|
||||||
|
const DummyComponent = () => {
|
||||||
|
// Define the state for the checkbox
|
||||||
|
const [isSwitchOn, setIsSwitchOn] = useState(false);
|
||||||
|
|
||||||
|
const audio = useRef();
|
||||||
|
|
||||||
|
// Function to toggle the switch
|
||||||
|
const handleToggle = () => {
|
||||||
|
setIsSwitchOn(!isSwitchOn);
|
||||||
|
if(audio.current){
|
||||||
|
audio.current.play();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box display={"flex"} justifyContent={"right"} p={"2rem"}>
|
||||||
|
<label className="switch">
|
||||||
|
<Input
|
||||||
|
type="checkbox"
|
||||||
|
checked={isSwitchOn}
|
||||||
|
onChange={handleToggle} // Toggle the switch on change
|
||||||
|
/>
|
||||||
|
<Box className="button">
|
||||||
|
<div className="light"></div>
|
||||||
|
<div className="dots"></div>
|
||||||
|
<div className="characters"></div>
|
||||||
|
<div className="shine"></div>
|
||||||
|
<div className="shadow"></div>
|
||||||
|
</Box>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<audio ref={audio} src={audioClick} />
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default DummyComponent;
|
||||||
@@ -27,10 +27,11 @@ import { Controller } from "react-hook-form";
|
|||||||
import { TiWarning } from "react-icons/ti";
|
import { TiWarning } from "react-icons/ti";
|
||||||
import { motion } from "framer-motion";
|
import { motion } from "framer-motion";
|
||||||
import { AddIcon, CloseIcon } from "@chakra-ui/icons";
|
import { AddIcon, CloseIcon } from "@chakra-ui/icons";
|
||||||
|
import CurrencyInput from "./CurrencyInput";
|
||||||
|
|
||||||
const today = new Date().toISOString().split("T")[0];
|
const today = new Date().toISOString().split("T")[0];
|
||||||
|
|
||||||
const formatDate = (dateString) => {
|
export const formatDatee = (dateString) => {
|
||||||
const date = new Date(dateString);
|
const date = new Date(dateString);
|
||||||
const year = date.getFullYear();
|
const year = date.getFullYear();
|
||||||
const month = String(date.getMonth() + 1).padStart(2, "0"); // Months are zero-based
|
const month = String(date.getMonth() + 1).padStart(2, "0"); // Months are zero-based
|
||||||
@@ -41,7 +42,7 @@ const formatDate = (dateString) => {
|
|||||||
const defaultDate = "8/2/2024";
|
const defaultDate = "8/2/2024";
|
||||||
|
|
||||||
// Format the default date as YYYY-MM-DD
|
// Format the default date as YYYY-MM-DD
|
||||||
const formattedDate = formatDate(defaultDate);
|
const formattedDate = formatDatee(defaultDate);
|
||||||
|
|
||||||
const FormField = ({
|
const FormField = ({
|
||||||
label,
|
label,
|
||||||
@@ -67,12 +68,13 @@ const FormField = ({
|
|||||||
handleInputChange,
|
handleInputChange,
|
||||||
align,
|
align,
|
||||||
maxLength,
|
maxLength,
|
||||||
|
dateValue,
|
||||||
...props
|
...props
|
||||||
}) => (
|
}) => (
|
||||||
<FormControl
|
<FormControl
|
||||||
w={width ? width : "49%"}
|
w={width ? width : "49%"}
|
||||||
isInvalid={errors[name]}
|
isInvalid={errors[name]}
|
||||||
isRequired={isRequired}
|
isRequired={type === "date" ? false: isRequired}
|
||||||
mb={2}
|
mb={2}
|
||||||
>
|
>
|
||||||
<FormLabel textAlign={"left"} fontSize={"xs"} color={"gray.600"}>
|
<FormLabel textAlign={"left"} fontSize={"xs"} color={"gray.600"}>
|
||||||
@@ -402,7 +404,7 @@ const FormField = ({
|
|||||||
w={6}
|
w={6}
|
||||||
h={6}
|
h={6}
|
||||||
src={
|
src={
|
||||||
" https://tanami.betadelivery.com/" +
|
import.meta.env.VITE_IMAGE_URL +
|
||||||
item?.logo
|
item?.logo
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
@@ -460,7 +462,51 @@ const FormField = ({
|
|||||||
</Tbody>
|
</Tbody>
|
||||||
</Table>
|
</Table>
|
||||||
);
|
);
|
||||||
} else {
|
} else if(type === 'date'){
|
||||||
|
return (
|
||||||
|
<Input
|
||||||
|
position={'relative'}
|
||||||
|
bg={"#F5F8F6"}
|
||||||
|
focusBorderColor="forestGreen.300"
|
||||||
|
size={"sm"}
|
||||||
|
fontSize={"sm"}
|
||||||
|
rounded={"sm"}
|
||||||
|
type={"date"}
|
||||||
|
{...field}
|
||||||
|
{...props}
|
||||||
|
placeholder={placeHolder ? placeHolder : label}
|
||||||
|
textAlign={arabic ? "right" : align ? align : "left"}
|
||||||
|
_placeholder={{ fontSize: "sm" }}
|
||||||
|
min={type === "date" ? today : undefined}
|
||||||
|
maxLength={maxLength}
|
||||||
|
// defaultValue={type === "date" && "2023-07-26" : undefined}
|
||||||
|
// defaultValue={value}
|
||||||
|
// value={dateValue}
|
||||||
|
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
}else if(type === 'number'){
|
||||||
|
return (
|
||||||
|
<CurrencyInput
|
||||||
|
position={'relative'}
|
||||||
|
bg={"#F5F8F6"}
|
||||||
|
focusBorderColor="forestGreen.300"
|
||||||
|
size={"sm"}
|
||||||
|
fontSize={"sm"}
|
||||||
|
rounded={"sm"}
|
||||||
|
{...field}
|
||||||
|
{...props}
|
||||||
|
placeholder={placeHolder ? placeHolder : label}
|
||||||
|
textAlign={"right"}
|
||||||
|
_placeholder={{ fontSize: "sm" }}
|
||||||
|
maxLength={maxLength}
|
||||||
|
// defaultValue={type === "date" && "2023-07-26" : undefined}
|
||||||
|
// defaultValue={value}
|
||||||
|
// value={dateValue}
|
||||||
|
|
||||||
|
/>
|
||||||
|
);} else{
|
||||||
return (
|
return (
|
||||||
<Input
|
<Input
|
||||||
bg={"#F5F8F6"}
|
bg={"#F5F8F6"}
|
||||||
@@ -474,7 +520,7 @@ const FormField = ({
|
|||||||
placeholder={placeHolder ? placeHolder : label}
|
placeholder={placeHolder ? placeHolder : label}
|
||||||
textAlign={arabic || type === "number" ? "right" : align ? align : "left"}
|
textAlign={arabic || type === "number" ? "right" : align ? align : "left"}
|
||||||
_placeholder={{ fontSize: "sm" }}
|
_placeholder={{ fontSize: "sm" }}
|
||||||
min={type === "date" ? today : undefined}
|
// min={type === "date" ? today : undefined}
|
||||||
maxLength={maxLength}
|
maxLength={maxLength}
|
||||||
// defaultValue={type === "date" && "2023-07-26" : undefined}
|
// defaultValue={type === "date" && "2023-07-26" : undefined}
|
||||||
// value={"2023-07-26"}
|
// value={"2023-07-26"}
|
||||||
@@ -490,7 +536,7 @@ const FormField = ({
|
|||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
{helperText && (
|
{helperText && (
|
||||||
<FormHelperText className="web-text-small">{helperText}</FormHelperText>
|
<FormHelperText color={'gray.500'} className="web-text-small">{helperText}</FormHelperText>
|
||||||
)}
|
)}
|
||||||
{type === "file" && (
|
{type === "file" && (
|
||||||
<FormHelperText className="web-text-small">
|
<FormHelperText className="web-text-small">
|
||||||
|
|||||||
@@ -59,7 +59,8 @@ const FormInputMain = ({
|
|||||||
value,
|
value,
|
||||||
handleInputChange,
|
handleInputChange,
|
||||||
align,
|
align,
|
||||||
maxLength
|
maxLength,
|
||||||
|
dateValue
|
||||||
},
|
},
|
||||||
key
|
key
|
||||||
) => (
|
) => (
|
||||||
@@ -83,10 +84,11 @@ const FormInputMain = ({
|
|||||||
handleImageChange={handleImageChange}
|
handleImageChange={handleImageChange}
|
||||||
removeImage={removeImage}
|
removeImage={removeImage}
|
||||||
width={width}
|
width={width}
|
||||||
value={type === "date" ? null :value}
|
value={value}
|
||||||
handleInputChange={handleInputChange}
|
handleInputChange={handleInputChange}
|
||||||
align={align}
|
align={align}
|
||||||
maxLength={maxLength}
|
maxLength={maxLength}
|
||||||
|
dateValue={dateValue}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -30,16 +30,16 @@ const FormInputView = ({
|
|||||||
<form>
|
<form>
|
||||||
{Object?.entries(groupedFields, groupedFieldsTwo).map(
|
{Object?.entries(groupedFields, groupedFieldsTwo).map(
|
||||||
([section, fields], index) => (
|
([section, fields], index) => (
|
||||||
<Box key={section}>
|
<Box key={index}>
|
||||||
<Heading as="h6" size="xs" mt={index === 0 ? 3 : 4}>
|
<Heading as="h6" size="xs" mt={index === 0 ? 3 : 4}>
|
||||||
{section}
|
{section}
|
||||||
</Heading>
|
</Heading>
|
||||||
{/* <Box display={"flex"} gap={0}> */}
|
{/* <Box display={"flex"} gap={0}> */}
|
||||||
<Box width={"100%"} display={"flex"} flexWrap={"wrap"} gap={4}>
|
<Box key={index} width={"100%"} display={"flex"} flexWrap={"wrap"} gap={4}>
|
||||||
{fields.map(
|
{fields.map(
|
||||||
({ value, label, id, width, btn, arabic, type, align }, key) =>
|
({ value, label, id, width, btn, arabic, type, align }, key) =>
|
||||||
type === "table" ? (
|
type === "table" ? (
|
||||||
<Table w={"100%"} variant="simple">
|
<Table key={id} w={"100%"} variant="simple">
|
||||||
<Thead>
|
<Thead>
|
||||||
<Tr>
|
<Tr>
|
||||||
{value?.map((item, index) => (
|
{value?.map((item, index) => (
|
||||||
@@ -121,7 +121,7 @@ const FormInputView = ({
|
|||||||
</Tbody>
|
</Tbody>
|
||||||
</Table>
|
</Table>
|
||||||
) : (
|
) : (
|
||||||
<Box w={!width ? "49%" : width}>
|
<Box key={id} w={!width ? "49%" : width}>
|
||||||
<FormLabel key={id} color={"gray.500"} fontSize={"xs"}>
|
<FormLabel key={id} color={"gray.500"} fontSize={"xs"}>
|
||||||
{label}
|
{label}
|
||||||
</FormLabel>
|
</FormLabel>
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import { AddIcon } from "@chakra-ui/icons";
|
import { AddIcon, ArrowBackIcon } from "@chakra-ui/icons";
|
||||||
import {
|
import {
|
||||||
Avatar,
|
Avatar,
|
||||||
Box,
|
Box,
|
||||||
Button,
|
Button,
|
||||||
|
HStack,
|
||||||
Popover,
|
Popover,
|
||||||
PopoverArrow,
|
PopoverArrow,
|
||||||
PopoverBody,
|
PopoverBody,
|
||||||
@@ -14,13 +15,14 @@ import {
|
|||||||
useColorMode,
|
useColorMode,
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import React, { useContext } from "react";
|
import React, { useContext } from "react";
|
||||||
import { Link } from "react-router-dom";
|
import { Link, useNavigate } from "react-router-dom";
|
||||||
import { IoMdDownload } from "react-icons/io";
|
import { IoMdDownload } from "react-icons/io";
|
||||||
import * as XLSX from "xlsx";
|
import * as XLSX from "xlsx";
|
||||||
import profile from "../assets/proavatar.webp";
|
import profile from "../assets/proavatar.webp";
|
||||||
import GlobalStateContext from "../Contexts/GlobalStateContext";
|
import GlobalStateContext from "../Contexts/GlobalStateContext";
|
||||||
import { MdOutlineDarkMode, MdOutlineLightMode } from "react-icons/md";
|
import { MdOutlineDarkMode, MdOutlineLightMode } from "react-icons/md";
|
||||||
import logoMini from "../assets/propic.png"
|
import logoMini from "../assets/propic.png"
|
||||||
|
import { BsBack } from "react-icons/bs";
|
||||||
|
|
||||||
const HeaderMain = ({
|
const HeaderMain = ({
|
||||||
link,
|
link,
|
||||||
@@ -30,6 +32,7 @@ const HeaderMain = ({
|
|||||||
logOutHandler,
|
logOutHandler,
|
||||||
slideDirecttion,
|
slideDirecttion,
|
||||||
}) => {
|
}) => {
|
||||||
|
const navigate = useNavigate()
|
||||||
const { colorMode, toggleColorMode } = useContext(GlobalStateContext);
|
const { colorMode, toggleColorMode } = useContext(GlobalStateContext);
|
||||||
|
|
||||||
|
|
||||||
@@ -38,7 +41,12 @@ const HeaderMain = ({
|
|||||||
className={` pt-2 pb-2 fw-400 border-bottom d-flex ${
|
className={` pt-2 pb-2 fw-400 border-bottom d-flex ${
|
||||||
slideDirecttion ? "flex-row-reverse ps-2" : ""
|
slideDirecttion ? "flex-row-reverse ps-2" : ""
|
||||||
} justify-content-between align-items-center`}
|
} justify-content-between align-items-center`}
|
||||||
|
// boxShadow={"0 0px 8px rgba(0, 0, 0, 0.2)"}
|
||||||
|
|
||||||
|
zIndex={999}
|
||||||
>
|
>
|
||||||
|
<HStack>
|
||||||
|
{/* <ArrowBackIcon onClick={()=>navigate(-1)} /> */}
|
||||||
<Text
|
<Text
|
||||||
as={"span"}
|
as={"span"}
|
||||||
fontWeight={"500"}
|
fontWeight={"500"}
|
||||||
@@ -48,6 +56,7 @@ const HeaderMain = ({
|
|||||||
{/* <icon /> */}
|
{/* <icon /> */}
|
||||||
{title}
|
{title}
|
||||||
</Text>
|
</Text>
|
||||||
|
</HStack>
|
||||||
|
|
||||||
|
|
||||||
<Box me={4} gap={2} className="d-flex justify-content-center ">
|
<Box me={4} gap={2} className="d-flex justify-content-center ">
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ const ImageViewer = ({ src, isOpen, onClose }) => {
|
|||||||
rounded={6}
|
rounded={6}
|
||||||
w={"100%"}
|
w={"100%"}
|
||||||
h={"100%"}
|
h={"100%"}
|
||||||
src={"https://tanami.betadelivery.com/" + src}
|
src={import.meta.env.VITE_IMAGE_URL + src}
|
||||||
/>
|
/>
|
||||||
</ModalBody>
|
</ModalBody>
|
||||||
</ModalContent>
|
</ModalContent>
|
||||||
|
|||||||
105
src/Components/Loaders/FullscreenLoaders.css
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
/* From Uiverse.io by abrahamcalsin */
|
||||||
|
.dot-spinner {
|
||||||
|
--uib-size: 2.8rem;
|
||||||
|
--uib-speed: .9s;
|
||||||
|
--uib-color: #004717;
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-start;
|
||||||
|
height: var(--uib-size);
|
||||||
|
width: var(--uib-size);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot-spinner__dot {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-start;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot-spinner__dot::before {
|
||||||
|
content: '';
|
||||||
|
height: 20%;
|
||||||
|
width: 20%;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: var(--uib-color);
|
||||||
|
transform: scale(0);
|
||||||
|
opacity: 0.5;
|
||||||
|
animation: pulse0112 calc(var(--uib-speed) * 1.111) ease-in-out infinite;
|
||||||
|
box-shadow: 0 0 20px rgba(18, 31, 53, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot-spinner__dot:nth-child(2) {
|
||||||
|
transform: rotate(45deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot-spinner__dot:nth-child(2)::before {
|
||||||
|
animation-delay: calc(var(--uib-speed) * -0.875);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot-spinner__dot:nth-child(3) {
|
||||||
|
transform: rotate(90deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot-spinner__dot:nth-child(3)::before {
|
||||||
|
animation-delay: calc(var(--uib-speed) * -0.75);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot-spinner__dot:nth-child(4) {
|
||||||
|
transform: rotate(135deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot-spinner__dot:nth-child(4)::before {
|
||||||
|
animation-delay: calc(var(--uib-speed) * -0.625);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot-spinner__dot:nth-child(5) {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot-spinner__dot:nth-child(5)::before {
|
||||||
|
animation-delay: calc(var(--uib-speed) * -0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot-spinner__dot:nth-child(6) {
|
||||||
|
transform: rotate(225deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot-spinner__dot:nth-child(6)::before {
|
||||||
|
animation-delay: calc(var(--uib-speed) * -0.375);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot-spinner__dot:nth-child(7) {
|
||||||
|
transform: rotate(270deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot-spinner__dot:nth-child(7)::before {
|
||||||
|
animation-delay: calc(var(--uib-speed) * -0.25);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot-spinner__dot:nth-child(8) {
|
||||||
|
transform: rotate(315deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot-spinner__dot:nth-child(8)::before {
|
||||||
|
animation-delay: calc(var(--uib-speed) * -0.125);
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes pulse0112 {
|
||||||
|
0%,
|
||||||
|
100% {
|
||||||
|
transform: scale(0);
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
transform: scale(1);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
import { Box, Spinner, Text } from "@chakra-ui/react";
|
import { Box, Spinner, Text } from "@chakra-ui/react";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
import './FullscreenLoaders.css'
|
||||||
|
|
||||||
const FullscreenLoaders = () => {
|
const FullscreenLoaders = ({height}) => {
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
display={"flex"}
|
display={"flex"}
|
||||||
@@ -9,16 +10,19 @@ const FullscreenLoaders = () => {
|
|||||||
flexDirection={'column'}
|
flexDirection={'column'}
|
||||||
alignItems={"center"}
|
alignItems={"center"}
|
||||||
w={"100%"}
|
w={"100%"}
|
||||||
h={"100vh"}
|
h={height ? height: "100vh"}
|
||||||
gap={4}
|
gap={4}
|
||||||
><Spinner
|
><div className="dot-spinner">
|
||||||
thickness='3px'
|
<div className="dot-spinner__dot"></div>
|
||||||
speed='0.65s'
|
<div className="dot-spinner__dot"></div>
|
||||||
emptyColor='green.100'
|
<div className="dot-spinner__dot"></div>
|
||||||
color='#004717'
|
<div className="dot-spinner__dot"></div>
|
||||||
size='lg'
|
<div className="dot-spinner__dot"></div>
|
||||||
/>
|
<div className="dot-spinner__dot"></div>
|
||||||
<Text color='#004717' fontSize={'md'} fontWeight={500}>Loading...</Text>
|
<div className="dot-spinner__dot"></div>
|
||||||
|
<div className="dot-spinner__dot"></div>
|
||||||
|
</div>
|
||||||
|
{/* <Text color='#004717' fontSize={'md'} fontWeight={500}>Loading...</Text> */}
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,12 +1,18 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
|
import './FullscreenLoaders.css'
|
||||||
|
|
||||||
const Loader01 = () => {
|
const Loader01 = () => {
|
||||||
return (
|
return (
|
||||||
<div className="lds-ellipsis ">
|
|
||||||
<div></div>
|
<div className="dot-spinner">
|
||||||
<div></div>
|
<div className="dot-spinner__dot"></div>
|
||||||
<div></div>
|
<div className="dot-spinner__dot"></div>
|
||||||
<div></div>
|
<div className="dot-spinner__dot"></div>
|
||||||
|
<div className="dot-spinner__dot"></div>
|
||||||
|
<div className="dot-spinner__dot"></div>
|
||||||
|
<div className="dot-spinner__dot"></div>
|
||||||
|
<div className="dot-spinner__dot"></div>
|
||||||
|
<div className="dot-spinner__dot"></div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
460
src/Components/MobileView.jsx
Normal file
@@ -0,0 +1,460 @@
|
|||||||
|
import {
|
||||||
|
Box,
|
||||||
|
Button,
|
||||||
|
Heading,
|
||||||
|
HStack,
|
||||||
|
Image,
|
||||||
|
Modal,
|
||||||
|
ModalContent,
|
||||||
|
ModalFooter,
|
||||||
|
ModalHeader,
|
||||||
|
ModalOverlay,
|
||||||
|
Progress,
|
||||||
|
Spinner,
|
||||||
|
Stack,
|
||||||
|
Text,
|
||||||
|
} from "@chakra-ui/react";
|
||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import Mobile from "../assets/mobileWing.png";
|
||||||
|
import mobileBanner from "../assets/welcome.avif";
|
||||||
|
import { GrDownload } from "react-icons/gr";
|
||||||
|
import { LuClock } from "react-icons/lu";
|
||||||
|
import { GiNetworkBars } from "react-icons/gi";
|
||||||
|
import { GrLinkedinOption } from "react-icons/gr";
|
||||||
|
import { FiInstagram } from "react-icons/fi";
|
||||||
|
import { IoBatteryHalf } from "react-icons/io5";
|
||||||
|
import { BiWifi } from "react-icons/bi";
|
||||||
|
import { useGetIOByIdQuery } from "../Services/io.service";
|
||||||
|
import { useNavigate, useParams } from "react-router-dom";
|
||||||
|
import FullscreenLoaders from "./Loaders/FullscreenLoaders";
|
||||||
|
import { formatDate } from "../Constants/Constants";
|
||||||
|
import { BsFileText } from "react-icons/bs";
|
||||||
|
|
||||||
|
const MobileView = ({ isOpen, onClose, finalRef, actionId }) => {
|
||||||
|
const [time, setTime] = useState(new Date());
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const params = useParams();
|
||||||
|
const id = actionId;
|
||||||
|
|
||||||
|
const {
|
||||||
|
data: IObyID,
|
||||||
|
isLoading: IObyIDisLoading,
|
||||||
|
error: IObyIDerror,
|
||||||
|
} = useGetIOByIdQuery(id, { skip: !id });
|
||||||
|
|
||||||
|
console.log(IObyID);
|
||||||
|
|
||||||
|
const keyMerits = IObyID?.data?.keyMerits || [];
|
||||||
|
const artifactsImage = IObyID?.data?.artifactsImage || [];
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const timer = setInterval(() => {
|
||||||
|
setTime(new Date());
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
return () => clearInterval(timer);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const formatTime = (date) => {
|
||||||
|
return date.toLocaleTimeString([], {
|
||||||
|
hour: "2-digit",
|
||||||
|
minute: "2-digit",
|
||||||
|
hour12: true,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
display={"flex"}
|
||||||
|
size={"xl"}
|
||||||
|
justifyContent={"center"}
|
||||||
|
isCentered
|
||||||
|
finalFocusRef={finalRef}
|
||||||
|
isOpen={isOpen}
|
||||||
|
onClose={onClose}
|
||||||
|
>
|
||||||
|
<ModalOverlay
|
||||||
|
backdropFilter="blur(5px)" // Add this line for backdrop blur
|
||||||
|
bg="rgba(0, 0, 0, 0.4)" // Optional: Adjust the overlay color and opacity
|
||||||
|
/>
|
||||||
|
<ModalContent backgroundColor={"transparent"} shadow={"none"}>
|
||||||
|
<HStack w={"100"} display={"flex"} justify={"center"}>
|
||||||
|
<Box
|
||||||
|
as="span"
|
||||||
|
boxShadow={"none"}
|
||||||
|
position={"relative"}
|
||||||
|
display={"flex"}
|
||||||
|
justifyContent={"center"}
|
||||||
|
h={"600px"}
|
||||||
|
w={"320px"}
|
||||||
|
sx={{
|
||||||
|
"@media (max-width: 2024px)": {
|
||||||
|
height:"695px",
|
||||||
|
width:"360px",
|
||||||
|
},
|
||||||
|
"@media (max-width: 1440px)": {
|
||||||
|
height:"600px",
|
||||||
|
width:"320px",
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Image
|
||||||
|
h={"100%"}
|
||||||
|
w={"100%"}
|
||||||
|
src={Mobile}
|
||||||
|
position={"absolute"}
|
||||||
|
top={"0"}
|
||||||
|
left={"0"}
|
||||||
|
/>
|
||||||
|
<Box
|
||||||
|
backgroundColor={"#fff"}
|
||||||
|
h={"98%"}
|
||||||
|
w={"96%"}
|
||||||
|
// m={2}
|
||||||
|
borderRadius={"47px"}
|
||||||
|
pt={"36px"}
|
||||||
|
px={"15px"}
|
||||||
|
>
|
||||||
|
{IObyIDisLoading ? (
|
||||||
|
<Box
|
||||||
|
display={"flex"}
|
||||||
|
justifyContent={"center"}
|
||||||
|
alignItems={"center"}
|
||||||
|
h={"100%"}
|
||||||
|
>
|
||||||
|
<Spinner
|
||||||
|
thickness='3px'
|
||||||
|
color='purple.900'
|
||||||
|
size='lg'
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<Box>
|
||||||
|
<Box
|
||||||
|
display={"flex"}
|
||||||
|
alignItems={"center"}
|
||||||
|
position={"absolute"}
|
||||||
|
left={"30px"}
|
||||||
|
top={"18px"}
|
||||||
|
>
|
||||||
|
<Text ml={1} mb={0}>
|
||||||
|
<GiNetworkBars fontSize={"10px"} />
|
||||||
|
</Text>
|
||||||
|
<Text ml={1} mb={0} fontSize={"10px"}>
|
||||||
|
{formatTime(time)}
|
||||||
|
</Text>
|
||||||
|
<Text ml={"5px"} mb={0}>
|
||||||
|
<GrLinkedinOption fontSize={"10px"} />
|
||||||
|
</Text>
|
||||||
|
{/* <Text ml={1} mb={0}><FiInstagram fontSize={"10px"} /></Text> */}
|
||||||
|
</Box>
|
||||||
|
<Box
|
||||||
|
display={"flex"}
|
||||||
|
alignItems={"center"}
|
||||||
|
position={"absolute"}
|
||||||
|
right={"36px"}
|
||||||
|
top={"17px"}
|
||||||
|
>
|
||||||
|
<Text mb={0}>
|
||||||
|
<BiWifi fontSize={"14px"} />
|
||||||
|
</Text>
|
||||||
|
<Text ml={1} mb={0}>
|
||||||
|
<IoBatteryHalf fontSize={"15px"} />
|
||||||
|
</Text>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
<Box
|
||||||
|
p={"10px"}
|
||||||
|
overflowY={"scroll"}
|
||||||
|
h={"483px"}
|
||||||
|
zIndex={"99"}
|
||||||
|
position={"relative"}
|
||||||
|
borderBottomLeftRadius={"23px"}
|
||||||
|
borderBottomRightRadius={"23px"}
|
||||||
|
sx={{
|
||||||
|
"@media (max-width: 2024px)": {
|
||||||
|
height:"575px",
|
||||||
|
},
|
||||||
|
"@media (max-width: 1440px)": {
|
||||||
|
height:"483px",
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Box
|
||||||
|
mb={4}
|
||||||
|
bg={"#f5f8f6"}
|
||||||
|
borderRadius={"20px"}
|
||||||
|
boxShadow={"rgba(0, 0, 0, 0.15) 0px 2px 8px"}
|
||||||
|
>
|
||||||
|
<Box position={"relative"}>
|
||||||
|
<Text
|
||||||
|
position={"absolute"}
|
||||||
|
top={"12px"}
|
||||||
|
left={"10px"}
|
||||||
|
backgroundColor={"#e4f6ea"}
|
||||||
|
fontSize={"10px"}
|
||||||
|
fontWeight={500}
|
||||||
|
color="green"
|
||||||
|
p={"7px 12px"}
|
||||||
|
borderRadius={"20px"}
|
||||||
|
>
|
||||||
|
Stock
|
||||||
|
</Text>
|
||||||
|
<Text
|
||||||
|
position={"absolute"}
|
||||||
|
top={"12px"}
|
||||||
|
right={"10px"}
|
||||||
|
fontSize={"10px"}
|
||||||
|
display={"flex"}
|
||||||
|
alignItems={"center"}
|
||||||
|
fontWeight={500}
|
||||||
|
backgroundColor={"#fff"}
|
||||||
|
p={"7px 12px"}
|
||||||
|
borderRadius={"20px"}
|
||||||
|
>
|
||||||
|
<LuClock color="#d8804e" />{" "}
|
||||||
|
<Text mb={0} ml={1}>
|
||||||
|
Closing Date {formatDate(IObyID?.data?.closingDate)}
|
||||||
|
</Text>
|
||||||
|
</Text>
|
||||||
|
{artifactsImage?.[0]?.artifactPathName && (
|
||||||
|
<Image
|
||||||
|
borderTopLeftRadius={"20px"}
|
||||||
|
borderTopRightRadius={"20px"}
|
||||||
|
h={"130px"}
|
||||||
|
w={"100%"}
|
||||||
|
src={
|
||||||
|
"https://tanami.betadelivery.com/" +
|
||||||
|
artifactsImage[0]?.artifactPathName
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
<Stack mt="3" bg={"#fff"} py={4} px={4}>
|
||||||
|
<Text
|
||||||
|
fontSize={"sm"}
|
||||||
|
fontWeight={"500"}
|
||||||
|
color={"#000"}
|
||||||
|
mb={0}
|
||||||
|
>
|
||||||
|
{IObyID?.data?.investmentType?.investmentTypeName}
|
||||||
|
</Text>
|
||||||
|
<Heading fontSize="16px" color={"#004717"}>
|
||||||
|
BHD {IObyID?.data?.goalAmount}
|
||||||
|
</Heading>
|
||||||
|
<Progress
|
||||||
|
colorScheme="green"
|
||||||
|
size="sm"
|
||||||
|
value={20}
|
||||||
|
borderRadius={"3px"}
|
||||||
|
/>
|
||||||
|
<Text
|
||||||
|
color={"#4e4e4e"}
|
||||||
|
fontSize={"xs"}
|
||||||
|
fontWeight={600}
|
||||||
|
mb={0}
|
||||||
|
>
|
||||||
|
0.0% funded
|
||||||
|
</Text>
|
||||||
|
<Text
|
||||||
|
fontSize={"xs"}
|
||||||
|
fontWeight={500}
|
||||||
|
mb={0}
|
||||||
|
color={"#9d9d9d"}
|
||||||
|
>
|
||||||
|
{IObyID?.data?.descriptionEnglish}
|
||||||
|
</Text>
|
||||||
|
</Stack>
|
||||||
|
<Box py={4} px={4}>
|
||||||
|
<Box display={"flex"} justifyContent={"space-between"}>
|
||||||
|
<Text
|
||||||
|
fontSize={"xs"}
|
||||||
|
mb={1}
|
||||||
|
fontWeight={500}
|
||||||
|
color={"#616161"}
|
||||||
|
>
|
||||||
|
Sponsor name:
|
||||||
|
</Text>
|
||||||
|
<Text fontSize={"xs"} mb={1} fontWeight={500}>
|
||||||
|
{IObyID?.data?.sponsor?.sponsorName}
|
||||||
|
</Text>
|
||||||
|
</Box>
|
||||||
|
<Box display={"flex"} justifyContent={"space-between"}>
|
||||||
|
<Text
|
||||||
|
fontSize={"xs"}
|
||||||
|
mb={1}
|
||||||
|
fontWeight={500}
|
||||||
|
color={"#616161"}
|
||||||
|
>
|
||||||
|
Estimated return:
|
||||||
|
</Text>
|
||||||
|
<Text fontSize={"xs"} mb={1} fontWeight={500}>
|
||||||
|
{IObyID?.data?.expectedReturn}
|
||||||
|
</Text>
|
||||||
|
</Box>
|
||||||
|
<Box display={"flex"} justifyContent={"space-between"}>
|
||||||
|
<Text
|
||||||
|
fontSize={"xs"}
|
||||||
|
mb={1}
|
||||||
|
fontWeight={500}
|
||||||
|
color={"#616161"}
|
||||||
|
>
|
||||||
|
Hoiding period:
|
||||||
|
</Text>
|
||||||
|
<Text fontSize={"xs"} mb={1} fontWeight={500}>
|
||||||
|
{IObyID?.data?.holdingPeriod}
|
||||||
|
</Text>
|
||||||
|
</Box>
|
||||||
|
<Box display={"flex"} justifyContent={"space-between"}>
|
||||||
|
<Text
|
||||||
|
fontSize={"xs"}
|
||||||
|
mb={1}
|
||||||
|
fontWeight={500}
|
||||||
|
color={"#616161"}
|
||||||
|
>
|
||||||
|
Minimum investment:
|
||||||
|
</Text>
|
||||||
|
<Text fontSize={"xs"} mb={1} fontWeight={500}>
|
||||||
|
{
|
||||||
|
IObyID?.data?.minInvestmentAmt?.[0]?.country
|
||||||
|
?.minInvestmentAmt
|
||||||
|
}
|
||||||
|
</Text>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
<Box
|
||||||
|
mb={4}
|
||||||
|
p={5}
|
||||||
|
bg={"#f5f8f6"}
|
||||||
|
borderRadius={"20px"}
|
||||||
|
boxShadow={"rgba(0, 0, 0, 0.15) 0px 2px 8px"}
|
||||||
|
>
|
||||||
|
<Heading fontSize="14px" fontWeight={600}>
|
||||||
|
Key Merits
|
||||||
|
</Heading>
|
||||||
|
<Box display={"flex"} alignItems={"center"}>
|
||||||
|
{keyMerits?.[0]?.icon?.iconFilePath && (
|
||||||
|
<Image
|
||||||
|
rounded={"md"}
|
||||||
|
display={"flex"}
|
||||||
|
p={1}
|
||||||
|
justifyContent={"center"}
|
||||||
|
alignItems={"center"}
|
||||||
|
src={
|
||||||
|
"https://tanami.betadelivery.com/" +
|
||||||
|
keyMerits[0].icon.iconFilePath
|
||||||
|
}
|
||||||
|
w={8}
|
||||||
|
h={8}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<Text fontSize={"xs"} mb={0}>
|
||||||
|
{IObyID?.data?.keyMerits[0]?.meritsDescription}
|
||||||
|
</Text>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
<Box
|
||||||
|
mb={4}
|
||||||
|
p={5}
|
||||||
|
borderRadius={"20px"}
|
||||||
|
boxShadow={"rgba(0, 0, 0, 0.15) 0px 2px 8px"}
|
||||||
|
>
|
||||||
|
<Heading fontSize="14px" fontWeight={600}>
|
||||||
|
Investment Documents
|
||||||
|
</Heading>
|
||||||
|
<Box
|
||||||
|
bg={"#f5f8f6"}
|
||||||
|
w={"150px"}
|
||||||
|
p={3}
|
||||||
|
borderRadius={"10px"}
|
||||||
|
>
|
||||||
|
<Box display={"flex"} alignItems={"center"} mb={2}>
|
||||||
|
{/* <Image
|
||||||
|
me={1}
|
||||||
|
src="https://tanami.betadelivery.com/public/icons/icon8.svg"
|
||||||
|
/> */}
|
||||||
|
<BsFileText color="forestGreen" fontSize="18px" />
|
||||||
|
<Text fontSize={"xs"} mb={0} ml={2}>
|
||||||
|
{IObyID?.data?.documents?.[0]?.documentName}
|
||||||
|
</Text>
|
||||||
|
</Box>
|
||||||
|
<Box
|
||||||
|
display={"flex"}
|
||||||
|
alignItems={"center"}
|
||||||
|
justifyContent={"space-between"}
|
||||||
|
>
|
||||||
|
<Text mb={0} fontSize={"sm"}>
|
||||||
|
{IObyID?.data?.documents?.[0]?.documentSize}
|
||||||
|
</Text>
|
||||||
|
<GrDownload fontSize={"15px"} />
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
<Box
|
||||||
|
mb={4}
|
||||||
|
p={4}
|
||||||
|
borderRadius={"20px"}
|
||||||
|
boxShadow={"rgba(0, 0, 0, 0.15) 0px 2px 8px"}
|
||||||
|
>
|
||||||
|
<Heading fontSize="14px" fontWeight={600}>
|
||||||
|
Videos
|
||||||
|
</Heading>
|
||||||
|
<video
|
||||||
|
autoPlay
|
||||||
|
loop
|
||||||
|
controls
|
||||||
|
style={{
|
||||||
|
borderRadius: "18px",
|
||||||
|
width: "100%",
|
||||||
|
height: "auto",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<source
|
||||||
|
src={
|
||||||
|
IObyID?.data?.artifactsVideo?.[0]
|
||||||
|
?.artifactStreamingURL
|
||||||
|
}
|
||||||
|
type="video/mp4"
|
||||||
|
style={{ height: "200px" }}
|
||||||
|
/>
|
||||||
|
Your browser does not support the video tag.
|
||||||
|
</video>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
<Box
|
||||||
|
position={"relative"}
|
||||||
|
p={4}
|
||||||
|
background={"#fff"}
|
||||||
|
padding={"24px"}
|
||||||
|
paddingBottom={"3px"}
|
||||||
|
borderBottomLeftRadius={"30px"}
|
||||||
|
borderBottomRightRadius="30px"
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
margin={"auto"}
|
||||||
|
width={"85%"}
|
||||||
|
bottom="10px"
|
||||||
|
left="0"
|
||||||
|
colorScheme="forestGreen"
|
||||||
|
mr={3}
|
||||||
|
w={"100%"}
|
||||||
|
fontWeight={500}
|
||||||
|
borderRadius={"20px"}
|
||||||
|
>
|
||||||
|
Invest
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
</HStack>
|
||||||
|
</ModalContent>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default MobileView;
|
||||||
@@ -1,9 +1,18 @@
|
|||||||
import { Box, Text } from '@chakra-ui/react';
|
import { Box, Text } from "@chakra-ui/react";
|
||||||
import React from 'react';
|
import React, { useRef } from "react";
|
||||||
|
import audioClick from "../assets/click-151673.mp3";
|
||||||
|
|
||||||
const SwitchButton = ({ isSwitchOn, setIsSwitchOn }) => {
|
const SwitchButton = ({ isSwitchOn, setIsSwitchOn }) => {
|
||||||
|
|
||||||
|
// const [isSwitchOn, setIsSwitchOn] = useState(false);
|
||||||
|
|
||||||
|
const audio = useRef();
|
||||||
|
|
||||||
const switch_onChange_handle = () => {
|
const switch_onChange_handle = () => {
|
||||||
setIsSwitchOn(!isSwitchOn);
|
setIsSwitchOn(!isSwitchOn);
|
||||||
|
if (audio.current) {
|
||||||
|
audio.current.play();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -15,7 +24,7 @@ const SwitchButton = ({ isSwitchOn, setIsSwitchOn }) => {
|
|||||||
alignItems="center"
|
alignItems="center"
|
||||||
// justifyContent={isSwitchOn ? "flex-end" : "flex-start"}
|
// justifyContent={isSwitchOn ? "flex-end" : "flex-start"}
|
||||||
width="90px"
|
width="90px"
|
||||||
height="24px"
|
height="25px"
|
||||||
borderRadius="20px"
|
borderRadius="20px"
|
||||||
backgroundColor={isSwitchOn ? "#004118" : "#ef0000"}
|
backgroundColor={isSwitchOn ? "#004118" : "#ef0000"}
|
||||||
onClick={switch_onChange_handle}
|
onClick={switch_onChange_handle}
|
||||||
@@ -24,16 +33,28 @@ const SwitchButton = ({ isSwitchOn, setIsSwitchOn }) => {
|
|||||||
fontWeight="100"
|
fontWeight="100"
|
||||||
transition="background-color 0.2s"
|
transition="background-color 0.2s"
|
||||||
_before={{
|
_before={{
|
||||||
|
// content: '""',
|
||||||
|
// position: "absolute",
|
||||||
|
// width: "20px",
|
||||||
|
// height: "20px",
|
||||||
|
// borderRadius: "50%",
|
||||||
|
// backgroundColor: "#FFF",
|
||||||
|
// boxShadow: "0 2px 4px rgba(0, 0, 0, 0.2)",
|
||||||
|
// transform: isSwitchOn ? "translateX(65px)" : "translateX(0)",
|
||||||
|
// transition: "transform 0.2s",
|
||||||
|
// left:'2px'
|
||||||
|
|
||||||
content: '""',
|
content: '""',
|
||||||
position: "absolute",
|
position: "absolute",
|
||||||
width: "20px",
|
height: "25px",
|
||||||
height: "20px",
|
width: "25px",
|
||||||
|
left: "0px",
|
||||||
|
background:
|
||||||
|
"conic-gradient(rgb(104, 104, 104), white, rgb(104, 104, 104), white, rgb(104, 104, 104))",
|
||||||
borderRadius: "50%",
|
borderRadius: "50%",
|
||||||
backgroundColor: "#FFF",
|
transitionDuration: ".3s",
|
||||||
boxShadow: "0 2px 4px rgba(0, 0, 0, 0.2)",
|
boxShadow: " 5px 2px 7px rgba(8, 8, 8, 0.308)",
|
||||||
transform: isSwitchOn ? "translateX(65px)" : "translateX(0)",
|
transform: isSwitchOn ? "translateX(65px)" : "translateX(0)",
|
||||||
transition: "transform 0.2s",
|
|
||||||
left:'2px'
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Text
|
<Text
|
||||||
@@ -46,9 +67,10 @@ const SwitchButton = ({ isSwitchOn, setIsSwitchOn }) => {
|
|||||||
left={isSwitchOn ? "10px" : "auto"}
|
left={isSwitchOn ? "10px" : "auto"}
|
||||||
right={isSwitchOn ? "auto" : "10px"}
|
right={isSwitchOn ? "auto" : "10px"}
|
||||||
>
|
>
|
||||||
{isSwitchOn ? 'Active' : 'InActive'}
|
{isSwitchOn ? "Active" : "InActive"}
|
||||||
</Text>
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
|
<audio ref={audio} src={audioClick} />
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
BIN
src/Components/mobileWing.png
Normal file
|
After Width: | Height: | Size: 7.3 KiB |
@@ -1,6 +1,77 @@
|
|||||||
|
|
||||||
import dns from "node:dns"
|
import dns from "node:dns"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export function getTomorrowDate() {
|
||||||
|
const today = new Date();
|
||||||
|
const tomorrow = new Date(today);
|
||||||
|
tomorrow.setDate(today.getDate() + 1);
|
||||||
|
|
||||||
|
// Format the date as YYYY-MM-DD (ISO 8601)
|
||||||
|
return tomorrow.toISOString().split('T')[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function removeTrailingZeros(value) {
|
||||||
|
// Convert the value to a number and then to a string
|
||||||
|
let number = parseFloat(value);
|
||||||
|
let result = number.toString();
|
||||||
|
|
||||||
|
// Check if the result contains a decimal point
|
||||||
|
if (result.includes('.')) {
|
||||||
|
// Remove trailing zeros if the decimal part is 0 or 00
|
||||||
|
result = result.replace(/(\.\d*?)0+$/, '$1'); // Remove trailing zeros
|
||||||
|
result = result.replace(/\.$/, ''); // Remove the decimal point if it's the last character
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function getCountdownTimer(utcDateString) {
|
||||||
|
// Parse the UTC datetime string into a Date object
|
||||||
|
const targetDate = new Date(utcDateString);
|
||||||
|
const now = new Date();
|
||||||
|
|
||||||
|
// Calculate the difference in milliseconds
|
||||||
|
const difference = targetDate - now;
|
||||||
|
|
||||||
|
if (difference <= 0) {
|
||||||
|
return 'The time has passed or is now!';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert the difference from milliseconds to a more readable format
|
||||||
|
const seconds = Math.floor(difference / 1000);
|
||||||
|
const minutes = Math.floor(seconds / 60);
|
||||||
|
const hours = Math.floor(minutes / 60);
|
||||||
|
const days = Math.floor(hours / 24);
|
||||||
|
|
||||||
|
const remainingDays = days;
|
||||||
|
const remainingHours = hours % 24;
|
||||||
|
const remainingMinutes = minutes % 60;
|
||||||
|
const remainingSeconds = seconds % 60;
|
||||||
|
|
||||||
|
return `${remainingDays === 0 ? "": remainingDays+"d"} ${remainingHours === 0 ? "": remainingHours+"h"} ${remainingMinutes}m `;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export function startCountdown(utcDateString) {
|
||||||
|
// Function to update the countdown
|
||||||
|
const updateCountdown = () => {
|
||||||
|
const countdown = getCountdownTimer(utcDateString);
|
||||||
|
console.log(countdown);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Update countdown immediately
|
||||||
|
updateCountdown();
|
||||||
|
|
||||||
|
// Set up interval to update countdown every minute (60000 milliseconds)
|
||||||
|
setInterval(updateCountdown, 60000);
|
||||||
|
}
|
||||||
|
|
||||||
export const getFileNameFromPath = (filePath) => {
|
export const getFileNameFromPath = (filePath) => {
|
||||||
const parts = filePath?.split("/");
|
const parts = filePath?.split("/");
|
||||||
return parts?.[parts?.length - 1];
|
return parts?.[parts?.length - 1];
|
||||||
@@ -42,3 +113,27 @@ export async function checkEmailValidity(email) {
|
|||||||
return false; // Error occurred
|
return false; // Error occurred
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Function to convert timestamp to readable date format in Gulf timezone
|
||||||
|
export function formatTimestampInGulfTimezone(timestamp) {
|
||||||
|
const date = new Date(timestamp);
|
||||||
|
const options = {
|
||||||
|
year: 'numeric',
|
||||||
|
month: 'long',
|
||||||
|
day: 'numeric',
|
||||||
|
hour: '2-digit',
|
||||||
|
minute: '2-digit',
|
||||||
|
second: '2-digit',
|
||||||
|
timeZone: 'Asia/Dubai', // Gulf Standard Time (GST) timezone
|
||||||
|
timeZoneName: 'short'
|
||||||
|
};
|
||||||
|
return date.toLocaleDateString('en-GB', options);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function formatDate(dateString) {
|
||||||
|
const options = { year: 'numeric', month: 'short', day: 'numeric' };
|
||||||
|
const date = new Date(dateString);
|
||||||
|
return date.toLocaleDateString('en-US', options);
|
||||||
|
}
|
||||||
@@ -46,7 +46,6 @@ const GlobalStateProvider = ({ children }) => {
|
|||||||
const [slideFromRight, setSlideFormRight] = useState(false);
|
const [slideFromRight, setSlideFormRight] = useState(false);
|
||||||
const { colorMode, toggleColorMode } = useColorMode();
|
const { colorMode, toggleColorMode } = useColorMode();
|
||||||
const [sponser, setSponser] = useState([]);
|
const [sponser, setSponser] = useState([]);
|
||||||
const [ioStatus, setIoStatus] = useState([]);
|
|
||||||
|
|
||||||
const [investors, setInvestors] = useState([
|
const [investors, setInvestors] = useState([
|
||||||
{
|
{
|
||||||
@@ -1450,7 +1449,6 @@ const GlobalStateProvider = ({ children }) => {
|
|||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const [IODetails, setIODetails] = useState({});
|
|
||||||
|
|
||||||
const [depositRequest, setDepositRequest] = useState([
|
const [depositRequest, setDepositRequest] = useState([
|
||||||
{
|
{
|
||||||
@@ -1724,6 +1722,17 @@ const GlobalStateProvider = ({ children }) => {
|
|||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ==============[ prod state ]===============================
|
||||||
|
const [IODetails, setIODetails] = useState(null);
|
||||||
|
const [ isIOloading, setIOloading ] = useState(false)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<GlobalStateContext.Provider
|
<GlobalStateContext.Provider
|
||||||
value={{
|
value={{
|
||||||
@@ -1795,8 +1804,10 @@ const GlobalStateProvider = ({ children }) => {
|
|||||||
setAcademicDocuments,
|
setAcademicDocuments,
|
||||||
iOArtifactsTwo,
|
iOArtifactsTwo,
|
||||||
setIOArtifactsTwo,
|
setIOArtifactsTwo,
|
||||||
ioStatus,
|
|
||||||
setIoStatus,
|
|
||||||
|
isIOloading,
|
||||||
|
setIOloading
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ import shield from "../assets/shield.png";
|
|||||||
import SplashScreen from "../Pages/SplashScreen";
|
import SplashScreen from "../Pages/SplashScreen";
|
||||||
import CutomBreadcrumb from "../Components/CutomBreadcrumb";
|
import CutomBreadcrumb from "../Components/CutomBreadcrumb";
|
||||||
import CustomBreadcrumb from "../Components/CutomBreadcrumb";
|
import CustomBreadcrumb from "../Components/CutomBreadcrumb";
|
||||||
|
import { getCountdownTimer } from "../Constants/Constants";
|
||||||
|
|
||||||
const DashboardLayout = ({ isOnline }) => {
|
const DashboardLayout = ({ isOnline }) => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@@ -107,7 +108,7 @@ const DashboardLayout = ({ isOnline }) => {
|
|||||||
// Set a timer to hide the splash screen after 3 seconds
|
// Set a timer to hide the splash screen after 3 seconds
|
||||||
const timer = setTimeout(() => {
|
const timer = setTimeout(() => {
|
||||||
setSplashVisible(false);
|
setSplashVisible(false);
|
||||||
},300); // 3000ms = 3 seconds
|
},1000); // 3000ms = 3 seconds
|
||||||
|
|
||||||
// Cleanup the timer
|
// Cleanup the timer
|
||||||
return () => clearTimeout(timer);
|
return () => clearTimeout(timer);
|
||||||
@@ -121,6 +122,9 @@ const DashboardLayout = ({ isOnline }) => {
|
|||||||
// dispach(loginUser(false));
|
// dispach(loginUser(false));
|
||||||
setIsAuthenticate(false);
|
setIsAuthenticate(false);
|
||||||
Cookies.remove("isAuthenticated");
|
Cookies.remove("isAuthenticated");
|
||||||
|
localStorage.removeItem('refreshToken')
|
||||||
|
localStorage.removeItem('accessToken')
|
||||||
|
localStorage.removeItem('refreshTokenExp')
|
||||||
navigate("/login");
|
navigate("/login");
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -132,7 +136,7 @@ const DashboardLayout = ({ isOnline }) => {
|
|||||||
case path.startsWith("/sponser"):
|
case path.startsWith("/sponser"):
|
||||||
return (
|
return (
|
||||||
<span className="d-flex align-items-end gap-2">
|
<span className="d-flex align-items-end gap-2">
|
||||||
<RiMoneyDollarBoxLine className="h4 m-0" /> Sponsorer
|
<RiMoneyDollarBoxLine className="h4 m-0" /> Sponsor
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
case path.startsWith("/investment-type"):
|
case path.startsWith("/investment-type"):
|
||||||
@@ -184,6 +188,30 @@ const DashboardLayout = ({ isOnline }) => {
|
|||||||
Investor Transactions
|
Investor Transactions
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
case path.startsWith("/deposit-request"):
|
||||||
|
return (
|
||||||
|
<span className="d-flex align-items-end gap-2">
|
||||||
|
<RiMoneyDollarBoxLine className="h4 m-0 fw-normal" />
|
||||||
|
Deposite pending request
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
case path.startsWith("/deposit-history"):
|
||||||
|
return (
|
||||||
|
<span className="d-flex align-items-end gap-2">
|
||||||
|
<RiExchangeBoxLine className="h4 m-0 fw-normal" />
|
||||||
|
Deposite withdrawal request
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
case path.startsWith("/withdraw-request"):
|
case path.startsWith("/withdraw-request"):
|
||||||
return (
|
return (
|
||||||
<span className="d-flex align-items-end gap-2">
|
<span className="d-flex align-items-end gap-2">
|
||||||
@@ -387,7 +415,7 @@ const DashboardLayout = ({ isOnline }) => {
|
|||||||
// onMouseOver={() => setIsDrawerOpen(true)}
|
// onMouseOver={() => setIsDrawerOpen(true)}
|
||||||
// onMouseLeave={() => setIsDrawerOpen(false)}
|
// onMouseLeave={() => setIsDrawerOpen(false)}
|
||||||
style={{
|
style={{
|
||||||
width: isDrawerOpen || openDrawerClick ? 232 : 74,
|
width: isDrawerOpen || openDrawerClick ? 230 : 74,
|
||||||
transition: "width 0.3s ease-in-out", // Smooth transition for width change
|
transition: "width 0.3s ease-in-out", // Smooth transition for width change
|
||||||
// overflow: "hidden",
|
// overflow: "hidden",
|
||||||
backgroundColor: "#0041180A",
|
backgroundColor: "#0041180A",
|
||||||
@@ -400,16 +428,18 @@ const DashboardLayout = ({ isOnline }) => {
|
|||||||
isDrawerOpen || openDrawerClick
|
isDrawerOpen || openDrawerClick
|
||||||
? "justify-content-start"
|
? "justify-content-start"
|
||||||
: "justify-content-center"
|
: "justify-content-center"
|
||||||
} p-3 pt-3 pb-4 position-relative `}
|
} p-3 pt-3 pb-3 position-relative `}
|
||||||
height={"10%"}
|
height={"10%"}
|
||||||
>
|
>
|
||||||
{isDrawerOpen || openDrawerClick ? (
|
{isDrawerOpen || openDrawerClick ? (
|
||||||
<Image
|
<Image
|
||||||
style={{
|
style={{
|
||||||
width: 120,
|
width: 110,
|
||||||
}}
|
}}
|
||||||
src={colorMode === "light" ? logo : logoDark}
|
src={colorMode === "light" ? logo : logoDark}
|
||||||
alt="Logo"
|
alt="Logo"
|
||||||
|
onClick={()=> navigate('/')}
|
||||||
|
cursor={"pointer"}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<Image
|
<Image
|
||||||
@@ -418,12 +448,14 @@ const DashboardLayout = ({ isOnline }) => {
|
|||||||
}}
|
}}
|
||||||
src={colorMode === "light" ? logoMini : logoMiniDark}
|
src={colorMode === "light" ? logoMini : logoMiniDark}
|
||||||
alt="Logo"
|
alt="Logo"
|
||||||
|
onClick={()=> navigate('/')}
|
||||||
|
cursor={"pointer"}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Box
|
<Box
|
||||||
className="ps-2 scroll-bar pe-1"
|
className="ps-2 scroll-bar pe-1 pt-3"
|
||||||
style={{
|
style={{
|
||||||
height: "90%",
|
height: "90%",
|
||||||
overflowY: "scroll",
|
overflowY: "scroll",
|
||||||
@@ -594,7 +626,7 @@ const DashboardLayout = ({ isOnline }) => {
|
|||||||
</Accordion>
|
</Accordion>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<Button
|
{/* <Button
|
||||||
colorScheme={"forestGreen"}
|
colorScheme={"forestGreen"}
|
||||||
rounded={"lg"}
|
rounded={"lg"}
|
||||||
// onMouseOver={() => setIsDrawerOpen(true)}
|
// onMouseOver={() => setIsDrawerOpen(true)}
|
||||||
@@ -614,20 +646,16 @@ const DashboardLayout = ({ isOnline }) => {
|
|||||||
) : (
|
) : (
|
||||||
<ArrowRightIcon className="web-text-small " />
|
<ArrowRightIcon className="web-text-small " />
|
||||||
)}
|
)}
|
||||||
</Button>
|
</Button> */}
|
||||||
|
<Text textAlign={'center'} fontWeight={500} fontSize={'xs'} color={"gray.600"}>{getCountdownTimer(localStorage.getItem('accessTokenExp'))}</Text>
|
||||||
|
|
||||||
<Box
|
|
||||||
id="google_translate_element"
|
|
||||||
display="block"
|
|
||||||
className="bg-danger"
|
|
||||||
/>
|
|
||||||
</aside>
|
</aside>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<main
|
<main
|
||||||
className={`h-100 ${slideFromRight ? "pe-3" : "ps-3"} d-flex flex-column gap-0`}
|
className={`h-100 ${slideFromRight ? "pe-3" : "ps-3"} d-flex flex-column gap-0`}
|
||||||
style={{
|
style={{
|
||||||
width: `calc(100% - ${isDrawerOpen || openDrawerClick ? 232 : 74}px)`,
|
width: `calc(100% - ${isDrawerOpen || openDrawerClick ? 230 : 74}px)`,
|
||||||
transition: "width 0.3s ease-in-out",
|
transition: "width 0.3s ease-in-out",
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -64,7 +64,6 @@ const BankDetails = () => {
|
|||||||
error,
|
error,
|
||||||
} = useGetBankQuery({ page: 1, size: 10 });
|
} = useGetBankQuery({ page: 1, size: 10 });
|
||||||
|
|
||||||
console.log(bankDetails?.data);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Simulate loading
|
// Simulate loading
|
||||||
@@ -116,7 +115,6 @@ const BankDetails = () => {
|
|||||||
return nameMatches;
|
return nameMatches;
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(bankDetails);
|
|
||||||
|
|
||||||
const extractedArray = filteredData?.map((item) => ({
|
const extractedArray = filteredData?.map((item) => ({
|
||||||
id: item?.id,
|
id: item?.id,
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import {
|
|||||||
Textarea,
|
Textarea,
|
||||||
Button,
|
Button,
|
||||||
Text,
|
Text,
|
||||||
|
useToast,
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import { useForm, Controller } from "react-hook-form";
|
import { useForm, Controller } from "react-hook-form";
|
||||||
import { yupResolver } from "@hookform/resolvers/yup";
|
import { yupResolver } from "@hookform/resolvers/yup";
|
||||||
@@ -19,8 +20,9 @@ import { v4 as uuidv4 } from "uuid";
|
|||||||
import GlobalStateContext from "../../Contexts/GlobalStateContext";
|
import GlobalStateContext from "../../Contexts/GlobalStateContext";
|
||||||
import { OPACITY_ON_LOAD } from "../../Layout/animations";
|
import { OPACITY_ON_LOAD } from "../../Layout/animations";
|
||||||
import FormInputMain from "../../Components/FormInputMain";
|
import FormInputMain from "../../Components/FormInputMain";
|
||||||
import { useGetContactQuery } from "../../Services/contact.service";
|
import { useGetContactQuery, useUpdateContactMutation } from "../../Services/contact.service";
|
||||||
import FullscreenLoaders from "../../Components/Loaders/FullscreenLoaders";
|
import FullscreenLoaders from "../../Components/Loaders/FullscreenLoaders";
|
||||||
|
import ToastBox from "../../Components/ToastBox";
|
||||||
|
|
||||||
export const addSponser = yup.object().shape({
|
export const addSponser = yup.object().shape({
|
||||||
phoneNumber: yup.string().required("Phone Number is required"),
|
phoneNumber: yup.string().required("Phone Number is required"),
|
||||||
@@ -37,8 +39,10 @@ export function debounce(func, delay) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const Contact = () => {
|
const Contact = () => {
|
||||||
|
const toast = useToast()
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [form, setForm] = useState({});
|
const [form, setForm] = useState({});
|
||||||
|
const [ isLoading, setIsLoading ] = useState(false)
|
||||||
|
|
||||||
// const { sponser, setSponser } = useContext(GlobalStateContext);
|
// const { sponser, setSponser } = useContext(GlobalStateContext);
|
||||||
const {
|
const {
|
||||||
@@ -50,22 +54,21 @@ const Contact = () => {
|
|||||||
resolver: yupResolver(addSponser),
|
resolver: yupResolver(addSponser),
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(errors);
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
data: contact,
|
data: contact,
|
||||||
isLoading: contactLoading,
|
isLoading: contactLoading,
|
||||||
error,
|
error,
|
||||||
} = useGetContactQuery({ page: 1, size: 10 });
|
} = useGetContactQuery();
|
||||||
|
const [ updateContact ] = useUpdateContactMutation()
|
||||||
|
|
||||||
console.log(contact?.data);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (contact) {
|
if (contact) {
|
||||||
reset({
|
reset({
|
||||||
phoneNumber: contact.phoneNumber,
|
phoneNumber: contact?.data[0]?.phoneNumber,
|
||||||
emailAddress: contact.emailAddress,
|
emailAddress: contact?.data[0]?.emailAddress,
|
||||||
websiteUrl: contact.websiteUrl,
|
websiteUrl: contact?.data[0]?.websiteUrl,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, [contact, reset]);
|
}, [contact, reset]);
|
||||||
@@ -82,7 +85,7 @@ const Contact = () => {
|
|||||||
type: "text",
|
type: "text",
|
||||||
isRequired: true,
|
isRequired: true,
|
||||||
section: "Add Details",
|
section: "Add Details",
|
||||||
defaultValue: contact?.phoneNumber || "",
|
// value: contact?.phoneNumber || "",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "E-mail ID",
|
label: "E-mail ID",
|
||||||
@@ -91,7 +94,7 @@ const Contact = () => {
|
|||||||
type: "text",
|
type: "text",
|
||||||
isRequired: true,
|
isRequired: true,
|
||||||
section: "Add Details",
|
section: "Add Details",
|
||||||
defaultValue: contact?.emailAddress || "",
|
// value: contact?.emailAddress || "",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Website URL",
|
label: "Website URL",
|
||||||
@@ -100,7 +103,7 @@ const Contact = () => {
|
|||||||
type: "text",
|
type: "text",
|
||||||
isRequired: true,
|
isRequired: true,
|
||||||
section: "Add Details",
|
section: "Add Details",
|
||||||
defaultValue: contact?.websiteUrl || "",
|
// value: contact?.websiteUrl || "",
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -113,11 +116,25 @@ const Contact = () => {
|
|||||||
return groups;
|
return groups;
|
||||||
}, {});
|
}, {});
|
||||||
|
|
||||||
const onSubmit = (data) => {
|
const onSubmit = async (data) => {
|
||||||
if (!Object.keys(errors).length) {
|
setIsLoading(true)
|
||||||
setForm(data);
|
try {
|
||||||
setAlert(true);
|
const res = await updateContact(data)
|
||||||
|
if (res?.data?.statusCode === 200) {
|
||||||
|
toast({
|
||||||
|
render: () => <ToastBox message={res?.data?.message} />,
|
||||||
|
});
|
||||||
|
setIsLoading(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
|
||||||
|
setIsLoading(false)
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -127,6 +144,7 @@ const Contact = () => {
|
|||||||
control={control}
|
control={control}
|
||||||
errors={errors}
|
errors={errors}
|
||||||
onSubmit={handleSubmit(onSubmit)}
|
onSubmit={handleSubmit(onSubmit)}
|
||||||
|
btnLoading={isLoading}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
|
|||||||
162
src/Pages/Dashbaord.jsx
Normal file
@@ -0,0 +1,162 @@
|
|||||||
|
import { Box, HStack, Icon, position, Text, VStack } from '@chakra-ui/react'
|
||||||
|
import React from 'react'
|
||||||
|
import { HiOutlineChartSquareBar } from 'react-icons/hi'
|
||||||
|
import { RiMoneyDollarBoxLine } from 'react-icons/ri'
|
||||||
|
import { TbTransactionDollar } from 'react-icons/tb'
|
||||||
|
import { VscSymbolClass } from 'react-icons/vsc'
|
||||||
|
import { TABLE_PAGINATION } from '../Constants/Paginations'
|
||||||
|
import FullscreenLoaders from '../Components/Loaders/FullscreenLoaders'
|
||||||
|
import { useGetIOprepopulateDataQuery, useGetIOsQuery } from '../Services/io.service'
|
||||||
|
import { useGetInvestorsQuery } from '../Services/investor.details.service'
|
||||||
|
import DonutChart from '../Components/Doughnut/DonutChart'
|
||||||
|
import { GoDotFill } from "react-icons/go";
|
||||||
|
import { useNavigate } from 'react-router-dom'
|
||||||
|
import LineChart from '../Components/Doughnut/LineChart'
|
||||||
|
import { PiChartLineUpDuotone } from 'react-icons/pi'
|
||||||
|
import ApexChart from '../Components/Doughnut/ApexDonut'
|
||||||
|
import ApexLine from '../Components/Doughnut/ApexLine'
|
||||||
|
import ReactApexChart from 'react-apexcharts'
|
||||||
|
import { BsGraphUpArrow } from "react-icons/bs";
|
||||||
|
|
||||||
|
|
||||||
|
const Dashbaord = () => {
|
||||||
|
const navigate = useNavigate()
|
||||||
|
const { data, isLoading: isIoPreLoading } = useGetIOprepopulateDataQuery();
|
||||||
|
const { data: IO, isLoading: isIoLoading } = useGetIOsQuery({ page: TABLE_PAGINATION?.page, size: TABLE_PAGINATION?.size });
|
||||||
|
const { data: investorDetails, isInvestorLoading } = useGetInvestorsQuery({ page: TABLE_PAGINATION?.page, size: TABLE_PAGINATION?.size });
|
||||||
|
const sortArrayByStatus = () => {
|
||||||
|
const sortedArrays = {
|
||||||
|
open: [],
|
||||||
|
closed: [],
|
||||||
|
processing: [],
|
||||||
|
draft: []
|
||||||
|
};
|
||||||
|
|
||||||
|
IO?.data?.rows.forEach(item => {
|
||||||
|
const status = item.ioStatus?.statusAdmin;
|
||||||
|
if (status === 'Open') {
|
||||||
|
sortedArrays.open.push(item);
|
||||||
|
} else if (status === 'Closed') {
|
||||||
|
sortedArrays.closed.push(item);
|
||||||
|
} else if (status === 'Processing') {
|
||||||
|
sortedArrays.processing.push(item);
|
||||||
|
} else if (status === 'Draft') {
|
||||||
|
sortedArrays.draft.push(item);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return sortedArrays;
|
||||||
|
};
|
||||||
|
const statusData = sortArrayByStatus()
|
||||||
|
const chartData = {
|
||||||
|
labels: ['Draft', 'Open', 'Processing', 'Closed',],
|
||||||
|
backgroundColor: ['#3182ce', '#004118', '#D69E2E', '#E53E3E'],
|
||||||
|
values: [statusData?.draft?.length, statusData?.open?.length, statusData?.processing?.length, statusData?.closed?.length]
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const series1= [{
|
||||||
|
data: [25, 66, 41, 89, 63, 25, 44, 12, 36, 9, 54]
|
||||||
|
}]
|
||||||
|
const options1= {
|
||||||
|
chart: {
|
||||||
|
type: 'line',
|
||||||
|
position:"absolute",
|
||||||
|
right:0,
|
||||||
|
width: 100,
|
||||||
|
height: 35,
|
||||||
|
sparkline: {
|
||||||
|
enabled: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
fixed: {
|
||||||
|
enabled: false
|
||||||
|
},
|
||||||
|
x: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
y: {
|
||||||
|
title: {
|
||||||
|
formatter: function (seriesName) {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
marker: {
|
||||||
|
show: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
isIoPreLoading || isIoLoading || isInvestorLoading ? <FullscreenLoaders /> :
|
||||||
|
<Box height={'100vh'} bg={'#fff'} roundedTop={0} pt={5} overflowX={"hidden"}>
|
||||||
|
<Box display={'flex'} gap={6} w={'100%'} pt={3} pb={3} p={3} >
|
||||||
|
<Box position={'relative'} cursor={'pointer'} onClick={() => navigate("/investor-details")} boxShadow={'lg'} color={"#004118"} p={4} rounded={'xl'} w={'25%'} display={'flex'} bg={'#f5f8f6'} flexDirection={'column'} alignItems={'start'} >
|
||||||
|
<Icon left={"10px"} bg={'#004118'} rounded={9} p={2} color={"#fff"} as={TbTransactionDollar} mb={6} boxSize={12} />
|
||||||
|
<Text as={'span'} fontSize={'xs'} fontWeight={500}>Total Investors</Text>
|
||||||
|
<Text as={'span'} fontSize={'32px'} fontWeight={600}>{investorDetails?.data?.totalItems}</Text>
|
||||||
|
<Icon position={'absolute'} right={6} bottom={6} boxSize={8} as={BsGraphUpArrow} />
|
||||||
|
{/* <ReactApexChart position={'absolute'} right={6} bottom={6} options={options1} series={series1} type="line" height={35} width={100} /> */}
|
||||||
|
</Box>
|
||||||
|
<Box position={'relative'} cursor={'pointer'} onClick={() => navigate("/view-io")} boxShadow={'lg'} bg={'#f5f8f6'} color={"#004118"} p={3} rounded={'xl'} w={'25%'} display={'flex'} flexDirection={'column'} alignItems={'start'} >
|
||||||
|
<Icon bg={'#004118'} rounded={9} p={2} color={"#fff"} as={HiOutlineChartSquareBar} mb={6} boxSize={12} />
|
||||||
|
<Text as={'span'} fontSize={'xs'} fontWeight={500}>Total IO</Text>
|
||||||
|
<Text as={'span'} fontSize={'32px'} fontWeight={600}>{IO?.data?.totalItems}</Text>
|
||||||
|
<Icon position={'absolute'} right={6} bottom={6} boxSize={8} as={BsGraphUpArrow} />
|
||||||
|
</Box>
|
||||||
|
<Box position={'relative'} cursor={'pointer'} onClick={() => navigate("/sponser")} boxShadow={'lg'} bg={'#f5f8f6'} color={"#004118"} p={3} rounded={'xl'} w={'25%'} display={'flex'} flexDirection={'column'} alignItems={'start'} >
|
||||||
|
<Icon bg={'#004118'} rounded={9} p={2} color={"#fff"} as={RiMoneyDollarBoxLine} mb={6} boxSize={12} />
|
||||||
|
<Text as={'span'} fontSize={'xs'} fontWeight={500}>Total sponors</Text>
|
||||||
|
<Text as={'span'} fontSize={'32px'} fontWeight={600}>{data?.data?.sponsor?.length}</Text>
|
||||||
|
<Icon position={'absolute'} right={6} bottom={6} boxSize={8} as={BsGraphUpArrow} />
|
||||||
|
</Box>
|
||||||
|
<Box position={'relative'} cursor={'pointer'} onClick={() => navigate("/investment-type")} boxShadow={'lg'} bg={'#f5f8f6'} color={"#004118"} p={3} rounded={'xl'} w={'25%'} display={'flex'} flexDirection={'column'} alignItems={'start'} >
|
||||||
|
<Icon bg={'#004118'} rounded={9} p={2} color={"#fff"} as={VscSymbolClass} mb={6} boxSize={12} />
|
||||||
|
<Text as={'span'} fontSize={'xs'} fontWeight={500}>Total Investment Type</Text>
|
||||||
|
<Text as={'span'} fontSize={'32px'} fontWeight={600}>{data?.data?.investmentType?.length}</Text>
|
||||||
|
<Icon position={'absolute'} right={6} bottom={6} boxSize={8} as={BsGraphUpArrow} />
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
<Box h={'70%'} w={"100%"} display={'flex'} pe={4} mt={2}>
|
||||||
|
<Box w={'60%'} h={'100%'} p={4} pe={6} pt={1} >
|
||||||
|
<Box position={'relative'} h={'100%'} boxShadow={'lg'} display={'flex'} justifyContent={'center'} rounded={'xl'} p={5} ps={0} pe={0}>
|
||||||
|
{/* <Text position={'absolute'} top={0} left={6} as={'span'} fontSize={'sm'}>Exchange rate currency</Text> */}
|
||||||
|
{/* <LineChart /> */}
|
||||||
|
<ApexLine/>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<Box boxShadow={'lg'} position={"relative"} bg={'#fff'} rounded={'xl'} w={'40%'} display={'flex'} justifyContent={'space-between'} flexDirection={'column'} h={"95%"} mt={1} p={4}>
|
||||||
|
<Text as={'span'} fontSize={'sm'}>IO Status</Text>
|
||||||
|
<Box display={'flex'} w={'100%'} h={'100%'} alignItems={'center'} justifyContent={'space-around'} >
|
||||||
|
{/* <Box display={'flex'} w={'70%'} alignItems={'center'} h={325} p={6}> */}
|
||||||
|
{/* <DonutChart data={chartData} /> */}
|
||||||
|
|
||||||
|
<ApexChart data={chartData} />
|
||||||
|
{/* </Box> */}
|
||||||
|
<VStack alignItems={'start'} justifyContent={'center'} flexWrap={'wrap'}>
|
||||||
|
{chartData?.labels?.map((item, index) => <Text key={index} as={'span'} display={'flex'} gap={0.5} alignItems={'center'} fontSize={'sm'} fontWeight={600}><GoDotFill color={chartData?.backgroundColor[index]} fontSize={30} />{item}</Text>)}
|
||||||
|
</VStack>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Dashbaord
|
||||||
@@ -31,6 +31,11 @@ import ToastBox from "../../../Components/ToastBox";
|
|||||||
import DataTable from "../../../Components/DataTable/DataTable";
|
import DataTable from "../../../Components/DataTable/DataTable";
|
||||||
import DepositRequestApprove from "./DepositRequestApprove";
|
import DepositRequestApprove from "./DepositRequestApprove";
|
||||||
import DepositRequestReject from "./DepositRequestReject";
|
import DepositRequestReject from "./DepositRequestReject";
|
||||||
|
import NormalTable from "../../../Components/DataTable/NormalTable";
|
||||||
|
import { useGetDepositRequestQuery } from "../../../Services/deposit.request.service";
|
||||||
|
import { current } from "@reduxjs/toolkit";
|
||||||
|
import { TABLE_PAGINATION } from "../../../Constants/Paginations";
|
||||||
|
import { removeTrailingZeros } from "../../../Constants/Constants";
|
||||||
|
|
||||||
const formatDate = (date) => new Date(date).toLocaleDateString(); // Simple date formatter
|
const formatDate = (date) => new Date(date).toLocaleDateString(); // Simple date formatter
|
||||||
|
|
||||||
@@ -42,7 +47,7 @@ const DepositRequest = () => {
|
|||||||
const [searchTerm, setSearchTerm] = useState("");
|
const [searchTerm, setSearchTerm] = useState("");
|
||||||
const [isLoading, setIsLoading] = useState(true);
|
const [isLoading, setIsLoading] = useState(true);
|
||||||
const [deleteAlert, setDeleteAlert] = useState(false);
|
const [deleteAlert, setDeleteAlert] = useState(false);
|
||||||
const [actionId, setActionId] = useState(false);
|
const [actionId, setActionId] = useState("");
|
||||||
const [mouseEntered, setMouseEntered] = useState(false);
|
const [mouseEntered, setMouseEntered] = useState(false);
|
||||||
const [mouseEnteredId, setMouseEnteredId] = useState("");
|
const [mouseEnteredId, setMouseEnteredId] = useState("");
|
||||||
const {
|
const {
|
||||||
@@ -56,30 +61,27 @@ const DepositRequest = () => {
|
|||||||
onClose: onRejectClose,
|
onClose: onRejectClose,
|
||||||
} = useDisclosure();
|
} = useDisclosure();
|
||||||
|
|
||||||
useEffect(() => {
|
const [pageSize, setPageSize] = useState(TABLE_PAGINATION?.size);
|
||||||
// Simulate loading
|
const [currentPage, setCurrentPage] = useState(TABLE_PAGINATION?.page);
|
||||||
const timer = setTimeout(() => {
|
|
||||||
setIsLoading(false);
|
const {
|
||||||
}, 1500);
|
data,
|
||||||
|
isLoading: depositRequestLoading,
|
||||||
|
error,
|
||||||
|
} = useGetDepositRequestQuery({ page: currentPage, size: pageSize });
|
||||||
|
|
||||||
|
|
||||||
// Cleanup the timer on component unmount
|
|
||||||
return () => clearTimeout(timer);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
// ====================================================[Table Setup]================================================================
|
// ====================================================[Table Setup]================================================================
|
||||||
const tableHeadRow = [
|
const tableHeadRow = [
|
||||||
"Sr.no",
|
// "Sr.no",
|
||||||
"Date",
|
|
||||||
"Client ID",
|
"Client ID",
|
||||||
"First Name",
|
"First Name",
|
||||||
"Last Name",
|
"Last Name",
|
||||||
"Country",
|
"Country",
|
||||||
"Phone Number",
|
"Phone Number",
|
||||||
"Currency",
|
|
||||||
"Deposit Amount",
|
|
||||||
"Fees",
|
|
||||||
"Total Amount",
|
|
||||||
"Amount in Investor currency",
|
"Amount in Investor currency",
|
||||||
|
"Deposit Date",
|
||||||
"Action",
|
"Action",
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -96,14 +98,14 @@ const DepositRequest = () => {
|
|||||||
});
|
});
|
||||||
}, 300);
|
}, 300);
|
||||||
|
|
||||||
// ====================================================[Table Filter]================================================================
|
const filteredData = data?.data?.rows
|
||||||
const filteredData = depositRequest.filter((item) => {
|
.filter((item) => {
|
||||||
// Filter by name (case insensitive)
|
// Filter by name (case insensitive)
|
||||||
const name = item.clientId;
|
const name = [item.firstName, item.lastName, item.countryName].filter(Boolean).join(' ');
|
||||||
const searchLower = searchTerm.toLowerCase();
|
const searchLower = searchTerm.toLowerCase();
|
||||||
const nameMatches = name.toLowerCase().includes(searchLower);
|
const nameMatches = name.toLowerCase().includes(searchLower);
|
||||||
|
|
||||||
// Filter by status
|
// Filter by status (Uncomment and use if needed)
|
||||||
// const status = item.status;
|
// const status = item.status;
|
||||||
// const statusLower = status ? "active" : "inactive";
|
// const statusLower = status ? "active" : "inactive";
|
||||||
|
|
||||||
@@ -113,162 +115,146 @@ const DepositRequest = () => {
|
|||||||
// (statusFilter === "inactive" && status === false);
|
// (statusFilter === "inactive" && status === false);
|
||||||
|
|
||||||
return nameMatches;
|
return nameMatches;
|
||||||
});
|
})
|
||||||
|
.sort((b, a) => new Date(a.createdAt) - new Date(b.createdAt));
|
||||||
|
|
||||||
const [extractedArray, setExtractedArray] = useState(
|
console.log(data?.data?.rows);
|
||||||
filteredData?.map((item, index) => ({
|
|
||||||
// id: item?.id,
|
|
||||||
"Sr.no": (
|
const extractedArray = filteredData?.map((item, index) => ({
|
||||||
<Text
|
// id: item?.id,
|
||||||
w={"30px"}
|
"Sr.no": (
|
||||||
justifyContent={slideFromRight ? "right" : "left"}
|
<Text
|
||||||
as={"span"}
|
w={"30px"}
|
||||||
color={"teal.900"}
|
justifyContent={slideFromRight ? "right" : "left"}
|
||||||
fontWeight={"500"}
|
as={"span"}
|
||||||
className="d-flex align-items-center web-text-small"
|
color={"teal.900"}
|
||||||
>
|
fontWeight={"500"}
|
||||||
{index + 1}
|
className="d-flex align-items-center web-text-small"
|
||||||
|
>
|
||||||
|
{index + 1}
|
||||||
|
</Text>
|
||||||
|
),
|
||||||
|
"Client ID": (
|
||||||
|
<Text
|
||||||
|
w={"60px"}
|
||||||
|
justifyContent={slideFromRight ? "right" : "left"}
|
||||||
|
as={"span"}
|
||||||
|
color={"teal.900"}
|
||||||
|
fontWeight={"500"}
|
||||||
|
className="d-flex align-items-center web-text-small"
|
||||||
|
>
|
||||||
|
{item?.clientReference_id}
|
||||||
|
</Text>
|
||||||
|
),
|
||||||
|
"First Name": (
|
||||||
|
<Box isTruncated={true} w={"70px"}>
|
||||||
|
<Text as={"span"} color={"teal.900"} fontWeight={"500"}>
|
||||||
|
{item?.firstName}
|
||||||
</Text>
|
</Text>
|
||||||
),
|
</Box>
|
||||||
Date: (
|
),
|
||||||
<Text
|
"Last Name": (
|
||||||
w={"60px"}
|
<Box w={"70px"} isTruncated={true}>
|
||||||
justifyContent={slideFromRight ? "right" : "left"}
|
<Text as={"span"} color={"teal.900"}>
|
||||||
as={"span"}
|
{item?.lastName}
|
||||||
color={"teal.900"}
|
|
||||||
fontWeight={"500"}
|
|
||||||
className="d-flex align-items-center web-text-small"
|
|
||||||
>
|
|
||||||
{item.date}
|
|
||||||
</Text>
|
</Text>
|
||||||
),
|
</Box>
|
||||||
"Client ID": (
|
),
|
||||||
<Text
|
Country: (
|
||||||
w={"60px"}
|
<Box w={"100px"} isTruncated={true}>
|
||||||
justifyContent={slideFromRight ? "right" : "left"}
|
<Text as={"span"} color={"teal.900"}>
|
||||||
as={"span"}
|
{item?.countryName}
|
||||||
color={"teal.900"}
|
|
||||||
fontWeight={"500"}
|
|
||||||
className="d-flex align-items-center web-text-small"
|
|
||||||
>
|
|
||||||
{item.clientId}
|
|
||||||
</Text>
|
</Text>
|
||||||
),
|
</Box>
|
||||||
"First Name": (
|
),
|
||||||
<Box isTruncated={true} w={"50px"}>
|
"Phone Number": (
|
||||||
<Text as={"span"} color={"teal.900"} fontWeight={"500"}>
|
<Box w={"80px"} isTruncated={true}>
|
||||||
{item.firstName}
|
<Text as={"span"} color={"teal.900"}>
|
||||||
</Text>
|
{item?.mobileNumber}
|
||||||
</Box>
|
</Text>
|
||||||
),
|
</Box>
|
||||||
"Last Name": (
|
),
|
||||||
<Box w={"50px"} isTruncated={true}>
|
"Amount in Investor currency": (
|
||||||
<Text as={"span"} color={"teal.900"}>
|
<Box display={'flex'} justifyContent={'end'} w={"100px"} isTruncated={true}>
|
||||||
{item.lastName}
|
<Text as={"span"} color={"teal.900"}>
|
||||||
</Text>
|
{/* {formatCurrency(removeTrailingZeros(item?.investorAmount))} */}
|
||||||
</Box>
|
{parseFloat(item?.investorAmount||0).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
|
||||||
),
|
<Badge ms={1} colorScheme="green">{item?.currencyCode}</Badge>
|
||||||
Country: (
|
</Text>
|
||||||
<Box w={"70px"} isTruncated={true}>
|
</Box>
|
||||||
<Text as={"span"} color={"teal.900"}>
|
),
|
||||||
{item.country}
|
"Deposit Date": (
|
||||||
</Text>
|
<Text
|
||||||
</Box>
|
w={"60px"}
|
||||||
),
|
justifyContent={slideFromRight ? "right" : "left"}
|
||||||
"Phone Number": (
|
as={"span"}
|
||||||
<Box w={"70px"} isTruncated={true}>
|
color={"teal.900"}
|
||||||
<Text as={"span"} color={"teal.900"}>
|
fontWeight={"500"}
|
||||||
{item.phoneNumber}
|
className="d-flex align-items-center web-text-small"
|
||||||
</Text>
|
>
|
||||||
</Box>
|
{formatDate(item?.createdAt)}
|
||||||
),
|
</Text>
|
||||||
Currency: (
|
),
|
||||||
<Box w={"50px"} isTruncated={true}>
|
Action: (
|
||||||
<Text as={"span"} color={"teal.900"}>
|
<Box display={"flex"} justifyContent={"center"} gap={2}>
|
||||||
<Badge px={2} py={1}>
|
<Tooltip
|
||||||
{item.currency}
|
rounded={"sm"}
|
||||||
</Badge>
|
fontSize={"xs"}
|
||||||
</Text>
|
label="Approve"
|
||||||
</Box>
|
bg="#fff"
|
||||||
),
|
color={"green.500"}
|
||||||
"Deposit Amount": (
|
placement="left-start"
|
||||||
<Box w={"50px"} isTruncated={true}>
|
>
|
||||||
<Text as={"span"} color={"teal.900"}>
|
<Button
|
||||||
{item.depositAmount}
|
// colorScheme="forestGreen"
|
||||||
</Text>
|
// color="green.500"
|
||||||
</Box>
|
|
||||||
),
|
|
||||||
Fees: (
|
|
||||||
<Box w={"auto"} isTruncated={true}>
|
|
||||||
<Text as={"span"} color={"teal.900"}>
|
|
||||||
{item.fees}
|
|
||||||
</Text>
|
|
||||||
</Box>
|
|
||||||
),
|
|
||||||
"Total Amount": (
|
|
||||||
<Box w={"auto"} isTruncated={true}>
|
|
||||||
<Text as={"span"} color={"teal.900"}>
|
|
||||||
{item.totalAmount}
|
|
||||||
</Text>
|
|
||||||
</Box>
|
|
||||||
),
|
|
||||||
"Amount in Investor currency": (
|
|
||||||
<Box w={"70px"} isTruncated={true}>
|
|
||||||
<Text as={"span"} color={"teal.900"}>
|
|
||||||
{item.amountcurrency}
|
|
||||||
</Text>
|
|
||||||
</Box>
|
|
||||||
),
|
|
||||||
Action: (
|
|
||||||
<Box display={"flex"} justifyContent={"space-around"} gap={2}>
|
|
||||||
<Tooltip
|
|
||||||
rounded={"sm"}
|
rounded={"sm"}
|
||||||
fontSize={"xs"}
|
size={"xs"}
|
||||||
label="Approve"
|
textTransform={"inherit"}
|
||||||
bg="#fff"
|
fontWeight={500}
|
||||||
color={"green.500"}
|
px={2}
|
||||||
placement="left-start"
|
py={1}
|
||||||
|
onClick={() => {
|
||||||
|
setActionId(item.id);
|
||||||
|
onConfirmOpen();
|
||||||
|
}}
|
||||||
|
colorScheme="green"
|
||||||
|
variant={"solid"}
|
||||||
|
cursor={"pointer"}
|
||||||
>
|
>
|
||||||
<Badge
|
<CheckIcon fontSize={"12px"} />
|
||||||
colorScheme="forestGreen"
|
</Button>
|
||||||
color="green.500"
|
</Tooltip>
|
||||||
rounded={"sm"}
|
<Tooltip
|
||||||
size={"xs"}
|
rounded={"sm"}
|
||||||
textTransform={"inherit"}
|
fontSize={"xs"}
|
||||||
fontWeight={500}
|
label="Reject"
|
||||||
px={2}
|
bg="#fff"
|
||||||
py={1}
|
color={"red.500"}
|
||||||
onClick={onConfirmOpen}
|
placement="left-start"
|
||||||
>
|
>
|
||||||
<CheckIcon fontSize={"12px"} />
|
<Button
|
||||||
</Badge>
|
colorScheme="red"
|
||||||
</Tooltip>
|
// color="red.500"
|
||||||
<Tooltip
|
|
||||||
rounded={"sm"}
|
rounded={"sm"}
|
||||||
fontSize={"xs"}
|
size={"xs"}
|
||||||
label="Reject"
|
textTransform={"inherit"}
|
||||||
bg="#fff"
|
fontWeight={500}
|
||||||
color={"red.500"}
|
px={2}
|
||||||
placement="left-start"
|
onClick={() => {
|
||||||
|
setActionId(item.id);
|
||||||
|
onRejectOpen();
|
||||||
|
}}
|
||||||
|
py={1}
|
||||||
|
// variant={"solid"}
|
||||||
>
|
>
|
||||||
<Badge
|
<CloseIcon fontSize={"10px"} />
|
||||||
colorScheme="red"
|
</Button>
|
||||||
color="red.500"
|
</Tooltip>
|
||||||
rounded={"sm"}
|
</Box>
|
||||||
size={"xs"}
|
),
|
||||||
textTransform={"inherit"}
|
}));
|
||||||
fontWeight={500}
|
|
||||||
px={2}
|
|
||||||
onClick={onRejectOpen}
|
|
||||||
py={1}
|
|
||||||
>
|
|
||||||
<CloseIcon fontSize={"10px"} />
|
|
||||||
</Badge>
|
|
||||||
</Tooltip>
|
|
||||||
</Box>
|
|
||||||
),
|
|
||||||
}))
|
|
||||||
);
|
|
||||||
|
|
||||||
const handleDelete = () => {
|
const handleDelete = () => {
|
||||||
const IOtype = investmentType.filter(
|
const IOtype = investmentType.filter(
|
||||||
@@ -307,17 +293,23 @@ const DepositRequest = () => {
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<HStack display={"flex"} alignItems={"center"}>
|
<HStack display={"flex"} alignItems={"center"}>
|
||||||
<Pagination totalItems={10} />
|
<Pagination
|
||||||
|
isLoading={depositRequestLoading}
|
||||||
|
pageSize={pageSize}
|
||||||
|
setPageSize={setPageSize}
|
||||||
|
currentPage={currentPage}
|
||||||
|
setCurrentPage={setCurrentPage}
|
||||||
|
totalItems={data?.data?.totalItems}
|
||||||
|
/>
|
||||||
</HStack>
|
</HStack>
|
||||||
</HStack>
|
</HStack>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<DataTable
|
<NormalTable
|
||||||
emptyMessage={`We don't have any Investment type `}
|
emptyMessage={`We don't have any Investment type `}
|
||||||
tableHeadRow={tableHeadRow}
|
tableHeadRow={tableHeadRow}
|
||||||
setData={setExtractedArray}
|
|
||||||
data={extractedArray}
|
data={extractedArray}
|
||||||
isLoading={isLoading}
|
isLoading={depositRequestLoading}
|
||||||
viewActionId={actionId}
|
viewActionId={actionId}
|
||||||
setViewActionId={setActionId}
|
setViewActionId={setActionId}
|
||||||
// totalPages={10}
|
// totalPages={10}
|
||||||
@@ -334,11 +326,17 @@ const DepositRequest = () => {
|
|||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
/>
|
/>
|
||||||
<DepositRequestApprove
|
<DepositRequestApprove
|
||||||
|
data={data?.data?.rows}
|
||||||
isOpen={isConfirmOpen}
|
isOpen={isConfirmOpen}
|
||||||
onClose={onConfirmClose}
|
onClose={onConfirmClose}
|
||||||
// firstField={firstField}
|
id={actionId}
|
||||||
|
// firstField={firstField}
|
||||||
|
/>
|
||||||
|
<DepositRequestReject
|
||||||
|
isOpen={isRejectOpen}
|
||||||
|
onClose={onRejectClose}
|
||||||
|
id={actionId}
|
||||||
/>
|
/>
|
||||||
<DepositRequestReject isOpen={isRejectOpen} onClose={onRejectClose} />
|
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,128 +1,226 @@
|
|||||||
import {
|
import {
|
||||||
Box,
|
Badge,
|
||||||
Button,
|
Box,
|
||||||
FormControl,
|
Button,
|
||||||
FormLabel,
|
FormControl,
|
||||||
Input,
|
FormLabel,
|
||||||
Modal,
|
Input,
|
||||||
ModalBody,
|
Modal,
|
||||||
ModalCloseButton,
|
ModalBody,
|
||||||
ModalContent,
|
ModalCloseButton,
|
||||||
ModalFooter,
|
ModalContent,
|
||||||
ModalHeader,
|
ModalFooter,
|
||||||
ModalOverlay,
|
ModalHeader,
|
||||||
Text,
|
ModalOverlay,
|
||||||
useDisclosure,
|
Text,
|
||||||
} from "@chakra-ui/react";
|
Textarea,
|
||||||
import React from "react";
|
useDisclosure,
|
||||||
import * as yup from "yup";
|
useToast,
|
||||||
import { yupResolver } from "@hookform/resolvers/yup";
|
} from "@chakra-ui/react";
|
||||||
import { useForm } from "react-hook-form";
|
import React, { useEffect, useState } from "react";
|
||||||
|
import * as yup from "yup";
|
||||||
|
import { yupResolver } from "@hookform/resolvers/yup";
|
||||||
|
import { useForm } from "react-hook-form";
|
||||||
|
import { useGetDepositRequestByIdQuery, useUpdateDepositRequestMutation } from "../../../Services/deposit.request.service";
|
||||||
|
import FullscreenLoaders from "../../../Components/Loaders/FullscreenLoaders";
|
||||||
|
import ToastBox from "../../../Components/ToastBox";
|
||||||
|
|
||||||
export const conformModalSchema = yup.object().shape({
|
const FILE_TYPES = ["image/jpeg", "image/png", "image/gif"];
|
||||||
fees: yup.string().required("File name is required"),
|
|
||||||
totalAmount: yup.string().required("File name is required"),
|
export const conformModalSchema = yup.object().shape({
|
||||||
|
investorAmount: yup.string().required("Investor amount is required"),
|
||||||
|
comment: yup.string().notRequired(),
|
||||||
|
supporting_FileName: yup.mixed().required("File is required"),
|
||||||
|
// .test("fileType", "Unsupported File Format", (value) => {
|
||||||
|
// return value && FILE_TYPES.includes(value.type);
|
||||||
|
// }),
|
||||||
|
});
|
||||||
|
|
||||||
|
const DepositRequestApprove = ({ isOpen, onClose, firstField, id, data:requestData }) => {
|
||||||
|
const toast = useToast()
|
||||||
|
const [file, setFile] = useState();
|
||||||
|
const [isBtnLoading , setIsBtnLoading] = useState(false)
|
||||||
|
|
||||||
|
const fileredData = requestData?.find((item)=> item?.id === id)
|
||||||
|
console.log(fileredData);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const [ updateDepositRequest ] = useUpdateDepositRequestMutation()
|
||||||
|
|
||||||
|
const {
|
||||||
|
register,
|
||||||
|
reset,
|
||||||
|
handleSubmit,
|
||||||
|
formState: { errors },
|
||||||
|
} = useForm({
|
||||||
|
resolver: yupResolver(conformModalSchema),
|
||||||
});
|
});
|
||||||
|
|
||||||
const DepositRequestApprove = ({ isOpen, onClose, firstField }) => {
|
useEffect(() => {
|
||||||
const {
|
reset({
|
||||||
register,
|
investorAmount:fileredData?.investorAmount
|
||||||
handleSubmit,
|
})
|
||||||
formState: { errors },
|
|
||||||
} = useForm({
|
|
||||||
resolver: yupResolver(conformModalSchema),
|
|
||||||
});
|
|
||||||
|
|
||||||
const onSubmit = (data) => {
|
|
||||||
setFile(data.document[0]);
|
|
||||||
|
|
||||||
const newDocument = {
|
}, [requestData, id])
|
||||||
...data,
|
|
||||||
document: data.document[0].name, // Store the document name
|
|
||||||
status: true,
|
|
||||||
id: uuidv4(),
|
|
||||||
createdAt: new Date().toISOString(),
|
|
||||||
Type: getFileIcon(file.type),
|
|
||||||
};
|
|
||||||
|
|
||||||
setCreate((prevCreate) => [...prevCreate, newDocument]);
|
const onSubmit = async(data) => {
|
||||||
onClose();
|
setIsBtnLoading(true)
|
||||||
};
|
const formData = new FormData();
|
||||||
|
|
||||||
const handleFileChange = (event) => {
|
formData.append("investorAmount", data.investorAmount);
|
||||||
const selectedFile = event.target.files[0];
|
formData.append("comment", data.comment);
|
||||||
setFile(selectedFile);
|
const file = data.supporting_FileName["0"];
|
||||||
};
|
formData.append("supporting_FileName", file);
|
||||||
|
|
||||||
return (
|
|
||||||
<Modal isOpen={isOpen} onClose={onClose} initialFocusRef={firstField}>
|
try {
|
||||||
<ModalOverlay />
|
const res = await updateDepositRequest({ id ,data: formData})
|
||||||
<ModalContent pb={4}>
|
|
||||||
<ModalHeader fontSize={"md"}>Confirm</ModalHeader>
|
|
||||||
<ModalCloseButton />
|
if (res?.error) {
|
||||||
|
toast({
|
||||||
|
render: () => (
|
||||||
|
<ToastBox message={res?.error?.data?.message} status={"error"} />
|
||||||
|
),
|
||||||
|
});
|
||||||
|
setIsBtnLoading(false)
|
||||||
|
}else if(res?.data?.statusCode === 200) {
|
||||||
|
toast({
|
||||||
|
render: () => (
|
||||||
|
<ToastBox message={res?.data?.message} />
|
||||||
|
),
|
||||||
|
});
|
||||||
|
setIsBtnLoading(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
heandleOnClose();
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleFileChange = (event) => {
|
||||||
|
const selectedFile = event.target.files[0];
|
||||||
|
setFile(selectedFile);
|
||||||
|
};
|
||||||
|
|
||||||
|
const { data, isLoading } =
|
||||||
|
(id, {
|
||||||
|
skip: !id,
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (data) {
|
||||||
|
reset({
|
||||||
|
investorAmount: data?.data?.investorAmount,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [data, reset]);
|
||||||
|
|
||||||
|
const heandleOnClose = () =>{
|
||||||
|
reset()
|
||||||
|
onClose()
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal isOpen={isOpen} onClose={heandleOnClose} initialFocusRef={firstField}>
|
||||||
|
<ModalOverlay />
|
||||||
|
|
||||||
|
<ModalContent pb={4}>
|
||||||
|
<ModalHeader fontSize={"md"}>Confirm</ModalHeader>
|
||||||
|
<ModalCloseButton />
|
||||||
|
{isLoading ? (
|
||||||
|
<FullscreenLoaders height={"50vh"} />
|
||||||
|
) : (
|
||||||
<Box as="form" onSubmit={handleSubmit(onSubmit)}>
|
<Box as="form" onSubmit={handleSubmit(onSubmit)}>
|
||||||
<ModalBody>
|
<ModalBody>
|
||||||
<FormControl mb={4}>
|
<FormControl mb={4} isRequired>
|
||||||
<FormLabel fontSize="sm">Deposit Amount</FormLabel>
|
<FormLabel fontSize="sm">Deposit Amount <Badge colorScheme="green">{fileredData?.currencyCode}</Badge></FormLabel>
|
||||||
<Input
|
<Input
|
||||||
focusBorderColor='green.400'
|
focusBorderColor="green.400"
|
||||||
name="fileName"
|
name="investorAmount"
|
||||||
{...register("fileName")}
|
{...register("investorAmount")}
|
||||||
fontSize="sm"
|
fontSize="sm"
|
||||||
type="text"
|
type="number"
|
||||||
size="sm"
|
size="sm"
|
||||||
placeholder={"$100,000"}
|
placeholder={"100,000"}
|
||||||
readOnly
|
textAlign={"right"}
|
||||||
|
// readOnly
|
||||||
/>
|
/>
|
||||||
</FormControl>
|
{errors.investorAmount && (
|
||||||
<FormControl mb={4}>
|
|
||||||
<FormLabel fontSize="sm">Fees</FormLabel>
|
|
||||||
<Input
|
|
||||||
focusBorderColor='green.400'
|
|
||||||
name="fileName"
|
|
||||||
{...register("fileName")}
|
|
||||||
fontSize="sm"
|
|
||||||
type="text"
|
|
||||||
size="sm"
|
|
||||||
placeholder={"$100,000"}
|
|
||||||
/>
|
|
||||||
{errors.fees && (
|
|
||||||
<Text fontSize="xs" color="red">
|
<Text fontSize="xs" color="red">
|
||||||
{errors.fees.message}
|
{errors.investorAmount.message}
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
|
</FormControl>
|
||||||
|
<FormControl mb={4} isRequired>
|
||||||
|
<FormLabel fontSize="sm">Upload Supporting</FormLabel>
|
||||||
|
<Input
|
||||||
|
focusBorderColor="green.400"
|
||||||
|
name="supporting_FileName"
|
||||||
|
{...register("supporting_FileName")}
|
||||||
|
fontSize="sm"
|
||||||
|
type="file"
|
||||||
|
size="sm"
|
||||||
|
placeholder={"$100,000"}
|
||||||
|
className="form-control"
|
||||||
|
accept="image/*"
|
||||||
|
/>
|
||||||
|
{errors.supporting_FileName && (
|
||||||
|
<Text fontSize="xs" color="red">
|
||||||
|
{errors.supporting_FileName.message}
|
||||||
</Text>
|
</Text>
|
||||||
)}
|
)}
|
||||||
</FormControl>
|
</FormControl>
|
||||||
<FormControl mb={4}>
|
<FormControl mb={4}>
|
||||||
<FormLabel fontSize="sm">Total Amount</FormLabel>
|
<FormLabel fontSize="sm">Comments</FormLabel>
|
||||||
<Input
|
<Textarea
|
||||||
focusBorderColor='green.400'
|
rows={5}
|
||||||
name="fileName"
|
focusBorderColor="green.400"
|
||||||
{...register("fileName")}
|
name="comment"
|
||||||
|
{...register("comment")}
|
||||||
fontSize="sm"
|
fontSize="sm"
|
||||||
type="text"
|
type="textarea"
|
||||||
size="sm"
|
size="sm"
|
||||||
placeholder={"$100,000"}
|
placeholder={"Enter your comments...."}
|
||||||
|
resize={"none"}
|
||||||
/>
|
/>
|
||||||
{errors.totalAmount && (
|
{errors.comment && (
|
||||||
<Text fontSize="xs" color="red">
|
<Text fontSize="xs" color="red">
|
||||||
{errors.totalAmount.message}
|
{errors.comment.message}
|
||||||
</Text>
|
</Text>
|
||||||
)}
|
)}
|
||||||
</FormControl>
|
</FormControl>
|
||||||
</ModalBody>
|
</ModalBody>
|
||||||
<ModalFooter>
|
<ModalFooter>
|
||||||
<Button colorScheme="gray" mr={3} onClick={onClose} size={'sm'} rounded={'sm'}>
|
<Button
|
||||||
|
colorScheme="gray"
|
||||||
|
mr={3}
|
||||||
|
onClick={onClose}
|
||||||
|
size={"sm"}
|
||||||
|
rounded={"sm"}
|
||||||
|
>
|
||||||
Cancel
|
Cancel
|
||||||
</Button>
|
</Button>
|
||||||
<Button colorScheme="forestGreen" variant="solid" size={'sm'} rounded={'sm'}>
|
<Button
|
||||||
|
colorScheme="forestGreen"
|
||||||
|
variant="solid"
|
||||||
|
size={"sm"}
|
||||||
|
rounded={"sm"}
|
||||||
|
isLoading={isBtnLoading}
|
||||||
|
type="submit"
|
||||||
|
>
|
||||||
Confirm
|
Confirm
|
||||||
</Button>
|
</Button>
|
||||||
</ModalFooter>
|
</ModalFooter>
|
||||||
</Box>
|
</Box>
|
||||||
</ModalContent>
|
)}
|
||||||
</Modal>
|
</ModalContent>
|
||||||
);
|
</Modal>
|
||||||
};
|
);
|
||||||
|
};
|
||||||
export default DepositRequestApprove;
|
|
||||||
|
|
||||||
|
export default DepositRequestApprove;
|
||||||
|
|||||||
@@ -1,99 +1,163 @@
|
|||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
Button,
|
Button,
|
||||||
FormControl,
|
FormControl,
|
||||||
FormLabel,
|
FormLabel,
|
||||||
Input,
|
Input,
|
||||||
Modal,
|
Modal,
|
||||||
ModalBody,
|
ModalBody,
|
||||||
ModalCloseButton,
|
ModalCloseButton,
|
||||||
ModalContent,
|
ModalContent,
|
||||||
ModalFooter,
|
ModalFooter,
|
||||||
ModalHeader,
|
ModalHeader,
|
||||||
ModalOverlay,
|
ModalOverlay,
|
||||||
Text,
|
Text,
|
||||||
Textarea,
|
Textarea,
|
||||||
useDisclosure,
|
useDisclosure,
|
||||||
} from "@chakra-ui/react";
|
useToast,
|
||||||
import React from "react";
|
} from "@chakra-ui/react";
|
||||||
import * as yup from "yup";
|
import React, { useEffect, useState } from "react";
|
||||||
import { yupResolver } from "@hookform/resolvers/yup";
|
import * as yup from "yup";
|
||||||
import { useForm } from "react-hook-form";
|
import { yupResolver } from "@hookform/resolvers/yup";
|
||||||
|
import { useForm } from "react-hook-form";
|
||||||
|
import { useDepositRejectMutation } from "../../../Services/deposit.request.service";
|
||||||
|
import ToastBox from "../../../Components/ToastBox";
|
||||||
|
|
||||||
export const conformModalSchema = yup.object().shape({
|
export const conformModalSchema = yup.object().shape({
|
||||||
comment: yup.string().required("Comment is required"),
|
comments: yup.string().required("Comment is required"),
|
||||||
|
});
|
||||||
|
|
||||||
|
const DepositRequestReject = ({ isOpen, onClose, firstField ,id}) => {
|
||||||
|
const [isBtnLoading , setIsBtnLoading] = useState(false)
|
||||||
|
|
||||||
|
const toast = useToast()
|
||||||
|
|
||||||
|
const {
|
||||||
|
register,
|
||||||
|
reset,
|
||||||
|
handleSubmit,
|
||||||
|
formState: { errors },
|
||||||
|
} = useForm({
|
||||||
|
resolver: yupResolver(conformModalSchema),
|
||||||
});
|
});
|
||||||
|
|
||||||
const DepositRequestReject = ({ isOpen, onClose, firstField }) => {
|
const [ depositReject ] = useDepositRejectMutation()
|
||||||
const {
|
|
||||||
register,
|
|
||||||
handleSubmit,
|
|
||||||
formState: { errors },
|
|
||||||
} = useForm({
|
|
||||||
resolver: yupResolver(conformModalSchema),
|
|
||||||
});
|
|
||||||
|
|
||||||
const onSubmit = (data) => {
|
|
||||||
setFile(data.document[0]);
|
|
||||||
|
|
||||||
const newDocument = {
|
const onSubmit = async(data) => {
|
||||||
...data,
|
setIsBtnLoading(true)
|
||||||
document: data.document[0].name, // Store the document name
|
try {
|
||||||
comment: true,
|
const res = await depositReject({ id ,data})
|
||||||
id: uuidv4(),
|
|
||||||
Type: getFileIcon(file.type),
|
|
||||||
};
|
|
||||||
|
|
||||||
setCreate((prevCreate) => [...prevCreate, newDocument]);
|
if (res?.error) {
|
||||||
onClose();
|
toast({
|
||||||
};
|
render: () => (
|
||||||
|
<ToastBox message={res?.error?.data?.message} status={"error"} />
|
||||||
|
),
|
||||||
|
});
|
||||||
|
setIsBtnLoading(false)
|
||||||
|
onClose();
|
||||||
|
|
||||||
const handleFileChange = (event) => {
|
}else if(res?.data?.statusCode === 200) {
|
||||||
const selectedFile = event.target.files[0];
|
toast({
|
||||||
setFile(selectedFile);
|
render: () => (
|
||||||
};
|
<ToastBox message={res?.data?.message} />
|
||||||
|
),
|
||||||
|
});
|
||||||
|
setIsBtnLoading(false)
|
||||||
|
onClose();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
|
||||||
<Modal isOpen={isOpen} onClose={onClose} initialFocusRef={firstField}>
|
|
||||||
<ModalOverlay />
|
|
||||||
<ModalContent pb={4}>
|
|
||||||
<ModalHeader fontSize={"md"}>Reject</ModalHeader>
|
|
||||||
<ModalCloseButton />
|
|
||||||
<Box as="form" onSubmit={handleSubmit(onSubmit)}>
|
|
||||||
<ModalBody>
|
|
||||||
<FormControl mb={4}>
|
|
||||||
<FormLabel fontSize="sm">Comment</FormLabel>
|
|
||||||
<Textarea rows={6}
|
|
||||||
focusBorderColor='green.400'
|
|
||||||
name="fileName"
|
|
||||||
{...register("fileName")}
|
|
||||||
fontSize="sm"
|
|
||||||
type="textarea"
|
|
||||||
size="md"
|
|
||||||
placeholder={"$100,000"}
|
|
||||||
rounded={'md'}
|
|
||||||
resize={'none'}
|
|
||||||
/>
|
|
||||||
{errors.comment && (
|
|
||||||
<Text fontSize="xs" color="red">
|
|
||||||
{errors.comment.message}
|
|
||||||
</Text>
|
|
||||||
)}
|
|
||||||
</FormControl>
|
|
||||||
</ModalBody>
|
|
||||||
<ModalFooter>
|
|
||||||
<Button colorScheme="gray" mr={3} onClick={onClose} size={'sm'} rounded={'sm'}>
|
|
||||||
Cancel
|
|
||||||
</Button>
|
|
||||||
<Button colorScheme="forestGreen" variant="solid" size={'sm'} rounded={'sm'}>
|
|
||||||
Send
|
|
||||||
</Button>
|
|
||||||
</ModalFooter>
|
|
||||||
</Box>
|
|
||||||
</ModalContent>
|
|
||||||
</Modal>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default DepositRequestReject;
|
const handleFileChange = (event) => {
|
||||||
|
const selectedFile = event.target.files[0];
|
||||||
|
setFile(selectedFile);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const { data, isLoading } =
|
||||||
|
(id, {
|
||||||
|
skip: !id,
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (data) {
|
||||||
|
reset({
|
||||||
|
investorAmount: data?.data?.investorAmount,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [data, reset]);
|
||||||
|
|
||||||
|
const heandleOnClose = () =>{
|
||||||
|
reset()
|
||||||
|
onClose()
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal isOpen={isOpen} onClose={heandleOnClose} initialFocusRef={firstField}>
|
||||||
|
<ModalOverlay />
|
||||||
|
<ModalContent pb={4}>
|
||||||
|
<ModalHeader fontSize={"md"}>Reject</ModalHeader>
|
||||||
|
<ModalCloseButton />
|
||||||
|
{isLoading ? (
|
||||||
|
<FullscreenLoaders height={"50vh"} />
|
||||||
|
) : (
|
||||||
|
<Box as="form" onSubmit={handleSubmit(onSubmit)}>
|
||||||
|
<ModalBody>
|
||||||
|
<FormControl mb={4} isRequired>
|
||||||
|
<FormLabel fontSize="sm">Comment</FormLabel>
|
||||||
|
<Textarea
|
||||||
|
rows={6}
|
||||||
|
focusBorderColor="green.400"
|
||||||
|
name="comments"
|
||||||
|
{...register("comments")}
|
||||||
|
fontSize="sm"
|
||||||
|
type="textarea"
|
||||||
|
size="md"
|
||||||
|
placeholder={"Enter your comments...."}
|
||||||
|
rounded={"md"}
|
||||||
|
resize={"none"}
|
||||||
|
/>
|
||||||
|
{errors.comments && (
|
||||||
|
<Text fontSize="xs" color="red">
|
||||||
|
{errors.comments.message}
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
|
</FormControl>
|
||||||
|
</ModalBody>
|
||||||
|
<ModalFooter>
|
||||||
|
<Button
|
||||||
|
colorScheme="gray"
|
||||||
|
mr={3}
|
||||||
|
onClick={onClose}
|
||||||
|
size={"sm"}
|
||||||
|
rounded={"sm"}
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
colorScheme="forestGreen"
|
||||||
|
variant="solid"
|
||||||
|
size={"sm"}
|
||||||
|
rounded={"sm"}
|
||||||
|
isLoading={isBtnLoading}
|
||||||
|
type="submit"
|
||||||
|
>
|
||||||
|
Send
|
||||||
|
</Button>
|
||||||
|
</ModalFooter>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
</ModalContent>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default DepositRequestReject;
|
||||||
|
|||||||
@@ -8,20 +8,27 @@ import {
|
|||||||
Text,
|
Text,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
useToast,
|
useToast,
|
||||||
useDisclosure
|
useDisclosure,
|
||||||
|
Link,
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import React, { useContext, useEffect, useState } from "react";
|
import React, { useContext, useEffect, useState } from "react";
|
||||||
import { HiDotsVertical } from "react-icons/hi";
|
import { HiDotsVertical } from "react-icons/hi";
|
||||||
import { Link, Link as RouterLink, useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { debounce } from "../../Master/Sponser/AddSponser";
|
import { debounce } from "../../Master/Sponser/AddSponser";
|
||||||
import { OPACITY_ON_LOAD } from "../../../Layout/animations";
|
import { OPACITY_ON_LOAD } from "../../../Layout/animations";
|
||||||
import Pagination from "../../../Components/Pagination";
|
import Pagination from "../../../Components/Pagination";
|
||||||
import GlobalStateContext from "../../../Contexts/GlobalStateContext";
|
import GlobalStateContext from "../../../Contexts/GlobalStateContext";
|
||||||
import CustomAlertDialog from "../../../Components/CustomAlertDialog";
|
import CustomAlertDialog from "../../../Components/CustomAlertDialog";
|
||||||
import ToastBox from "../../../Components/ToastBox";
|
import ToastBox from "../../../Components/ToastBox";
|
||||||
import DataTable from "../../../Components/DataTable/DataTable";
|
import NormalTable from "../../../Components/DataTable/NormalTable";
|
||||||
import ConfirmModal from "./ConfirmModal";
|
import ConfirmModal from "./ConfirmModal";
|
||||||
import RejectModal from "./RejectModal";
|
import RejectModal from "./RejectModal";
|
||||||
|
import {
|
||||||
|
useDepositRejectMutation,
|
||||||
|
useGetDepositHistoryQuery,
|
||||||
|
} from "../../../Services/deposit.request.service";
|
||||||
|
import { ExternalLinkIcon } from "@chakra-ui/icons";
|
||||||
|
import { TABLE_PAGINATION } from "../../../Constants/Paginations";
|
||||||
|
|
||||||
const formatDate = (date) => new Date(date).toLocaleDateString(); // Simple date formatter
|
const formatDate = (date) => new Date(date).toLocaleDateString(); // Simple date formatter
|
||||||
|
|
||||||
@@ -36,42 +43,40 @@ const DepositHistory = () => {
|
|||||||
const [actionId, setActionId] = useState(false);
|
const [actionId, setActionId] = useState(false);
|
||||||
const [mouseEntered, setMouseEntered] = useState(false);
|
const [mouseEntered, setMouseEntered] = useState(false);
|
||||||
const [mouseEnteredId, setMouseEnteredId] = useState("");
|
const [mouseEnteredId, setMouseEnteredId] = useState("");
|
||||||
const {
|
// const {
|
||||||
isOpen: isConfirmOpen,
|
// isOpen: isConfirmOpen,
|
||||||
onOpen: onConfirmOpen,
|
// onOpen: onConfirmOpen,
|
||||||
onClose: onConfirmClose,
|
// onClose: onConfirmClose,
|
||||||
} = useDisclosure();
|
// } = useDisclosure();
|
||||||
const {
|
// const {
|
||||||
isOpen: isRejectOpen,
|
// isOpen: isRejectOpen,
|
||||||
onOpen: onRejectOpen,
|
// onOpen: onRejectOpen,
|
||||||
onClose: onRejectClose,
|
// onClose: onRejectClose,
|
||||||
} = useDisclosure();
|
// } = useDisclosure();
|
||||||
|
|
||||||
|
const [pageSize, setPageSize] = useState(TABLE_PAGINATION?.size);
|
||||||
|
const [currentPage, setCurrentPage] = useState(TABLE_PAGINATION?.page);
|
||||||
|
|
||||||
|
const {
|
||||||
|
data,
|
||||||
|
error,
|
||||||
|
isLoading: depositHistoryLoading,
|
||||||
|
} = useGetDepositHistoryQuery({ page: currentPage, size: pageSize });
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
// Simulate loading
|
|
||||||
const timer = setTimeout(() => {
|
|
||||||
setIsLoading(false);
|
|
||||||
}, 1500);
|
|
||||||
|
|
||||||
// Cleanup the timer on component unmount
|
|
||||||
return () => clearTimeout(timer);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
// ====================================================[Table Setup]================================================================
|
// ====================================================[Table Setup]================================================================
|
||||||
const tableHeadRow = [
|
const tableHeadRow = [
|
||||||
"Sr.no",
|
// "Sr.no",
|
||||||
"Date",
|
|
||||||
"Client ID",
|
"Client ID",
|
||||||
"First Name",
|
"First Name",
|
||||||
"Last Name",
|
"Last Name",
|
||||||
"Country",
|
"Country",
|
||||||
"Phone Number",
|
"Phone Number",
|
||||||
"Currency",
|
|
||||||
"Deposit Amount",
|
|
||||||
"Fees",
|
|
||||||
"Total Amount",
|
|
||||||
"Amount in Investor currency",
|
"Amount in Investor currency",
|
||||||
|
"Deposit Date",
|
||||||
"Status",
|
"Status",
|
||||||
|
"Supporting's",
|
||||||
];
|
];
|
||||||
|
|
||||||
const handleUpdateStatus = debounce((id) => {
|
const handleUpdateStatus = debounce((id) => {
|
||||||
@@ -87,22 +92,37 @@ const DepositHistory = () => {
|
|||||||
});
|
});
|
||||||
}, 300);
|
}, 300);
|
||||||
|
|
||||||
// ====================================================[Table Filter]================================================================
|
|
||||||
const filteredData = depositHistory.filter((item) => {
|
|
||||||
// Filter by name (case insensitive)
|
|
||||||
const name = item.clientId;
|
|
||||||
const searchLower = searchTerm.toLowerCase();
|
|
||||||
const nameMatches = name.toLowerCase().includes(searchLower);
|
|
||||||
|
|
||||||
return nameMatches;
|
|
||||||
});
|
|
||||||
|
|
||||||
|
const filteredData = data?.data?.rows
|
||||||
|
.filter((item) => {
|
||||||
|
// Filter by name (case insensitive)
|
||||||
|
const name = [item.firstName, item.lastName, item.countryName].filter(Boolean).join(' ');
|
||||||
|
const searchLower = searchTerm.toLowerCase();
|
||||||
|
const nameMatches = name.toLowerCase().includes(searchLower);
|
||||||
|
|
||||||
|
// Filter by status (Uncomment and use if needed)
|
||||||
|
// const status = item.status;
|
||||||
|
// const statusLower = status ? "active" : "inactive";
|
||||||
|
|
||||||
|
// const statusMatches =
|
||||||
|
// statusFilter === "all" ||
|
||||||
|
// (statusFilter === "active" && status === true) ||
|
||||||
|
// (statusFilter === "inactive" && status === false);
|
||||||
|
|
||||||
|
return nameMatches;
|
||||||
|
})
|
||||||
|
.sort((b, a) => new Date(a.createdAt) - new Date(b.createdAt));
|
||||||
|
|
||||||
|
|
||||||
// const handleView = (id) => {
|
// const handleView = (id) => {
|
||||||
// setActionId(id);
|
// setActionId(id);
|
||||||
// onViewOpen();
|
// onViewOpen();
|
||||||
// };
|
// };
|
||||||
|
|
||||||
const [extractedArray, setExtractedArray] = useState(
|
const extractedArray =
|
||||||
filteredData?.map((item, index) => ({
|
filteredData?.map((item, index) => ({
|
||||||
"Sr.no": (
|
"Sr.no": (
|
||||||
<Text
|
<Text
|
||||||
@@ -116,18 +136,6 @@ const DepositHistory = () => {
|
|||||||
{index + 1}
|
{index + 1}
|
||||||
</Text>
|
</Text>
|
||||||
),
|
),
|
||||||
"Date": (
|
|
||||||
<Text
|
|
||||||
w={"60px"}
|
|
||||||
justifyContent={slideFromRight ? "right" : "left"}
|
|
||||||
as={"span"}
|
|
||||||
color={"teal.900"}
|
|
||||||
fontWeight={"500"}
|
|
||||||
className="d-flex align-items-center web-text-small"
|
|
||||||
>
|
|
||||||
{item.date}
|
|
||||||
</Text>
|
|
||||||
),
|
|
||||||
"Client ID": (
|
"Client ID": (
|
||||||
<Text
|
<Text
|
||||||
w={"60px"}
|
w={"60px"}
|
||||||
@@ -137,98 +145,108 @@ const DepositHistory = () => {
|
|||||||
fontWeight={"500"}
|
fontWeight={"500"}
|
||||||
className="d-flex align-items-center web-text-small"
|
className="d-flex align-items-center web-text-small"
|
||||||
>
|
>
|
||||||
{item.clientId}
|
{item?.clientReference_id}
|
||||||
</Text>
|
</Text>
|
||||||
),
|
),
|
||||||
"First Name": (
|
"First Name": (
|
||||||
<Box isTruncated={true} w={"50px"}>
|
<Box isTruncated={true} w={"60px"}>
|
||||||
<Text as={"span"} color={"teal.900"} fontWeight={"500"}>
|
<Text as={"span"} color={"teal.900"} fontWeight={"500"}>
|
||||||
{item.firstName}
|
{item?.firstName}
|
||||||
</Text>
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
),
|
),
|
||||||
"Last Name": (
|
"Last Name": (
|
||||||
<Box w={"50px"} isTruncated={true}>
|
<Box w={"70px"} isTruncated={true}>
|
||||||
<Text as={"span"} color={"teal.900"}>
|
<Text as={"span"} color={"teal.900"}>
|
||||||
{item.lastName}
|
{item?.lastName}
|
||||||
</Text>
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
),
|
),
|
||||||
Country: (
|
Country: (
|
||||||
<Box w={"70px"} isTruncated={true}>
|
<Box w={"80px"} isTruncated={true}>
|
||||||
<Text as={"span"} color={"teal.900"}>
|
<Text as={"span"} color={"teal.900"}>
|
||||||
{item.country}
|
{item?.countryName}
|
||||||
</Text>
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
),
|
),
|
||||||
"Phone Number": (
|
"Phone Number": (
|
||||||
<Box w={"70px"} isTruncated={true}>
|
<Box w={"80px"} isTruncated={true}>
|
||||||
<Text as={"span"} color={"teal.900"}>
|
<Text as={"span"} color={"teal.900"}>
|
||||||
{item.phoneNumber}
|
{item?.mobileNumber}
|
||||||
</Text>
|
|
||||||
</Box>
|
|
||||||
),
|
|
||||||
Currency: (
|
|
||||||
<Box w={"50px"} isTruncated={true}>
|
|
||||||
<Text as={"span"} color={"teal.900"}>
|
|
||||||
<Badge px={2} py={1}>
|
|
||||||
{item.currency}
|
|
||||||
</Badge>
|
|
||||||
</Text>
|
|
||||||
</Box>
|
|
||||||
),
|
|
||||||
"Deposit Amount": (
|
|
||||||
<Box w={"50px"} isTruncated={true}>
|
|
||||||
<Text as={"span"} color={"teal.900"}>
|
|
||||||
{item.depositAmount}
|
|
||||||
</Text>
|
|
||||||
</Box>
|
|
||||||
),
|
|
||||||
Fees: (
|
|
||||||
<Box w={"auto"} isTruncated={true}>
|
|
||||||
<Text as={"span"} color={"teal.900"}>
|
|
||||||
{item.fees}
|
|
||||||
</Text>
|
|
||||||
</Box>
|
|
||||||
),
|
|
||||||
"Total Amount": (
|
|
||||||
<Box w={"auto"} isTruncated={true}>
|
|
||||||
<Text as={"span"} color={"teal.900"}>
|
|
||||||
{item.totalAmount}
|
|
||||||
</Text>
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
),
|
),
|
||||||
"Amount in Investor currency": (
|
"Amount in Investor currency": (
|
||||||
<Box w={"70px"} isTruncated={true}>
|
<Box w={"100px"} isTruncated={true}>
|
||||||
<Text as={"span"} color={"teal.900"}>
|
<Text as={"span"} color={"teal.900"}>
|
||||||
{item.amountcurrency}
|
{/* <Badge px={2} py={1}> */}
|
||||||
|
{item?.investorAmount} <Badge ms={1} colorScheme="green">{item?.currencyCode}</Badge>
|
||||||
|
{/* </Badge> */}
|
||||||
</Text>
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
),
|
),
|
||||||
|
"Deposit Date": (
|
||||||
|
<Text
|
||||||
|
w={"60px"}
|
||||||
|
justifyContent={slideFromRight ? "right" : "left"}
|
||||||
|
as={"span"}
|
||||||
|
color={"teal.900"}
|
||||||
|
fontWeight={"500"}
|
||||||
|
className="d-flex align-items-center web-text-small"
|
||||||
|
>
|
||||||
|
{formatDate(item?.createdAt)}
|
||||||
|
</Text>
|
||||||
|
),
|
||||||
Status: (
|
Status: (
|
||||||
<Box w={"70px"} isTruncated={true} cursor={'pointer'}>
|
<Box w={"70px"} isTruncated={true} cursor={"pointer"}>
|
||||||
<Text
|
<Text
|
||||||
// onClick={() => {
|
|
||||||
// setActionId(item.id);
|
|
||||||
// onConfirmOpen();
|
|
||||||
// }}
|
|
||||||
onClick={() => {
|
|
||||||
setActionId(item.id);
|
|
||||||
if (item.status === "Approved") {
|
|
||||||
onConfirmOpen();
|
|
||||||
} else {
|
|
||||||
onRejectOpen();
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
as={"span"}
|
as={"span"}
|
||||||
color={item.status === "Approved" ? "green" : "red"}
|
color={item.transactionStatus === "Approved" ? "green.500" : "red.500"}
|
||||||
|
fontWeight={700}
|
||||||
>
|
>
|
||||||
{item.status}
|
{item.transactionStatus}
|
||||||
</Text>
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
),
|
),
|
||||||
|
"Supporting's": (
|
||||||
|
<Text
|
||||||
|
w={"60px"}
|
||||||
|
justifyContent={slideFromRight ? "right" : "left"}
|
||||||
|
as={"span"}
|
||||||
|
color={"teal.900"}
|
||||||
|
fontWeight={"500"}
|
||||||
|
className="d-flex align-items-center web-text-small"
|
||||||
|
>
|
||||||
|
{/* {item?.supporting_FileName} */}
|
||||||
|
<Badge
|
||||||
|
px={2}
|
||||||
|
py={0.5}
|
||||||
|
display={"flex"}
|
||||||
|
alignItems={"center"}
|
||||||
|
textTransform={"inherit"}
|
||||||
|
fontWeight={500}
|
||||||
|
colorScheme={"forestGreen"}
|
||||||
|
>
|
||||||
|
<Link
|
||||||
|
href={import.meta.env.VITE_IMAGE_URL + item?.supporting_FileName}
|
||||||
|
isExternal
|
||||||
|
>
|
||||||
|
<Box
|
||||||
|
as="span"
|
||||||
|
cursor={"pointer"}
|
||||||
|
>
|
||||||
|
View
|
||||||
|
</Box>
|
||||||
|
<ExternalLinkIcon />
|
||||||
|
</Link>
|
||||||
|
{/* <Link to="www.google.com" isExternal>
|
||||||
|
<Box as="span">View</Box> <ExternalLinkIcon />
|
||||||
|
</Link> */}
|
||||||
|
</Badge>
|
||||||
|
</Text>
|
||||||
|
),
|
||||||
}))
|
}))
|
||||||
);
|
|
||||||
|
|
||||||
const handleDelete = () => {
|
const handleDelete = () => {
|
||||||
const IOtype = investmentType.filter(
|
const IOtype = investmentType.filter(
|
||||||
@@ -245,15 +263,14 @@ const DepositHistory = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Box {...OPACITY_ON_LOAD} overflowY={"scroll"} height={"100vh"} pb={38}>
|
<Box {...OPACITY_ON_LOAD} overflowY={"scroll"} height={"100vh"} pb={38}>
|
||||||
<ConfirmModal
|
{/* <ConfirmModal
|
||||||
isOpen={isConfirmOpen}
|
isOpen={isConfirmOpen}
|
||||||
onClose={onConfirmClose}
|
onClose={onConfirmClose}
|
||||||
// firstField={firstField}
|
|
||||||
/>
|
/>
|
||||||
<RejectModal
|
<RejectModal
|
||||||
isOpen={isRejectOpen}
|
isOpen={isRejectOpen}
|
||||||
onClose={onRejectClose}
|
onClose={onRejectClose}
|
||||||
/>
|
/> */}
|
||||||
<Box bg="white.500">
|
<Box bg="white.500">
|
||||||
<HStack
|
<HStack
|
||||||
display={"flex"}
|
display={"flex"}
|
||||||
@@ -276,17 +293,24 @@ const DepositHistory = () => {
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<HStack display={"flex"} alignItems={"center"}>
|
<HStack display={"flex"} alignItems={"center"}>
|
||||||
<Pagination totalItems={10} />
|
<Pagination
|
||||||
|
isLoading={depositHistoryLoading}
|
||||||
|
pageSize={pageSize}
|
||||||
|
setPageSize={setPageSize}
|
||||||
|
currentPage={currentPage}
|
||||||
|
setCurrentPage={setCurrentPage}
|
||||||
|
totalItems={data?.data?.totalItems}
|
||||||
|
/>
|
||||||
</HStack>
|
</HStack>
|
||||||
</HStack>
|
</HStack>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<DataTable
|
<NormalTable
|
||||||
emptyMessage={`We don't have any Investment type `}
|
emptyMessage={`We don't have any Investment type `}
|
||||||
tableHeadRow={tableHeadRow}
|
tableHeadRow={tableHeadRow}
|
||||||
setData={setExtractedArray}
|
// setData={setExtractedArray}
|
||||||
data={extractedArray}
|
data={extractedArray}
|
||||||
isLoading={isLoading}
|
isLoading={depositHistoryLoading}
|
||||||
viewActionId={actionId}
|
viewActionId={actionId}
|
||||||
setViewActionId={setActionId}
|
setViewActionId={setActionId}
|
||||||
setMouseEnteredId={setMouseEnteredId}
|
setMouseEnteredId={setMouseEnteredId}
|
||||||
|
|||||||
250
src/Pages/IO_Management/CreateIO/AddCashDetails.jsx
Normal file
@@ -0,0 +1,250 @@
|
|||||||
|
import {
|
||||||
|
Box,
|
||||||
|
Button,
|
||||||
|
Drawer,
|
||||||
|
DrawerBody,
|
||||||
|
DrawerCloseButton,
|
||||||
|
DrawerContent,
|
||||||
|
DrawerFooter,
|
||||||
|
DrawerHeader,
|
||||||
|
DrawerOverlay,
|
||||||
|
FormControl,
|
||||||
|
FormErrorMessage,
|
||||||
|
FormLabel,
|
||||||
|
Input,
|
||||||
|
Select,
|
||||||
|
Stack,
|
||||||
|
Textarea,
|
||||||
|
useToast,
|
||||||
|
} from "@chakra-ui/react";
|
||||||
|
import * as yup from "yup";
|
||||||
|
import React, { useState, useEffect, useContext } from "react";
|
||||||
|
import { useForm, Controller } from "react-hook-form";
|
||||||
|
import { yupResolver } from "@hookform/resolvers/yup";
|
||||||
|
import CustomAlertDialog from "../../../Components/CustomAlertDialog";
|
||||||
|
import { v4 as uuidv4 } from "uuid";
|
||||||
|
import { useCreateIoCashMutation, useCreateVideoArtifactsMutation, useUpdateVideoArtifactsMutation } from "../../../Services/io.service";
|
||||||
|
import { useParams } from "react-router-dom";
|
||||||
|
import ToastBox from "../../../Components/ToastBox";
|
||||||
|
import GlobalStateContext from "../../../Contexts/GlobalStateContext";
|
||||||
|
import CurrencyInput from "../../../Components/CurrencyInput";
|
||||||
|
|
||||||
|
const cashDetails = yup.object().shape({
|
||||||
|
transactionDate: yup.string().required("Artifact name is required"),
|
||||||
|
ioTransType_xid: yup.number().required("Artifact name is required"),
|
||||||
|
transactionAmount: yup.number().required("Artifact name is required"),
|
||||||
|
comments: yup.string().notRequired(),
|
||||||
|
});
|
||||||
|
|
||||||
|
const AddCashDetails = ({ isOpen, onClose, firstField, actionId, setActionId, data }) => {
|
||||||
|
const params = useParams()
|
||||||
|
const id = params?.id
|
||||||
|
const [file, setFile] = useState("");
|
||||||
|
const [fileName, setFileName] = useState("");
|
||||||
|
const [isLoading, setIsLoading] = useState(false)
|
||||||
|
const [alert, setAlert] = useState(false);
|
||||||
|
const toast = useToast();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ======================[ Cotext Api ]
|
||||||
|
const { IODetails } = useContext(GlobalStateContext);
|
||||||
|
const found = data?.find((item) => item?.id === actionId);
|
||||||
|
|
||||||
|
|
||||||
|
const [createArtifactsVideo] = useCreateVideoArtifactsMutation()
|
||||||
|
const [updateVideoArtifacts] = useUpdateVideoArtifactsMutation()
|
||||||
|
// const {
|
||||||
|
// data
|
||||||
|
// } = useGetArtifactsQuery(id)
|
||||||
|
|
||||||
|
const {
|
||||||
|
control,
|
||||||
|
handleSubmit,
|
||||||
|
watch,
|
||||||
|
reset,
|
||||||
|
formState: { errors },
|
||||||
|
} = useForm({
|
||||||
|
resolver: yupResolver(cashDetails),
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
const [createIoCash] = useCreateIoCashMutation()
|
||||||
|
|
||||||
|
|
||||||
|
const onSubmit = async (data) => {
|
||||||
|
|
||||||
|
setIsLoading(true)
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
const res = await createIoCash({ data, id })
|
||||||
|
if (res?.data?.statusCode === 200) {
|
||||||
|
setIsLoading(false);
|
||||||
|
toast({
|
||||||
|
render: () => <ToastBox message={res?.data?.message} />,
|
||||||
|
});
|
||||||
|
handleClose()
|
||||||
|
}else if(res?.error?.status === 400){
|
||||||
|
setIsLoading(false);
|
||||||
|
toast({
|
||||||
|
render: () => <ToastBox message={res?.error?.data?.message } status={"error"} />,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const handleConfirm = () => {
|
||||||
|
handleSubmit(onSubmit)();
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSave = () => {
|
||||||
|
handleSubmit(onSubmit)();
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleClose = () => {
|
||||||
|
setAlert(false)
|
||||||
|
onClose()
|
||||||
|
reset({
|
||||||
|
transactionAmount:""
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Drawer
|
||||||
|
size={"md"}
|
||||||
|
isOpen={isOpen}
|
||||||
|
placement="right"
|
||||||
|
initialFocusRef={firstField}
|
||||||
|
onClose={handleClose}
|
||||||
|
>
|
||||||
|
<DrawerOverlay />
|
||||||
|
<DrawerContent>
|
||||||
|
<DrawerCloseButton />
|
||||||
|
<DrawerHeader fontSize={"sm"}>IO Cash Details</DrawerHeader>
|
||||||
|
|
||||||
|
<DrawerBody>
|
||||||
|
<Stack spacing={4}>
|
||||||
|
<FormControl isInvalid={errors.transactionDate} isRequired>
|
||||||
|
<FormLabel fontSize={"sm"}>Date Selection</FormLabel>
|
||||||
|
<Controller
|
||||||
|
name="transactionDate"
|
||||||
|
control={control}
|
||||||
|
render={({ field }) => (
|
||||||
|
<Input {...field} fontSize={"sm"} type="date" size={"sm"} />
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<FormErrorMessage fontSize={"xs"} fontWeight={500}>
|
||||||
|
{errors.transactionDate?.message}
|
||||||
|
</FormErrorMessage>
|
||||||
|
</FormControl>
|
||||||
|
|
||||||
|
|
||||||
|
<FormControl isInvalid={errors.ioTransType_xid} isRequired>
|
||||||
|
<FormLabel fontSize={"sm"}>Cash transaction</FormLabel>
|
||||||
|
<Controller
|
||||||
|
name="ioTransType_xid"
|
||||||
|
control={control}
|
||||||
|
render={({ field }) => (
|
||||||
|
<Select
|
||||||
|
{...field}
|
||||||
|
placeholder="Select an option"
|
||||||
|
fontSize={"sm"}
|
||||||
|
size={"sm"}
|
||||||
|
>
|
||||||
|
{IODetails?.ioCashTransaction?.map(({ id, transactionName }) => (
|
||||||
|
<option key={id} value={id}>
|
||||||
|
{transactionName}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<FormErrorMessage fontSize={"xs"} fontWeight={500}>
|
||||||
|
{errors.ioTransType_xid?.message}
|
||||||
|
</FormErrorMessage>
|
||||||
|
</FormControl>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<FormControl isInvalid={errors.transactionAmount} isRequired>
|
||||||
|
<FormLabel fontSize={"sm"}>Transaction Amount</FormLabel>
|
||||||
|
<Controller
|
||||||
|
name="transactionAmount"
|
||||||
|
control={control}
|
||||||
|
render={({ field }) => (
|
||||||
|
<CurrencyInput {...field} textAlign={'right'} fontSize={"sm"} type="number" size={"sm"} />
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<FormErrorMessage fontSize={"xs"} fontWeight={500}>
|
||||||
|
{errors.transactionAmount?.message}
|
||||||
|
</FormErrorMessage>
|
||||||
|
</FormControl>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<FormControl isInvalid={errors.comments}>
|
||||||
|
<FormLabel fontSize={"sm"}>Comments</FormLabel>
|
||||||
|
<Controller
|
||||||
|
name="comments"
|
||||||
|
control={control}
|
||||||
|
render={({ field }) => (
|
||||||
|
<Textarea {...field} textAlign={'right'} fontSize={"sm"} type="text" size={"sm"} />
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<FormErrorMessage fontSize={"xs"} fontWeight={500}>
|
||||||
|
{errors.comments?.message}
|
||||||
|
</FormErrorMessage>
|
||||||
|
</FormControl>
|
||||||
|
|
||||||
|
</Stack>
|
||||||
|
</DrawerBody>
|
||||||
|
|
||||||
|
<DrawerFooter>
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
colorScheme={"forestGreen"}
|
||||||
|
rounded={"sm"}
|
||||||
|
size={"sm"}
|
||||||
|
mr={3}
|
||||||
|
onClick={handleClose}
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
colorScheme={"forestGreen"}
|
||||||
|
rounded={"sm"}
|
||||||
|
size={"sm"}
|
||||||
|
|
||||||
|
onClick={() => setAlert(true)}
|
||||||
|
>
|
||||||
|
Save
|
||||||
|
</Button>
|
||||||
|
</DrawerFooter>
|
||||||
|
</DrawerContent>
|
||||||
|
</Drawer>
|
||||||
|
|
||||||
|
|
||||||
|
<CustomAlertDialog
|
||||||
|
isOpen={alert}
|
||||||
|
onClose={() => setAlert(false)}
|
||||||
|
alertHandler={handleSave}
|
||||||
|
message={"Are you sure you want to add cash details?"}
|
||||||
|
isLoading={isLoading}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AddCashDetails;
|
||||||
234
src/Pages/IO_Management/CreateIO/AddIONav.jsx
Normal file
@@ -0,0 +1,234 @@
|
|||||||
|
import {
|
||||||
|
Box,
|
||||||
|
Button,
|
||||||
|
Drawer,
|
||||||
|
DrawerBody,
|
||||||
|
DrawerCloseButton,
|
||||||
|
DrawerContent,
|
||||||
|
DrawerFooter,
|
||||||
|
DrawerHeader,
|
||||||
|
DrawerOverlay,
|
||||||
|
FormControl,
|
||||||
|
FormErrorMessage,
|
||||||
|
FormLabel,
|
||||||
|
Input,
|
||||||
|
Select,
|
||||||
|
Stack,
|
||||||
|
Textarea,
|
||||||
|
useToast,
|
||||||
|
} from "@chakra-ui/react";
|
||||||
|
import * as yup from "yup";
|
||||||
|
import React, { useState, useEffect, useContext } from "react";
|
||||||
|
import { useForm, Controller } from "react-hook-form";
|
||||||
|
import { yupResolver } from "@hookform/resolvers/yup";
|
||||||
|
import CustomAlertDialog from "../../../Components/CustomAlertDialog";
|
||||||
|
import { v4 as uuidv4 } from "uuid";
|
||||||
|
import { useCreateIoCashMutation, useCreateIoNavMutation, useCreateVideoArtifactsMutation, useUpdateVideoArtifactsMutation } from "../../../Services/io.service";
|
||||||
|
import { useParams } from "react-router-dom";
|
||||||
|
import ToastBox from "../../../Components/ToastBox";
|
||||||
|
import GlobalStateContext from "../../../Contexts/GlobalStateContext";
|
||||||
|
import CurrencyInput from "../../../Components/CurrencyInput";
|
||||||
|
import { formatDatee } from "../../../Components/FormField";
|
||||||
|
|
||||||
|
const ioNav = yup.object().shape({
|
||||||
|
transactionDate: yup.string().required("Artifact name is required"),
|
||||||
|
transactionAmount: yup.number().required("Artifact name is required"),
|
||||||
|
comments: yup.string().notRequired(),
|
||||||
|
});
|
||||||
|
|
||||||
|
const AddIONav = ({ isOpen, onClose, firstField, actionId, setActionId, data }) => {
|
||||||
|
const params = useParams()
|
||||||
|
const id = params?.id
|
||||||
|
const [file, setFile] = useState("");
|
||||||
|
const [fileName, setFileName] = useState("");
|
||||||
|
const [isLoading, setIsLoading] = useState(false)
|
||||||
|
const [alert, setAlert] = useState(false);
|
||||||
|
const toast = useToast();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ======================[ Cotext Api ]
|
||||||
|
const { IODetails } = useContext(GlobalStateContext);
|
||||||
|
const found = data?.find((item) => item?.id === actionId);
|
||||||
|
|
||||||
|
|
||||||
|
const [createIoNav] = useCreateIoNavMutation()
|
||||||
|
// const {
|
||||||
|
// data
|
||||||
|
// } = useGetArtifactsQuery(id)
|
||||||
|
|
||||||
|
const {
|
||||||
|
control,
|
||||||
|
handleSubmit,
|
||||||
|
watch,
|
||||||
|
reset,
|
||||||
|
formState: { errors },
|
||||||
|
} = useForm({
|
||||||
|
resolver: yupResolver(ioNav),
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
const [createIoCash] = useCreateIoCashMutation()
|
||||||
|
|
||||||
|
|
||||||
|
const onSubmit = async (data) => {
|
||||||
|
|
||||||
|
setIsLoading(true)
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
const res = await createIoNav({ data, id })
|
||||||
|
if (res?.data?.statusCode === 201) {
|
||||||
|
setIsLoading(false);
|
||||||
|
toast({
|
||||||
|
render: () => <ToastBox message={res?.data?.message} />,
|
||||||
|
});
|
||||||
|
handleClose()
|
||||||
|
}else if(res?.error?.status === 400){
|
||||||
|
setIsLoading(false);
|
||||||
|
toast({
|
||||||
|
render: () => <ToastBox message={res?.error?.data?.message } status={"error"} />,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const handleConfirm = () => {
|
||||||
|
handleSubmit(onSubmit)();
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSave = () => {
|
||||||
|
handleSubmit(onSubmit)();
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleClose = () => {
|
||||||
|
setAlert(false)
|
||||||
|
onClose()
|
||||||
|
reset({
|
||||||
|
transactionDate:"",
|
||||||
|
transactionAmount:"",
|
||||||
|
comments:""
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const today = formatDatee(new Date(), 'yyyy-MM-dd');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Drawer
|
||||||
|
size={"md"}
|
||||||
|
isOpen={isOpen}
|
||||||
|
placement="right"
|
||||||
|
initialFocusRef={firstField}
|
||||||
|
onClose={handleClose}
|
||||||
|
>
|
||||||
|
<DrawerOverlay />
|
||||||
|
<DrawerContent>
|
||||||
|
<DrawerCloseButton />
|
||||||
|
<DrawerHeader fontSize={"sm"}>IO Nav Details</DrawerHeader>
|
||||||
|
|
||||||
|
<DrawerBody>
|
||||||
|
<Stack spacing={4}>
|
||||||
|
<FormControl isInvalid={errors.transactionDate} isRequired>
|
||||||
|
<FormLabel fontSize={"sm"}>Date Selection</FormLabel>
|
||||||
|
<Controller
|
||||||
|
name="transactionDate"
|
||||||
|
control={control}
|
||||||
|
render={({ field }) => (
|
||||||
|
<Input {...field}
|
||||||
|
max={today} // Set max attribute to today’s date
|
||||||
|
fontSize={"sm"} type="date" size={"sm"} />
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<FormErrorMessage fontSize={"xs"} fontWeight={500}>
|
||||||
|
{errors.transactionDate?.message}
|
||||||
|
</FormErrorMessage>
|
||||||
|
</FormControl>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<FormControl isInvalid={errors.transactionAmount} isRequired>
|
||||||
|
<FormLabel fontSize={"sm"}>Transaction Amount</FormLabel>
|
||||||
|
<Controller
|
||||||
|
name="transactionAmount"
|
||||||
|
control={control}
|
||||||
|
render={({ field }) => (
|
||||||
|
<CurrencyInput {...field} textAlign={'right'} fontSize={"sm"} type="number" size={"sm"} />
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<FormErrorMessage fontSize={"xs"} fontWeight={500}>
|
||||||
|
{errors.transactionAmount?.message}
|
||||||
|
</FormErrorMessage>
|
||||||
|
</FormControl>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<FormControl isInvalid={errors.comments}>
|
||||||
|
<FormLabel fontSize={"sm"}>Comments</FormLabel>
|
||||||
|
<Controller
|
||||||
|
name="comments"
|
||||||
|
control={control}
|
||||||
|
render={({ field }) => (
|
||||||
|
<Textarea {...field} fontSize={"sm"} type="text" size={"sm"} />
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<FormErrorMessage fontSize={"xs"} fontWeight={500}>
|
||||||
|
{errors.comments?.message}
|
||||||
|
</FormErrorMessage>
|
||||||
|
</FormControl>
|
||||||
|
|
||||||
|
</Stack>
|
||||||
|
</DrawerBody>
|
||||||
|
|
||||||
|
<DrawerFooter>
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
colorScheme={"forestGreen"}
|
||||||
|
rounded={"sm"}
|
||||||
|
size={"sm"}
|
||||||
|
mr={3}
|
||||||
|
onClick={handleClose}
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
colorScheme={"forestGreen"}
|
||||||
|
rounded={"sm"}
|
||||||
|
size={"sm"}
|
||||||
|
|
||||||
|
onClick={() => setAlert(true)}
|
||||||
|
>
|
||||||
|
Save
|
||||||
|
</Button>
|
||||||
|
</DrawerFooter>
|
||||||
|
</DrawerContent>
|
||||||
|
</Drawer>
|
||||||
|
|
||||||
|
|
||||||
|
<CustomAlertDialog
|
||||||
|
isOpen={alert}
|
||||||
|
onClose={() => setAlert(false)}
|
||||||
|
alertHandler={handleSave}
|
||||||
|
message={"Are you sure you want to add NAV details?"}
|
||||||
|
isLoading={isLoading}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AddIONav;
|
||||||
|
|
||||||
@@ -15,6 +15,7 @@ import ViewIOdataHeader from "../ViewIO/ViewIOdataHeader";
|
|||||||
import { useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
import FullscreenLoaders from "../../../Components/Loaders/FullscreenLoaders";
|
import FullscreenLoaders from "../../../Components/Loaders/FullscreenLoaders";
|
||||||
import { useGetIOprepopulateDataQuery } from "../../../Services/io.service";
|
import { useGetIOprepopulateDataQuery } from "../../../Services/io.service";
|
||||||
|
import UnderConstruction from "../../UnderConstruction";
|
||||||
|
|
||||||
const CreateIO = () => {
|
const CreateIO = () => {
|
||||||
const id = useParams()?.id;
|
const id = useParams()?.id;
|
||||||
@@ -57,18 +58,24 @@ const CreateIO = () => {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Investors",
|
label: "Investors",
|
||||||
Content: Investors,
|
// Content: Investors,
|
||||||
isDisabled: id ? false : false,
|
Content: UnderConstruction,
|
||||||
|
isDisabled: id ? false : true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "IO Cash Details",
|
label: "IO Cash Detail",
|
||||||
Content: IOCashDetails,
|
Content: IOCashDetails,
|
||||||
isDisabled: id ? false : false,
|
isDisabled: id ? false : true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "IO NAV Details",
|
label: "IO NAV Details",
|
||||||
Content: IONAVDetails,
|
Content: IONAVDetails,
|
||||||
isDisabled: id ? false : false,
|
isDisabled: id ? false : true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Distribution to Investors",
|
||||||
|
Content: IONAVDetails,
|
||||||
|
isDisabled: id ? false : true,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -86,19 +93,23 @@ const CreateIO = () => {
|
|||||||
height={"100vh"}
|
height={"100vh"}
|
||||||
pb={10}
|
pb={10}
|
||||||
>
|
>
|
||||||
<Box paddingInline={"12px"} mt={2}>
|
{id && <Box
|
||||||
|
ps={1}
|
||||||
|
pe={2} mt={2}>
|
||||||
{/* <span
|
{/* <span
|
||||||
onClick={() => navigate(-1)}
|
onClick={() => navigate(-1)}
|
||||||
style={{ fontSize: "15px", cursor: "pointer" }}
|
style={{ fontSize: "15px", cursor: "pointer" }}
|
||||||
>
|
>
|
||||||
<ArrowBackIcon cursor={"pointer"} /> Back
|
<ArrowBackIcon cursor={"pointer"} /> Back
|
||||||
</span> */}
|
</span> */}
|
||||||
<ViewIOdataHeader />
|
<ViewIOdataHeader isLoading={isLoading} data={data?.data} />
|
||||||
</Box>
|
</Box>}
|
||||||
<Tabs
|
<Tabs
|
||||||
index={activeIndex}
|
index={activeIndex}
|
||||||
onChange={(index) => setActiveIndex(index)}
|
onChange={(index) => setActiveIndex(index)}
|
||||||
mt={2}
|
mt={2}
|
||||||
|
ps={1}
|
||||||
|
pe={2}
|
||||||
>
|
>
|
||||||
<TabList>
|
<TabList>
|
||||||
{tabs?.map(({ label, isDisabled }, index) => (
|
{tabs?.map(({ label, isDisabled }, index) => (
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import {
|
|||||||
Text,
|
Text,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
useDisclosure,
|
useDisclosure,
|
||||||
|
useToast,
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import React, { useContext, useEffect, useRef, useState } from "react";
|
import React, { useContext, useEffect, useRef, useState } from "react";
|
||||||
import DataTable from "../../../Components/DataTable/DataTable";
|
import DataTable from "../../../Components/DataTable/DataTable";
|
||||||
@@ -30,8 +31,10 @@ import {
|
|||||||
} from "../../../Services/io.service";
|
} from "../../../Services/io.service";
|
||||||
import { getFileNameFromPath } from "../../../Constants/Constants";
|
import { getFileNameFromPath } from "../../../Constants/Constants";
|
||||||
import ImageViewer from "../../../Components/ImageViewer";
|
import ImageViewer from "../../../Components/ImageViewer";
|
||||||
|
import ToastBox from "../../../Components/ToastBox";
|
||||||
|
|
||||||
const IOArtifacts = ({ enableNextTab, index, data }) => {
|
const IOArtifacts = ({ enableNextTab, index, data }) => {
|
||||||
|
const toast = useToast()
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
const id = params?.id;
|
const id = params?.id;
|
||||||
|
|
||||||
@@ -107,10 +110,12 @@ const IOArtifacts = ({ enableNextTab, index, data }) => {
|
|||||||
setIsLoadingBtn(true);
|
setIsLoadingBtn(true);
|
||||||
try {
|
try {
|
||||||
const res = await deleteVideoArtifacts(id);
|
const res = await deleteVideoArtifacts(id);
|
||||||
console.log(res?.data?.statusCode);
|
|
||||||
if (res?.data?.statusCode === 200) {
|
if (res?.data?.statusCode === 200) {
|
||||||
setDeleteAlertVideo(false);
|
setDeleteAlertVideo(false);
|
||||||
setIsLoadingBtn(false);
|
setIsLoadingBtn(false);
|
||||||
|
toast({
|
||||||
|
render: () => <ToastBox message={res?.data?.message} status="error" />,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
@@ -121,10 +126,15 @@ const IOArtifacts = ({ enableNextTab, index, data }) => {
|
|||||||
setIsLoadingBtn(true);
|
setIsLoadingBtn(true);
|
||||||
try {
|
try {
|
||||||
const res = await deleteImageArtifacts(id);
|
const res = await deleteImageArtifacts(id);
|
||||||
console.log(res?.data?.statusCode);
|
console.log(res);
|
||||||
|
|
||||||
if (res?.data?.statusCode === 200) {
|
if (res?.data?.statusCode === 200) {
|
||||||
setDeleteAlertImage(false);
|
setDeleteAlertImage(false);
|
||||||
setIsLoadingBtn(false);
|
setIsLoadingBtn(false);
|
||||||
|
toast({
|
||||||
|
render: () => <ToastBox message={res?.data?.message} status="error" />,
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
@@ -170,7 +180,7 @@ const IOArtifacts = ({ enableNextTab, index, data }) => {
|
|||||||
colorScheme={"forestGreen"}
|
colorScheme={"forestGreen"}
|
||||||
>
|
>
|
||||||
<Link
|
<Link
|
||||||
href={"https://tanami.betadelivery.com/" + item?.artifactPathName}
|
href={import.meta.env.VITE_IMAGE_URL + item?.artifactPathName}
|
||||||
isExternal
|
isExternal
|
||||||
>
|
>
|
||||||
<Box
|
<Box
|
||||||
@@ -342,7 +352,9 @@ const IOArtifacts = ({ enableNextTab, index, data }) => {
|
|||||||
Manage IO Images
|
Manage IO Images
|
||||||
</Box>
|
</Box>
|
||||||
<HStack>
|
<HStack>
|
||||||
<SetDisplayOrder data={IObyID?.data?.artifactsImage} />
|
|
||||||
|
|
||||||
|
{IObyID?.data?.artifactsImage?.length !== 0 &&<SetDisplayOrder data={IObyID?.data?.artifactsImage} />}
|
||||||
<Button
|
<Button
|
||||||
leftIcon={<AddIcon />}
|
leftIcon={<AddIcon />}
|
||||||
onClick={onOpen}
|
onClick={onOpen}
|
||||||
@@ -378,7 +390,7 @@ const IOArtifacts = ({ enableNextTab, index, data }) => {
|
|||||||
Manage IO videos
|
Manage IO videos
|
||||||
</Box>
|
</Box>
|
||||||
<HStack>
|
<HStack>
|
||||||
<SetDisplayOrder data={IObyID?.data?.artifactsImage} />
|
{IObyID?.data?.artifactsVideo?.length !== 0 &&<SetDisplayOrder data={IObyID?.data?.artifactsVideo} />}
|
||||||
<Button
|
<Button
|
||||||
leftIcon={<AddIcon />}
|
leftIcon={<AddIcon />}
|
||||||
onClick={onOpenVideo}
|
onClick={onOpenVideo}
|
||||||
|
|||||||
@@ -27,24 +27,28 @@ import ToastBox from "../../../Components/ToastBox";
|
|||||||
|
|
||||||
const investmentVideoSchema = yup.object().shape({
|
const investmentVideoSchema = yup.object().shape({
|
||||||
artifactName: yup.string().required("Artifact name is required"),
|
artifactName: yup.string().required("Artifact name is required"),
|
||||||
artifactStreamingURL: yup.string().required("Artifact streaming URL is required").url("Invalid URL format"),
|
artifactStreamingURL: yup.string()
|
||||||
|
.required("Artifact streaming URL is required")
|
||||||
|
.url("Invalid URL format")
|
||||||
|
.matches(/\.mp4$/, "URL must end with .mp4"),
|
||||||
});
|
});
|
||||||
|
|
||||||
const IOArtifactsAdd = ({ isOpen, onClose, firstField, actionId, setActionId, data}) => {
|
const IOArtifactsAdd = ({ isOpen, onClose, firstField, actionId, setActionId, data }) => {
|
||||||
const params = useParams()
|
const params = useParams()
|
||||||
const id = params?.id
|
const id = params?.id
|
||||||
const [file, setFile] = useState("");
|
const [file, setFile] = useState("");
|
||||||
const [fileName, setFileName] = useState("");
|
const [fileName, setFileName] = useState("");
|
||||||
const [ isLoading, setIsLoading] = useState(false)
|
const [isLoading, setIsLoading] = useState(false)
|
||||||
const [alert, setAlert] = useState(false);
|
const [alert, setAlert] = useState(false);
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
|
|
||||||
|
|
||||||
const found = data?.find((item) => item?.id === actionId);
|
const found = data?.find((item) => item?.id === actionId);
|
||||||
console.log(found);
|
console.log(actionId);
|
||||||
|
|
||||||
const [ createArtifactsVideo ] = useCreateVideoArtifactsMutation()
|
|
||||||
const [ updateVideoArtifacts ] = useUpdateVideoArtifactsMutation()
|
const [createArtifactsVideo] = useCreateVideoArtifactsMutation()
|
||||||
|
const [updateVideoArtifacts] = useUpdateVideoArtifactsMutation()
|
||||||
// const {
|
// const {
|
||||||
// data
|
// data
|
||||||
// } = useGetArtifactsQuery(id)
|
// } = useGetArtifactsQuery(id)
|
||||||
@@ -63,7 +67,7 @@ const IOArtifactsAdd = ({ isOpen, onClose, firstField, actionId, setActionId, d
|
|||||||
|
|
||||||
// useEffect to reset the form when `found` changes
|
// useEffect to reset the form when `found` changes
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (found) {
|
if (found && actionId) {
|
||||||
reset({
|
reset({
|
||||||
artifactName: found?.artifactName,
|
artifactName: found?.artifactName,
|
||||||
artifactStreamingURL: found?.artifactStreamingURL,
|
artifactStreamingURL: found?.artifactStreamingURL,
|
||||||
@@ -71,8 +75,6 @@ const IOArtifactsAdd = ({ isOpen, onClose, firstField, actionId, setActionId, d
|
|||||||
}
|
}
|
||||||
}, [found, reset]);
|
}, [found, reset]);
|
||||||
|
|
||||||
console.log(watch());
|
|
||||||
|
|
||||||
|
|
||||||
const onSubmit = async (data) => {
|
const onSubmit = async (data) => {
|
||||||
setIsLoading(true)
|
setIsLoading(true)
|
||||||
@@ -83,25 +85,26 @@ const IOArtifactsAdd = ({ isOpen, onClose, firstField, actionId, setActionId, d
|
|||||||
|
|
||||||
|
|
||||||
if (found) {
|
if (found) {
|
||||||
const res = await updateVideoArtifacts({data, id: found?.id})
|
const res = await updateVideoArtifacts({ data, id: found?.id })
|
||||||
if (res?.data?.statusCode === 200) {
|
if (res?.data?.statusCode === 200) {
|
||||||
toast({
|
toast({
|
||||||
render: () => <ToastBox message={res?.data?.message} />,
|
render: () => <ToastBox message={res?.data?.message} />,
|
||||||
});
|
});
|
||||||
setAlert(false);
|
setAlert(false);
|
||||||
setIsLoading(false)
|
setIsLoading(false)
|
||||||
handleClose();
|
handleClose();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
const res = await createArtifactsVideo({data, id})
|
const res = await createArtifactsVideo({ data, id })
|
||||||
if (res?.data?.statusCode === 200) {
|
if (res?.data?.statusCode === 200) {
|
||||||
toast({
|
toast({
|
||||||
render: () => <ToastBox message={res?.data?.message} />,
|
render: () => <ToastBox message={res?.data?.message} />,
|
||||||
});
|
});
|
||||||
setAlert(false);
|
setAlert(false);
|
||||||
setIsLoading(false)
|
setIsLoading(false)
|
||||||
handleClose();
|
setActionId(false);
|
||||||
|
handleClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -128,12 +131,16 @@ const IOArtifactsAdd = ({ isOpen, onClose, firstField, actionId, setActionId, d
|
|||||||
onClose()
|
onClose()
|
||||||
reset()
|
reset()
|
||||||
setActionId(false);
|
setActionId(false);
|
||||||
|
reset({
|
||||||
|
artifactName: "",
|
||||||
|
artifactStreamingURL: "",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Drawer
|
<Drawer
|
||||||
size={"md"}
|
size={"md"}
|
||||||
isOpen={isOpen}
|
isOpen={isOpen}
|
||||||
placement="right"
|
placement="right"
|
||||||
initialFocusRef={firstField}
|
initialFocusRef={firstField}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import {
|
import {
|
||||||
|
Avatar,
|
||||||
Box,
|
Box,
|
||||||
Button,
|
Button,
|
||||||
HStack,
|
HStack,
|
||||||
@@ -9,23 +10,27 @@ import {
|
|||||||
Text,
|
Text,
|
||||||
Th,
|
Th,
|
||||||
Tr,
|
Tr,
|
||||||
|
useDisclosure,
|
||||||
useToast,
|
useToast,
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import React, { useContext, useEffect, useState } from "react";
|
import React, { useContext, useEffect, useRef, useState } from "react";
|
||||||
import { OPACITY_ON_LOAD } from "../../../Layout/animations";
|
import { OPACITY_ON_LOAD } from "../../../Layout/animations";
|
||||||
import DataTable from "../../../Components/DataTable/DataTable";
|
import NormalTable from "../../../Components/DataTable/NormalTable";
|
||||||
import Pagination from "../../../Components/Pagination";
|
import Pagination from "../../../Components/Pagination";
|
||||||
import GlobalStateContext from "../../../Contexts/GlobalStateContext";
|
import GlobalStateContext from "../../../Contexts/GlobalStateContext";
|
||||||
import CustomAlertDialog from "../../../Components/CustomAlertDialog";
|
import CustomAlertDialog from "../../../Components/CustomAlertDialog";
|
||||||
import ToastBox from "../../../Components/ToastBox";
|
import ToastBox from "../../../Components/ToastBox";
|
||||||
import { debounce } from "../../Master/Sponser/AddSponser";
|
import { debounce } from "../../Master/Sponser/AddSponser";
|
||||||
|
import { AddIcon } from "@chakra-ui/icons";
|
||||||
|
import AddCashDetails from "./AddCashDetails";
|
||||||
|
|
||||||
const formatDate = (date) => new Date(date).toLocaleDateString(); // Simple date formatter
|
const formatDate = (date) => new Date(date).toLocaleDateString(); // Simple date formatter
|
||||||
|
|
||||||
const IOCashDetails = () => {
|
const IOCashDetails = () => {
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
const { caseDetails, setCaseDetails, slideFromRight } =
|
const firstField = useRef();
|
||||||
useContext(GlobalStateContext);
|
const { isOpen, onOpen, onClose } = useDisclosure();
|
||||||
|
const { caseDetails, setCaseDetails, IODetails } = useContext(GlobalStateContext);
|
||||||
const [searchTerm, setSearchTerm] = useState("");
|
const [searchTerm, setSearchTerm] = useState("");
|
||||||
const [isLoading, setIsLoading] = useState(true);
|
const [isLoading, setIsLoading] = useState(true);
|
||||||
const [deleteAlert, setDeleteAlert] = useState(false);
|
const [deleteAlert, setDeleteAlert] = useState(false);
|
||||||
@@ -52,7 +57,7 @@ const IOCashDetails = () => {
|
|||||||
// Table setup
|
// Table setup
|
||||||
const tableHeadRow = [
|
const tableHeadRow = [
|
||||||
"Date",
|
"Date",
|
||||||
"Particulars",
|
"Transaction type",
|
||||||
"Amount",
|
"Amount",
|
||||||
"Comments",
|
"Comments",
|
||||||
"Update by ",
|
"Update by ",
|
||||||
@@ -71,52 +76,52 @@ const IOCashDetails = () => {
|
|||||||
}, 300);
|
}, 300);
|
||||||
|
|
||||||
// Table filter
|
// Table filter
|
||||||
const filteredData = caseDetails.filter((item) => {
|
const filteredData = IODetails?.ioCashHistory?.filter((item) => {
|
||||||
const name = item.date;
|
const name = item.transactionType;
|
||||||
const searchLower = searchTerm.toLowerCase();
|
const searchLower = searchTerm.toLowerCase();
|
||||||
const nameMatches = name.toLowerCase().includes(searchLower);
|
const nameMatches = name.toLowerCase().includes(searchLower);
|
||||||
return nameMatches;
|
return nameMatches;
|
||||||
});
|
}).sort((b, a) => new Date(a.createdAt) - new Date(b.createdAt));
|
||||||
|
|
||||||
|
|
||||||
const [ extractedArray, setExtractedArray ] = useState(filteredData?.map((item, index) => ({
|
const extractedArray = filteredData?.map((item, index) => ({
|
||||||
id: item?.id,
|
id: item?.id,
|
||||||
"Date": (
|
"Date": (
|
||||||
<Text
|
<Text
|
||||||
justifyContent={slideFromRight ? "right" : "center"}
|
justifyContent={"center"}
|
||||||
as={"span"}
|
as={"span"}
|
||||||
color={"teal.900"}
|
color={"teal.900"}
|
||||||
fontWeight={"500"}
|
fontWeight={"500"}
|
||||||
className="d-flex align-items-center web-text-small"
|
className="d-flex align-items-center web-text-small"
|
||||||
>
|
>
|
||||||
{item.date}
|
{item?.transactionDate}
|
||||||
</Text>
|
</Text>
|
||||||
),
|
),
|
||||||
"Particulars": (
|
"Transaction type": (
|
||||||
<Text
|
<Text
|
||||||
justifyContent={slideFromRight ? "right" : "center"}
|
justifyContent ={"center"}
|
||||||
as={"span"}
|
as={"span"}
|
||||||
color={"teal.900"}
|
color={"teal.900"}
|
||||||
fontWeight={"500"}
|
fontWeight={"500"}
|
||||||
className="d-flex align-items-center web-text-small"
|
className="d-flex align-items-center web-text-small"
|
||||||
>
|
>
|
||||||
{item.particulars}
|
{item?.transactionType}
|
||||||
</Text>
|
</Text>
|
||||||
),
|
),
|
||||||
"Amount": (
|
"Amount": (
|
||||||
<Text
|
<Text
|
||||||
justifyContent={slideFromRight ? "right" : "center"}
|
justifyContent ={"center"}
|
||||||
as={"span"}
|
as={"span"}
|
||||||
color={"teal.900"}
|
color={"teal.900"}
|
||||||
fontWeight={"500"}
|
fontWeight={"500"}
|
||||||
className="d-flex align-items-center web-text-small"
|
className="d-flex align-items-center web-text-small"
|
||||||
>
|
>
|
||||||
{item.amount}
|
{`$${parseFloat(item.transactionAmount||0).toLocaleString()}`}
|
||||||
</Text>
|
</Text>
|
||||||
),
|
),
|
||||||
"Comments": (
|
"Comments": (
|
||||||
<Text
|
<Text
|
||||||
justifyContent={slideFromRight ? "right" : "center"}
|
justifyContent ={"center"}
|
||||||
as={"span"}
|
as={"span"}
|
||||||
color={"teal.900"}
|
color={"teal.900"}
|
||||||
fontWeight={"500"}
|
fontWeight={"500"}
|
||||||
@@ -127,18 +132,20 @@ const IOCashDetails = () => {
|
|||||||
),
|
),
|
||||||
"Update by ": (
|
"Update by ": (
|
||||||
<Text
|
<Text
|
||||||
justifyContent={slideFromRight ? "right" : "center"}
|
justifyContent ={"center"}
|
||||||
as={"span"}
|
as={"span"}
|
||||||
color={"teal.900"}
|
color={"teal.900"}
|
||||||
fontWeight={"500"}
|
fontWeight={"500"}
|
||||||
|
gap={2}
|
||||||
className="d-flex align-items-center web-text-small"
|
className="d-flex align-items-center web-text-small"
|
||||||
>
|
>
|
||||||
{item.updateBy}
|
|
||||||
|
<Avatar size='sm' name={item.creator?.firstName} src={item.creator?.profilePhoto} />{item.creator?.firstName}
|
||||||
</Text>
|
</Text>
|
||||||
),
|
),
|
||||||
"Update On": (
|
"Update On": (
|
||||||
<Text
|
<Text
|
||||||
justifyContent={slideFromRight ? "right" : "center"}
|
justifyContent ={"center"}
|
||||||
as={"span"}
|
as={"span"}
|
||||||
color={"teal.900"}
|
color={"teal.900"}
|
||||||
fontWeight={"500"}
|
fontWeight={"500"}
|
||||||
@@ -147,7 +154,7 @@ const IOCashDetails = () => {
|
|||||||
{item.updateOn}
|
{item.updateOn}
|
||||||
</Text>
|
</Text>
|
||||||
),
|
),
|
||||||
})));
|
}));
|
||||||
|
|
||||||
const handleDelete = () => {
|
const handleDelete = () => {
|
||||||
const updatedSponsors = sponser.filter(
|
const updatedSponsors = sponser.filter(
|
||||||
@@ -260,18 +267,17 @@ const IOCashDetails = () => {
|
|||||||
onChange={(e) => setSearchTerm(e.target.value)}
|
onChange={(e) => setSearchTerm(e.target.value)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<HStack display={"flex"} alignItems={"center"}>
|
|
||||||
<Pagination totalItems={10} />
|
{IODetails?.isInvestedAmount ? <Button onClick={onOpen} leftIcon={<AddIcon/>} colorScheme="forestGreen" size={'sm'} rounded={'sm'} fontSize={'xs'} >Add IO Cash</Button>:null}
|
||||||
</HStack>
|
|
||||||
</HStack>
|
</HStack>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<DataTable
|
<NormalTable
|
||||||
centered={true}
|
centered={true}
|
||||||
emptyMessage={`We don't have any Sponers`}
|
emptyMessage={`We don't have any Sponers`}
|
||||||
tableHeadRow={tableHeadRow}
|
tableHeadRow={tableHeadRow}
|
||||||
data={extractedArray}
|
data={extractedArray}
|
||||||
setData={setExtractedArray}
|
|
||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
viewActionId={actionId}
|
viewActionId={actionId}
|
||||||
setViewActionId={setActionId}
|
setViewActionId={setActionId}
|
||||||
@@ -287,6 +293,24 @@ const IOCashDetails = () => {
|
|||||||
alertHandler={handleDelete}
|
alertHandler={handleDelete}
|
||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<AddCashDetails
|
||||||
|
isOpen={isOpen}
|
||||||
|
onClose={onClose}
|
||||||
|
firstField={firstField} />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -33,13 +33,15 @@ import oman from "../../../assets/oman_flag.png";
|
|||||||
import qatar from "../../../assets/qatar_flag.png";
|
import qatar from "../../../assets/qatar_flag.png";
|
||||||
import uae from "../../../assets/uae_flag.png";
|
import uae from "../../../assets/uae_flag.png";
|
||||||
import saudi from "../../../assets/saudi_arabia_flag.png";
|
import saudi from "../../../assets/saudi_arabia_flag.png";
|
||||||
|
import { formatDatee } from "../../../Components/FormField";
|
||||||
|
import { removeTrailingZeros } from "../../../Constants/Constants";
|
||||||
|
|
||||||
const schema = yup.object().shape({
|
const schema = yup.object().shape({
|
||||||
investmentNameEnglish: yup
|
investmentNameEnglish: yup
|
||||||
.string()
|
.string()
|
||||||
.required("IO name in English is required")
|
.required("IO name in English is required")
|
||||||
.min(3, "IO name in English must be at least 3 characters long")
|
.min(3, "IO name in English must be at least 3 characters long")
|
||||||
.max(50, "IO name in English must be at most 50 characters long"),
|
.max(150, "IO name in English must be at most 150 characters long"),
|
||||||
|
|
||||||
investmentNameArabic: yup
|
investmentNameArabic: yup
|
||||||
.string()
|
.string()
|
||||||
@@ -58,12 +60,15 @@ const schema = yup.object().shape({
|
|||||||
.required("Description in Arabic is required")
|
.required("Description in Arabic is required")
|
||||||
.min(10, "Description in Arabic must be at least 10 characters long")
|
.min(10, "Description in Arabic must be at least 10 characters long")
|
||||||
.max(2000, "Description in Arabic must be at most 500 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
|
goalAmount: yup
|
||||||
.number()
|
.number()
|
||||||
.required("Goal amount is required")
|
.typeError("Goal Amount is must be number")
|
||||||
.positive("Goal amount must be a positive number")
|
.required('Goal amount is required')
|
||||||
.min(1, "Goal amount must be at least 1"),
|
.positive('Goal amount must be a positive number'),
|
||||||
|
|
||||||
closingDate: yup
|
closingDate: yup
|
||||||
.date()
|
.date()
|
||||||
@@ -71,6 +76,7 @@ const schema = yup.object().shape({
|
|||||||
.min(new Date(), "Closing date cannot be in the past"),
|
.min(new Date(), "Closing date cannot be in the past"),
|
||||||
|
|
||||||
holdingPeriod: yup.string().required("Holding period is required"),
|
holdingPeriod: yup.string().required("Holding period is required"),
|
||||||
|
holdingPeriodArabic: yup.string().required("Holding period is required"),
|
||||||
|
|
||||||
// minInvestmentAmount: yup
|
// minInvestmentAmount: yup
|
||||||
// .number()
|
// .number()
|
||||||
@@ -95,6 +101,9 @@ const schema = yup.object().shape({
|
|||||||
const IODetails = ({ enableNextTab, index, data }) => {
|
const IODetails = ({ enableNextTab, index, data }) => {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
@@ -113,7 +122,7 @@ const IODetails = ({ enableNextTab, index, data }) => {
|
|||||||
const id = params?.id;
|
const id = params?.id;
|
||||||
|
|
||||||
// ======================[ Cotext Api ]
|
// ======================[ Cotext Api ]
|
||||||
const { investmentType, sponser, IODetails, setIODetails } =
|
const { investmentType, sponser, setIOStatus, setIODetails, setIOloading } =
|
||||||
useContext(GlobalStateContext);
|
useContext(GlobalStateContext);
|
||||||
|
|
||||||
// ======================[ RTK Querry Api ]
|
// ======================[ RTK Querry Api ]
|
||||||
@@ -124,8 +133,6 @@ const IODetails = ({ enableNextTab, index, data }) => {
|
|||||||
error: IObyIDerror,
|
error: IObyIDerror,
|
||||||
} = useGetIOByIdQuery(id, { skip: !id });
|
} = useGetIOByIdQuery(id, { skip: !id });
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const [creatIO] = useCreateIOMutation();
|
const [creatIO] = useCreateIOMutation();
|
||||||
const [updateIO] = useUpdateIOMutation();
|
const [updateIO] = useUpdateIOMutation();
|
||||||
|
|
||||||
@@ -147,22 +154,24 @@ const IODetails = ({ enableNextTab, index, data }) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const miniValue = data?.country?.map(
|
const miniValue = data?.country?.map(
|
||||||
({ countryName, flagIcon, minInvestmentAmt, countryCode, id }, index) => {
|
({ countryName, flagIcon, minInvestmentAmt, countryCode, id, currency }, index) => {
|
||||||
return {
|
return {
|
||||||
id:id,
|
id:id,
|
||||||
country: countryName,
|
country: countryName,
|
||||||
value: minInvestmentAmt,
|
value: minInvestmentAmt,
|
||||||
logo: flagIcon,
|
logo: flagIcon,
|
||||||
curr: countryCode,
|
curr: currency?.currencyCode,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const minInvestmentById = IObyID?.data?.minInvestmentAmt?.map(({minInvestmentAmt, country, country_xid})=>{
|
|
||||||
|
|
||||||
|
const minInvestmentById = IObyID?.data?.minInvestmentAmt?.map(({minInvestmentAmt, country, country_xid, })=>{
|
||||||
return{
|
return{
|
||||||
id:country_xid,
|
id:country_xid,
|
||||||
country: country?.countryName,
|
country: country?.countryName,
|
||||||
value: minInvestmentAmt,
|
value: removeTrailingZeros(minInvestmentAmt),
|
||||||
logo: country?.flagIcon,
|
logo: country?.flagIcon,
|
||||||
curr: country?.countryCode,
|
curr: country?.countryCode,
|
||||||
}
|
}
|
||||||
@@ -170,12 +179,18 @@ const IODetails = ({ enableNextTab, index, data }) => {
|
|||||||
|
|
||||||
|
|
||||||
const [values, setValues] = useState(id?minInvestmentById:miniValue);
|
const [values, setValues] = useState(id?minInvestmentById:miniValue);
|
||||||
|
const formatNumber = (num) => {
|
||||||
|
// Remove non-numeric characters and format with commas
|
||||||
|
return num.replace(/\D/g, '')
|
||||||
|
.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
|
||||||
|
};
|
||||||
// console.log(values);
|
// console.log(values);
|
||||||
|
|
||||||
// ======================[ Validator filter ]
|
// ======================[ Validator filter ]
|
||||||
const {
|
const {
|
||||||
control,
|
control,
|
||||||
reset,
|
reset,
|
||||||
|
watch,
|
||||||
setValue,
|
setValue,
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
formState: { errors },
|
formState: { errors },
|
||||||
@@ -184,6 +199,7 @@ const IODetails = ({ enableNextTab, index, data }) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
setIOloading(IObyIDisLoading)
|
||||||
setIODetails({
|
setIODetails({
|
||||||
...IObyID?.data,
|
...IObyID?.data,
|
||||||
});
|
});
|
||||||
@@ -194,21 +210,25 @@ const IODetails = ({ enableNextTab, index, data }) => {
|
|||||||
descriptionEnglish: IObyID?.data?.descriptionEnglish,
|
descriptionEnglish: IObyID?.data?.descriptionEnglish,
|
||||||
descriptionArabic: IObyID?.data?.descriptionArabic,
|
descriptionArabic: IObyID?.data?.descriptionArabic,
|
||||||
goalAmount: IObyID?.data?.goalAmount,
|
goalAmount: IObyID?.data?.goalAmount,
|
||||||
closingDate: IObyID?.data?.closingDate,
|
closingDate: formatDatee(IObyID?.data?.closingDate),
|
||||||
holdingPeriod: IObyID?.data?.holdingPeriod,
|
holdingPeriod: IObyID?.data?.holdingPeriod,
|
||||||
ISIN: IObyID?.data?.ISIN,
|
ISIN: IObyID?.data?.ISIN,
|
||||||
comment: IObyID?.data?.comment,
|
comment: IObyID?.data?.comment,
|
||||||
expectedReturn: IObyID?.data?.expectedReturn,
|
expectedReturn: IObyID?.data?.expectedReturn,
|
||||||
investmentType_xid: IObyID?.data?.investmentType_xid,
|
investmentType_xid: IObyID?.data?.investmentType_xid,
|
||||||
investmentType_xid: IObyID?.data?.investmentType_xid,
|
|
||||||
InvestmentDetails: IObyID?.data?.InvestmentDetails,
|
InvestmentDetails: IObyID?.data?.InvestmentDetails,
|
||||||
minInvestmentAmount: IObyID?.data?.minInvestmentAmount,
|
minInvestmentAmount: IObyID?.data?.minInvestmentAmount,
|
||||||
|
holdingPeriodArabic: IObyID?.data?.minInvestmentAmount,
|
||||||
|
expectedReturnArabic: IObyID?.data?.minInvestmentAmount,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}, [id, IObyID]);
|
}, [id, IObyID]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// const minInvestmentById =
|
// const minInvestmentById =
|
||||||
|
|
||||||
//=======================[ Creator ]
|
//=======================[ Creator ]
|
||||||
@@ -221,6 +241,8 @@ const IODetails = ({ enableNextTab, index, data }) => {
|
|||||||
isRequired: true,
|
isRequired: true,
|
||||||
section: " ",
|
section: " ",
|
||||||
width: "49%",
|
width: "49%",
|
||||||
|
maxLength:150,
|
||||||
|
helperText:`Maximum length should be 150 characters. You have entered ${watch()?.investmentNameEnglish?.length || 0} characters.`
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "IO Name (Arabic)",
|
label: "IO Name (Arabic)",
|
||||||
@@ -231,6 +253,8 @@ const IODetails = ({ enableNextTab, index, data }) => {
|
|||||||
arabic: true,
|
arabic: true,
|
||||||
section: " ",
|
section: " ",
|
||||||
width: "49%",
|
width: "49%",
|
||||||
|
maxLength:150,
|
||||||
|
helperText:`Maximum length should be 150 characters. You have entered ${watch()?.investmentNameArabic?.length || 0} characters.`
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Description",
|
label: "Description",
|
||||||
@@ -240,7 +264,8 @@ const IODetails = ({ enableNextTab, index, data }) => {
|
|||||||
isRequired: true,
|
isRequired: true,
|
||||||
section: " ",
|
section: " ",
|
||||||
width: "49%",
|
width: "49%",
|
||||||
maxLength:1000
|
maxLength:1000,
|
||||||
|
helperText:`Maximum length should be 1000 characters. You have entered ${watch()?.descriptionEnglish?.length || 0} characters.`
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Description (Arabic)",
|
label: "Description (Arabic)",
|
||||||
@@ -251,8 +276,59 @@ const IODetails = ({ enableNextTab, index, data }) => {
|
|||||||
arabic: true,
|
arabic: true,
|
||||||
section: " ",
|
section: " ",
|
||||||
width: "49%",
|
width: "49%",
|
||||||
|
maxLength:1000,
|
||||||
|
helperText:`Maximum length should be 1000 characters. You have entered ${watch()?.descriptionArabic?.length || 0} characters.`
|
||||||
|
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: "Holding Period",
|
||||||
|
name: "holdingPeriod",
|
||||||
|
type: "text",
|
||||||
|
placeHolder: "1Y",
|
||||||
|
isRequired: true,
|
||||||
|
section: " ",
|
||||||
|
width: "49%",
|
||||||
|
value: IObyID?.data?.holdingPeriod,
|
||||||
|
maxLength:20,
|
||||||
|
helperText:`Maximum length should be 20 characters. You have entered ${watch()?.holdingPeriod?.length || 0} characters.`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Holding Period (Arabic)",
|
||||||
|
name: "holdingPeriodArabic",
|
||||||
|
type: "text",
|
||||||
|
placeHolder: "1Y",
|
||||||
|
isRequired: true,
|
||||||
|
arabic: true,
|
||||||
|
section: " ",
|
||||||
|
width: "49%",
|
||||||
|
value: IObyID?.data?.holdingPeriodArabic,
|
||||||
|
maxLength:20,
|
||||||
|
helperText:`Maximum length should be 20 characters. You have entered ${watch()?.holdingPeriodArabic?.length || 0} characters.`
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
label: "Expected Return",
|
||||||
|
name: "expectedReturn",
|
||||||
|
type: "text",
|
||||||
|
isRequired: true,
|
||||||
|
section: " ",
|
||||||
|
width: "49%",
|
||||||
|
value: IObyID?.data?.expectedReturn,
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
label: "Expected Return (Arabic)",
|
||||||
|
name: "expectedReturnArabic",
|
||||||
|
type: "text",
|
||||||
|
isRequired: true,
|
||||||
|
arabic: true,
|
||||||
|
section: " ",
|
||||||
|
width: "49%",
|
||||||
|
value: IObyID?.data?.expectedReturnArabic,
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
label: "Investment Type",
|
label: "Investment Type",
|
||||||
placeHolder: "Select option",
|
placeHolder: "Select option",
|
||||||
@@ -265,7 +341,7 @@ const IODetails = ({ enableNextTab, index, data }) => {
|
|||||||
value: IObyID?.data?.investmentType_xid,
|
value: IObyID?.data?.investmentType_xid,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Sponsorer Name",
|
label: "Sponsor Name",
|
||||||
placeHolder: "Select option",
|
placeHolder: "Select option",
|
||||||
name: "sponserName",
|
name: "sponserName",
|
||||||
type: "select",
|
type: "select",
|
||||||
@@ -288,32 +364,13 @@ const IODetails = ({ enableNextTab, index, data }) => {
|
|||||||
{
|
{
|
||||||
label: "Closing Date",
|
label: "Closing Date",
|
||||||
name: "closingDate",
|
name: "closingDate",
|
||||||
value: formatDate(IObyID?.data?.closingDate),
|
// value: "IObyID?.data?.closingDate",
|
||||||
type: "date",
|
type: "date",
|
||||||
isRequired: true,
|
isRequired: true,
|
||||||
section: " ",
|
section: " ",
|
||||||
width: "32.3%",
|
width: "32.3%",
|
||||||
helperText: IObyID && `Current closing date is : ${formatDate(IObyID?.data?.closingDate)}`
|
dateValue:formatDatee(IObyID?.data?.closingDate),
|
||||||
},
|
// helperText: IObyID && `Current closing date is : ${formatDate(IObyID?.data?.closingDate)}`
|
||||||
{
|
|
||||||
label: "Holding Period",
|
|
||||||
name: "holdingPeriod",
|
|
||||||
type: "text",
|
|
||||||
placeHolder: "1Y",
|
|
||||||
isRequired: true,
|
|
||||||
section: " ",
|
|
||||||
width: "32.3%",
|
|
||||||
value: IObyID?.data?.holdingPeriod,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Expected Return",
|
|
||||||
placeHolder: "$00.00",
|
|
||||||
name: "expectedReturn",
|
|
||||||
type: "text",
|
|
||||||
isRequired: true,
|
|
||||||
section: " ",
|
|
||||||
width: "32.3%",
|
|
||||||
value: IObyID?.data?.expectedReturn,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "ISIN",
|
label: "ISIN",
|
||||||
@@ -343,7 +400,6 @@ const IODetails = ({ enableNextTab, index, data }) => {
|
|||||||
width: "100%",
|
width: "100%",
|
||||||
isRequired: true,
|
isRequired: true,
|
||||||
options: investmentTypeOptions,
|
options: investmentTypeOptions,
|
||||||
type: "table",
|
|
||||||
handleInputChange: handleInputChange,
|
handleInputChange: handleInputChange,
|
||||||
value: values,
|
value: values,
|
||||||
},
|
},
|
||||||
@@ -357,7 +413,8 @@ const IODetails = ({ enableNextTab, index, data }) => {
|
|||||||
width: "100%",
|
width: "100%",
|
||||||
options: investmentTypeOptions,
|
options: investmentTypeOptions,
|
||||||
value: IObyID?.data?.comment,
|
value: IObyID?.data?.comment,
|
||||||
maxLength:100
|
maxLength:100,
|
||||||
|
helperText:`Maximum length should be 100 characters. You have entered ${watch()?.comment?.length || 0} characters.`
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
//=======================[ Editor ]
|
//=======================[ Editor ]
|
||||||
@@ -567,6 +624,11 @@ const IODetails = ({ enableNextTab, index, data }) => {
|
|||||||
toast({
|
toast({
|
||||||
render: () => <ToastBox message={res?.error?.data?.message } status={"error"} />,
|
render: () => <ToastBox message={res?.error?.data?.message } status={"error"} />,
|
||||||
});
|
});
|
||||||
|
}else if(res?.error?.status === 500){
|
||||||
|
setIsLoading(false);
|
||||||
|
toast({
|
||||||
|
render: () => <ToastBox message={res?.error?.data?.message } status={"error"} />,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
@@ -592,8 +654,9 @@ const IODetails = ({ enableNextTab, index, data }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return IObyIDisLoading ? (
|
return IObyIDisLoading ? (
|
||||||
<FullscreenLoaders />
|
<FullscreenLoaders height={'70vh'} />
|
||||||
) : (
|
) : (
|
||||||
|
|
||||||
<FormInputMain
|
<FormInputMain
|
||||||
p={0.1}
|
p={0.1}
|
||||||
w={250}
|
w={250}
|
||||||
|
|||||||
@@ -1,14 +1,19 @@
|
|||||||
import React, { useContext, useEffect, useState } from 'react'
|
import React, { useContext, useEffect, useRef, useState } from 'react'
|
||||||
import GlobalStateContext from '../../../Contexts/GlobalStateContext';
|
import GlobalStateContext from '../../../Contexts/GlobalStateContext';
|
||||||
import { Box, HStack, Input,Text, Table, Tbody, Th, Tr } from '@chakra-ui/react';
|
import { Box, HStack, Input,Text, Table, Tbody, Th, Tr, Avatar, useDisclosure,Button } from '@chakra-ui/react';
|
||||||
import { OPACITY_ON_LOAD } from '../../../Layout/animations';
|
import { OPACITY_ON_LOAD } from '../../../Layout/animations';
|
||||||
import Pagination from '../../../Components/Pagination';
|
import Pagination from '../../../Components/Pagination';
|
||||||
import DataTable from '../../../Components/DataTable/DataTable';
|
import NormalTable from '../../../Components/DataTable/NormalTable';
|
||||||
import CustomAlertDialog from '../../../Components/CustomAlertDialog';
|
import CustomAlertDialog from '../../../Components/CustomAlertDialog';
|
||||||
|
import { formatDatee } from '../../../Components/FormField';
|
||||||
|
import { AddIcon } from '@chakra-ui/icons';
|
||||||
|
import AddIONav from './AddIONav';
|
||||||
|
|
||||||
const IONAVDetails = () => {
|
const IONAVDetails = () => {
|
||||||
const { navDetails, setNavDetails, slideFromRight } =
|
const { navDetails, setNavDetails, IODetails } =
|
||||||
useContext(GlobalStateContext);
|
useContext(GlobalStateContext);
|
||||||
|
const firstField = useRef();
|
||||||
|
const { isOpen, onOpen, onClose } = useDisclosure();
|
||||||
const [searchTerm, setSearchTerm] = useState("");
|
const [searchTerm, setSearchTerm] = useState("");
|
||||||
const [isLoading, setIsLoading] = useState(true);
|
const [isLoading, setIsLoading] = useState(true);
|
||||||
const [deleteAlert, setDeleteAlert] = useState(false);
|
const [deleteAlert, setDeleteAlert] = useState(false);
|
||||||
@@ -17,6 +22,10 @@ const IONAVDetails = () => {
|
|||||||
const [mouseEnteredId, setMouseEnteredId] = useState("");
|
const [mouseEnteredId, setMouseEnteredId] = useState("");
|
||||||
|
|
||||||
|
|
||||||
|
console.log(IODetails?.ioNAVHistory);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Simulate loading
|
// Simulate loading
|
||||||
const timer = setTimeout(() => {
|
const timer = setTimeout(() => {
|
||||||
@@ -29,50 +38,76 @@ const IONAVDetails = () => {
|
|||||||
|
|
||||||
// Table setup
|
// Table setup
|
||||||
const tableHeadRow = [
|
const tableHeadRow = [
|
||||||
"Sr.No",
|
// "Sr.No",
|
||||||
"As On Date",
|
"Valuation Date",
|
||||||
"IO NAV Value",
|
"NAV",
|
||||||
|
"Last NAV update",
|
||||||
|
"Investment Closed",
|
||||||
"Comments",
|
"Comments",
|
||||||
"Update by ",
|
"Update by ",
|
||||||
"Update On",
|
// "Update On",
|
||||||
];
|
];
|
||||||
|
|
||||||
// Table filter
|
// Table filter
|
||||||
const filteredData = navDetails?.filter((item) => {
|
const filteredData = IODetails?.ioNAVHistory?.filter((item) => {
|
||||||
const name = item.updateBy;
|
const name = item.transactionType;
|
||||||
const searchLower = searchTerm.toLowerCase();
|
const searchLower = searchTerm.toLowerCase();
|
||||||
const nameMatches = name.toLowerCase().includes(searchLower);
|
const nameMatches = name.toLowerCase().includes(searchLower);
|
||||||
return nameMatches;
|
return nameMatches;
|
||||||
});
|
}).sort((b, a) => new Date(a.transactionDate) - new Date(b.transactionDate));
|
||||||
|
|
||||||
const [ extractedArray, setExtractedArray ] = useState(filteredData?.map((item, index) => ({
|
const extractedArray=filteredData?.map((item, index) => ({
|
||||||
id: item?.id,
|
id: item?.id,
|
||||||
"Sr.No": index +1,
|
"Sr.No": index +1,
|
||||||
"As On Date": (
|
"Valuation Date": (
|
||||||
<Text
|
<Text
|
||||||
justifyContent={slideFromRight ? "right" : "center"}
|
justifyContent={"center"}
|
||||||
as={"span"}
|
as={"span"}
|
||||||
color={"teal.900"}
|
color={"teal.900"}
|
||||||
fontWeight={"500"}
|
fontWeight={"500"}
|
||||||
className="d-flex align-items-center web-text-small"
|
className="d-flex align-items-center web-text-small"
|
||||||
>
|
>
|
||||||
{item.date}
|
{formatDatee(item.transactionDate)}
|
||||||
</Text>
|
</Text>
|
||||||
),
|
),
|
||||||
"IO NAV Value": (
|
"NAV": (
|
||||||
<Text
|
<Text
|
||||||
justifyContent={slideFromRight ? "right" : "center"}
|
justifyContent={"center"}
|
||||||
as={"span"}
|
as={"span"}
|
||||||
color={"teal.900"}
|
color={"teal.900"}
|
||||||
fontWeight={"500"}
|
fontWeight={"500"}
|
||||||
className="d-flex align-items-center web-text-small"
|
className="d-flex align-items-center web-text-small"
|
||||||
>
|
>
|
||||||
{`$${item.IONavValue}`}
|
{/* {`${item.transactionAmount}`} */}
|
||||||
|
|
||||||
|
{`$${parseFloat(item.transactionAmount||0).toLocaleString()}`}
|
||||||
|
</Text>
|
||||||
|
),
|
||||||
|
"Last NAV update": (
|
||||||
|
<Text
|
||||||
|
justifyContent={"center"}
|
||||||
|
as={"span"}
|
||||||
|
color={"teal.900"}
|
||||||
|
fontWeight={"500"}
|
||||||
|
className="d-flex align-items-center web-text-small"
|
||||||
|
>
|
||||||
|
{item.previousNAVvalue && `${item.previousNAVvalue}`}
|
||||||
|
</Text>
|
||||||
|
),
|
||||||
|
"Investment Closed": (
|
||||||
|
<Text
|
||||||
|
justifyContent={"center"}
|
||||||
|
as={"span"}
|
||||||
|
color={"teal.900"}
|
||||||
|
fontWeight={"500"}
|
||||||
|
className="d-flex align-items-center web-text-small"
|
||||||
|
>
|
||||||
|
{item.initialNAVvalue&& `${item.initialNAVvalue}`}
|
||||||
</Text>
|
</Text>
|
||||||
),
|
),
|
||||||
"Comments": (
|
"Comments": (
|
||||||
<Text
|
<Text
|
||||||
justifyContent={slideFromRight ? "right" : "center"}
|
justifyContent={"center"}
|
||||||
as={"span"}
|
as={"span"}
|
||||||
color={"teal.900"}
|
color={"teal.900"}
|
||||||
fontWeight={"500"}
|
fontWeight={"500"}
|
||||||
@@ -83,18 +118,20 @@ const IONAVDetails = () => {
|
|||||||
),
|
),
|
||||||
"Update by ": (
|
"Update by ": (
|
||||||
<Text
|
<Text
|
||||||
justifyContent={slideFromRight ? "right" : "center"}
|
justifyContent ={"center"}
|
||||||
as={"span"}
|
as={"span"}
|
||||||
color={"teal.900"}
|
color={"teal.900"}
|
||||||
fontWeight={"500"}
|
fontWeight={"500"}
|
||||||
|
gap={2}
|
||||||
className="d-flex align-items-center web-text-small"
|
className="d-flex align-items-center web-text-small"
|
||||||
>
|
>
|
||||||
{item.updateBy}
|
|
||||||
|
<Avatar size='sm' name={"faisal"} src={null} />Faisal
|
||||||
</Text>
|
</Text>
|
||||||
),
|
),
|
||||||
"Update On": (
|
"Update On": (
|
||||||
<Text
|
<Text
|
||||||
justifyContent={slideFromRight ? "right" : "center"}
|
justifyContent={"center"}
|
||||||
as={"span"}
|
as={"span"}
|
||||||
color={"teal.900"}
|
color={"teal.900"}
|
||||||
fontWeight={"500"}
|
fontWeight={"500"}
|
||||||
@@ -103,7 +140,7 @@ const IONAVDetails = () => {
|
|||||||
{item.updateOn}
|
{item.updateOn}
|
||||||
</Text>
|
</Text>
|
||||||
),
|
),
|
||||||
})));
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -142,18 +179,21 @@ const IONAVDetails = () => {
|
|||||||
onChange={(e) => setSearchTerm(e.target.value)}
|
onChange={(e) => setSearchTerm(e.target.value)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<HStack display={"flex"} alignItems={"center"}>
|
{/* <HStack display={"flex"} alignItems={"center"}>
|
||||||
<Pagination totalItems={10} />
|
<Pagination totalItems={10} />
|
||||||
</HStack>
|
</HStack> */}
|
||||||
|
|
||||||
|
|
||||||
|
{IODetails?.isInvestedAmount ? <Button onClick={onOpen} leftIcon={<AddIcon/>} colorScheme="forestGreen" size={'sm'} rounded={'sm'} fontSize={'xs'} >Add IO NAV</Button>:null}
|
||||||
|
|
||||||
</HStack>
|
</HStack>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<DataTable
|
<NormalTable
|
||||||
centered={true}
|
centered={true}
|
||||||
emptyMessage={`We don't have any Sponers`}
|
emptyMessage={`We don't have any Sponers`}
|
||||||
tableHeadRow={tableHeadRow}
|
tableHeadRow={tableHeadRow}
|
||||||
data={extractedArray}
|
data={extractedArray}
|
||||||
setData={setExtractedArray}
|
|
||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
viewActionId={actionId}
|
viewActionId={actionId}
|
||||||
setViewActionId={setActionId}
|
setViewActionId={setActionId}
|
||||||
@@ -169,6 +209,15 @@ const IONAVDetails = () => {
|
|||||||
alertHandler={handleDelete}
|
alertHandler={handleDelete}
|
||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<AddIONav
|
||||||
|
isOpen={isOpen}
|
||||||
|
onClose={onClose}
|
||||||
|
firstField={firstField} />
|
||||||
|
|
||||||
|
|
||||||
</Box>
|
</Box>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,9 +36,8 @@ import { TbFileTypeDocx } from "react-icons/tb";
|
|||||||
import SetDisplayOrder from "./SetDisplayOrder";
|
import SetDisplayOrder from "./SetDisplayOrder";
|
||||||
|
|
||||||
const downloadFile = (filePath, fileName) => {
|
const downloadFile = (filePath, fileName) => {
|
||||||
console.log("https://tanami.betadelivery.com/" + filePath);
|
|
||||||
|
|
||||||
fetch("https://tanami.betadelivery.com/" + filePath)
|
fetch(import.meta.env.VITE_IMAGE_URL+filePath)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new Error("Network response was not ok");
|
throw new Error("Network response was not ok");
|
||||||
@@ -72,10 +71,10 @@ const downloadFile = (filePath, fileName) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const InvestmentDocument = ({ control, errors, enableNextTab, index }) => {
|
const InvestmentDocument = ({ control, errors, enableNextTab, index, }) => {
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
const id = params?.id;
|
const id = params?.id;
|
||||||
const { slideFromRight, create, setCreate } = useContext(GlobalStateContext);
|
const { slideFromRight, create, setCreate, IODetails } = useContext(GlobalStateContext);
|
||||||
const firstField = useRef();
|
const firstField = useRef();
|
||||||
const secondField = useRef();
|
const secondField = useRef();
|
||||||
const thirdField = useRef();
|
const thirdField = useRef();
|
||||||
@@ -101,13 +100,18 @@ const InvestmentDocument = ({ control, errors, enableNextTab, index }) => {
|
|||||||
|
|
||||||
const [deleteIODocs] = useDeleteIODocsMutation();
|
const [deleteIODocs] = useDeleteIODocsMutation();
|
||||||
|
|
||||||
const {
|
// const {
|
||||||
data,
|
// data,
|
||||||
error,
|
// error,
|
||||||
isLoading: isIODocLoading,
|
// isLoading: isIODocLoading,
|
||||||
} = useGetInvestmentDocumentsQuery(id, {
|
// } = useGetInvestmentDocumentsQuery(id, {
|
||||||
skip: !id,
|
// skip: !id,
|
||||||
});
|
// });
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const tableHeadRow = ["Sr.no", "Type", "File Name", "Document", "Action"];
|
const tableHeadRow = ["Sr.no", "Type", "File Name", "Document", "Action"];
|
||||||
|
|
||||||
@@ -126,7 +130,7 @@ const InvestmentDocument = ({ control, errors, enableNextTab, index }) => {
|
|||||||
});
|
});
|
||||||
}, 300);
|
}, 300);
|
||||||
|
|
||||||
const filteredData = data?.data?.filter((item) =>
|
const filteredData = IODetails?.documents?.filter((item) =>
|
||||||
item?.documentName?.toLowerCase().includes(searchTerm.toLowerCase())
|
item?.documentName?.toLowerCase().includes(searchTerm.toLowerCase())
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -294,7 +298,9 @@ const InvestmentDocument = ({ control, errors, enableNextTab, index }) => {
|
|||||||
return (
|
return (
|
||||||
<Box>
|
<Box>
|
||||||
<Box display="flex" justifyContent="end" mb={4} gap={2}>
|
<Box display="flex" justifyContent="end" mb={4} gap={2}>
|
||||||
<SetDisplayOrder data={filteredData} />
|
|
||||||
|
|
||||||
|
{filteredData?.length !== 0 &&<SetDisplayOrder data={filteredData} />}
|
||||||
<Button
|
<Button
|
||||||
leftIcon={<AddIcon />}
|
leftIcon={<AddIcon />}
|
||||||
onClick={onOpen}
|
onClick={onOpen}
|
||||||
@@ -319,7 +325,7 @@ const InvestmentDocument = ({ control, errors, enableNextTab, index }) => {
|
|||||||
secondField={secondField}
|
secondField={secondField}
|
||||||
/>
|
/>
|
||||||
<InvestmentEdit
|
<InvestmentEdit
|
||||||
data={data?.data}
|
data={IODetails?.documents}
|
||||||
id={actionId}
|
id={actionId}
|
||||||
isOpen={isEditOpen}
|
isOpen={isEditOpen}
|
||||||
onClose={onEditClose}
|
onClose={onEditClose}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import {
|
|||||||
Box,
|
Box,
|
||||||
Button,
|
Button,
|
||||||
HStack,
|
HStack,
|
||||||
|
Icon,
|
||||||
Input,
|
Input,
|
||||||
Menu,
|
Menu,
|
||||||
MenuButton,
|
MenuButton,
|
||||||
@@ -24,21 +25,40 @@ import {
|
|||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import React, { useContext, useEffect, useState } from "react";
|
import React, { useContext, useEffect, useState } from "react";
|
||||||
import { OPACITY_ON_LOAD } from "../../../Layout/animations";
|
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 { HiDotsVertical } from "react-icons/hi";
|
||||||
import { Link, Link as RouterLink } from "react-router-dom";
|
import { Link, Link as RouterLink, useParams } from "react-router-dom";
|
||||||
import Pagination from "../../../Components/Pagination";
|
import Pagination from "../../../Components/Pagination";
|
||||||
import GlobalStateContext from "../../../Contexts/GlobalStateContext";
|
import GlobalStateContext from "../../../Contexts/GlobalStateContext";
|
||||||
import CustomAlertDialog from "../../../Components/CustomAlertDialog";
|
import CustomAlertDialog from "../../../Components/CustomAlertDialog";
|
||||||
import ToastBox from "../../../Components/ToastBox";
|
import ToastBox from "../../../Components/ToastBox";
|
||||||
import { debounce } from "../../Master/Sponser/AddSponser";
|
import { debounce } from "../../Master/Sponser/AddSponser";
|
||||||
|
import { formatCurrency } from "../../../Components/CurrencyInput";
|
||||||
|
import { FiRefreshCw } from "react-icons/fi";
|
||||||
|
import { useGetIOByIdQuery } from "../../../Services/io.service";
|
||||||
|
import { RepeatIcon } from "@chakra-ui/icons";
|
||||||
|
|
||||||
const formatDate = (date) => new Date(date).toLocaleDateString(); // Simple date formatter
|
const formatDate = (date) => new Date(date).toLocaleDateString(); // Simple date formatter
|
||||||
|
|
||||||
const Investors = () => {
|
const Investors = ({data}) => {
|
||||||
|
const params = useParams()
|
||||||
|
const id = params?.id
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
const { investors, setInvestors, slideFromRight } =
|
const { investors, setInvestors, slideFromRight, IODetails } =
|
||||||
useContext(GlobalStateContext);
|
useContext(GlobalStateContext);
|
||||||
|
|
||||||
|
|
||||||
|
console.log(params?.id);
|
||||||
|
|
||||||
|
const {
|
||||||
|
data: IObyID,
|
||||||
|
isLoading: IObyIDisLoading,
|
||||||
|
error: IObyIDerror,
|
||||||
|
refetch
|
||||||
|
} = useGetIOByIdQuery(id, { skip: !id });
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const [searchTerm, setSearchTerm] = useState("");
|
const [searchTerm, setSearchTerm] = useState("");
|
||||||
const [isLoading, setIsLoading] = useState(true);
|
const [isLoading, setIsLoading] = useState(true);
|
||||||
const [deleteAlert, setDeleteAlert] = useState(false);
|
const [deleteAlert, setDeleteAlert] = useState(false);
|
||||||
@@ -84,6 +104,7 @@ const Investors = () => {
|
|||||||
"Market Value",
|
"Market Value",
|
||||||
"Return on Investment",
|
"Return on Investment",
|
||||||
"Distribution",
|
"Distribution",
|
||||||
|
"Distribution Percent",
|
||||||
"Total Return",
|
"Total Return",
|
||||||
"Total return on Investment",
|
"Total return on Investment",
|
||||||
];
|
];
|
||||||
@@ -100,7 +121,7 @@ const Investors = () => {
|
|||||||
}, 300);
|
}, 300);
|
||||||
|
|
||||||
// Table filter
|
// Table filter
|
||||||
const filteredData = investors.filter((item) => {
|
const filteredData = IODetails?.investors?.filter((item) => {
|
||||||
const name = item.firstName;
|
const name = item.firstName;
|
||||||
const searchLower = searchTerm.toLowerCase();
|
const searchLower = searchTerm.toLowerCase();
|
||||||
const nameMatches = name.toLowerCase().includes(searchLower);
|
const nameMatches = name.toLowerCase().includes(searchLower);
|
||||||
@@ -108,7 +129,9 @@ const Investors = () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
const [ extractedArray, setExtractedArray ] = useState(filteredData?.map((item, index) => ({
|
|
||||||
|
|
||||||
|
const extractedArray = filteredData?.map((item, index) => ({
|
||||||
id: item?.id,
|
id: item?.id,
|
||||||
"Client ID": (
|
"Client ID": (
|
||||||
<Text
|
<Text
|
||||||
@@ -118,7 +141,7 @@ const Investors = () => {
|
|||||||
fontWeight={"500"}
|
fontWeight={"500"}
|
||||||
className="d-flex align-items-center web-text-small"
|
className="d-flex align-items-center web-text-small"
|
||||||
>
|
>
|
||||||
{item.clientId}
|
{item?.clientReference_id}
|
||||||
</Text>
|
</Text>
|
||||||
),
|
),
|
||||||
"First name": (
|
"First name": (
|
||||||
@@ -151,7 +174,8 @@ const Investors = () => {
|
|||||||
fontWeight={"500"}
|
fontWeight={"500"}
|
||||||
className="d-flex align-items-center web-text-small"
|
className="d-flex align-items-center web-text-small"
|
||||||
>
|
>
|
||||||
{`$${item.investedAmount}`}
|
{/* {`$${formatCurrency(item.InvestedAmount_USD)}`} */}
|
||||||
|
{`$${parseFloat(item.InvestedAmount_USD||0).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`}
|
||||||
</Text>
|
</Text>
|
||||||
),
|
),
|
||||||
"Percentage": (
|
"Percentage": (
|
||||||
@@ -162,7 +186,7 @@ const Investors = () => {
|
|||||||
fontWeight={"500"}
|
fontWeight={"500"}
|
||||||
className="d-flex align-items-center web-text-small"
|
className="d-flex align-items-center web-text-small"
|
||||||
>
|
>
|
||||||
{item.percentage}
|
{item.Investor_Holidings} %
|
||||||
</Text>
|
</Text>
|
||||||
),
|
),
|
||||||
"Market Value": (
|
"Market Value": (
|
||||||
@@ -173,7 +197,7 @@ const Investors = () => {
|
|||||||
fontWeight={"500"}
|
fontWeight={"500"}
|
||||||
className="d-flex align-items-center web-text-small"
|
className="d-flex align-items-center web-text-small"
|
||||||
>
|
>
|
||||||
{`$${item.marketValue}`}
|
{`$${parseFloat(item.Market_Value ||0).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`}
|
||||||
</Text>
|
</Text>
|
||||||
),
|
),
|
||||||
"Return on Investment": (
|
"Return on Investment": (
|
||||||
@@ -185,7 +209,7 @@ const Investors = () => {
|
|||||||
h={6}
|
h={6}
|
||||||
className="d-flex align-items-center web-text-small"
|
className="d-flex align-items-center web-text-small"
|
||||||
>
|
>
|
||||||
{item.returnOnInvestment}
|
{item.Return_On_Investment || 0} %
|
||||||
</Text>
|
</Text>
|
||||||
),
|
),
|
||||||
"Distribution": (
|
"Distribution": (
|
||||||
@@ -196,7 +220,20 @@ const Investors = () => {
|
|||||||
fontWeight={"500"}
|
fontWeight={"500"}
|
||||||
className="d-flex align-items-center web-text-small"
|
className="d-flex align-items-center web-text-small"
|
||||||
>
|
>
|
||||||
{`$${item.distribution}`}
|
{/* {`$${item.Distribution_Amt}`} */}
|
||||||
|
{`$${parseFloat(item.Distribution_Amt||0).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`}
|
||||||
|
</Text>
|
||||||
|
),
|
||||||
|
"Distribution Percent": (
|
||||||
|
<Text
|
||||||
|
justifyContent={slideFromRight ? "right" : "center"}
|
||||||
|
as={"span"}
|
||||||
|
color={"teal.900"}
|
||||||
|
fontWeight={"500"}
|
||||||
|
className="d-flex align-items-center web-text-small"
|
||||||
|
>
|
||||||
|
{/* {`$${item.Distribution_Amt}`} */}
|
||||||
|
{`${parseFloat(item.Distribution_Per||0).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })} %`}
|
||||||
</Text>
|
</Text>
|
||||||
),
|
),
|
||||||
"Total Return": (
|
"Total Return": (
|
||||||
@@ -207,7 +244,8 @@ const Investors = () => {
|
|||||||
fontWeight={"500"}
|
fontWeight={"500"}
|
||||||
className="d-flex align-items-center web-text-small"
|
className="d-flex align-items-center web-text-small"
|
||||||
>
|
>
|
||||||
{`$${item.totalReturn}`}
|
{/* {`$${formatCurrency(item.Total_Return) || 0}`} */}
|
||||||
|
{`$${parseFloat(item.Total_Return||0).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`}
|
||||||
</Text>
|
</Text>
|
||||||
),
|
),
|
||||||
"Total return on Investment": (
|
"Total return on Investment": (
|
||||||
@@ -218,10 +256,10 @@ const Investors = () => {
|
|||||||
fontWeight={"500"}
|
fontWeight={"500"}
|
||||||
className="d-flex align-items-center web-text-small"
|
className="d-flex align-items-center web-text-small"
|
||||||
>
|
>
|
||||||
{item.totalReturnOnInvestment}
|
{item.Total_Return_On_Investment||0} %
|
||||||
</Text>
|
</Text>
|
||||||
),
|
),
|
||||||
})));
|
}));
|
||||||
|
|
||||||
const handleDelete = () => {
|
const handleDelete = () => {
|
||||||
const updatedSponsors = sponser.filter(
|
const updatedSponsors = sponser.filter(
|
||||||
@@ -357,6 +395,11 @@ const Investors = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const handleRefresh = () =>{
|
||||||
|
refetch()
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box {...OPACITY_ON_LOAD} pb={0}>
|
<Box {...OPACITY_ON_LOAD} pb={0}>
|
||||||
<Box bg="white.500">
|
<Box bg="white.500">
|
||||||
@@ -365,7 +408,9 @@ const Investors = () => {
|
|||||||
justifyContent={"space-between"}
|
justifyContent={"space-between"}
|
||||||
pb={3}
|
pb={3}
|
||||||
spacing="24px"
|
spacing="24px"
|
||||||
|
|
||||||
>
|
>
|
||||||
|
<span>
|
||||||
<Input
|
<Input
|
||||||
type="search"
|
type="search"
|
||||||
width={300}
|
width={300}
|
||||||
@@ -376,19 +421,22 @@ const Investors = () => {
|
|||||||
value={searchTerm}
|
value={searchTerm}
|
||||||
onChange={(e) => setSearchTerm(e.target.value)}
|
onChange={(e) => setSearchTerm(e.target.value)}
|
||||||
/>
|
/>
|
||||||
|
<Icon ms={3} 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 display={"flex"} alignItems={"center"}>
|
|
||||||
<Pagination totalItems={10} />
|
|
||||||
</HStack>
|
</HStack>
|
||||||
</HStack>
|
</HStack>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<DataTable
|
<NormalTable
|
||||||
centered={true}
|
centered={true}
|
||||||
emptyMessage={`We don't have any Sponers `}
|
emptyMessage={`We don't have any Sponers `}
|
||||||
tableHeadRow={tableHeadRow}
|
tableHeadRow={tableHeadRow}
|
||||||
data={extractedArray}
|
data={extractedArray}
|
||||||
setData={setExtractedArray}
|
|
||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
viewActionId={actionId}
|
viewActionId={actionId}
|
||||||
setViewActionId={setActionId}
|
setViewActionId={setActionId}
|
||||||
|
|||||||
@@ -40,14 +40,14 @@ const KeyMerits = ({ enableNextTab, index, data: prepopData }) => {
|
|||||||
|
|
||||||
// =====================[ variables ]
|
// =====================[ variables ]
|
||||||
const id = params?.id;
|
const id = params?.id;
|
||||||
const { data, isLoading, error } = useGetKeyMeritsQuery(id, {
|
// const { data, isLoading, error } = useGetKeyMeritsQuery(id, {
|
||||||
skip: !id,
|
// skip: !id,
|
||||||
});
|
// });
|
||||||
|
|
||||||
|
const { IODetails} = useContext(GlobalStateContext);
|
||||||
|
|
||||||
|
|
||||||
console.log(data?.data);
|
|
||||||
|
|
||||||
const { keyMerits, setKeyMerits, slideFromRight } =
|
|
||||||
useContext(GlobalStateContext);
|
|
||||||
|
|
||||||
const firstField = useRef();
|
const firstField = useRef();
|
||||||
const [searchTerm, setSearchTerm] = useState("");
|
const [searchTerm, setSearchTerm] = useState("");
|
||||||
@@ -57,6 +57,7 @@ const KeyMerits = ({ enableNextTab, index, data: prepopData }) => {
|
|||||||
const [isBtnLoading, setIsBtnLoading] = useState(false);
|
const [isBtnLoading, setIsBtnLoading] = useState(false);
|
||||||
const [mouseEnteredId, setMouseEnteredId] = useState("");
|
const [mouseEnteredId, setMouseEnteredId] = useState("");
|
||||||
const { isOpen, onOpen, onClose } = useDisclosure();
|
const { isOpen, onOpen, onClose } = useDisclosure();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
isOpen: isEditOpen,
|
isOpen: isEditOpen,
|
||||||
onOpen: onEditOpen,
|
onOpen: onEditOpen,
|
||||||
@@ -66,20 +67,9 @@ const KeyMerits = ({ enableNextTab, index, data: prepopData }) => {
|
|||||||
|
|
||||||
const tableHeadRow = ["Sr.no", "Title", "Sub title", "Icon", "Action"];
|
const tableHeadRow = ["Sr.no", "Title", "Sub title", "Icon", "Action"];
|
||||||
|
|
||||||
const handleUpdateStatus = debounce((id) => {
|
|
||||||
setKeyMerits((prevKeyMerits) =>
|
|
||||||
prevKeyMerits.map((keyMerits) =>
|
|
||||||
keyMerits.id === id
|
|
||||||
? { ...keyMerits, status: !keyMerits.status }
|
|
||||||
: keyMerits
|
|
||||||
)
|
|
||||||
);
|
|
||||||
toast({
|
|
||||||
render: () => <ToastBox message={"Status changed succesfully.!"} />,
|
|
||||||
});
|
|
||||||
}, 300);
|
|
||||||
|
|
||||||
const filteredData = data?.data?.filter((item) => {
|
|
||||||
|
const filteredData = IODetails?.keyMerits?.filter((item) => {
|
||||||
// Filter by name (case insensitive)
|
// Filter by name (case insensitive)
|
||||||
const name = item.meritsHeader;
|
const name = item.meritsHeader;
|
||||||
const searchLower = searchTerm.toLowerCase();
|
const searchLower = searchTerm.toLowerCase();
|
||||||
@@ -111,7 +101,7 @@ const KeyMerits = ({ enableNextTab, index, data: prepopData }) => {
|
|||||||
id: item.id,
|
id: item.id,
|
||||||
"Sr.no": (
|
"Sr.no": (
|
||||||
<Text
|
<Text
|
||||||
justifyContent={slideFromRight ? "right" : "left"}
|
justifyContent={"left"}
|
||||||
as={"span"}
|
as={"span"}
|
||||||
color={"teal.900"}
|
color={"teal.900"}
|
||||||
fontWeight={"500"}
|
fontWeight={"500"}
|
||||||
@@ -122,7 +112,7 @@ const KeyMerits = ({ enableNextTab, index, data: prepopData }) => {
|
|||||||
),
|
),
|
||||||
Title: (
|
Title: (
|
||||||
<Text
|
<Text
|
||||||
justifyContent={slideFromRight ? "right" : "left"}
|
justifyContent={"left"}
|
||||||
as={"span"}
|
as={"span"}
|
||||||
color={"teal.900"}
|
color={"teal.900"}
|
||||||
fontWeight={"500"}
|
fontWeight={"500"}
|
||||||
@@ -146,7 +136,7 @@ const KeyMerits = ({ enableNextTab, index, data: prepopData }) => {
|
|||||||
p={1}
|
p={1}
|
||||||
justifyContent={"center"}
|
justifyContent={"center"}
|
||||||
alignItems={"center"}
|
alignItems={"center"}
|
||||||
src={" https://tanami.betadelivery.com/" + item?.icon?.iconFilePath}
|
src={import.meta.env.VITE_IMAGE_URL+ item?.icon?.iconFilePath}
|
||||||
w={8}
|
w={8}
|
||||||
h={8}
|
h={8}
|
||||||
/>
|
/>
|
||||||
@@ -224,7 +214,7 @@ const KeyMerits = ({ enableNextTab, index, data: prepopData }) => {
|
|||||||
),
|
),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
return isLoading ? (
|
return false ? (
|
||||||
<FullscreenLoaders />
|
<FullscreenLoaders />
|
||||||
) : (
|
) : (
|
||||||
<Box>
|
<Box>
|
||||||
@@ -241,7 +231,9 @@ const KeyMerits = ({ enableNextTab, index, data: prepopData }) => {
|
|||||||
/> */}
|
/> */}
|
||||||
|
|
||||||
<Box display={"flex"} gap={2} as="span">
|
<Box display={"flex"} gap={2} as="span">
|
||||||
<SetDisplayOrder data={filteredData} />
|
|
||||||
|
|
||||||
|
{filteredData?.length !== 0 &&<SetDisplayOrder data={filteredData} />}
|
||||||
<Button
|
<Button
|
||||||
leftIcon={<AddIcon />}
|
leftIcon={<AddIcon />}
|
||||||
onClick={onOpen}
|
onClick={onOpen}
|
||||||
@@ -269,7 +261,7 @@ const KeyMerits = ({ enableNextTab, index, data: prepopData }) => {
|
|||||||
isOpen={isEditOpen}
|
isOpen={isEditOpen}
|
||||||
onClose={onEditCloseOpen}
|
onClose={onEditCloseOpen}
|
||||||
firstField={firstField}
|
firstField={firstField}
|
||||||
data={data?.data}
|
data={IODetails?.keyMerits}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
<DataTable
|
<DataTable
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ const SetDisplayOrder = ({ data }) => {
|
|||||||
p={1}
|
p={1}
|
||||||
justifyContent={"center"}
|
justifyContent={"center"}
|
||||||
alignItems={"center"}
|
alignItems={"center"}
|
||||||
src={"https://tanami.betadelivery.com/" + item?.icon?.iconFilePath}
|
src={import.meta.env.VITE_IMAGE_URL + item?.icon?.iconFilePath}
|
||||||
w={8}
|
w={8}
|
||||||
h={8}
|
h={8}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -39,13 +39,8 @@ const InvestmentEdit = ({ isOpen, onClose, thirdField, id, data }) => {
|
|||||||
const [updateInvestmentDocuments] = useUpdateInvestmentDocumentsMutation();
|
const [updateInvestmentDocuments] = useUpdateInvestmentDocumentsMutation();
|
||||||
|
|
||||||
// =====================[ variables ]
|
// =====================[ variables ]
|
||||||
// const id = params?.id;
|
|
||||||
console.log(id);
|
|
||||||
console.log(data);
|
|
||||||
const filterObject = data?.find((item) => item?.id === id);
|
const filterObject = data?.find((item) => item?.id === id);
|
||||||
|
|
||||||
console.log(filterObject);
|
|
||||||
|
|
||||||
const getFileTitle = (type) => {
|
const getFileTitle = (type) => {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case "application/pdf":
|
case "application/pdf":
|
||||||
@@ -74,12 +69,16 @@ const InvestmentEdit = ({ isOpen, onClose, thirdField, id, data }) => {
|
|||||||
resolver: yupResolver(investmentDocSchema),
|
resolver: yupResolver(investmentDocSchema),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
console.log(errors);
|
||||||
|
|
||||||
|
|
||||||
// useEffect to reset the form when `found` changes
|
// useEffect to reset the form when `found` changes
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (filterObject) {
|
if (filterObject) {
|
||||||
reset({
|
reset({
|
||||||
document: filterObject?.documentPath,
|
document: filterObject?.documentPath,
|
||||||
fileName: filterObject?.documentName,
|
fileName: filterObject?.documentName,
|
||||||
|
documentNameArabic: filterObject?.documentNameArabic,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, [filterObject, reset]);
|
}, [filterObject, reset]);
|
||||||
@@ -89,6 +88,7 @@ const InvestmentEdit = ({ isOpen, onClose, thirdField, id, data }) => {
|
|||||||
reset({
|
reset({
|
||||||
fileName: filteredObject?.fileName,
|
fileName: filteredObject?.fileName,
|
||||||
document: filteredObject?.document,
|
document: filteredObject?.document,
|
||||||
|
documentNameArabic: filterObject?.documentNameArabic,
|
||||||
Type: filteredObject?.Type,
|
Type: filteredObject?.Type,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -158,6 +158,7 @@ const InvestmentEdit = ({ isOpen, onClose, thirdField, id, data }) => {
|
|||||||
if (Object.keys(errors).length === 0) {
|
if (Object.keys(errors).length === 0) {
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append("documentName", data.fileName);
|
formData.append("documentName", data.fileName);
|
||||||
|
formData.append("documentNameArabic", data.documentNameArabic);
|
||||||
typeof data?.document !== "string"
|
typeof data?.document !== "string"
|
||||||
? formData.append("document", data?.document[0])
|
? formData.append("document", data?.document[0])
|
||||||
: null;
|
: null;
|
||||||
@@ -171,7 +172,6 @@ const InvestmentEdit = ({ isOpen, onClose, thirdField, id, data }) => {
|
|||||||
setFile(selectedFile);
|
setFile(selectedFile);
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log(filteredObject);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Drawer
|
<Drawer
|
||||||
@@ -200,6 +200,27 @@ const InvestmentEdit = ({ isOpen, onClose, thirdField, id, data }) => {
|
|||||||
</Text>
|
</Text>
|
||||||
)}
|
)}
|
||||||
</FormControl>
|
</FormControl>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<FormControl mb={4} isRequired>
|
||||||
|
<FormLabel fontSize="sm">File Name ( Arabic )</FormLabel>
|
||||||
|
<Input
|
||||||
|
name="documentNameArabic"
|
||||||
|
{...register("documentNameArabic")}
|
||||||
|
fontSize="sm"
|
||||||
|
type="text"
|
||||||
|
size="sm"
|
||||||
|
textAlign={'right'}
|
||||||
|
/>
|
||||||
|
{errors.documentNameArabic && (
|
||||||
|
<Text mt={1} fontSize="xs" fontWeight={500} color="red">
|
||||||
|
{errors.documentNameArabic.message}
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
|
</FormControl>
|
||||||
|
|
||||||
<FormControl mb={4} isInvalid={errors.Type}>
|
<FormControl mb={4} isInvalid={errors.Type}>
|
||||||
<FormLabel fontSize="sm">Document</FormLabel>
|
<FormLabel fontSize="sm">Document</FormLabel>
|
||||||
<Input
|
<Input
|
||||||
@@ -209,6 +230,7 @@ const InvestmentEdit = ({ isOpen, onClose, thirdField, id, data }) => {
|
|||||||
className="form-control"
|
className="form-control"
|
||||||
type="file"
|
type="file"
|
||||||
size="sm"
|
size="sm"
|
||||||
|
accept=".pdf, .doc, .docx"
|
||||||
onChange={handleFileChange}
|
onChange={handleFileChange}
|
||||||
/>
|
/>
|
||||||
{errors.document && (
|
{errors.document && (
|
||||||
|
|||||||
@@ -11,13 +11,15 @@ import {
|
|||||||
FormControl,
|
FormControl,
|
||||||
FormErrorMessage,
|
FormErrorMessage,
|
||||||
FormLabel,
|
FormLabel,
|
||||||
|
Icon,
|
||||||
Image,
|
Image,
|
||||||
Input,
|
Input,
|
||||||
Stack,
|
Stack,
|
||||||
|
Text,
|
||||||
useToast,
|
useToast,
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import * as yup from "yup";
|
import * as yup from "yup";
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useRef, useState } from "react";
|
||||||
import { useForm, Controller } from "react-hook-form";
|
import { useForm, Controller } from "react-hook-form";
|
||||||
import { yupResolver } from "@hookform/resolvers/yup";
|
import { yupResolver } from "@hookform/resolvers/yup";
|
||||||
import CustomAlertDialog from "../../Components/CustomAlertDialog";
|
import CustomAlertDialog from "../../Components/CustomAlertDialog";
|
||||||
@@ -27,6 +29,9 @@ import {
|
|||||||
} from "../../Services/io.service";
|
} from "../../Services/io.service";
|
||||||
import { useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
import ToastBox from "../../Components/ToastBox";
|
import ToastBox from "../../Components/ToastBox";
|
||||||
|
import { bytesToMB } from "./InvestmentDocuments";
|
||||||
|
import { formatTimestampInGulfTimezone } from "../../Constants/Constants";
|
||||||
|
import { IoMdRemoveCircleOutline } from "react-icons/io";
|
||||||
|
|
||||||
const investmentImageSchema = yup.object().shape({
|
const investmentImageSchema = yup.object().shape({
|
||||||
artifactName: yup.string().required("Artifact image name is required"),
|
artifactName: yup.string().required("Artifact image name is required"),
|
||||||
@@ -41,8 +46,6 @@ const IOArtifactsAdd = ({
|
|||||||
setActionId,
|
setActionId,
|
||||||
data,
|
data,
|
||||||
}) => {
|
}) => {
|
||||||
console.log(actionId);
|
|
||||||
console.log(data);
|
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
const id = params?.id;
|
const id = params?.id;
|
||||||
const [file, setFile] = useState(null);
|
const [file, setFile] = useState(null);
|
||||||
@@ -55,7 +58,8 @@ const IOArtifactsAdd = ({
|
|||||||
const [updateImageArtifacts] = useUpdateImageArtifactsMutation();
|
const [updateImageArtifacts] = useUpdateImageArtifactsMutation();
|
||||||
|
|
||||||
const found = data?.find((item) => item?.id === actionId);
|
const found = data?.find((item) => item?.id === actionId);
|
||||||
console.log(found);
|
const fileInputRef = useRef(null);
|
||||||
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
control,
|
control,
|
||||||
@@ -78,7 +82,6 @@ const IOArtifactsAdd = ({
|
|||||||
}
|
}
|
||||||
}, [found, reset]);
|
}, [found, reset]);
|
||||||
|
|
||||||
console.log(watch());
|
|
||||||
|
|
||||||
const onSubmit = async (data) => {
|
const onSubmit = async (data) => {
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
@@ -86,29 +89,25 @@ const IOArtifactsAdd = ({
|
|||||||
formData.append("artifactName", data.artifactName);
|
formData.append("artifactName", data.artifactName);
|
||||||
|
|
||||||
file && formData.append("artifactPathName", file); // Assuming artifactPathName is an array of files
|
file && formData.append("artifactPathName", file); // Assuming artifactPathName is an array of files
|
||||||
|
|
||||||
console.log("FormData:", formData);
|
|
||||||
for (let [key, value] of formData.entries()) {
|
|
||||||
console.log(`${key}:`, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (found) {
|
if (found) {
|
||||||
const res = await updateImageArtifacts({
|
const res = await updateImageArtifacts({
|
||||||
data: formData,
|
data: formData,
|
||||||
id: found?.id,
|
id: found?.id,
|
||||||
});
|
});
|
||||||
console.log(res?.error);
|
|
||||||
if (res?.data?.statusCode === 200) {
|
if (res?.data?.statusCode === 200) {
|
||||||
toast({
|
toast({
|
||||||
render: () => <ToastBox message={res?.data?.message} />,
|
render: () => <ToastBox message={res?.data?.message} />,
|
||||||
});
|
});
|
||||||
reset();
|
|
||||||
setFile(null);
|
setFile(null);
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
setAlert(false);
|
setAlert(false);
|
||||||
setPreview(null);
|
setPreview(null);
|
||||||
onClose();
|
onClose();
|
||||||
|
reset({
|
||||||
|
artifactName: "",
|
||||||
|
artifactPathName: "",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res?.error) {
|
if (res?.error) {
|
||||||
@@ -126,7 +125,10 @@ const IOArtifactsAdd = ({
|
|||||||
toast({
|
toast({
|
||||||
render: () => <ToastBox message={res?.data?.message} />,
|
render: () => <ToastBox message={res?.data?.message} />,
|
||||||
});
|
});
|
||||||
reset();
|
reset({
|
||||||
|
artifactName: "",
|
||||||
|
artifactPathName: "",
|
||||||
|
});
|
||||||
setFile(null);
|
setFile(null);
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
setAlert(false);
|
setAlert(false);
|
||||||
@@ -153,6 +155,8 @@ const IOArtifactsAdd = ({
|
|||||||
reader.readAsDataURL(file);
|
reader.readAsDataURL(file);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const handleSave = () => {
|
const handleSave = () => {
|
||||||
handleSubmit(onSubmit)();
|
handleSubmit(onSubmit)();
|
||||||
};
|
};
|
||||||
@@ -169,6 +173,18 @@ const IOArtifactsAdd = ({
|
|||||||
setActionId(false);
|
setActionId(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const handleRemove = () => {
|
||||||
|
|
||||||
|
setFile(null)
|
||||||
|
setPreview(null)
|
||||||
|
// Reset the file input value
|
||||||
|
if (fileInputRef.current) {
|
||||||
|
fileInputRef.current.value = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Drawer
|
<Drawer
|
||||||
@@ -214,6 +230,7 @@ const IOArtifactsAdd = ({
|
|||||||
fontSize={"sm"}
|
fontSize={"sm"}
|
||||||
size={"sm"}
|
size={"sm"}
|
||||||
className="form-control"
|
className="form-control"
|
||||||
|
ref={fileInputRef} // Set the ref here
|
||||||
/>
|
/>
|
||||||
<FormErrorMessage fontSize={"xs"} fontWeight={500}>
|
<FormErrorMessage fontSize={"xs"} fontWeight={500}>
|
||||||
{!preview &&
|
{!preview &&
|
||||||
@@ -221,18 +238,29 @@ const IOArtifactsAdd = ({
|
|||||||
errors.artifactPathName?.message}
|
errors.artifactPathName?.message}
|
||||||
</FormErrorMessage>
|
</FormErrorMessage>
|
||||||
{preview && (
|
{preview && (
|
||||||
<Image
|
<>
|
||||||
rounded={"md"}
|
<Image
|
||||||
src={preview}
|
rounded={"md"}
|
||||||
alt="Image Preview"
|
src={preview}
|
||||||
mt={2}
|
alt="Image Preview"
|
||||||
/>
|
mt={3}
|
||||||
|
width={'100%'}
|
||||||
|
height={300}
|
||||||
|
objectFit={'cover'}
|
||||||
|
/>
|
||||||
|
<Box w={'100%'} position={'relative'} mt={2} fontSize={'xs'} display={'flex'} flexDirection={'column'} as="span">
|
||||||
|
<Text as={'span'}>Name: {file?.name}</Text>
|
||||||
|
<Text as={'span'} fontSize={'xs'}>File size: {bytesToMB(file?.size)}</Text>
|
||||||
|
<Text as={'span'} fontSize={'xs'}>Last update: {formatTimestampInGulfTimezone(file?.lastModified)}</Text>
|
||||||
|
<Icon onClick={() => handleRemove()} _hover={{ bg: "gray.100" }} transition={'all 0-5s'} cursor={'pointer'} position={'absolute'} right={0} p={1} bottom={0} rounded={'lg'} boxSize={7} as={IoMdRemoveCircleOutline} />
|
||||||
|
</Box>
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
{found && !preview && (
|
{found && !preview && (
|
||||||
<Image
|
<Image
|
||||||
rounded={"md"}
|
rounded={"md"}
|
||||||
src={
|
src={
|
||||||
"https://tanami.betadelivery.com/" +
|
import.meta.env.VITE_IMAGE_URL +
|
||||||
watch()?.artifactPathName
|
watch()?.artifactPathName
|
||||||
}
|
}
|
||||||
alt="Image Preview"
|
alt="Image Preview"
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import {
|
|||||||
DrawerHeader,
|
DrawerHeader,
|
||||||
DrawerOverlay,
|
DrawerOverlay,
|
||||||
FormControl,
|
FormControl,
|
||||||
|
FormHelperText,
|
||||||
FormLabel,
|
FormLabel,
|
||||||
Input,
|
Input,
|
||||||
Text,
|
Text,
|
||||||
@@ -59,6 +60,7 @@ export const investmentDocSchema = yup.object().shape({
|
|||||||
// return value && value.size <= 2 * 1024 * 1024; // 2MB in bytes
|
// return value && value.size <= 2 * 1024 * 1024; // 2MB in bytes
|
||||||
// })
|
// })
|
||||||
fileName: yup.string().required("File name is required"),
|
fileName: yup.string().required("File name is required"),
|
||||||
|
documentNameArabic: yup.string().required("File name Arabic is required")
|
||||||
});
|
});
|
||||||
|
|
||||||
const InvestmentDocuments = ({
|
const InvestmentDocuments = ({
|
||||||
@@ -94,11 +96,10 @@ const InvestmentDocuments = ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const onSubmit = async (data) => {
|
const onSubmit = async (data) => {
|
||||||
console.log("sibmited");
|
|
||||||
console.log(errors);
|
|
||||||
if (Object.keys(errors).length === 0) {
|
if (Object.keys(errors).length === 0) {
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append("documentName", data.fileName);
|
formData.append("documentName", data.fileName);
|
||||||
|
formData.append("documentNameArabic", data.documentNameArabic);
|
||||||
formData.append("document", data?.document[0]);
|
formData.append("document", data?.document[0]);
|
||||||
setFormData(formData);
|
setFormData(formData);
|
||||||
setAlert(true);
|
setAlert(true);
|
||||||
@@ -109,7 +110,7 @@ const InvestmentDocuments = ({
|
|||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
try {
|
try {
|
||||||
const res = await createInvestmentDocument({ data: formData, id });
|
const res = await createInvestmentDocument({ data: formData, id });
|
||||||
console.log(res);
|
|
||||||
if (res?.error) {
|
if (res?.error) {
|
||||||
toast({
|
toast({
|
||||||
render: () => (
|
render: () => (
|
||||||
@@ -214,6 +215,27 @@ const InvestmentDocuments = ({
|
|||||||
</Text>
|
</Text>
|
||||||
)}
|
)}
|
||||||
</FormControl>
|
</FormControl>
|
||||||
|
|
||||||
|
|
||||||
|
<FormControl mb={4} isRequired>
|
||||||
|
<FormLabel fontSize="sm">File Name ( Arabic )</FormLabel>
|
||||||
|
<Input
|
||||||
|
name="documentNameArabic"
|
||||||
|
{...register("documentNameArabic")}
|
||||||
|
fontSize="sm"
|
||||||
|
type="text"
|
||||||
|
size="sm"
|
||||||
|
textAlign={'right'}
|
||||||
|
/>
|
||||||
|
{errors.documentNameArabic && (
|
||||||
|
<Text mt={1} fontSize="xs" fontWeight={500} color="red">
|
||||||
|
{errors.documentNameArabic.message}
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
|
</FormControl>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<FormControl mb={4} isRequired>
|
<FormControl mb={4} isRequired>
|
||||||
<FormLabel fontSize="sm">Document</FormLabel>
|
<FormLabel fontSize="sm">Document</FormLabel>
|
||||||
<Input
|
<Input
|
||||||
@@ -231,6 +253,8 @@ const InvestmentDocuments = ({
|
|||||||
{errors.document.message}
|
{errors.document.message}
|
||||||
</Text>
|
</Text>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
<FormHelperText mt={1} fontSize="xs" fontWeight={500} color="gray.500">File size should be max 2mb</FormHelperText>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
{file && (
|
{file && (
|
||||||
<Box mt={4}>
|
<Box mt={4}>
|
||||||
|
|||||||
@@ -71,7 +71,6 @@ const KeyMeritsAdd = ({ isOpen, onClose, firstField, id, icons }) => {
|
|||||||
|
|
||||||
const onSubmit = (data) => {
|
const onSubmit = (data) => {
|
||||||
if (Object.keys(errors).length === 0) {
|
if (Object.keys(errors).length === 0) {
|
||||||
console.log("hit");
|
|
||||||
setFormData(data);
|
setFormData(data);
|
||||||
setAlert(true);
|
setAlert(true);
|
||||||
}
|
}
|
||||||
@@ -81,30 +80,24 @@ const KeyMeritsAdd = ({ isOpen, onClose, firstField, id, icons }) => {
|
|||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
try {
|
try {
|
||||||
const res = await createKeyMerits({ data: formData, id });
|
const res = await createKeyMerits({ data: formData, id });
|
||||||
|
console.log(res?.error?.status);
|
||||||
|
|
||||||
if (res?.data?.statusCode === 201) {
|
if (res?.data?.statusCode === 201) {
|
||||||
toast({
|
toast({
|
||||||
render: () => <ToastBox message={res?.data?.message} />,
|
render: () => <ToastBox message={res?.data?.message} />,
|
||||||
});
|
});
|
||||||
setAlert(false);
|
handleClose()
|
||||||
onClose();
|
|
||||||
setIsLoading(false);
|
|
||||||
reset();
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (res?.error?.data?.code === 400) {
|
if (res?.error?.status === 400 || res?.error?.status === 500 ) {
|
||||||
toast({
|
toast({
|
||||||
render: () => (
|
render: () => (
|
||||||
<ToastBox message={res?.error?.data?.message} status={"error"} />
|
<ToastBox message={res?.error?.data?.message} status={"error"} />
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
onClose();
|
|
||||||
setAlert(false);
|
setAlert(false);
|
||||||
reset();
|
|
||||||
setFile(null);
|
|
||||||
setSelectedImageIcon(null);
|
|
||||||
setSelectedIcon("Select Icon");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -119,12 +112,7 @@ const KeyMeritsAdd = ({ isOpen, onClose, firstField, id, icons }) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
onClose();
|
handleClose()
|
||||||
setAlert(false);
|
|
||||||
reset();
|
|
||||||
setFile(null);
|
|
||||||
setSelectedImageIcon(null);
|
|
||||||
setSelectedIcon("Select Icon");
|
|
||||||
}
|
}
|
||||||
reset();
|
reset();
|
||||||
};
|
};
|
||||||
@@ -135,7 +123,6 @@ const KeyMeritsAdd = ({ isOpen, onClose, firstField, id, icons }) => {
|
|||||||
|
|
||||||
const handleFileChange = (e) => {
|
const handleFileChange = (e) => {
|
||||||
const file = e.target.files[0];
|
const file = e.target.files[0];
|
||||||
console.log(file);
|
|
||||||
if (file) {
|
if (file) {
|
||||||
setFile(URL.createObjectURL(file));
|
setFile(URL.createObjectURL(file));
|
||||||
}
|
}
|
||||||
@@ -149,6 +136,7 @@ const KeyMeritsAdd = ({ isOpen, onClose, firstField, id, icons }) => {
|
|||||||
|
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
onClose();
|
onClose();
|
||||||
|
setIsLoading(false);
|
||||||
setAlert(false);
|
setAlert(false);
|
||||||
reset();
|
reset();
|
||||||
setFile(null);
|
setFile(null);
|
||||||
@@ -296,18 +284,18 @@ const KeyMeritsAdd = ({ isOpen, onClose, firstField, id, icons }) => {
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Box display="flex" alignItems="center">
|
<Box display="flex" alignItems="center">
|
||||||
<Image
|
{selectedImageIcon && <Image
|
||||||
src={`https://tanami.betadelivery.com/${selectedImageIcon}`}
|
src={`${import.meta.env.VITE_IMAGE_URL}${selectedImageIcon}`}
|
||||||
alt={selectedImageIcon}
|
alt={selectedImageIcon}
|
||||||
boxSize="1rem"
|
boxSize="1rem"
|
||||||
mr="12px"
|
mr="12px"
|
||||||
/>{" "}
|
/>}{" "}
|
||||||
<Text as={"span"} fontSize={"sm"} fontWeight={500}>
|
<Text as={"span"} fontSize={"sm"} fontWeight={500}>
|
||||||
{selectedIcon}
|
{selectedIcon}
|
||||||
</Text>
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
</MenuButton>
|
</MenuButton>
|
||||||
<MenuList minW="415px" size={"sm"} fontWeight={500}>
|
<MenuList overflow={'scroll'} minW="415px" size={"sm"} fontWeight={500}>
|
||||||
{icons?.map(({ iconName, id, iconFilePath }) => (
|
{icons?.map(({ iconName, id, iconFilePath }) => (
|
||||||
<MenuItem
|
<MenuItem
|
||||||
key={id}
|
key={id}
|
||||||
@@ -317,7 +305,7 @@ const KeyMeritsAdd = ({ isOpen, onClose, firstField, id, icons }) => {
|
|||||||
>
|
>
|
||||||
<Box display="flex" alignItems="center">
|
<Box display="flex" alignItems="center">
|
||||||
<Image
|
<Image
|
||||||
src={`https://tanami.betadelivery.com/${iconFilePath}`}
|
src={`${import.meta.env.VITE_IMAGE_URL}${iconFilePath}`}
|
||||||
alt={iconName}
|
alt={iconName}
|
||||||
boxSize="1rem"
|
boxSize="1rem"
|
||||||
mr="12px"
|
mr="12px"
|
||||||
|
|||||||
@@ -59,6 +59,8 @@ const KeyMeritsEdit = ({
|
|||||||
const [selectedImageIcon, setSelectedImageIcon] = useState(null);
|
const [selectedImageIcon, setSelectedImageIcon] = useState(null);
|
||||||
|
|
||||||
const found = data?.find((item) => item?.id === actionId);
|
const found = data?.find((item) => item?.id === actionId);
|
||||||
|
console.log(found);
|
||||||
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
control,
|
control,
|
||||||
@@ -71,6 +73,9 @@ const KeyMeritsEdit = ({
|
|||||||
});
|
});
|
||||||
// useEffect to reset the form when `found` changes
|
// useEffect to reset the form when `found` changes
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
setValue("icon_xid", found?.icon?.id);
|
||||||
|
setSelectedIcon(found?.icon?.iconName); // Update selected icon name
|
||||||
|
setSelectedImageIcon(found?.icon?.iconFilePath);
|
||||||
if (found) {
|
if (found) {
|
||||||
reset({
|
reset({
|
||||||
meritsHeader: found?.meritsHeader,
|
meritsHeader: found?.meritsHeader,
|
||||||
@@ -91,10 +96,7 @@ const KeyMeritsEdit = ({
|
|||||||
toast({
|
toast({
|
||||||
render: () => <ToastBox message={res?.data?.message} />,
|
render: () => <ToastBox message={res?.data?.message} />,
|
||||||
});
|
});
|
||||||
setAlert(false);
|
handleClose()
|
||||||
onClose();
|
|
||||||
setIsLoading(false);
|
|
||||||
reset();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (res?.error?.data?.code === 400) {
|
if (res?.error?.data?.code === 400) {
|
||||||
@@ -103,10 +105,7 @@ const KeyMeritsEdit = ({
|
|||||||
<ToastBox message={res?.error?.data?.message} status={"error"} />
|
<ToastBox message={res?.error?.data?.message} status={"error"} />
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
setAlert(false);
|
handleClose()
|
||||||
onClose();
|
|
||||||
setIsLoading(false);
|
|
||||||
reset();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -121,10 +120,7 @@ const KeyMeritsEdit = ({
|
|||||||
),
|
),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
setIsLoading(false);
|
handleClose()
|
||||||
setAlert(false);
|
|
||||||
onClose();
|
|
||||||
reset();
|
|
||||||
}
|
}
|
||||||
reset();
|
reset();
|
||||||
};
|
};
|
||||||
@@ -133,7 +129,6 @@ const KeyMeritsEdit = ({
|
|||||||
handleSubmit(onSubmit)();
|
handleSubmit(onSubmit)();
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log(errors);
|
|
||||||
|
|
||||||
const handleIconSelect = (id, iconName, iconFilePath) => {
|
const handleIconSelect = (id, iconName, iconFilePath) => {
|
||||||
setValue("icon_xid", id);
|
setValue("icon_xid", id);
|
||||||
@@ -141,6 +136,14 @@ const KeyMeritsEdit = ({
|
|||||||
setSelectedImageIcon(iconFilePath);
|
setSelectedImageIcon(iconFilePath);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleClose = () => {
|
||||||
|
setIsLoading(false);
|
||||||
|
setAlert(false);
|
||||||
|
onClose();
|
||||||
|
reset();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Drawer
|
<Drawer
|
||||||
@@ -280,12 +283,12 @@ const KeyMeritsEdit = ({
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Box display="flex" alignItems="center">
|
<Box display="flex" alignItems="center">
|
||||||
<Image
|
{selectedImageIcon&&<Image
|
||||||
src={`https://tanami.betadelivery.com/${selectedImageIcon}`}
|
src={`${import.meta.env.VITE_IMAGE_URL}${selectedImageIcon}`}
|
||||||
alt={selectedImageIcon}
|
alt={selectedImageIcon}
|
||||||
boxSize="1rem"
|
boxSize="1rem"
|
||||||
mr="12px"
|
mr="12px"
|
||||||
/>{" "}
|
/>}{" "}
|
||||||
<Text as={"span"} fontSize={"sm"} fontWeight={500}>
|
<Text as={"span"} fontSize={"sm"} fontWeight={500}>
|
||||||
{selectedIcon}
|
{selectedIcon}
|
||||||
</Text>
|
</Text>
|
||||||
@@ -301,7 +304,7 @@ const KeyMeritsEdit = ({
|
|||||||
>
|
>
|
||||||
<Box display="flex" alignItems="center">
|
<Box display="flex" alignItems="center">
|
||||||
<Image
|
<Image
|
||||||
src={`https://tanami.betadelivery.com/${iconFilePath}`}
|
src={`${import.meta.env.VITE_IMAGE_URL}${iconFilePath}`}
|
||||||
alt={iconName}
|
alt={iconName}
|
||||||
boxSize="1rem"
|
boxSize="1rem"
|
||||||
mr="12px"
|
mr="12px"
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import React, { useContext, useEffect, useState } from 'react';
|
||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
Button,
|
Button,
|
||||||
@@ -12,10 +13,93 @@ import {
|
|||||||
ModalHeader,
|
ModalHeader,
|
||||||
ModalOverlay,
|
ModalOverlay,
|
||||||
Text,
|
Text,
|
||||||
Textarea,
|
useToast,
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
|
import { useForm } from 'react-hook-form';
|
||||||
|
import * as yup from 'yup';
|
||||||
|
import { yupResolver } from '@hookform/resolvers/yup';
|
||||||
|
import GlobalStateContext from '../../../../Contexts/GlobalStateContext';
|
||||||
|
import { useParams } from 'react-router-dom';
|
||||||
|
import { useAmountIvestmentMutation } from '../../../../Services/io.service';
|
||||||
|
import ToastBox from '../../../../Components/ToastBox';
|
||||||
|
|
||||||
|
// Validation schema
|
||||||
|
const validationSchema = yup.object().shape({
|
||||||
|
transactionDate: yup.date().required('Date is required'),
|
||||||
|
Total_Amount: yup.number().required('Amount is required'),
|
||||||
|
amountInvested: yup.number().required('Amount to invest is required'),
|
||||||
|
IoCash: yup.number().positive('IO Cash must be positive').required('IO Cash is required'),
|
||||||
|
});
|
||||||
|
|
||||||
|
// Function to format currency
|
||||||
|
const formatCurrency = (value) => {
|
||||||
|
if (isNaN(value)) return '';
|
||||||
|
const formatted = parseFloat(value).toFixed(2).toString();
|
||||||
|
const [integer, decimal] = formatted.split('.');
|
||||||
|
const formattedInteger = integer.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
|
||||||
|
return decimal ? `${formattedInteger}.${decimal}` : formattedInteger;
|
||||||
|
};
|
||||||
|
|
||||||
const AmountInvested = ({ isOpen, onClose }) => {
|
const AmountInvested = ({ isOpen, onClose }) => {
|
||||||
|
const params = useParams();
|
||||||
|
const toast = useToast();
|
||||||
|
const id = params?.id;
|
||||||
|
const { control, register, handleSubmit, reset, watch, formState: { errors } } = useForm({
|
||||||
|
resolver: yupResolver(validationSchema),
|
||||||
|
});
|
||||||
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
const { IODetails } = useContext(GlobalStateContext);
|
||||||
|
const [amountInvested] = useAmountIvestmentMutation();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (IODetails?.totalAmtInvestmentInUSD) {
|
||||||
|
const totalAmount = parseFloat(IODetails.totalAmtInvestmentInUSD);
|
||||||
|
const ioCashUpdate = parseFloat(IODetails.totalAmtInvestmentInUSD)
|
||||||
|
reset({
|
||||||
|
Total_Amount: totalAmount,
|
||||||
|
IoCash: ioCashUpdate,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [IODetails, reset]);
|
||||||
|
|
||||||
|
const onSubmit = async (data) => {
|
||||||
|
console.log(data);
|
||||||
|
setIsLoading(true);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await amountInvested({ data, id });
|
||||||
|
console.log(res);
|
||||||
|
if (res?.data?.statusCode === 200) {
|
||||||
|
toast({
|
||||||
|
render: () => <ToastBox message={res?.data?.message} />,
|
||||||
|
});
|
||||||
|
setIsLoading(false);
|
||||||
|
onClose();
|
||||||
|
} else if (res?.error?.status === 400) {
|
||||||
|
toast({
|
||||||
|
render: () => (
|
||||||
|
<ToastBox message={res?.error?.data?.message} status={"error"} />
|
||||||
|
),
|
||||||
|
});
|
||||||
|
setIsLoading(false);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
setIsLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleAmountChange = (e) => {
|
||||||
|
const amount = parseFloat(e.target.value) || 0;
|
||||||
|
const totalAmount = parseFloat(IODetails?.totalAmtInvestmentInUSD) || 0;
|
||||||
|
const ioCash = (totalAmount - amount).toFixed(2);
|
||||||
|
|
||||||
|
reset({
|
||||||
|
amountInvested: parseFloat(amount),
|
||||||
|
IoCash: parseFloat(ioCash),
|
||||||
|
Total_Amount: IODetails?.totalAmtInvestmentInUSD
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal isOpen={isOpen} onClose={onClose}>
|
<Modal isOpen={isOpen} onClose={onClose}>
|
||||||
<ModalOverlay />
|
<ModalOverlay />
|
||||||
@@ -23,73 +107,92 @@ const AmountInvested = ({ isOpen, onClose }) => {
|
|||||||
<ModalHeader fontSize={'md'}>Amount Invested</ModalHeader>
|
<ModalHeader fontSize={'md'}>Amount Invested</ModalHeader>
|
||||||
<ModalCloseButton />
|
<ModalCloseButton />
|
||||||
<ModalBody>
|
<ModalBody>
|
||||||
<FormControl mb={"15px"}>
|
<form onSubmit={handleSubmit(onSubmit)}>
|
||||||
<FormLabel as={"label"} fontSize={"sm"} fontWeight={500}>
|
<FormControl mb={"15px"} isInvalid={!!errors.transactionDate} isRequired>
|
||||||
Date
|
<FormLabel as={"label"} fontSize={"sm"} fontWeight={500}>
|
||||||
</FormLabel>
|
Date
|
||||||
<Input
|
</FormLabel>
|
||||||
placeholder="Select Date"
|
<Input
|
||||||
size="sm"
|
type="date"
|
||||||
rounded={'sm'}
|
{...register('transactionDate')}
|
||||||
fontSize={"sm"}
|
size="sm"
|
||||||
focusBorderColor="forestGreen.300"
|
rounded={'sm'}
|
||||||
type="date"
|
fontSize={"sm"}
|
||||||
/>
|
focusBorderColor="forestGreen.300"
|
||||||
</FormControl>
|
/>
|
||||||
|
{errors.transactionDate && <Text color="red.500">{errors.transactionDate.message}</Text>}
|
||||||
|
</FormControl>
|
||||||
|
|
||||||
<FormControl mb={"15px"} >
|
<FormControl mb={"15px"} isInvalid={!!errors.Total_Amount} isReadOnly>
|
||||||
<FormLabel as={"label"} fontSize={"sm"} fontWeight={500}>Amount</FormLabel>
|
<FormLabel as={"label"} fontSize={"sm"} fontWeight={500}>Amount</FormLabel>
|
||||||
<Input
|
<Input
|
||||||
size="sm"
|
type="text"
|
||||||
rounded={'sm'}
|
value={formatCurrency(watch('Total_Amount'))}
|
||||||
textAlign={'end'}
|
size="sm"
|
||||||
readOnly
|
rounded={'sm'}
|
||||||
value={"$ 100000"}
|
textAlign={'end'}
|
||||||
focusBorderColor="forestGreen.300"
|
focusBorderColor="forestGreen.300"
|
||||||
fontSize={"sm"} placeholder="$00.00" />
|
fontSize={"sm"}
|
||||||
</FormControl>
|
readOnly
|
||||||
|
/>
|
||||||
|
{errors.Total_Amount && <Text color="red.500">{errors.Total_Amount.message}</Text>}
|
||||||
|
</FormControl>
|
||||||
|
|
||||||
<FormControl mb={"15px"} >
|
<FormControl mb={"15px"} isInvalid={!!errors.amountInvested} isRequired>
|
||||||
<FormLabel as={"label"} fontSize={"sm"} fontWeight={500}>Amount to invest</FormLabel>
|
<FormLabel as={"label"} fontSize={"sm"} fontWeight={500}>Amount to invest</FormLabel>
|
||||||
<Input
|
<Input
|
||||||
size="sm"
|
type="number"
|
||||||
rounded={'sm'}
|
{...register('amountInvested')}
|
||||||
textAlign={'end'}
|
size="sm"
|
||||||
focusBorderColor="forestGreen.300"
|
rounded={'sm'}
|
||||||
fontSize={"sm"} placeholder="$00.00" />
|
textAlign={'end'}
|
||||||
</FormControl>
|
focusBorderColor="forestGreen.300"
|
||||||
|
fontSize={"sm"}
|
||||||
|
onChange={handleAmountChange}
|
||||||
|
/>
|
||||||
|
{errors.amountInvested && <Text color="red.500">{errors.amountInvested.message}</Text>}
|
||||||
|
</FormControl>
|
||||||
|
|
||||||
<FormControl mb={"15px"}>
|
<FormControl mb={"15px"} isInvalid={!!errors.IoCash}>
|
||||||
<FormLabel as={"label"} fontSize={"sm"} fontWeight={500}>
|
<FormLabel as={"label"} fontSize={"sm"} fontWeight={500}>
|
||||||
IO Cash
|
IO Cash
|
||||||
</FormLabel>
|
</FormLabel>
|
||||||
<Input
|
<Input
|
||||||
size="sm"
|
type="text"
|
||||||
rounded={'sm'}
|
value={formatCurrency(watch('IoCash'))}
|
||||||
placeholder="$00.00"
|
size="sm"
|
||||||
focusBorderColor="forestGreen.300"
|
rounded={'sm'}
|
||||||
fontSize={"sm"} />
|
focusBorderColor="forestGreen.300"
|
||||||
</FormControl>
|
fontSize={"sm"}
|
||||||
|
textAlign={'right'}
|
||||||
|
readOnly
|
||||||
|
/>
|
||||||
|
{errors.IoCash && <Text color="red.500">{errors.IoCash.message}</Text>}
|
||||||
|
</FormControl>
|
||||||
|
|
||||||
|
<ModalFooter>
|
||||||
|
<Button
|
||||||
|
type="submit"
|
||||||
|
bg={"hsla(139, 100%, 14%, 1)"}
|
||||||
|
mr={3}
|
||||||
|
color={"#fff"}
|
||||||
|
_hover={{
|
||||||
|
bg: "hsl(139deg 98.99% 26.59%)",
|
||||||
|
}}
|
||||||
|
size={'sm'}
|
||||||
|
rounded={"sm"}
|
||||||
|
isLoading={isLoading}
|
||||||
|
>
|
||||||
|
Save
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
size={'sm'}
|
||||||
|
rounded={"sm"} mr={3} onClick={onClose}>
|
||||||
|
Close
|
||||||
|
</Button>
|
||||||
|
</ModalFooter>
|
||||||
|
</form>
|
||||||
</ModalBody>
|
</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>
|
</ModalContent>
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import {
|
|||||||
Box,
|
Box,
|
||||||
Button,
|
Button,
|
||||||
FormControl,
|
FormControl,
|
||||||
|
FormErrorMessage,
|
||||||
FormLabel,
|
FormLabel,
|
||||||
HStack,
|
HStack,
|
||||||
Input,
|
Input,
|
||||||
@@ -23,8 +24,61 @@ import {
|
|||||||
import DataTable from "../../../../Components/DataTable/DataTable";
|
import DataTable from "../../../../Components/DataTable/DataTable";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { AddIcon } from "@chakra-ui/icons";
|
import { AddIcon } from "@chakra-ui/icons";
|
||||||
|
import { useGetDistributionInvestorMutation } from "../../../../Services/io.service";
|
||||||
|
import { useParams } from "react-router-dom";
|
||||||
|
import { useEffect } from "react";
|
||||||
|
import { Controller, useForm } from "react-hook-form";
|
||||||
|
import * as yup from "yup";
|
||||||
|
import { yupResolver } from "@hookform/resolvers/yup";
|
||||||
|
|
||||||
|
|
||||||
|
export const investor = yup.object().shape({
|
||||||
|
amount: yup.string().required("Amount is required"),
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const DistributionInvestor = ({ isOpen, onClose, }) => {
|
||||||
|
|
||||||
|
|
||||||
|
const params = useParams()
|
||||||
|
const id = params?.id
|
||||||
|
|
||||||
|
// const {
|
||||||
|
// data:IObyID,
|
||||||
|
// error,
|
||||||
|
// isLoading,
|
||||||
|
// } = useGetDistributionInvestorMutation(id);
|
||||||
|
|
||||||
|
const [ getDistributionInvestment ] = useGetDistributionInvestorMutation()
|
||||||
|
|
||||||
|
const {
|
||||||
|
control,
|
||||||
|
handleSubmit,
|
||||||
|
formState: { errors },
|
||||||
|
reset,
|
||||||
|
} = useForm({
|
||||||
|
resolver: yupResolver(investor),
|
||||||
|
});
|
||||||
|
|
||||||
|
// useEffect(()=>{
|
||||||
|
// try {
|
||||||
|
// const res = getDistributionInvestment({id,data})
|
||||||
|
// console.log(res);
|
||||||
|
|
||||||
|
// } catch (error) {
|
||||||
|
|
||||||
|
// }
|
||||||
|
// },[])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// console.log(IObyID);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const DistributionInvestor = ({ isOpen, onClose }) => {
|
|
||||||
// ====================================================[Table Setup]================================================================
|
// ====================================================[Table Setup]================================================================
|
||||||
const tableHeadRow = [
|
const tableHeadRow = [
|
||||||
"Sr No.",
|
"Sr No.",
|
||||||
@@ -205,22 +259,48 @@ const DistributionInvestor = ({ isOpen, onClose }) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const onSubmit = (data) =>{
|
||||||
|
console.log( data );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal size={"xl"} isOpen={isOpen} onClose={onClose}>
|
<Modal size={"xl"} isOpen={isOpen} onClose={onClose}>
|
||||||
<ModalOverlay />
|
<ModalOverlay />
|
||||||
<ModalContent maxW={1000}>
|
<ModalContent maxW={1000}>
|
||||||
<ModalHeader fontSize={"md"}>Distribution To Investor Transaction</ModalHeader>
|
<ModalHeader fontSize={"md"}>
|
||||||
|
Distribution To Investor Transaction
|
||||||
|
</ModalHeader>
|
||||||
<ModalCloseButton />
|
<ModalCloseButton />
|
||||||
<ModalBody>
|
<ModalBody>
|
||||||
<Text as="label" mb='5px' fontSize='sm' fontWeight={500}>Amount to Distribute</Text>
|
{/* <Text as="label" mb="5px" fontSize="sm" fontWeight={500}>
|
||||||
<HStack mb={4}>
|
Amount to Distribute
|
||||||
<Input placeholder="$00.00" size={"sm"} className="col" />
|
</Text> */}
|
||||||
|
<HStack onSubmit={handleSubmit(onSubmit)} as={"form"} mb={4}>
|
||||||
{/* <Input placeholder="$00.00" size={"sm"} className="col" /> */}
|
{/* <Input placeholder="$00.00" size={"sm"} className="col" /> */}
|
||||||
|
<FormControl isInvalid={errors.amount}>
|
||||||
|
<FormLabel fontSize={"sm"}> Amount to Distribute</FormLabel>
|
||||||
|
<Controller
|
||||||
|
name="amount"
|
||||||
|
control={control}
|
||||||
|
render={({ field }) => (
|
||||||
|
<Input {...field} fontSize={"sm"} type="number" size={"sm"} textAlign={"right"} />
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<FormErrorMessage fontSize={"xs"} fontWeight={500}>
|
||||||
|
{errors.amount?.message}
|
||||||
|
</FormErrorMessage>
|
||||||
|
</FormControl>
|
||||||
<Button
|
<Button
|
||||||
// leftIcon={<AddIcon />}
|
// leftIcon={<AddIcon />}
|
||||||
size={"sm"}
|
size={"sm"}
|
||||||
rounded={"sm"}
|
rounded={"sm"}
|
||||||
colorScheme="forestGreen"
|
colorScheme="forestGreen"
|
||||||
|
type="submit"
|
||||||
>
|
>
|
||||||
Calculate
|
Calculate
|
||||||
</Button>
|
</Button>
|
||||||
@@ -243,14 +323,12 @@ const DistributionInvestor = ({ isOpen, onClose }) => {
|
|||||||
_hover={{
|
_hover={{
|
||||||
bg: "hsl(139deg 98.99% 26.59%)",
|
bg: "hsl(139deg 98.99% 26.59%)",
|
||||||
}}
|
}}
|
||||||
size={'sm'}
|
size={"sm"}
|
||||||
rounded={"sm"}
|
rounded={"sm"}
|
||||||
>
|
>
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button size={"sm"} rounded={"sm"} mr={3} onClick={onClose}>
|
||||||
size={'sm'}
|
|
||||||
rounded={"sm"} mr={3} onClick={onClose}>
|
|
||||||
Close
|
Close
|
||||||
</Button>
|
</Button>
|
||||||
</ModalFooter>
|
</ModalFooter>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import {
|
|||||||
Box,
|
Box,
|
||||||
Button,
|
Button,
|
||||||
FormControl,
|
FormControl,
|
||||||
|
FormErrorMessage,
|
||||||
FormLabel,
|
FormLabel,
|
||||||
Input,
|
Input,
|
||||||
Modal,
|
Modal,
|
||||||
@@ -11,52 +12,168 @@ import {
|
|||||||
ModalFooter,
|
ModalFooter,
|
||||||
ModalHeader,
|
ModalHeader,
|
||||||
ModalOverlay,
|
ModalOverlay,
|
||||||
|
Select,
|
||||||
|
Stack,
|
||||||
Text,
|
Text,
|
||||||
Textarea,
|
Textarea,
|
||||||
|
useToast,
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
|
import { useContext, useState } from "react";
|
||||||
|
import * as yup from "yup";
|
||||||
|
import GlobalStateContext from "../../../../Contexts/GlobalStateContext";
|
||||||
|
import { Controller, useForm } from "react-hook-form";
|
||||||
|
import { yupResolver } from "@hookform/resolvers/yup";
|
||||||
|
import CurrencyInput from "../../../../Components/CurrencyInput";
|
||||||
|
import { useCreateIoNavMutation } from "../../../../Services/io.service";
|
||||||
|
import ToastBox from "../../../../Components/ToastBox";
|
||||||
|
import { useParams } from "react-router-dom";
|
||||||
|
import { formatDatee } from "../../../../Components/FormField";
|
||||||
|
|
||||||
|
const ioNav = yup.object().shape({
|
||||||
|
transactionDate: yup.string().required("Artifact name is required"),
|
||||||
|
// ioTransType_xid: yup.number().required("Artifact name is required"),
|
||||||
|
transactionAmount: yup.number().required("Artifact name is required"),
|
||||||
|
comments: yup.string().notRequired(),
|
||||||
|
});
|
||||||
|
|
||||||
const UpdateIONav = ({ isOpen, onClose }) => {
|
const UpdateIONav = ({ isOpen, onClose }) => {
|
||||||
|
const params = useParams()
|
||||||
|
const toast = useToast();
|
||||||
|
const id = params?.id
|
||||||
|
const { IODetails } = useContext(GlobalStateContext);
|
||||||
|
const [isLoading, setIsLoading] = useState(false)
|
||||||
|
const {
|
||||||
|
control,
|
||||||
|
handleSubmit,
|
||||||
|
watch,
|
||||||
|
reset,
|
||||||
|
formState: { errors },
|
||||||
|
} = useForm({
|
||||||
|
resolver: yupResolver(ioNav),
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
const [createIoNav] = useCreateIoNavMutation()
|
||||||
|
|
||||||
|
|
||||||
|
const onSubmit = async (data) => {
|
||||||
|
setIsLoading(true);
|
||||||
|
try {
|
||||||
|
const res = await createIoNav({ data, id })
|
||||||
|
if (res?.data?.statusCode === 201) {
|
||||||
|
setIsLoading(false);
|
||||||
|
toast({
|
||||||
|
render: () => <ToastBox message={res?.data?.message} />,
|
||||||
|
});
|
||||||
|
handleClose()
|
||||||
|
} else if (res?.error?.status === 400) {
|
||||||
|
setIsLoading(false);
|
||||||
|
toast({
|
||||||
|
render: () => <ToastBox message={res?.error?.data?.message} status={"error"} />,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const handleClose = () => {
|
||||||
|
onClose()
|
||||||
|
reset()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const today = formatDatee(new Date(), 'yyyy-MM-dd');
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal isOpen={isOpen} onClose={onClose}>
|
<Modal isOpen={isOpen} onClose={onClose}>
|
||||||
<ModalOverlay />
|
<ModalOverlay />
|
||||||
<ModalContent>
|
<ModalContent as={'form'} onSubmit={handleSubmit(onSubmit)} >
|
||||||
<ModalHeader fontSize={'md'}>Update iO NAV Transaction</ModalHeader>
|
<ModalHeader fontSize={'md'}>Update iO NAV Transaction</ModalHeader>
|
||||||
<ModalCloseButton />
|
<ModalCloseButton />
|
||||||
<ModalBody>
|
<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"} >
|
<Stack spacing={4}>
|
||||||
<FormLabel as={"label"} fontSize={"sm"} fontWeight={500}>Amount</FormLabel>
|
<FormControl isInvalid={errors.transactionDate} isRequired>
|
||||||
<Input
|
<FormLabel fontSize={"sm"}>Date Selection</FormLabel>
|
||||||
size="sm"
|
<Controller
|
||||||
rounded={'sm'}
|
name="transactionDate"
|
||||||
textAlign={'end'}
|
control={control}
|
||||||
focusBorderColor="forestGreen.300"
|
render={({ field }) => (
|
||||||
fontSize={"sm"} placeholder="$00.00" />
|
<Input {...field}
|
||||||
</FormControl>
|
max={today} // Set max attribute to today’s date
|
||||||
|
fontSize={"sm"} type="date" size={"sm"} />
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<FormErrorMessage fontSize={"xs"} fontWeight={500}>
|
||||||
|
{errors.transactionDate?.message}
|
||||||
|
</FormErrorMessage>
|
||||||
|
</FormControl>
|
||||||
|
|
||||||
<FormControl mb={"15px"}>
|
|
||||||
<FormLabel as={"label"} fontSize={"sm"} fontWeight={500}>
|
{/* <FormControl isInvalid={errors.ioTransType_xid} isRequired>
|
||||||
Comments
|
<FormLabel fontSize={"sm"}>Cash transaction</FormLabel>
|
||||||
</FormLabel>
|
<Controller
|
||||||
<Textarea
|
name="ioTransType_xid"
|
||||||
size="sm"
|
control={control}
|
||||||
rounded={'sm'}
|
render={({ field }) => (
|
||||||
focusBorderColor="forestGreen.300"
|
<Select
|
||||||
fontSize={"sm"} placeholder="Write Comments" />
|
{...field}
|
||||||
</FormControl>
|
placeholder="Select an option"
|
||||||
|
fontSize={"sm"}
|
||||||
|
size={"sm"}
|
||||||
|
>
|
||||||
|
{IODetails?.ioCashTransaction?.map(({ id, transactionName }) => (
|
||||||
|
<option key={id} value={id}>
|
||||||
|
{transactionName}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<FormErrorMessage fontSize={"xs"} fontWeight={500}>
|
||||||
|
{errors.ioTransType_xid?.message}
|
||||||
|
</FormErrorMessage>
|
||||||
|
</FormControl> */}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<FormControl isInvalid={errors.transactionAmount} isRequired>
|
||||||
|
<FormLabel fontSize={"sm"}>Transaction Amount</FormLabel>
|
||||||
|
<Controller
|
||||||
|
name="transactionAmount"
|
||||||
|
control={control}
|
||||||
|
render={({ field }) => (
|
||||||
|
<CurrencyInput {...field} textAlign={'right'} fontSize={"sm"} type="number" size={"sm"} />
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<FormErrorMessage fontSize={"xs"} fontWeight={500}>
|
||||||
|
{errors.transactionAmount?.message}
|
||||||
|
</FormErrorMessage>
|
||||||
|
</FormControl>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<FormControl isInvalid={errors.comments}>
|
||||||
|
<FormLabel fontSize={"sm"}>Comments</FormLabel>
|
||||||
|
<Controller
|
||||||
|
name="comments"
|
||||||
|
control={control}
|
||||||
|
render={({ field }) => (
|
||||||
|
<Textarea {...field} textAlign={'right'} fontSize={"sm"} type="text" size={"sm"} />
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<FormErrorMessage fontSize={"xs"} fontWeight={500}>
|
||||||
|
{errors.comments?.message}
|
||||||
|
</FormErrorMessage>
|
||||||
|
</FormControl>
|
||||||
|
</Stack>
|
||||||
</ModalBody>
|
</ModalBody>
|
||||||
<ModalFooter>
|
<ModalFooter>
|
||||||
<Button
|
<Button
|
||||||
@@ -68,6 +185,8 @@ const UpdateIONav = ({ isOpen, onClose }) => {
|
|||||||
}}
|
}}
|
||||||
size={'sm'}
|
size={'sm'}
|
||||||
rounded={"sm"}
|
rounded={"sm"}
|
||||||
|
type="submit"
|
||||||
|
isLoading={isLoading}
|
||||||
>
|
>
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import { ChevronDownIcon } from "@chakra-ui/icons";
|
import { ChevronDownIcon } from "@chakra-ui/icons";
|
||||||
import React, { useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import {
|
import {
|
||||||
Badge,
|
Badge,
|
||||||
Button,
|
Button,
|
||||||
|
FormControl,
|
||||||
FormLabel,
|
FormLabel,
|
||||||
Menu,
|
Menu,
|
||||||
MenuButton,
|
MenuButton,
|
||||||
@@ -15,6 +16,7 @@ import {
|
|||||||
ModalFooter,
|
ModalFooter,
|
||||||
ModalHeader,
|
ModalHeader,
|
||||||
ModalOverlay,
|
ModalOverlay,
|
||||||
|
FormErrorMessage
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import {
|
import {
|
||||||
useGetIOprepopulateDataQuery,
|
useGetIOprepopulateDataQuery,
|
||||||
@@ -22,18 +24,20 @@ import {
|
|||||||
} from "../../../../Services/io.service";
|
} from "../../../../Services/io.service";
|
||||||
import { useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
|
|
||||||
const UpdateIOStatus = ({ isOpen, onClose }) => {
|
const UpdateIOStatus = ({ isOpen, onClose, status }) => {
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
const id = params?.id;
|
const id = params?.id;
|
||||||
const [selectedItem, setSelectedItem] = useState("Open");
|
const [selectedItem, setSelectedItem] = useState();
|
||||||
const [isLoadingg, setIsLoading] = useState(false);
|
const [isLoadingg, setIsLoading] = useState(false);
|
||||||
const { data, error, isLoading } = useGetIOprepopulateDataQuery();
|
const [error, setError] = useState("");
|
||||||
const [selectedStatusId, setSelectedStatusId] = useState(data?.data?.ioStatus[0]?.id);
|
const [selectedStatusId, setSelectedStatusId] = useState('');
|
||||||
|
|
||||||
|
const { data } = useGetIOprepopulateDataQuery();
|
||||||
const [updateStatusIo] = useUpdateStatusIoMutation();
|
const [updateStatusIo] = useUpdateStatusIoMutation();
|
||||||
console.log(data?.data?.ioStatus);
|
|
||||||
|
|
||||||
console.log(data?.data?.ioStatus);
|
// useEffect(() => {
|
||||||
|
// setSelectedStatusId(status?.[0]?.id);
|
||||||
|
// }, [status]);
|
||||||
|
|
||||||
const handleMenuItemClick = (item, id) => {
|
const handleMenuItemClick = (item, id) => {
|
||||||
setSelectedItem(item);
|
setSelectedItem(item);
|
||||||
@@ -41,7 +45,12 @@ const UpdateIOStatus = ({ isOpen, onClose }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleSubmit = async () => {
|
const handleSubmit = async () => {
|
||||||
setIsLoading(true)
|
if (!selectedStatusId) {
|
||||||
|
setError("Please select status");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setError("");
|
||||||
|
setIsLoading(true);
|
||||||
try {
|
try {
|
||||||
const res = await updateStatusIo({
|
const res = await updateStatusIo({
|
||||||
data: {
|
data: {
|
||||||
@@ -50,55 +59,119 @@ const UpdateIOStatus = ({ isOpen, onClose }) => {
|
|||||||
id,
|
id,
|
||||||
});
|
});
|
||||||
console.log(res);
|
console.log(res);
|
||||||
setIsLoading(false)
|
setIsLoading(false);
|
||||||
onClose()
|
handleClose();
|
||||||
} catch (error) {}
|
} catch (error) {
|
||||||
|
setIsLoading(false);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleClose = () => {
|
||||||
|
setSelectedItem(null)
|
||||||
|
setSelectedStatusId(null)
|
||||||
|
onClose()
|
||||||
|
setError("")
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal isOpen={isOpen} onClose={onClose}>
|
<Modal isOpen={isOpen} onClose={handleClose}>
|
||||||
<ModalOverlay />
|
<ModalOverlay />
|
||||||
<ModalContent>
|
<ModalContent>
|
||||||
<ModalHeader fontSize={"md"}>Update IO Status Transaction</ModalHeader>
|
<ModalHeader fontSize={"md"}>Update IO Status Transaction</ModalHeader>
|
||||||
<ModalCloseButton />
|
<ModalCloseButton />
|
||||||
<ModalBody>
|
<ModalBody>
|
||||||
<FormLabel as={"label"} fontSize={"sm"} fontWeight={500}>
|
<FormControl isInvalid={!!error}>
|
||||||
Status
|
<FormLabel as={"label"} fontSize={"sm"} fontWeight={500}>
|
||||||
</FormLabel>
|
Status
|
||||||
<Menu>
|
</FormLabel>
|
||||||
<MenuButton
|
<Menu>
|
||||||
as={Button}
|
<MenuButton
|
||||||
rightIcon={<ChevronDownIcon />}
|
as={Button}
|
||||||
fontSize={"sm"}
|
rightIcon={<ChevronDownIcon />}
|
||||||
fontWeight={500}
|
fontSize={"sm"}
|
||||||
w={"100%"}
|
fontWeight={500}
|
||||||
textAlign={"left"}
|
w={"100%"}
|
||||||
>
|
textAlign={"left"}
|
||||||
{selectedItem}
|
>
|
||||||
</MenuButton>
|
{selectedItem ? (
|
||||||
<MenuList w={"400px"}>
|
<Badge
|
||||||
{data?.data?.ioStatus?.map(({ id, statusAdmin }) => (
|
rounded={"full"}
|
||||||
<MenuItem
|
pt={1.5}
|
||||||
key={id}
|
pb={1.5}
|
||||||
fontSize={"sm"}
|
ps={4}
|
||||||
onClick={() => handleMenuItemClick(statusAdmin, id)}
|
pe={4}
|
||||||
>
|
mt={1.5}
|
||||||
<Badge py={"1px"} px={"8px"}>
|
mb={1.5}
|
||||||
{statusAdmin}
|
textTransform={"none"}
|
||||||
|
colorScheme={
|
||||||
|
selectedItem === "Draft"
|
||||||
|
? "gray"
|
||||||
|
: selectedItem === "Processing"
|
||||||
|
? "yellow"
|
||||||
|
: selectedItem === "Open"
|
||||||
|
? "blue"
|
||||||
|
: selectedItem === "Closed"
|
||||||
|
? "green"
|
||||||
|
: selectedItem === "Exited"
|
||||||
|
? "red"
|
||||||
|
: selectedItem === "Canclled"
|
||||||
|
? "orange"
|
||||||
|
: "purple"
|
||||||
|
}
|
||||||
|
py={"3px"} px={"8px"}
|
||||||
|
>
|
||||||
|
{selectedItem}
|
||||||
</Badge>
|
</Badge>
|
||||||
</MenuItem>
|
) : "Select Item"}
|
||||||
))}
|
</MenuButton>
|
||||||
</MenuList>
|
|
||||||
</Menu>
|
{status?.length > 0 ?<MenuList w={"400px"}>
|
||||||
|
{status?.map(({ id, statusAdmin }) => (
|
||||||
|
<MenuItem
|
||||||
|
key={id}
|
||||||
|
fontSize={"sm"}
|
||||||
|
onClick={() => handleMenuItemClick(statusAdmin, id)}
|
||||||
|
>
|
||||||
|
<Badge
|
||||||
|
rounded={"full"}
|
||||||
|
pt={1.5}
|
||||||
|
pb={1.5}
|
||||||
|
ps={4}
|
||||||
|
pe={4}
|
||||||
|
mt={1.5}
|
||||||
|
mb={1.5}
|
||||||
|
textTransform={"none"}
|
||||||
|
colorScheme={
|
||||||
|
statusAdmin === "Draft"
|
||||||
|
? "gray"
|
||||||
|
: statusAdmin === "Processing"
|
||||||
|
? "yellow"
|
||||||
|
: statusAdmin === "Open"
|
||||||
|
? "blue"
|
||||||
|
: statusAdmin === "Closed"
|
||||||
|
? "green"
|
||||||
|
: statusAdmin === "Exited"
|
||||||
|
? "red"
|
||||||
|
: statusAdmin === "Canclled"
|
||||||
|
? "orange"
|
||||||
|
: "purple"
|
||||||
|
}
|
||||||
|
py={"1px"} px={"8px"}
|
||||||
|
>
|
||||||
|
{statusAdmin}
|
||||||
|
</Badge>
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
</MenuList>:""}
|
||||||
|
</Menu>
|
||||||
|
<FormErrorMessage fontSize={'xs'} fontWeight={600} >{error}</FormErrorMessage>
|
||||||
|
</FormControl>
|
||||||
</ModalBody>
|
</ModalBody>
|
||||||
<ModalFooter>
|
<ModalFooter>
|
||||||
<Button
|
<Button
|
||||||
bg={"hsla(139, 100%, 14%, 1)"}
|
colorScheme="forestGreen"
|
||||||
mr={3}
|
mr={3}
|
||||||
color={"#fff"}
|
color={"#fff"}
|
||||||
_hover={{
|
|
||||||
bg: "hsl(139deg 98.99% 26.59%)",
|
|
||||||
}}
|
|
||||||
size={"sm"}
|
size={"sm"}
|
||||||
rounded={"sm"}
|
rounded={"sm"}
|
||||||
onClick={handleSubmit}
|
onClick={handleSubmit}
|
||||||
@@ -106,7 +179,7 @@ const UpdateIOStatus = ({ isOpen, onClose }) => {
|
|||||||
>
|
>
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
<Button size={"sm"} rounded={"sm"} mr={3} onClick={onClose}>
|
<Button size={"sm"} rounded={"sm"} mr={3} onClick={handleClose}>
|
||||||
Close
|
Close
|
||||||
</Button>
|
</Button>
|
||||||
</ModalFooter>
|
</ModalFooter>
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import {
|
|||||||
Tag,
|
Tag,
|
||||||
Text,
|
Text,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
|
useDisclosure,
|
||||||
useToast,
|
useToast,
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import React, { useContext, useEffect, useState } from "react";
|
import React, { useContext, useEffect, useState } from "react";
|
||||||
@@ -37,6 +38,11 @@ import CustomAlertDialog from "../../../Components/CustomAlertDialog";
|
|||||||
import ToastBox from "../../../Components/ToastBox";
|
import ToastBox from "../../../Components/ToastBox";
|
||||||
import { useGetIOsQuery } from "../../../Services/io.service";
|
import { useGetIOsQuery } from "../../../Services/io.service";
|
||||||
import { TABLE_PAGINATION } from "../../../Constants/Paginations";
|
import { TABLE_PAGINATION } from "../../../Constants/Paginations";
|
||||||
|
import { formatCurrency } from "../../../Components/CurrencyInput";
|
||||||
|
import { IoIosPhonePortrait } from "react-icons/io";
|
||||||
|
import MobileView from "../../../Components/MobileView";
|
||||||
|
import { ImMobile } from "react-icons/im";
|
||||||
|
import { removeTrailingZeros } from "../../../Constants/Constants";
|
||||||
// import { debounce } from "./AddIOCharges";
|
// import { debounce } from "./AddIOCharges";
|
||||||
|
|
||||||
const formatDate = (date) => new Date(date).toLocaleDateString(); // Simple date formatter
|
const formatDate = (date) => new Date(date).toLocaleDateString(); // Simple date formatter
|
||||||
@@ -54,27 +60,28 @@ const ViewIOTable = () => {
|
|||||||
const [mouseEntered, setMouseEntered] = useState(false);
|
const [mouseEntered, setMouseEntered] = useState(false);
|
||||||
const [mouseEnteredId, setMouseEnteredId] = useState("");
|
const [mouseEnteredId, setMouseEnteredId] = useState("");
|
||||||
|
|
||||||
|
const { isOpen: isOpen, onOpen: onOpen, onClose: onClose } = useDisclosure();
|
||||||
|
|
||||||
// ===============================[ Paginations ]
|
// ===============================[ Paginations ]
|
||||||
const [pageSize, setPageSize] = useState(TABLE_PAGINATION?.size);
|
const [pageSize, setPageSize] = useState(TABLE_PAGINATION?.size);
|
||||||
const [currentPage, setCurrentPage] = useState(TABLE_PAGINATION?.page);
|
const [currentPage, setCurrentPage] = useState(TABLE_PAGINATION?.page);
|
||||||
|
|
||||||
// ===============================[ RTK Api calls ]
|
// ===============================[ RTK Api calls ]
|
||||||
const {
|
const { data, isLoading, error } = useGetIOsQuery({
|
||||||
data,
|
page: currentPage,
|
||||||
isLoading,
|
size: pageSize,
|
||||||
error,
|
});
|
||||||
} = useGetIOsQuery({ page: currentPage, size: pageSize });
|
|
||||||
console.log(data);
|
|
||||||
|
|
||||||
// ===============================[ Table Header ]
|
// ===============================[ Table Header ]
|
||||||
const tableHeadRow = [
|
const tableHeadRow = [
|
||||||
"IO ID",
|
"IO ID",
|
||||||
"IO Name",
|
"IO Name",
|
||||||
"Sponsorer",
|
"Sponsor",
|
||||||
"Investment Type",
|
"Investment Type",
|
||||||
"Goal Amount",
|
"Goal Amount",
|
||||||
"Holding Period",
|
"Holding Period",
|
||||||
"IO Status",
|
"IO Status",
|
||||||
|
"Preview",
|
||||||
"Action",
|
"Action",
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -94,8 +101,6 @@ const ViewIOTable = () => {
|
|||||||
return nameMatches && statusMatches;
|
return nameMatches && statusMatches;
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(filteredData);
|
|
||||||
|
|
||||||
const extractedArray = filteredData?.map((item, index) => ({
|
const extractedArray = filteredData?.map((item, index) => ({
|
||||||
"IO ID": (
|
"IO ID": (
|
||||||
<Box w={"auto"} isTruncated={true}>
|
<Box w={"auto"} isTruncated={true}>
|
||||||
@@ -121,14 +126,24 @@ const ViewIOTable = () => {
|
|||||||
"Investment Type": (
|
"Investment Type": (
|
||||||
<Box w={"auto"} isTruncated={true}>
|
<Box w={"auto"} isTruncated={true}>
|
||||||
<Text as={"span"} color={"teal.900"} fontWeight={"500"}>
|
<Text as={"span"} color={"teal.900"} fontWeight={"500"}>
|
||||||
{item?.investmentType?.investmentTypeName ? item.investmentType?.investmentTypeName : "---"}
|
{item?.investmentType?.investmentTypeName
|
||||||
|
? item.investmentType?.investmentTypeName
|
||||||
|
: "---"}
|
||||||
</Text>
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
),
|
),
|
||||||
"Goal Amount": (
|
"Goal Amount": (
|
||||||
<Box w={"auto"} isTruncated={true}>
|
<Box w={"100%"} display={"flex"} alignItems={"center"}>
|
||||||
<Text as={"span"} color={"teal.900"} fontWeight={"500"}>
|
<Text
|
||||||
{item.goalAmount ? item.goalAmount : "---"}
|
w={"100%"}
|
||||||
|
textAlign={"center"}
|
||||||
|
as={"span"}
|
||||||
|
color={"teal.900"}
|
||||||
|
fontWeight={"500"}
|
||||||
|
>
|
||||||
|
{item.goalAmount
|
||||||
|
? formatCurrency(removeTrailingZeros(item.goalAmount))
|
||||||
|
: "---"}
|
||||||
</Text>
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
),
|
),
|
||||||
@@ -142,63 +157,87 @@ const ViewIOTable = () => {
|
|||||||
"IO Status": (
|
"IO Status": (
|
||||||
<Box w={"auto"} isTruncated={true}>
|
<Box w={"auto"} isTruncated={true}>
|
||||||
<Badge
|
<Badge
|
||||||
rounded={"sm"}
|
rounded={"full"}
|
||||||
pt={0.5}
|
pt={1}
|
||||||
pb={0.5}
|
pb={1}
|
||||||
ps={4}
|
ps={4}
|
||||||
pe={4}
|
pe={4}
|
||||||
|
mt={1.5}
|
||||||
|
mb={1.5}
|
||||||
textTransform={"none"}
|
textTransform={"none"}
|
||||||
color={
|
// variant={"solid"}
|
||||||
item?.ioStatus?.statusAdmin === "Draft"
|
|
||||||
? "yellow.500"
|
|
||||||
: item.ioStatus === "Pending"
|
|
||||||
? "#6226EF"
|
|
||||||
: "#EF3826"
|
|
||||||
}
|
|
||||||
colorScheme={
|
colorScheme={
|
||||||
item?.ioStatus?.statusAdmin === "Draft"
|
item?.ioStatus?.statusAdmin === "Draft"
|
||||||
|
? "gray"
|
||||||
|
: item?.ioStatus?.statusAdmin === "Processing"
|
||||||
? "yellow"
|
? "yellow"
|
||||||
: item.ioStatus?.statusAdmin === "Pending"
|
: item?.ioStatus?.statusAdmin === "Open"
|
||||||
? "purple"
|
? "blue"
|
||||||
: "red"
|
: item?.ioStatus?.statusAdmin === "Closed"
|
||||||
|
? "green"
|
||||||
|
: item?.ioStatus?.statusAdmin === "Exited"
|
||||||
|
? "red"
|
||||||
|
: item?.ioStatus?.statusAdmin === "Canclled"
|
||||||
|
? "orange"
|
||||||
|
: "purple"
|
||||||
}
|
}
|
||||||
|
boxShadow={"0 4px 6px rgba(0, 0, 0, 0.1)"} // Adjusted shadow
|
||||||
>
|
>
|
||||||
{item.ioStatus?.statusAdmin}
|
{item.ioStatus?.statusAdmin}
|
||||||
</Badge>
|
</Badge>
|
||||||
</Box>
|
</Box>
|
||||||
),
|
),
|
||||||
|
Preview: (
|
||||||
|
<Box display={"flex"} justifyContent={"start"}>
|
||||||
|
<Badge
|
||||||
|
display={"flex"} px={2} py={1} alignItems={"center"}
|
||||||
|
color={"#000"}
|
||||||
|
fontWeight={500}
|
||||||
|
bg="purple.200"
|
||||||
|
onClick={() =>{
|
||||||
|
setActionId(item.id)
|
||||||
|
onOpen();
|
||||||
|
}}
|
||||||
|
rounded={"sm"}
|
||||||
|
size={"xs"}
|
||||||
|
variant={"ghost"}
|
||||||
|
cursor={"pointer"}
|
||||||
|
>
|
||||||
|
<ImMobile className="me-1" /> View
|
||||||
|
</Badge>
|
||||||
|
</Box>
|
||||||
|
),
|
||||||
Action: (
|
Action: (
|
||||||
<Box display={"flex"} justifyContent={"center"} gap={2}>
|
<Box display={"flex"} justifyContent={"center"} gap={2}>
|
||||||
<Tooltip
|
{/* <Tooltip
|
||||||
rounded={"sm"}
|
rounded={"sm"}
|
||||||
fontSize={"xs"}
|
fontSize={"xs"}
|
||||||
label="View"
|
label="View"
|
||||||
bg="#fff"
|
bg="#fff"
|
||||||
color={"green.500"}
|
color={"green.500"}
|
||||||
placement="top"
|
placement="top"
|
||||||
|
> */}
|
||||||
|
<Button
|
||||||
|
// _hover={{ color: "green.500" }}
|
||||||
|
colorScheme="green"
|
||||||
|
// transition={"0.5s all"}
|
||||||
|
onClick={() => {
|
||||||
|
navigate(`/view-io/${item.id}`);
|
||||||
|
}}
|
||||||
|
// color="green.300"
|
||||||
|
rounded={"sm"}
|
||||||
|
size={"xs"}
|
||||||
>
|
>
|
||||||
<Button
|
<ViewIcon me={2} /> View
|
||||||
// _hover={{ color: "green.500" }}
|
</Button>
|
||||||
colorScheme="green"
|
{/* </Tooltip> */}
|
||||||
// transition={"0.5s all"}
|
|
||||||
onClick={() => {
|
|
||||||
navigate(`/view-io/${item.id}`);
|
|
||||||
}}
|
|
||||||
// color="green.300"
|
|
||||||
rounded={"sm"}
|
|
||||||
size={"xs"}
|
|
||||||
>
|
|
||||||
<ViewIcon />
|
|
||||||
</Button>
|
|
||||||
</Tooltip>
|
|
||||||
|
|
||||||
<Tooltip
|
{/* <Tooltip
|
||||||
rounded={"sm"}
|
rounded={"sm"}
|
||||||
fontSize={"xs"}
|
fontSize={"xs"}
|
||||||
label="View"
|
label="Edit"
|
||||||
bg="#fff"
|
bg="#fff"
|
||||||
color={"green.500"}
|
color={"blue.500"}
|
||||||
placement="top"
|
placement="top"
|
||||||
>
|
>
|
||||||
<Button
|
<Button
|
||||||
@@ -214,7 +253,7 @@ const ViewIOTable = () => {
|
|||||||
>
|
>
|
||||||
<EditIcon />
|
<EditIcon />
|
||||||
</Button>
|
</Button>
|
||||||
</Tooltip>
|
</Tooltip> */}
|
||||||
|
|
||||||
{/* <Tooltip
|
{/* <Tooltip
|
||||||
rounded={"sm"}
|
rounded={"sm"}
|
||||||
@@ -244,8 +283,6 @@ const ViewIOTable = () => {
|
|||||||
|
|
||||||
const handleDelete = () => {};
|
const handleDelete = () => {};
|
||||||
|
|
||||||
console.log(extractedArray);
|
|
||||||
|
|
||||||
return (
|
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">
|
<Box bg="white.500">
|
||||||
@@ -291,9 +328,14 @@ const ViewIOTable = () => {
|
|||||||
<option value="Closed">Closed</option>
|
<option value="Closed">Closed</option>
|
||||||
</Select>
|
</Select>
|
||||||
|
|
||||||
|
<Pagination
|
||||||
<Pagination isLoading={isLoading} pageSize={pageSize} setPageSize={setPageSize} currentPage={currentPage} setCurrentPage={setCurrentPage} totalItems={data?.data?.totalItems} />
|
isLoading={isLoading}
|
||||||
|
pageSize={pageSize}
|
||||||
|
setPageSize={setPageSize}
|
||||||
|
currentPage={currentPage}
|
||||||
|
setCurrentPage={setCurrentPage}
|
||||||
|
totalItems={data?.data?.totalItems}
|
||||||
|
/>
|
||||||
|
|
||||||
{/* <Link to={"/create-io"}>
|
{/* <Link to={"/create-io"}>
|
||||||
<Button
|
<Button
|
||||||
@@ -325,6 +367,8 @@ const ViewIOTable = () => {
|
|||||||
setMouseEntered={setMouseEntered}
|
setMouseEntered={setMouseEntered}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<MobileView isOpen={isOpen} onClose={onClose} actionId={actionId} />
|
||||||
|
|
||||||
<CustomAlertDialog
|
<CustomAlertDialog
|
||||||
onClose={() => setDeleteAlert(false)}
|
onClose={() => setDeleteAlert(false)}
|
||||||
isOpen={deleteAlert}
|
isOpen={deleteAlert}
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ import IOArtifacts from "../CreateIO/IOArtifacts";
|
|||||||
import IOCashDetails from "../CreateIO/IOCashDetails";
|
import IOCashDetails from "../CreateIO/IOCashDetails";
|
||||||
import IONAVDetails from "../CreateIO/IONAVDetails";
|
import IONAVDetails from "../CreateIO/IONAVDetails";
|
||||||
import { useGetIOprepopulateDataQuery } from "../../../Services/io.service";
|
import { useGetIOprepopulateDataQuery } from "../../../Services/io.service";
|
||||||
|
import UnderConstruction from "../../UnderConstruction";
|
||||||
|
|
||||||
|
|
||||||
const ViewIOdata = () => {
|
const ViewIOdata = () => {
|
||||||
@@ -44,6 +45,9 @@ const ViewIOdata = () => {
|
|||||||
const { isOpen, onOpen, onClose } = useDisclosure();
|
const { isOpen, onOpen, onClose } = useDisclosure();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [isEditing, setIsEditing] = useState(false);
|
const [isEditing, setIsEditing] = useState(false);
|
||||||
|
const { IODetails, setIODetails } = useContext(GlobalStateContext);
|
||||||
|
console.log(IODetails?.isInvestedAmount);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const tabs = [
|
const tabs = [
|
||||||
@@ -52,9 +56,11 @@ const ViewIOdata = () => {
|
|||||||
{ label: "Key merits", content: <KeyMerits data={data?.data} /> },
|
{ label: "Key merits", content: <KeyMerits data={data?.data} /> },
|
||||||
{ label: "IO artifacts", content: <IOArtifacts data={data?.data} /> },
|
{ label: "IO artifacts", content: <IOArtifacts data={data?.data} /> },
|
||||||
{ label: "Investors", content: <Investors data={data?.data} /> },
|
{ label: "Investors", content: <Investors data={data?.data} /> },
|
||||||
|
// { label: "Investors", content: <UnderConstruction h={'75vh'} /> },
|
||||||
{ label: "IO Cash Details", content: <IOCashDetails data={data?.data} /> },
|
{ label: "IO Cash Details", content: <IOCashDetails data={data?.data} /> },
|
||||||
{ label: "IO NAV Details", content: <IONAVDetails data={data?.data} /> },
|
{ label: "IO NAV Details", content: <IONAVDetails data={data?.data} /> },
|
||||||
// { label: "Distribution", content: <ViewDistribution /> },
|
// { label: "Distribution to Investors", content: <IONAVDetails data={data?.data} /> },
|
||||||
|
{ label: "Distribution to Investors", content: <UnderConstruction h={'75vh'} /> },
|
||||||
];
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -74,7 +80,15 @@ const ViewIOdata = () => {
|
|||||||
<Box display={'flex'} >
|
<Box display={'flex'} >
|
||||||
{tabs.map(({ label }, index) => (
|
{tabs.map(({ label }, index) => (
|
||||||
<Tab
|
<Tab
|
||||||
disabled={true}
|
px={3}
|
||||||
|
isDisabled={
|
||||||
|
index === 0 ||
|
||||||
|
index === 1 ||
|
||||||
|
index === 2 ||
|
||||||
|
index === 3 ||
|
||||||
|
index === 4 ?
|
||||||
|
false :
|
||||||
|
!IODetails?.isInvestedAmount}
|
||||||
key={index}
|
key={index}
|
||||||
fontSize={"sm"}
|
fontSize={"sm"}
|
||||||
_selected={{
|
_selected={{
|
||||||
@@ -89,7 +103,7 @@ const ViewIOdata = () => {
|
|||||||
</TabList>
|
</TabList>
|
||||||
<TabPanels>
|
<TabPanels>
|
||||||
{tabs.map(({ content }, index) => (
|
{tabs.map(({ content }, index) => (
|
||||||
<TabPanel key={index}>{content}</TabPanel>
|
<TabPanel key={index}>{content}</TabPanel>
|
||||||
))}
|
))}
|
||||||
</TabPanels>
|
</TabPanels>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import {
|
|||||||
Badge,
|
Badge,
|
||||||
Box,
|
Box,
|
||||||
Icon,
|
Icon,
|
||||||
|
HStack,
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import header from "../../../assets/IOheader.png";
|
import header from "../../../assets/IOheader.png";
|
||||||
import { HiDotsVertical } from "react-icons/hi";
|
import { HiDotsVertical } from "react-icons/hi";
|
||||||
@@ -39,17 +40,17 @@ import Exit from "./HeaderModal/Exit";
|
|||||||
import Cancle from "./HeaderModal/Cancle";
|
import Cancle from "./HeaderModal/Cancle";
|
||||||
import { AddIcon } from "@chakra-ui/icons";
|
import { AddIcon } from "@chakra-ui/icons";
|
||||||
import { GrGallery } from "react-icons/gr";
|
import { GrGallery } from "react-icons/gr";
|
||||||
|
import Loader01 from "../../../Components/Loaders/Loader01";
|
||||||
|
// import { formatCurrency } from "../../../Components/CurrencyInput";
|
||||||
|
// import { removeTrailingZeros } from "../../../Constants/Constants";
|
||||||
|
|
||||||
const ViewIOdataHeader = () => {
|
const ViewIOdataHeader = ({data, isLoading}) => {
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
const id = params?.id;
|
const id = params?.id;
|
||||||
const { isOpen, onOpen, onClose } = useDisclosure();
|
const { isOpen, onOpen, onClose } = useDisclosure();
|
||||||
const btnRef = useRef();
|
const btnRef = useRef();
|
||||||
const { IODetails } = useContext(GlobalStateContext);
|
const { IODetails, isIOloading } = useContext(GlobalStateContext);
|
||||||
console.log(
|
|
||||||
"=================>>>>>",
|
|
||||||
IODetails?.artifactsImage?.[0]?.artifactPathName
|
|
||||||
);
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
isOpen: isInvestmentOpen,
|
isOpen: isInvestmentOpen,
|
||||||
@@ -91,27 +92,104 @@ const ViewIOdataHeader = () => {
|
|||||||
onOpen: onCancleOpen,
|
onOpen: onCancleOpen,
|
||||||
onClose: onCancleClose,
|
onClose: onCancleClose,
|
||||||
} = useDisclosure();
|
} = useDisclosure();
|
||||||
|
|
||||||
const bg = {
|
const bg = {
|
||||||
bg: "#fff",
|
bg: "#fff",
|
||||||
};
|
};
|
||||||
|
|
||||||
const hover = {
|
const hover = {
|
||||||
textDecoration: "underline",
|
textDecoration: "underline",
|
||||||
background: "#fff",
|
background: "#fff",
|
||||||
};
|
};
|
||||||
|
|
||||||
const style = {
|
const style = {
|
||||||
fontSize: "0.875rem",
|
fontSize: "0.875rem",
|
||||||
fontWeight: "400",
|
fontWeight: "400",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
console.log(import.meta.env.VITE_IMAGE_URL +
|
||||||
|
IODetails?.artifactsImage?.[0]?.artifactPathName);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const menu = [
|
||||||
|
{
|
||||||
|
id:1,
|
||||||
|
title:"Amount Invested",
|
||||||
|
onClickFunction: onInvestmentOpen
|
||||||
|
},
|
||||||
|
// {
|
||||||
|
// id:2,
|
||||||
|
// title:"Fees & Expenses",
|
||||||
|
// onClickFunction:onFeesOpen
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// id:3,
|
||||||
|
// title:"Distribution From Sponsors",
|
||||||
|
// onClickFunction:onDistSponsorOpen
|
||||||
|
// },
|
||||||
|
{
|
||||||
|
id:6,
|
||||||
|
title:"Distribution To Investors",
|
||||||
|
onClickFunction:onDistInvestorOpen
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id:5,
|
||||||
|
title:"Update IO NAV",
|
||||||
|
onClickFunction:onUpdateNavOpen
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id:8,
|
||||||
|
title:"Exit",
|
||||||
|
onClickFunction:onExitOpen
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id:9,
|
||||||
|
title:"Cancel",
|
||||||
|
onClickFunction:onCancleOpen
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id:10,
|
||||||
|
title:"Update IO Status",
|
||||||
|
onClickFunction:onUpdateStatusOpen
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
// console.log(IODetails?.mainTranscation);
|
||||||
|
|
||||||
|
|
||||||
|
// Extract titles from apiTransaction
|
||||||
|
const apiTransactionTitles = IODetails?.mainTranscation?.map(transaction => transaction.id);
|
||||||
|
// Filter menu items
|
||||||
|
const filteredMenu = menu?.filter(item => apiTransactionTitles?.includes(item.id));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
IODetails?.investmentNameEnglish ?
|
||||||
<Box
|
<Box
|
||||||
display={"flex"}
|
display={"flex"}
|
||||||
alignItems={"center"}
|
alignItems={"center"}
|
||||||
justifyContent={"start"}
|
justifyContent={"space-between"}
|
||||||
gap={8}
|
gap={8}
|
||||||
bg={"#caf5d8"}
|
bg={
|
||||||
|
IODetails?.ioStatus?.statusAdmin === "Draft"
|
||||||
|
? "#EDF2F7"
|
||||||
|
: IODetails?.ioStatus?.statusAdmin === "Processing"
|
||||||
|
? "#FEFBBF"
|
||||||
|
: IODetails?.ioStatus?.statusAdmin === "Open"
|
||||||
|
? "#BEE2F8"
|
||||||
|
: IODetails?.ioStatus?.statusAdmin === "Closed"
|
||||||
|
? "#C6F6D5"
|
||||||
|
: IODetails?.ioStatus?.statusAdmin === "Exited"
|
||||||
|
? "red.500"
|
||||||
|
: IODetails?.ioStatus?.statusAdmin === "Canclled"
|
||||||
|
? "orange.500"
|
||||||
|
: IODetails?.ioStatus?.statusAdmin === "DeActivate"
|
||||||
|
? "#E9D8FD"
|
||||||
|
: null
|
||||||
|
}
|
||||||
rounded={"md"}
|
rounded={"md"}
|
||||||
// bgGradient='linear(to-r, #caf5d8, #f5e8ca)'
|
// bgGradient='linear(to-r, #caf5d8, #f5e8ca)'
|
||||||
// bgGradient='linear(to-r, #caf5d8, #d4a5a5)'
|
// bgGradient='linear(to-r, #caf5d8, #d4a5a5)'
|
||||||
@@ -120,10 +198,12 @@ const ViewIOdataHeader = () => {
|
|||||||
// bgGradient='linear(to-r, #ffd54f, #caf5d8)'
|
// bgGradient='linear(to-r, #ffd54f, #caf5d8)'
|
||||||
// bgGradient='linear(to-r, #caf5d8, #a8e6cf)'
|
// bgGradient='linear(to-r, #caf5d8, #a8e6cf)'
|
||||||
boxShadow={"md"}
|
boxShadow={"md"}
|
||||||
paddingRight={"10px"}
|
|
||||||
borderRadius={"10px"}
|
|
||||||
position={"relative"}
|
position={"relative"}
|
||||||
>
|
>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<HStack gap={8}>
|
||||||
<Box h={100} w={200} p={1.5}>
|
<Box h={100} w={200} p={1.5}>
|
||||||
{/* <Image rounded={'md'} h={"100%"} src={ " https://tanami.betadelivery.com/" + IODetails?.ioName} alt={IODetails?.ioName}/> */}
|
{/* <Image rounded={'md'} h={"100%"} src={ " https://tanami.betadelivery.com/" + IODetails?.ioName} alt={IODetails?.ioName}/> */}
|
||||||
{IODetails?.artifactsImage?.[0]?.artifactPathName ? (
|
{IODetails?.artifactsImage?.[0]?.artifactPathName ? (
|
||||||
@@ -133,7 +213,7 @@ const ViewIOdataHeader = () => {
|
|||||||
w={"100%"}
|
w={"100%"}
|
||||||
objectFit={"cover"}
|
objectFit={"cover"}
|
||||||
src={
|
src={
|
||||||
" https://tanami.betadelivery.com/" +
|
import.meta.env.VITE_IMAGE_URL +
|
||||||
IODetails?.artifactsImage?.[0]?.artifactPathName
|
IODetails?.artifactsImage?.[0]?.artifactPathName
|
||||||
}
|
}
|
||||||
alt={IODetails?.ioName}
|
alt={IODetails?.ioName}
|
||||||
@@ -152,23 +232,6 @@ const ViewIOdataHeader = () => {
|
|||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
{/* <Box display={"flex"} flexDirection={"column"} gap={2}>
|
|
||||||
<Text as={"span"} fontSize={"sm"} fontWeight={"500"}>
|
|
||||||
IO name: <Text as={'span'} ms={2}>{foundObject?.ioName}</Text>
|
|
||||||
</Text>
|
|
||||||
<Text as={"span"} fontSize={"sm"} fontWeight={"500"}>
|
|
||||||
Sponsor name: <Text as={'span'} ms={2}>{foundObject?.sponserName}</Text>
|
|
||||||
</Text>
|
|
||||||
</Box> */}
|
|
||||||
|
|
||||||
{/* <Box display={"flex"} flexDirection={"column"} gap={2}>
|
|
||||||
<Text as={"span"} fontSize={"xs"} color={"gray.500"} fontWeight={"500"}>
|
|
||||||
IO ID
|
|
||||||
</Text>
|
|
||||||
<Text as={"span"} fontSize={"sm"} fontWeight={"500"}>
|
|
||||||
{IODetails?.io_id ? IODetails?.io_id : "---"}
|
|
||||||
</Text>
|
|
||||||
</Box> */}
|
|
||||||
|
|
||||||
<Box display={"flex"} w={"auto"} flexDirection={"column"} gap={2}>
|
<Box display={"flex"} w={"auto"} flexDirection={"column"} gap={2}>
|
||||||
<Text as={"span"} fontSize={"xs"} color={"gray.500"} fontWeight={"500"}>
|
<Text as={"span"} fontSize={"xs"} color={"gray.500"} fontWeight={"500"}>
|
||||||
@@ -183,7 +246,7 @@ const ViewIOdataHeader = () => {
|
|||||||
|
|
||||||
<Box display={"flex"} flexDirection={"column"} gap={2}>
|
<Box display={"flex"} flexDirection={"column"} gap={2}>
|
||||||
<Text as={"span"} fontSize={"xs"} color={"gray.500"} fontWeight={"500"}>
|
<Text as={"span"} fontSize={"xs"} color={"gray.500"} fontWeight={"500"}>
|
||||||
Sponsorer Name
|
Sponsor Name
|
||||||
</Text>
|
</Text>
|
||||||
<Text as={"span"} fontSize={"sm"} fontWeight={"500"}>
|
<Text as={"span"} fontSize={"sm"} fontWeight={"500"}>
|
||||||
{IODetails?.sponsor?.sponsorName
|
{IODetails?.sponsor?.sponsorName
|
||||||
@@ -191,26 +254,38 @@ const ViewIOdataHeader = () => {
|
|||||||
: "---"}
|
: "---"}
|
||||||
</Text>
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
|
</HStack>
|
||||||
|
|
||||||
|
|
||||||
|
<HStack gap={8} me={20}>
|
||||||
|
|
||||||
<Box display={"flex"} flexDirection={"column"} gap={2}>
|
<Box display={"flex"} flexDirection={"column"} gap={2}>
|
||||||
<Text as={"span"} fontSize={"xs"} color={"gray.500"} fontWeight={"500"}>
|
<Text as={"span"} textAlign={'center'} fontSize={"xs"} color={"gray.500"} fontWeight={"500"}>
|
||||||
IO Status
|
IO Status
|
||||||
</Text>
|
</Text>
|
||||||
<Badge
|
<Badge
|
||||||
rounded={"sm"}
|
rounded={"full"}
|
||||||
pt={0.5}
|
pt={0}
|
||||||
pb={0.5}
|
pb={0.5}
|
||||||
ps={4}
|
ps={4}
|
||||||
pe={4}
|
pe={4}
|
||||||
textTransform={"none"}
|
textTransform={"none"}
|
||||||
variant={"solid"}
|
|
||||||
color={"#fff"}
|
// variant={"solid"}
|
||||||
colorScheme={
|
colorScheme={
|
||||||
IODetails?.ioStatus?.statusAdmin === "Draft"
|
IODetails?.ioStatus?.statusAdmin === "Draft"
|
||||||
|
? "gray"
|
||||||
|
: IODetails?.ioStatus?.statusAdmin === "Processing"
|
||||||
|
? "yellow"
|
||||||
|
: IODetails?.ioStatus?.statusAdmin === "Open"
|
||||||
? "blue"
|
? "blue"
|
||||||
: IODetails?.ioStatus?.statusAdmin === "Pending"
|
: IODetails?.ioStatus?.statusAdmin === "Closed"
|
||||||
? "purple"
|
? "green"
|
||||||
: "forestGreen"
|
: IODetails?.ioStatus?.statusAdmin === "Exited"
|
||||||
|
? "red"
|
||||||
|
: IODetails?.ioStatus?.statusAdmin === "Canclled"
|
||||||
|
? "orange"
|
||||||
|
: "purple"
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{IODetails?.ioStatus?.statusAdmin
|
{IODetails?.ioStatus?.statusAdmin
|
||||||
@@ -218,31 +293,39 @@ const ViewIOdataHeader = () => {
|
|||||||
: "---"}
|
: "---"}
|
||||||
</Badge>
|
</Badge>
|
||||||
</Box>
|
</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"}>
|
<Text as={"span"} fontSize={"xs"} color={"gray.500"} fontWeight={"500"}>
|
||||||
IO NAV
|
IO MV
|
||||||
</Text>
|
</Text>
|
||||||
<Text as={"span"} fontSize={"sm"} fontWeight={"500"}>
|
<Text as={"span"} fontSize={"sm"} fontWeight={"500"}>
|
||||||
{IODetails?.currentValuation ? IODetails?.currentValuation : "00.00"}
|
{/* {IODetails?.ioNAV ? formatCurrency(removeTrailingZeros(IODetails?.ioNAV)) : "00.00"} */}
|
||||||
|
{parseFloat(IODetails?.ioNAV||0).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
|
||||||
</Text>
|
</Text>
|
||||||
</Box>
|
</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"}>
|
<Text as={"span"} fontSize={"xs"} color={"gray.500"} fontWeight={"500"}>
|
||||||
IO cash
|
IO cash
|
||||||
</Text>
|
</Text>
|
||||||
<Text as={"span"} fontSize={"sm"} fontWeight={"500"}>
|
<Text as={"span"} fontSize={"sm"} fontWeight={"500"}>
|
||||||
{IODetails?.ioCash ? IODetails?.ioCash : "00.00"}
|
{/* {IODetails?.ioCash ? formatCurrency(removeTrailingZeros(IODetails?.ioCash)) : "00.00"} */}
|
||||||
|
{parseFloat(IODetails?.ioCash||0).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
|
||||||
</Text>
|
</Text>
|
||||||
</Box>
|
</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"}>
|
<Text as={"span"} fontSize={"xs"} color={"gray.500"} fontWeight={"500"}>
|
||||||
IO MV NAV
|
IO NAV
|
||||||
</Text>
|
</Text>
|
||||||
<Text as={"span"} fontSize={"sm"} fontWeight={"500"}>
|
<Text as={"span"} fontSize={"sm"} fontWeight={"500"}>
|
||||||
{IODetails?.marketValue ? IODetails?.marketValue : "00.00"}
|
{/* {IODetails?.ioMVNAV ? formatCurrency(removeTrailingZeros(IODetails?.ioMVNAV)) : "00.00"} */}
|
||||||
|
{parseFloat(IODetails?.ioMVNAV||0).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
|
||||||
</Text>
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
|
</HStack>
|
||||||
|
|
||||||
<Box
|
<Box
|
||||||
position={"absolute"}
|
position={"absolute"}
|
||||||
right={3}
|
right={3}
|
||||||
@@ -272,113 +355,16 @@ const ViewIOdataHeader = () => {
|
|||||||
>
|
>
|
||||||
Tansaction
|
Tansaction
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem onClick={onInvestmentOpen} className="border-bottom">
|
|
||||||
Amount Invested
|
{filteredMenu?.map(({id, title, onClickFunction})=><MenuItem key={id} onClick={onClickFunction} className="border-bottom">
|
||||||
</MenuItem>
|
{title}
|
||||||
<MenuItem onClick={onFeesOpen} className="border-bottom">
|
</MenuItem>)}
|
||||||
Fees & Expenses
|
|
||||||
</MenuItem>
|
|
||||||
<MenuItem onClick={onDistSponsorOpen} className="border-bottom">
|
|
||||||
Distribution from Sponsors
|
|
||||||
</MenuItem>
|
|
||||||
<MenuItem onClick={onDistInvestorOpen} className="border-bottom">
|
|
||||||
Distribution To investors
|
|
||||||
</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>
|
</MenuList>
|
||||||
</Menu>
|
</Menu>
|
||||||
|
|
||||||
{/* Drawer */}
|
|
||||||
{/* <Drawer
|
|
||||||
isOpen={isOpen}
|
|
||||||
placement="right"
|
|
||||||
onClose={onClose}
|
|
||||||
finalFocusRef={btnRef}
|
|
||||||
>
|
|
||||||
<DrawerOverlay />
|
|
||||||
<DrawerContent>
|
|
||||||
<DrawerCloseButton />
|
|
||||||
<DrawerHeader>Transaction</DrawerHeader>
|
|
||||||
|
|
||||||
<DrawerBody>
|
|
||||||
<Box
|
|
||||||
display={"grid"}
|
|
||||||
alignContent={"left"}
|
|
||||||
justifyItems={"start"}
|
|
||||||
>
|
|
||||||
<Button
|
|
||||||
onClick={onInvestmentOpen}
|
|
||||||
bg={bg}
|
|
||||||
_hover={hover}
|
|
||||||
paddingInline={"0px"}
|
|
||||||
>
|
|
||||||
Amount Invested
|
|
||||||
</Button>
|
|
||||||
<Divider />
|
|
||||||
<Button
|
|
||||||
onClick={onFeesOpen}
|
|
||||||
bg={bg}
|
|
||||||
_hover={hover}
|
|
||||||
paddingInline={"0px"}
|
|
||||||
>
|
|
||||||
Fees & Expenses
|
|
||||||
</Button>
|
|
||||||
<Divider />
|
|
||||||
<Button
|
|
||||||
onClick={onDistSponsorOpen}
|
|
||||||
bg={bg}
|
|
||||||
_hover={hover}
|
|
||||||
paddingInline={"0px"}
|
|
||||||
>
|
|
||||||
Distribution from Sponsors
|
|
||||||
</Button>
|
|
||||||
<Divider />
|
|
||||||
<Button
|
|
||||||
onClick={onDistInvestorOpen}
|
|
||||||
bg={bg}
|
|
||||||
_hover={hover}
|
|
||||||
paddingInline={"0px"}
|
|
||||||
>
|
|
||||||
Distribution To Investors
|
|
||||||
</Button>
|
|
||||||
<Divider />
|
|
||||||
<Button
|
|
||||||
onClick={onUpdateNavOpen}
|
|
||||||
bg={bg}
|
|
||||||
_hover={hover}
|
|
||||||
paddingInline={"0px"}
|
|
||||||
>
|
|
||||||
Update IO NAV
|
|
||||||
</Button>
|
|
||||||
<Divider />
|
|
||||||
<Button
|
|
||||||
onClick={onUpdateStatusOpen}
|
|
||||||
bg={bg}
|
|
||||||
_hover={hover}
|
|
||||||
paddingInline={"0px"}
|
|
||||||
>
|
|
||||||
Update IO Status
|
|
||||||
</Button>
|
|
||||||
<Divider />
|
|
||||||
</Box>
|
|
||||||
</DrawerBody>
|
|
||||||
|
|
||||||
<DrawerFooter>
|
|
||||||
<Button variant="outline" mr={3} onClick={onClose}>
|
|
||||||
Cancel
|
|
||||||
</Button>
|
|
||||||
</DrawerFooter>
|
|
||||||
</DrawerContent>
|
|
||||||
</Drawer> */}
|
|
||||||
|
|
||||||
{/* Modals */}
|
{/* Modals */}
|
||||||
<AmountInvested isOpen={isInvestmentOpen} onClose={onInvestmentClose} />
|
<AmountInvested isOpen={isInvestmentOpen} onClose={onInvestmentClose} />
|
||||||
@@ -395,11 +381,29 @@ const ViewIOdataHeader = () => {
|
|||||||
/>
|
/>
|
||||||
<UpdateIONav isOpen={isUpdateNavOpen} onClose={onUpdateNavClose} />
|
<UpdateIONav isOpen={isUpdateNavOpen} onClose={onUpdateNavClose} />
|
||||||
<UpdateIOStatus
|
<UpdateIOStatus
|
||||||
|
status={IODetails?.nextStatus}
|
||||||
isOpen={isUpdateStatusOpen}
|
isOpen={isUpdateStatusOpen}
|
||||||
onClose={onUpdateStatusClose}
|
onClose={onUpdateStatusClose}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
|
||||||
|
</Box>:
|
||||||
|
|
||||||
|
<Box
|
||||||
|
display={"flex"}
|
||||||
|
alignItems={"center"}
|
||||||
|
justifyContent={"center"}
|
||||||
|
rounded={"md"}
|
||||||
|
height={100}
|
||||||
|
bg={"#fff"}
|
||||||
|
// bgGradient='linear(to-r, #caf5d8, #f5e8ca)'
|
||||||
|
// bgGradient='linear(to-r, #caf5d8, #d4a5a5)'
|
||||||
|
// bgGradient='linear(to-r, #caf5d8, #d4a5a5)'
|
||||||
|
// bgGradient='linear(to-r, #caf5d8, #b3e5fc)'
|
||||||
|
// bgGradient='linear(to-r, #ffd54f, #caf5d8)'
|
||||||
|
// bgGradient='linear(to-r, #caf5d8, #a8e6cf)'
|
||||||
|
boxShadow={"md"}
|
||||||
|
> <Loader01 /></Box>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ import { useGetIOByIdQuery } from "../../../Services/io.service";
|
|||||||
import * as yup from "yup";
|
import * as yup from "yup";
|
||||||
import { yupResolver } from "@hookform/resolvers/yup";
|
import { yupResolver } from "@hookform/resolvers/yup";
|
||||||
import { formatDate } from "../../Master/Sponser/Sponsers";
|
import { formatDate } from "../../Master/Sponser/Sponsers";
|
||||||
|
import { formatCurrency } from "../../../Components/CurrencyInput";
|
||||||
|
import { removeTrailingZeros } from "../../../Constants/Constants";
|
||||||
|
|
||||||
const schema = yup.object().shape({
|
const schema = yup.object().shape({
|
||||||
investmentNameEnglish: yup
|
investmentNameEnglish: yup
|
||||||
@@ -104,31 +106,33 @@ const ViewIOdetails = () => {
|
|||||||
investmentNameArabic: IObyID?.data?.investmentNameArabic,
|
investmentNameArabic: IObyID?.data?.investmentNameArabic,
|
||||||
descriptionEnglish: IObyID?.data?.descriptionEnglish,
|
descriptionEnglish: IObyID?.data?.descriptionEnglish,
|
||||||
descriptionArabic: IObyID?.data?.descriptionArabic,
|
descriptionArabic: IObyID?.data?.descriptionArabic,
|
||||||
goalAmount: IObyID?.data?.goalAmount,
|
goalAmount: removeTrailingZeros(IObyID?.data?.goalAmount),
|
||||||
closingDate: IObyID?.data?.closingDate,
|
closingDate: IObyID?.data?.closingDate,
|
||||||
holdingPeriod: IObyID?.data?.holdingPeriod,
|
holdingPeriod: IObyID?.data?.holdingPeriod,
|
||||||
ISIN: IObyID?.data?.ISIN,
|
ISIN: IObyID?.data?.ISIN,
|
||||||
comment: IObyID?.data?.comment,
|
comment: IObyID?.data?.comment,
|
||||||
expectedReturn: IObyID?.data?.expectedReturn,
|
expectedReturn: IObyID?.data?.expectedReturn,
|
||||||
investmentType_xid: IObyID?.data?.investmentType_xid,
|
investmentType_xid: IObyID?.data?.investmentType_xid,
|
||||||
investmentType_xid: IObyID?.data?.investmentType_xid,
|
|
||||||
InvestmentDetails: IObyID?.data?.InvestmentDetails,
|
InvestmentDetails: IObyID?.data?.InvestmentDetails,
|
||||||
minInvestmentAmount: IObyID?.data?.minInvestmentAmount,
|
minInvestmentAmount: IObyID?.data?.minInvestmentAmount,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, [id, IObyID]);
|
}, [id, IObyID]);
|
||||||
console.log(IObyID);
|
|
||||||
|
|
||||||
const minInvestmentById = IObyID?.data?.minInvestmentAmt?.map(({minInvestmentAmt, country, id})=>{
|
const minInvestmentById = IObyID?.data?.minInvestmentAmt?.map(({minInvestmentAmt, country, currencyCode, id})=>{
|
||||||
return{
|
return{
|
||||||
id:id,
|
id:id,
|
||||||
country: country?.countryName,
|
country: country?.countryName,
|
||||||
value: minInvestmentAmt,
|
value: removeTrailingZeros(minInvestmentAmt),
|
||||||
logo: country?.flagIcon,
|
logo: country?.flagIcon,
|
||||||
curr: country?.countryCode,
|
curr: currencyCode,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
console.log();
|
||||||
|
|
||||||
|
|
||||||
//=======================[ Editor ]
|
//=======================[ Editor ]
|
||||||
const formFields = [
|
const formFields = [
|
||||||
{
|
{
|
||||||
@@ -177,6 +181,61 @@ const ViewIOdetails = () => {
|
|||||||
section: " ",
|
section: " ",
|
||||||
width: "49%",
|
width: "49%",
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
label: "Holding Period",
|
||||||
|
name: "holdingPeriod",
|
||||||
|
value: IObyID?.data?.holdingPeriod ? IObyID?.data?.holdingPeriod : "---",
|
||||||
|
type: "text",
|
||||||
|
isRequired: true,
|
||||||
|
placeHolder: "1Y",
|
||||||
|
section: " ",
|
||||||
|
width: "49%",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Holding Period (Arabic)",
|
||||||
|
name: "holdingPeriodArabic",
|
||||||
|
value: IObyID?.data?.holdingPeriodArabic ? IObyID?.data?.holdingPeriodArabic : "---",
|
||||||
|
type: "text",
|
||||||
|
isRequired: true,
|
||||||
|
arabic: true,
|
||||||
|
placeHolder: "1Y",
|
||||||
|
section: " ",
|
||||||
|
width: "49%",
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
label: "Expected Return",
|
||||||
|
placeHolder: "$00.00",
|
||||||
|
name: "expectedReturn",
|
||||||
|
type: "number",
|
||||||
|
isRequired: true,
|
||||||
|
value: IObyID?.data?.expectedReturn
|
||||||
|
? IObyID?.data?.expectedReturn
|
||||||
|
: "---",
|
||||||
|
section: " ",
|
||||||
|
width: "49%",
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
label: "Expected Return (Arabic)",
|
||||||
|
name: "expectedReturnArabic",
|
||||||
|
placeHolder: "$00.00",
|
||||||
|
type: "number",
|
||||||
|
isRequired: true,
|
||||||
|
arabic: true,
|
||||||
|
value: IObyID?.data?.expectedReturnArabic
|
||||||
|
? IObyID?.data?.expectedReturnArabic
|
||||||
|
: "---",
|
||||||
|
section: " ",
|
||||||
|
width: "49%",
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
label: "Investment Type",
|
label: "Investment Type",
|
||||||
placeHolder: "Select option",
|
placeHolder: "Select option",
|
||||||
@@ -190,7 +249,7 @@ const ViewIOdetails = () => {
|
|||||||
width: "32.3%",
|
width: "32.3%",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Sponsorer Name",
|
label: "Sponsor Name",
|
||||||
placeHolder: "Select option",
|
placeHolder: "Select option",
|
||||||
name: "sponsor_xid",
|
name: "sponsor_xid",
|
||||||
type: "select",
|
type: "select",
|
||||||
@@ -204,10 +263,12 @@ const ViewIOdetails = () => {
|
|||||||
{
|
{
|
||||||
label: "Goal Amount",
|
label: "Goal Amount",
|
||||||
placeHolder: "$00.00",
|
placeHolder: "$00.00",
|
||||||
value: IObyID?.data?.goalAmount ? IObyID?.data?.goalAmount : "---",
|
value: IObyID?.data?.goalAmount?parseFloat(IObyID?.data?.goalAmount||0).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 }) : "---",
|
||||||
|
|
||||||
name: "goalAmount",
|
name: "goalAmount",
|
||||||
type: "number",
|
type: "number",
|
||||||
isRequired: true,
|
isRequired: true,
|
||||||
|
arabic:true,
|
||||||
section: " ",
|
section: " ",
|
||||||
width: "32.3%",
|
width: "32.3%",
|
||||||
},
|
},
|
||||||
@@ -222,28 +283,6 @@ const ViewIOdetails = () => {
|
|||||||
section: " ",
|
section: " ",
|
||||||
width: "32.3%",
|
width: "32.3%",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
label: "Holding Period",
|
|
||||||
name: "holdingPeriod",
|
|
||||||
value: IObyID?.data?.holdingPeriod ? IObyID?.data?.holdingPeriod : "---",
|
|
||||||
type: "text",
|
|
||||||
isRequired: true,
|
|
||||||
placeHolder: "1Y",
|
|
||||||
section: " ",
|
|
||||||
width: "32.3%",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Expected Return",
|
|
||||||
placeHolder: "$00.00",
|
|
||||||
name: "expectedReturn",
|
|
||||||
type: "number",
|
|
||||||
isRequired: true,
|
|
||||||
value: IObyID?.data?.expectedReturn
|
|
||||||
? IObyID?.data?.expectedReturn
|
|
||||||
: "---",
|
|
||||||
section: " ",
|
|
||||||
width: "32.3%",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
label: "ISIN",
|
label: "ISIN",
|
||||||
placeHolder: "$00.00",
|
placeHolder: "$00.00",
|
||||||
@@ -274,7 +313,6 @@ const ViewIOdetails = () => {
|
|||||||
section: " ",
|
section: " ",
|
||||||
width: "100%",
|
width: "100%",
|
||||||
isRequired: true,
|
isRequired: true,
|
||||||
type: "table",
|
|
||||||
value: minInvestmentById,
|
value: minInvestmentById,
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -299,7 +337,7 @@ const ViewIOdetails = () => {
|
|||||||
}, {});
|
}, {});
|
||||||
|
|
||||||
if (!IObyID?.data) {
|
if (!IObyID?.data) {
|
||||||
return <FullscreenLoaders />;
|
return <FullscreenLoaders height={'70vh'} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -68,7 +68,6 @@ const InvestorDetails = () => {
|
|||||||
error,
|
error,
|
||||||
} = useGetInvestorsQuery({ page: currentPage, size: pageSize });
|
} = useGetInvestorsQuery({ page: currentPage, size: pageSize });
|
||||||
|
|
||||||
console.log(investorDetails);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Simulate loading
|
// Simulate loading
|
||||||
@@ -82,7 +81,7 @@ const InvestorDetails = () => {
|
|||||||
|
|
||||||
// ====================================================[Table Setup]================================================================
|
// ====================================================[Table Setup]================================================================
|
||||||
const tableHeadRow = [
|
const tableHeadRow = [
|
||||||
"Sr N/O",
|
// "Sr N/O",
|
||||||
"Client ID",
|
"Client ID",
|
||||||
"First Name",
|
"First Name",
|
||||||
"Last Name",
|
"Last Name",
|
||||||
@@ -109,7 +108,7 @@ const InvestorDetails = () => {
|
|||||||
// ====================================================[Table Filter]================================================================
|
// ====================================================[Table Filter]================================================================
|
||||||
const filteredData = investorDetails?.data?.rows?.filter((item) => {
|
const filteredData = investorDetails?.data?.rows?.filter((item) => {
|
||||||
// Filter by name (case insensitive)
|
// Filter by name (case insensitive)
|
||||||
const name = item.clientReference_id;
|
const name = [item?.principal?.firstName, item?.principal?.lastName, item?.country?.countryName, item?.principal?.mobileNumber, item?.principal?.emailAddress].filter(Boolean).join(' ');
|
||||||
const searchLower = searchTerm.toLowerCase();
|
const searchLower = searchTerm.toLowerCase();
|
||||||
const nameMatches = name?.toLowerCase().includes(searchLower);
|
const nameMatches = name?.toLowerCase().includes(searchLower);
|
||||||
|
|
||||||
@@ -125,7 +124,6 @@ const InvestorDetails = () => {
|
|||||||
return nameMatches;
|
return nameMatches;
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(investorDetails);
|
|
||||||
|
|
||||||
const extractedArray = filteredData?.map((item) => ({
|
const extractedArray = filteredData?.map((item) => ({
|
||||||
id: item?.id,
|
id: item?.id,
|
||||||
@@ -264,6 +262,9 @@ const InvestorDetails = () => {
|
|||||||
onEditOpen();
|
onEditOpen();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
console.log(investorDetails?.data?.totalItems);
|
||||||
|
|
||||||
|
|
||||||
return (
|
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">
|
<Box bg="white.500">
|
||||||
@@ -371,6 +372,7 @@ const InvestorDetails = () => {
|
|||||||
currentPage={currentPage}
|
currentPage={currentPage}
|
||||||
setCurrentPage={setCurrentPage}
|
setCurrentPage={setCurrentPage}
|
||||||
totalItems={investorDetails?.data?.totalItems}
|
totalItems={investorDetails?.data?.totalItems}
|
||||||
|
|
||||||
/>
|
/>
|
||||||
</HStack>
|
</HStack>
|
||||||
</HStack>
|
</HStack>
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ const ProfileView = () => {
|
|||||||
skip: !id,
|
skip: !id,
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(data?.data);
|
|
||||||
|
|
||||||
const foundObject = data?.data;
|
const foundObject = data?.data;
|
||||||
|
|
||||||
@@ -238,6 +237,7 @@ const ProfileView = () => {
|
|||||||
View Details
|
View Details
|
||||||
</Tab>
|
</Tab>
|
||||||
<Tab
|
<Tab
|
||||||
|
isDisabled={true}
|
||||||
fontSize={"sm"}
|
fontSize={"sm"}
|
||||||
_selected={{
|
_selected={{
|
||||||
color: "#004118",
|
color: "#004118",
|
||||||
@@ -247,6 +247,7 @@ const ProfileView = () => {
|
|||||||
Portfolio
|
Portfolio
|
||||||
</Tab>
|
</Tab>
|
||||||
<Tab
|
<Tab
|
||||||
|
isDisabled={true}
|
||||||
fontSize={"sm"}
|
fontSize={"sm"}
|
||||||
_selected={{
|
_selected={{
|
||||||
color: "#004118",
|
color: "#004118",
|
||||||
@@ -256,6 +257,7 @@ const ProfileView = () => {
|
|||||||
Transaction
|
Transaction
|
||||||
</Tab>
|
</Tab>
|
||||||
<Tab
|
<Tab
|
||||||
|
isDisabled={true}
|
||||||
fontSize={"sm"}
|
fontSize={"sm"}
|
||||||
_selected={{
|
_selected={{
|
||||||
color: "#004118",
|
color: "#004118",
|
||||||
|
|||||||
@@ -22,8 +22,21 @@ import {
|
|||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import GlobalStateContext from "../Contexts/GlobalStateContext";
|
import GlobalStateContext from "../Contexts/GlobalStateContext";
|
||||||
import Cookies from "js-cookie";
|
import Cookies from "js-cookie";
|
||||||
import { validationSchema } from "../Validations/Validations";
|
|
||||||
import ToastBox from "../Components/ToastBox";
|
import ToastBox from "../Components/ToastBox";
|
||||||
|
import { useLoginMutation } from "../Services/token.serivce";
|
||||||
|
|
||||||
|
|
||||||
|
// import { yupResolver } from "@hookform/resolvers/yup";
|
||||||
|
import * as Yup from "yup";
|
||||||
|
|
||||||
|
|
||||||
|
const validationSchema = Yup.object().shape({
|
||||||
|
emailAddress: Yup.string()
|
||||||
|
.email("Invalid email address")
|
||||||
|
.required("Email address is required"),
|
||||||
|
password_hash: Yup.string().required("Password is required"),
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
const Login = () => {
|
const Login = () => {
|
||||||
const [show, setShow] = useState(false);
|
const [show, setShow] = useState(false);
|
||||||
@@ -36,43 +49,77 @@ const Login = () => {
|
|||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
|
const [login] = useLoginMutation()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isAuthenticate) {
|
if (isAuthenticate) {
|
||||||
navigate("/");
|
navigate("/sponser");
|
||||||
}
|
}
|
||||||
}, [navigate, isAuthenticate]);
|
}, [navigate, isAuthenticate]);
|
||||||
|
|
||||||
const onSubmit = (value) => {
|
const onSubmit = async (value) => {
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
if (value.name === "admin@tanami.com" && value.password === "Admin@123") {
|
try {
|
||||||
return setTimeout(() => {
|
const res = await login(value).unwrap();
|
||||||
// dispatch(loginUser(true));
|
|
||||||
|
if (res?.statusCode === 200) {
|
||||||
|
toast({
|
||||||
|
render: () => (
|
||||||
|
<ToastBox status={"success"} message={res?.message} />
|
||||||
|
),
|
||||||
|
})
|
||||||
|
setIsLoading(false);
|
||||||
setIsAuthenticate(true);
|
setIsAuthenticate(true);
|
||||||
setIsLoading(false);
|
|
||||||
toast({
|
|
||||||
render: () => (
|
|
||||||
<ToastBox status={"success"} message={"Login Successfully"} />
|
|
||||||
),
|
|
||||||
});
|
|
||||||
|
|
||||||
Cookies.set("isAuthenticated", true, { expires: 7 });
|
Cookies.set("isAuthenticated", true, { expires: 7 });
|
||||||
navigate("/");
|
navigate("/sponser");
|
||||||
}, 2000); // 3-second delay
|
reset();
|
||||||
} else {
|
}
|
||||||
return setTimeout(() => {
|
|
||||||
// dispatch(loginUser(true));
|
|
||||||
setIsAuthenticate(false);
|
|
||||||
setIsLoading(false);
|
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
if (err) {
|
||||||
toast({
|
toast({
|
||||||
render: () => (
|
render: () => (
|
||||||
<ToastBox status={"error"} message={"Invalid credentials"} />
|
<ToastBox status={"error"} message={err?.data?.message} />
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
reset();
|
setIsLoading(false);
|
||||||
navigate("/login");
|
}
|
||||||
}, 2000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// if (value.emailAddress === "admin@tanami.com" && value.password_hash === "Admin@123") {
|
||||||
|
// return setTimeout(() => {
|
||||||
|
// // dispatch(loginUser(true));
|
||||||
|
// setIsAuthenticate(true);
|
||||||
|
// setIsLoading(false);
|
||||||
|
// toast({
|
||||||
|
// render: () => (
|
||||||
|
// <ToastBox status={"success"} message={"Login Successfully"} />
|
||||||
|
// ),
|
||||||
|
// });
|
||||||
|
|
||||||
|
// Cookies.set("isAuthenticated", true, { expires: 7 });
|
||||||
|
// navigate("/");
|
||||||
|
// }, 2000); // 3-second delay
|
||||||
|
// } else {
|
||||||
|
// return setTimeout(() => {
|
||||||
|
// // dispatch(loginUser(true));
|
||||||
|
// setIsAuthenticate(false);
|
||||||
|
// setIsLoading(false);
|
||||||
|
|
||||||
|
// toast({
|
||||||
|
// render: () => (
|
||||||
|
// <ToastBox status={"error"} message={"Invalid credentials"} />
|
||||||
|
// ),
|
||||||
|
// });
|
||||||
|
// reset();
|
||||||
|
// navigate("/login");
|
||||||
|
// }, 2000);
|
||||||
|
// }
|
||||||
};
|
};
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@@ -84,6 +131,9 @@ const Login = () => {
|
|||||||
resolver: yupResolver(validationSchema),
|
resolver: yupResolver(validationSchema),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
console.log(errors);
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
@@ -138,18 +188,18 @@ const Login = () => {
|
|||||||
</FormLabel>
|
</FormLabel>
|
||||||
|
|
||||||
<Input
|
<Input
|
||||||
{...register("name")}
|
{...register("emailAddress")}
|
||||||
focusBorderColor="green.500"
|
focusBorderColor="green.500"
|
||||||
type="text"
|
type="text"
|
||||||
name="name"
|
name="emailAddress"
|
||||||
variant="filled"
|
variant="filled"
|
||||||
placeholder="Email"
|
placeholder="Email"
|
||||||
size="lg"
|
size="lg"
|
||||||
className="web-text-medium"
|
className="web-text-medium"
|
||||||
/>
|
/>
|
||||||
{errors.name && (
|
{errors.emailAddress && (
|
||||||
<span className="text-danger web-text-small fw-bold ps-2 d-flex align-items-center gap-1 mt-1">
|
<span className="text-danger web-text-small fw-bold ps-2 d-flex align-items-center gap-1 mt-1">
|
||||||
<TiWarning className="fw-bold fs-5 " /> {errors.name.message}
|
<TiWarning className="fw-bold fs-5 " /> {errors.emailAddress.message}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</FormControl>
|
</FormControl>
|
||||||
@@ -161,7 +211,7 @@ const Login = () => {
|
|||||||
|
|
||||||
<InputGroup size="lg">
|
<InputGroup size="lg">
|
||||||
<Input
|
<Input
|
||||||
{...register("password")}
|
{...register("password_hash")}
|
||||||
className="web-text-medium"
|
className="web-text-medium"
|
||||||
focusBorderColor="green.500"
|
focusBorderColor="green.500"
|
||||||
variant="filled"
|
variant="filled"
|
||||||
@@ -181,9 +231,9 @@ const Login = () => {
|
|||||||
</Button>
|
</Button>
|
||||||
</InputRightElement>
|
</InputRightElement>
|
||||||
</InputGroup>
|
</InputGroup>
|
||||||
{errors.password && (
|
{errors.password_hash && (
|
||||||
<span className="text-danger web-text-small fw-bold ps-2 d-flex align-items-center gap-1 mt-1">
|
<span className="text-danger web-text-small fw-bold ps-2 d-flex align-items-center gap-1 mt-1">
|
||||||
<TiWarning className="fw-bold fs-5 " /> {errors.password.message}
|
<TiWarning className="fw-bold fs-5 " /> {errors.password_hash.message}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</FormControl>
|
</FormControl>
|
||||||
|
|||||||
@@ -29,6 +29,9 @@ import {
|
|||||||
useUpdateExchangeRateMutation,
|
useUpdateExchangeRateMutation,
|
||||||
} from "../../../Services/exchange.rate.service";
|
} from "../../../Services/exchange.rate.service";
|
||||||
import ToastBox from "../../../Components/ToastBox";
|
import ToastBox from "../../../Components/ToastBox";
|
||||||
|
import { getTomorrowDate } from "../../../Constants/Constants";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Convert date to YYYY-MM-DD format
|
// Convert date to YYYY-MM-DD format
|
||||||
const formatDateValue = (date) => {
|
const formatDateValue = (date) => {
|
||||||
@@ -44,7 +47,7 @@ const formatDateValue = (date) => {
|
|||||||
return [year, month, day].join("-");
|
return [year, month, day].join("-");
|
||||||
};
|
};
|
||||||
|
|
||||||
const EditExchangeRate = ({ id, setIsLoading, updateHistory }) => {
|
const EditExchangeRate = ({ id, setIsLoading }) => {
|
||||||
const btnRef = useRef();
|
const btnRef = useRef();
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
const { isOpen, onOpen, onClose } = useDisclosure();
|
const { isOpen, onOpen, onClose } = useDisclosure();
|
||||||
@@ -73,9 +76,7 @@ const EditExchangeRate = ({ id, setIsLoading, updateHistory }) => {
|
|||||||
rate: rate,
|
rate: rate,
|
||||||
};
|
};
|
||||||
const res = await updateExchange({ data, id });
|
const res = await updateExchange({ data, id });
|
||||||
console.log(res?.data?.statusCode);
|
|
||||||
if (res?.data?.statusCode === 200) {
|
if (res?.data?.statusCode === 200) {
|
||||||
console.log("hit");
|
|
||||||
toast({
|
toast({
|
||||||
render: () => <ToastBox message={res?.data?.message} />,
|
render: () => <ToastBox message={res?.data?.message} />,
|
||||||
});
|
});
|
||||||
@@ -88,7 +89,6 @@ const EditExchangeRate = ({ id, setIsLoading, updateHistory }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{" "}
|
|
||||||
<Tooltip
|
<Tooltip
|
||||||
rounded={"sm"}
|
rounded={"sm"}
|
||||||
fontSize={"xs"}
|
fontSize={"xs"}
|
||||||
@@ -115,79 +115,97 @@ const EditExchangeRate = ({ id, setIsLoading, updateHistory }) => {
|
|||||||
</Button>
|
</Button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Drawer
|
<Drawer
|
||||||
size={"md"}
|
// size={"md"}
|
||||||
isOpen={isOpen}
|
isOpen={isOpen}
|
||||||
placement="right"
|
placement="right"
|
||||||
onClose={onClose}
|
onClose={onClose}
|
||||||
finalFocusRef={btnRef}
|
finalFocusRef={btnRef}
|
||||||
>
|
>
|
||||||
<form onSubmit={(e) =>{
|
<form
|
||||||
e.preventDefault()
|
onSubmit={(e) => {
|
||||||
setAlert(true)}}>
|
e.preventDefault();
|
||||||
<DrawerOverlay />
|
setAlert(true);
|
||||||
<DrawerContent>
|
}}
|
||||||
<DrawerCloseButton />
|
>
|
||||||
<DrawerHeader fontSize={"md"}>Edit rate</DrawerHeader>
|
<DrawerOverlay />
|
||||||
|
<DrawerContent>
|
||||||
|
<DrawerCloseButton />
|
||||||
|
<DrawerHeader fontSize={"md"}>Edit rate</DrawerHeader>
|
||||||
|
|
||||||
<DrawerBody>
|
<DrawerBody>
|
||||||
|
<Box display={"flex"} mb={5}>
|
||||||
<Box display={"flex"} mb={5}>
|
<Box
|
||||||
<Box w={"50%"} display={"flex"} flexDirection={"column"} gap={1}>
|
w={"50%"}
|
||||||
<FormLabel fontSize={"sm"}>From</FormLabel>
|
display={"flex"}
|
||||||
<Text as={"span"} fontSize={"sm"} fontWeight={"bold"}>
|
flexDirection={"column"}
|
||||||
{foundObject?.fromCurrency?.currencyCode}
|
gap={1}
|
||||||
</Text>
|
>
|
||||||
|
<FormLabel fontSize={"sm"}>From</FormLabel>
|
||||||
|
<Text as={"span"} fontSize={"sm"} fontWeight={"bold"}>
|
||||||
|
{foundObject?.fromCurrency?.currencyCode}
|
||||||
|
</Text>
|
||||||
|
</Box>
|
||||||
|
<Box
|
||||||
|
w={"50%"}
|
||||||
|
display={"flex"}
|
||||||
|
flexDirection={"column"}
|
||||||
|
gap={1}
|
||||||
|
>
|
||||||
|
<FormLabel fontSize={"sm"}>To</FormLabel>
|
||||||
|
<Text as={"span"} fontSize={"sm"} fontWeight={"bold"}>
|
||||||
|
{foundObject?.toCurrency?.currencyCode}
|
||||||
|
</Text>
|
||||||
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
<Box w={"50%"} display={"flex"} flexDirection={"column"} gap={1}>
|
|
||||||
<FormLabel fontSize={"sm"}>To</FormLabel>
|
<FormControl mb={4}>
|
||||||
<Text as={"span"} fontSize={"sm"} fontWeight={"bold"}>
|
<FormLabel fontSize={"sm"}>Last effective date</FormLabel>
|
||||||
{foundObject?.toCurrency?.currencyCode}
|
<Text color={'gray.500'} fontSize={"sm"}>
|
||||||
|
{formatDate(foundObject?.effectiveFrom)}
|
||||||
</Text>
|
</Text>
|
||||||
</Box>
|
</FormControl>
|
||||||
</Box>
|
<FormControl mb={4}>
|
||||||
|
<FormLabel fontSize={"sm"}>Effective from</FormLabel>
|
||||||
|
<Text fontSize={"sm"}>
|
||||||
|
{formatDate(getTomorrowDate())}
|
||||||
|
</Text>
|
||||||
|
</FormControl>
|
||||||
|
|
||||||
<FormControl mb={4}>
|
<FormControl mb={4} isRequired>
|
||||||
<FormLabel fontSize={"sm"}>Effective from</FormLabel>
|
<FormLabel fontSize={"sm"}>Rate</FormLabel>
|
||||||
<Text fontSize={"sm"}>
|
<Input
|
||||||
{formatDate(foundObject?.effectiveFrom)}
|
required
|
||||||
</Text>
|
type="number"
|
||||||
</FormControl>
|
placeholder="Type rate here..."
|
||||||
|
size={"sm"}
|
||||||
|
value={rate}
|
||||||
|
onChange={(e) => setRate(e.target.value)}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
</DrawerBody>
|
||||||
|
|
||||||
<FormControl mb={4} isRequired>
|
<DrawerFooter>
|
||||||
<FormLabel fontSize={"sm"}>Rate</FormLabel>
|
<Button
|
||||||
<Input
|
variant="outline"
|
||||||
required
|
colorScheme={"forestGreen"}
|
||||||
type="number"
|
rounded={"sm"}
|
||||||
placeholder="Type rate here..."
|
|
||||||
size={"sm"}
|
size={"sm"}
|
||||||
value={rate}
|
mr={3}
|
||||||
onChange={(e) => setRate(e.target.value)}
|
onClick={onClose}
|
||||||
/>
|
>
|
||||||
</FormControl>
|
Cancel
|
||||||
</DrawerBody>
|
</Button>
|
||||||
|
|
||||||
<DrawerFooter>
|
<Button
|
||||||
<Button
|
colorScheme={"forestGreen"}
|
||||||
variant="outline"
|
rounded={"sm"}
|
||||||
colorScheme={"forestGreen"}
|
size={"sm"}
|
||||||
rounded={"sm"}
|
type="submit"
|
||||||
size={"sm"}
|
>
|
||||||
mr={3}
|
Save
|
||||||
onClick={onClose}
|
</Button>
|
||||||
>
|
</DrawerFooter>
|
||||||
Cancel
|
</DrawerContent>
|
||||||
</Button>
|
|
||||||
|
|
||||||
<Button
|
|
||||||
colorScheme={"forestGreen"}
|
|
||||||
rounded={"sm"}
|
|
||||||
size={"sm"}
|
|
||||||
type="submit"
|
|
||||||
>
|
|
||||||
Save
|
|
||||||
</Button>
|
|
||||||
</DrawerFooter>
|
|
||||||
</DrawerContent>
|
|
||||||
</form>
|
</form>
|
||||||
</Drawer>
|
</Drawer>
|
||||||
<CustomAlertDialog
|
<CustomAlertDialog
|
||||||
|
|||||||
@@ -34,10 +34,11 @@ import { useGetAllExchangeRatesQuery } from "../../../Services/exchange.rate.ser
|
|||||||
import { TABLE_PAGINATION } from "../../../Constants/Paginations";
|
import { TABLE_PAGINATION } from "../../../Constants/Paginations";
|
||||||
import NormalTable from "../../../Components/DataTable/NormalTable";
|
import NormalTable from "../../../Components/DataTable/NormalTable";
|
||||||
import { MdHistory } from "react-icons/md";
|
import { MdHistory } from "react-icons/md";
|
||||||
|
import { formatCurrency } from "../../../Components/CurrencyInput";
|
||||||
|
|
||||||
const ExchangeRate = () => {
|
const ExchangeRate = () => {
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate();
|
||||||
const { slideFromRight, rateExchange, setRateExchange } =
|
const { slideFromRight, rateExchange, setRateExchange } =
|
||||||
useContext(GlobalStateContext);
|
useContext(GlobalStateContext);
|
||||||
const [searchTerm, setSearchTerm] = useState("");
|
const [searchTerm, setSearchTerm] = useState("");
|
||||||
@@ -46,47 +47,18 @@ const ExchangeRate = () => {
|
|||||||
const [actionId, setActionId] = useState(false);
|
const [actionId, setActionId] = useState(false);
|
||||||
const [mouseEntered, setMouseEntered] = useState(false);
|
const [mouseEntered, setMouseEntered] = useState(false);
|
||||||
const [mouseEnteredId, setMouseEnteredId] = useState("");
|
const [mouseEnteredId, setMouseEnteredId] = useState("");
|
||||||
const [history, setHistory] = useState([]);
|
|
||||||
|
|
||||||
// ===============================[ Paginations ]
|
// ===============================[ Paginations ]
|
||||||
const [pageSize, setPageSize] = useState(TABLE_PAGINATION?.size);
|
const [pageSize, setPageSize] = useState(TABLE_PAGINATION?.size);
|
||||||
const [currentPage, setCurrentPage] = useState(1);
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
data,
|
data,
|
||||||
isLoading: isExchangeRateLoading,
|
isLoading: isExchangeRateLoading,
|
||||||
errors,
|
errors,
|
||||||
} = useGetAllExchangeRatesQuery({ page: currentPage, size: pageSize })
|
} = useGetAllExchangeRatesQuery({ page: currentPage, size: pageSize });
|
||||||
|
|
||||||
console.log(data?.data);
|
console.log(data?.data);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const updateHistory = (id, previousRate, newRate, effectFrom) => {
|
|
||||||
setHistory((prevHistory) => [
|
|
||||||
...prevHistory,
|
|
||||||
{ id, effectFrom, previousRate, newRate },
|
|
||||||
]);
|
|
||||||
};
|
|
||||||
|
|
||||||
// ====================================================[Table Filter]================================================================
|
|
||||||
const filteredData = rateExchange.filter((item) => {
|
|
||||||
// Filter by name (case insensitive)
|
|
||||||
const name = item.fromCurr;
|
|
||||||
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;
|
|
||||||
});
|
|
||||||
|
|
||||||
// ====================================================[Table Setup]================================================================
|
// ====================================================[Table Setup]================================================================
|
||||||
const tableHeadRow = [
|
const tableHeadRow = [
|
||||||
@@ -129,7 +101,7 @@ const ExchangeRate = () => {
|
|||||||
fontWeight={"600"}
|
fontWeight={"600"}
|
||||||
className="d-flex align-items-center fw- web-text-small"
|
className="d-flex align-items-center fw- web-text-small"
|
||||||
>
|
>
|
||||||
{item?.toCurrency?.currencyCode}
|
{item?.toCurrency?.currencyCode}
|
||||||
</Text>
|
</Text>
|
||||||
),
|
),
|
||||||
"Effective from": (
|
"Effective from": (
|
||||||
@@ -145,13 +117,13 @@ const ExchangeRate = () => {
|
|||||||
),
|
),
|
||||||
Rate: (
|
Rate: (
|
||||||
<Text
|
<Text
|
||||||
justifyContent={slideFromRight ? "right" : "left"}
|
justifyContent={"left"}
|
||||||
as={"span"}
|
as={"span"}
|
||||||
color={"gray.600"}
|
color={"gray.600"}
|
||||||
fontWeight={"600"}
|
fontWeight={"600"}
|
||||||
className="d-flex align-items-center web-text-small"
|
className="d-flex align-items-center web-text-small"
|
||||||
>
|
>
|
||||||
{item.rate}
|
{formatCurrency(item.rate)}
|
||||||
</Text>
|
</Text>
|
||||||
),
|
),
|
||||||
|
|
||||||
@@ -163,34 +135,32 @@ const ExchangeRate = () => {
|
|||||||
<EditExchangeRate
|
<EditExchangeRate
|
||||||
setIsLoading={setIsLoading}
|
setIsLoading={setIsLoading}
|
||||||
id={item.id}
|
id={item.id}
|
||||||
updateHistory={updateHistory}
|
// updateHistory={updateHistory}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Tooltip
|
<Tooltip
|
||||||
rounded={"sm"}
|
rounded={"sm"}
|
||||||
fontSize={"xs"}
|
fontSize={"xs"}
|
||||||
label="History"
|
label="History"
|
||||||
bg="#fff"
|
bg="#fff"
|
||||||
color={"purple.500"}
|
color={"purple.500"}
|
||||||
placement="top"
|
placement="top"
|
||||||
>
|
>
|
||||||
<Button
|
<Button
|
||||||
// _hover={{ color: "purple.500" }}
|
// _hover={{ color: "purple.500" }}
|
||||||
// transition={"0.5s all"}
|
// transition={"0.5s all"}
|
||||||
// color="purple.400"
|
// color="purple.400"
|
||||||
colorScheme="purple"
|
colorScheme="purple"
|
||||||
rounded={"sm"}
|
rounded={"sm"}
|
||||||
size={{base:'xs', lg:'xs'}}
|
size={{ base: "xs", lg: "xs" }}
|
||||||
onClick={() => navigate(`currency-history/${item?.id}`)}
|
onClick={() => navigate(`currency-history/${item?.id}`)}
|
||||||
|
display={"flex"}
|
||||||
display={'flex'}
|
alignItems={"center"}
|
||||||
alignItems={'center'}
|
gap={1}
|
||||||
gap={1}
|
>
|
||||||
|
<MdHistory />
|
||||||
>
|
</Button>
|
||||||
<MdHistory />
|
</Tooltip>
|
||||||
</Button>
|
|
||||||
</Tooltip>
|
|
||||||
</Box>
|
</Box>
|
||||||
),
|
),
|
||||||
}));
|
}));
|
||||||
@@ -230,8 +200,6 @@ const ExchangeRate = () => {
|
|||||||
value={searchTerm}
|
value={searchTerm}
|
||||||
onChange={(e) => setSearchTerm(e.target.value)}
|
onChange={(e) => setSearchTerm(e.target.value)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
||||||
</HStack>
|
</HStack>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
|
|||||||
@@ -7,21 +7,25 @@ import * as yup from "yup";
|
|||||||
import { useNavigate, useParams } from "react-router-dom";
|
import { useNavigate, useParams } from "react-router-dom";
|
||||||
import FormInputMain from "../../../Components/FormInputMain";
|
import FormInputMain from "../../../Components/FormInputMain";
|
||||||
import SwitchButton from "../../../Components/SwitchButton";
|
import SwitchButton from "../../../Components/SwitchButton";
|
||||||
import {useCreateInvestmentTypeMutation,
|
import {
|
||||||
|
useCreateInvestmentTypeMutation,
|
||||||
useGetInvestmentTypeByIdQuery,
|
useGetInvestmentTypeByIdQuery,
|
||||||
useUpdateInvestmentTypeMutation,
|
useUpdateInvestmentTypeMutation,
|
||||||
} from "../../../Services/investment.type.service";
|
} from "../../../Services/investment.type.service";
|
||||||
import ToastBox from "../../../Components/ToastBox";
|
import ToastBox from "../../../Components/ToastBox";
|
||||||
import CustomAlertDialog from "../../../Components/CustomAlertDialog";
|
import CustomAlertDialog from "../../../Components/CustomAlertDialog";
|
||||||
|
import FullscreenLoaders from "../../../Components/Loaders/FullscreenLoaders";
|
||||||
|
|
||||||
// ======================= [validation] =========================
|
// ======================= [validation] =========================
|
||||||
|
|
||||||
export const addInvestmentType = yup.object().shape({
|
export const addInvestmentType = yup.object().shape({
|
||||||
investmentTypeName: yup.string()
|
investmentTypeName: yup.string()
|
||||||
.required('Investment type is required')
|
.required('Investment type is required')
|
||||||
.max(50, 'Investment name cannot be more than 50 characters'),
|
.max(50, 'Investment name cannot be more than 50 characters'),
|
||||||
note: yup.string().notRequired(),
|
note: yup.string()
|
||||||
investmentTypeNameArabic: yup.string().required(),
|
.optional()
|
||||||
|
.max(255, 'Note cannot exceed 255 characters'),
|
||||||
|
investmentTypeNameArabic: yup.string().required("Investment type in arabic required"),
|
||||||
noteArabic: yup.string().notRequired(),
|
noteArabic: yup.string().notRequired(),
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -60,13 +64,14 @@ const AddInvestmentType = () => {
|
|||||||
const {
|
const {
|
||||||
control,
|
control,
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
|
watch,
|
||||||
formState: { errors },
|
formState: { errors },
|
||||||
reset,
|
reset,
|
||||||
} = useForm({
|
} = useForm({
|
||||||
resolver: yupResolver(addInvestmentType),
|
resolver: yupResolver(addInvestmentType),
|
||||||
});
|
});
|
||||||
|
|
||||||
const {data: investmentTypeByIdData,error,isLoading,} = useGetInvestmentTypeByIdQuery(id, { skip: !id });
|
const { data: investmentTypeByIdData, error, isLoading, } = useGetInvestmentTypeByIdQuery(id, { skip: !id });
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -81,6 +86,7 @@ const AddInvestmentType = () => {
|
|||||||
note: investmentTypeByIdData?.data?.note,
|
note: investmentTypeByIdData?.data?.note,
|
||||||
noteArabic: investmentTypeByIdData?.data?.noteArabic,
|
noteArabic: investmentTypeByIdData?.data?.noteArabic,
|
||||||
});
|
});
|
||||||
|
setIsSwitchOn(investmentTypeByIdData?.data?.isActive)
|
||||||
}
|
}
|
||||||
}, [investmentTypeByIdData, reset]);
|
}, [investmentTypeByIdData, reset]);
|
||||||
|
|
||||||
@@ -88,7 +94,7 @@ const AddInvestmentType = () => {
|
|||||||
return <FullscreenLoaders />;
|
return <FullscreenLoaders />;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================ [API]===============================
|
// ============================ [API]===============================
|
||||||
|
|
||||||
const handleConfirm = async () => {
|
const handleConfirm = async () => {
|
||||||
setIsLoadingBtn(true);
|
setIsLoadingBtn(true);
|
||||||
@@ -169,7 +175,8 @@ const AddInvestmentType = () => {
|
|||||||
type: "text",
|
type: "text",
|
||||||
isRequired: true,
|
isRequired: true,
|
||||||
section: "Add Details",
|
section: "Add Details",
|
||||||
maxLength:50
|
maxLength: 50,
|
||||||
|
helperText:`Maximum length should be 50 characters. You have entered ${watch()?.investmentTypeName?.length || 0} characters.`
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Investment Type (Arabic) ",
|
label: "Investment Type (Arabic) ",
|
||||||
@@ -179,7 +186,8 @@ const AddInvestmentType = () => {
|
|||||||
isRequired: true,
|
isRequired: true,
|
||||||
section: "Add Details",
|
section: "Add Details",
|
||||||
arabic: true,
|
arabic: true,
|
||||||
maxLength:255
|
maxLength: 255,
|
||||||
|
helperText:`Maximum length should be 255 characters. You have entered ${watch()?.investmentTypeNameArabic?.length || 0} characters.`
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Description (English)",
|
label: "Description (English)",
|
||||||
@@ -188,7 +196,8 @@ const AddInvestmentType = () => {
|
|||||||
type: "textarea",
|
type: "textarea",
|
||||||
// isRequired: true,
|
// isRequired: true,
|
||||||
section: "Add Details",
|
section: "Add Details",
|
||||||
maxLength:255
|
maxLength: 255,
|
||||||
|
helperText:`Maximum length should be 255 characters. You have entered ${watch()?.note?.length || 0} characters.`
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Description (Arabic)",
|
label: "Description (Arabic)",
|
||||||
@@ -198,7 +207,8 @@ const AddInvestmentType = () => {
|
|||||||
// isRequired: true,
|
// isRequired: true,
|
||||||
arabic: true,
|
arabic: true,
|
||||||
section: "Add Details",
|
section: "Add Details",
|
||||||
maxLength:255
|
maxLength: 255,
|
||||||
|
helperText:`Maximum length should be 255 characters. You have entered ${watch()?.noteArabic?.length || 0} characters.`
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -212,6 +222,8 @@ const AddInvestmentType = () => {
|
|||||||
type: "text",
|
type: "text",
|
||||||
isRequired: true,
|
isRequired: true,
|
||||||
section: "Add Details",
|
section: "Add Details",
|
||||||
|
maxLength: 50,
|
||||||
|
helperText:`Maximum length should be 50 characters. You have entered ${watch()?.investmentTypeName?.length || 0} characters.`
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Investment Type (Arabic)",
|
label: "Investment Type (Arabic)",
|
||||||
@@ -221,6 +233,8 @@ const AddInvestmentType = () => {
|
|||||||
isRequired: true,
|
isRequired: true,
|
||||||
section: "Add Details",
|
section: "Add Details",
|
||||||
arabic: true,
|
arabic: true,
|
||||||
|
maxLength: 255,
|
||||||
|
helperText:`Maximum length should be 255 characters. You have entered ${watch()?.investmentTypeNameArabic?.length || 0} characters.`
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Description (English)",
|
label: "Description (English)",
|
||||||
@@ -229,6 +243,8 @@ const AddInvestmentType = () => {
|
|||||||
type: "textarea",
|
type: "textarea",
|
||||||
// isRequired: true,
|
// isRequired: true,
|
||||||
section: "Add Details",
|
section: "Add Details",
|
||||||
|
maxLength: 255,
|
||||||
|
helperText:`Maximum length should be 255 characters. You have entered ${watch()?.note?.length || 0} characters.`
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Description (Arabic)",
|
label: "Description (Arabic)",
|
||||||
@@ -238,6 +254,8 @@ const AddInvestmentType = () => {
|
|||||||
// isRequired: true,
|
// isRequired: true,
|
||||||
arabic: true,
|
arabic: true,
|
||||||
section: "Add Details",
|
section: "Add Details",
|
||||||
|
maxLength: 255,
|
||||||
|
helperText:`Maximum length should be 255 characters. You have entered ${watch()?.noteArabic?.length || 0} characters.`
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -275,37 +293,38 @@ const AddInvestmentType = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box {...OPACITY_ON_LOAD} overflowY={"scroll"} height={"100vh"} pb={14}>
|
isLoading ? <FullscreenLoaders /> :
|
||||||
|
<Box {...OPACITY_ON_LOAD} overflowY={"scroll"} height={"100vh"} pb={14}>
|
||||||
|
|
||||||
{/* ===================== [Switch Button] ======================== */}
|
{/* ===================== [Switch Button] ======================== */}
|
||||||
|
|
||||||
<Box mt={5} display={"flex"} justifyContent={"right"} mr={5}>
|
<Box mt={5} display={"flex"} justifyContent={"right"} mr={5}>
|
||||||
<SwitchButton isSwitchOn={isSwitchOn} setIsSwitchOn={setIsSwitchOn} />
|
<SwitchButton isSwitchOn={isSwitchOn} setIsSwitchOn={setIsSwitchOn} />
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{/* ====================== [Form Input] ====================== */}
|
{/* ====================== [Form Input] ====================== */}
|
||||||
|
|
||||||
<FormInputMain
|
<FormInputMain
|
||||||
groupedFields={params?.id ? groupedEditFields : groupedFields}
|
groupedFields={params?.id ? groupedEditFields : groupedFields}
|
||||||
control={control}
|
control={control}
|
||||||
errors={errors}
|
errors={errors}
|
||||||
onSubmit={handleSubmit(onSubmit)}
|
onSubmit={handleSubmit(onSubmit)}
|
||||||
submitTitle={params?.id ? "Update" : "Submit"}
|
submitTitle={params?.id ? "Update" : "Submit"}
|
||||||
// btnLoading={isLoadingBtn}
|
// btnLoading={isLoadingBtn}
|
||||||
>
|
>
|
||||||
</FormInputMain>
|
</FormInputMain>
|
||||||
|
|
||||||
{/* ======================= [Modal] =========================== */}
|
{/* ======================= [Modal] =========================== */}
|
||||||
|
|
||||||
<CustomAlertDialog
|
<CustomAlertDialog
|
||||||
isOpen={alert}
|
isOpen={alert}
|
||||||
onClose={() => setAlert(false)}
|
onClose={() => setAlert(false)}
|
||||||
alertHandler={handleConfirm}
|
alertHandler={handleConfirm}
|
||||||
message={"Are you sure you want to add this?"}
|
message={"Are you sure you want to add this?"}
|
||||||
isLoading={isLoadingBtn}
|
isLoading={isLoadingBtn}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -12,13 +12,18 @@ import ToastBox from "../../../Components/ToastBox";
|
|||||||
import FullscreenLoaders from "../../../Components/Loaders/FullscreenLoaders";
|
import FullscreenLoaders from "../../../Components/Loaders/FullscreenLoaders";
|
||||||
import CustomAlertDialog from "../../../Components/CustomAlertDialog";
|
import CustomAlertDialog from "../../../Components/CustomAlertDialog";
|
||||||
import SwitchButton from "../../../Components/SwitchButton";
|
import SwitchButton from "../../../Components/SwitchButton";
|
||||||
|
import DummyComponent from "../../../Components/DummyComponent";
|
||||||
|
|
||||||
// ======================= [validation] =========================
|
// ======================= [validation] =========================
|
||||||
|
|
||||||
export const addSponser = yup.object().shape({
|
export const addSponser = yup.object().shape({
|
||||||
sponsorName: yup.string().required("Sponser name is required"),
|
sponsorName: yup.
|
||||||
sponsorNameArabic: yup.string().required("Sponser name is required"),
|
string()
|
||||||
email: yup.string().email("Must be a valid email").notRequired(),
|
.required('Sponsor Name is required')
|
||||||
|
.min(3, 'Sponsor Name must be at least 3 characters long')
|
||||||
|
.max(50, 'Investment Type Name cannot exceed 50 characters'),
|
||||||
|
sponsorNameArabic: yup.string().required("Sponser name in arabic is required"),
|
||||||
|
email: yup.string().email("Invalid email address").notRequired(),
|
||||||
// .test("emailValidity", "Email address is invalid", async function (value) {
|
// .test("emailValidity", "Email address is invalid", async function (value) {
|
||||||
// if (!value) {
|
// if (!value) {
|
||||||
// return true; // Allow if the field is empty
|
// return true; // Allow if the field is empty
|
||||||
@@ -61,6 +66,7 @@ const AddSponser = () => {
|
|||||||
|
|
||||||
const {
|
const {
|
||||||
control,
|
control,
|
||||||
|
watch,
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
formState: { errors },
|
formState: { errors },
|
||||||
reset,
|
reset,
|
||||||
@@ -78,9 +84,15 @@ const AddSponser = () => {
|
|||||||
sponsorNameArabic: sponserByIdData?.data?.sponsorNameArabic,
|
sponsorNameArabic: sponserByIdData?.data?.sponsorNameArabic,
|
||||||
email: sponserByIdData?.data?.email,
|
email: sponserByIdData?.data?.email,
|
||||||
});
|
});
|
||||||
|
setIsSwitchOn(sponserByIdData?.data?.isActive)
|
||||||
|
console.log(sponserByIdData?.data?.isActive);
|
||||||
|
|
||||||
}
|
}
|
||||||
}, [sponserByIdData, reset]);
|
}, [sponserByIdData, reset]);
|
||||||
|
|
||||||
|
// console.log(isSwitchOn);
|
||||||
|
|
||||||
|
|
||||||
if (false) {
|
if (false) {
|
||||||
return <FullscreenLoaders />;
|
return <FullscreenLoaders />;
|
||||||
}
|
}
|
||||||
@@ -109,15 +121,15 @@ const AddSponser = () => {
|
|||||||
setIsLoadingBtn(false);
|
setIsLoadingBtn(false);
|
||||||
setAlert(false);
|
setAlert(false);
|
||||||
navigate("/sponser");
|
navigate("/sponser");
|
||||||
} else {
|
} else if(response?.error?.status === 400) {
|
||||||
toast({
|
toast({
|
||||||
render: () => (
|
render: () => (
|
||||||
<ToastBox message={"Something Went Wrong"} status={"error"} />
|
<ToastBox message={response?.error?.data?.message} status={"error"} />
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
|
|
||||||
setIsLoadingBtn(false);
|
setIsLoadingBtn(false);
|
||||||
navigate("/sponser");
|
setAlert(false)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -148,7 +160,7 @@ const AddSponser = () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
setIsLoadingBtn(false);
|
setIsLoadingBtn(false);
|
||||||
navigate("/sponser");
|
setAlert(false)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -164,24 +176,26 @@ const AddSponser = () => {
|
|||||||
|
|
||||||
const formFields = [
|
const formFields = [
|
||||||
{
|
{
|
||||||
label: "Sponser name (English)",
|
label: "Sponsor name (English)",
|
||||||
placeHolder: " ",
|
placeHolder: " ",
|
||||||
name: "sponsorName",
|
name: "sponsorName",
|
||||||
type: "text",
|
type: "text",
|
||||||
isRequired: true,
|
isRequired: true,
|
||||||
section: "Add Details",
|
section: "",
|
||||||
maxLength:50
|
maxLength:50,
|
||||||
|
helperText:`Maximum length should be 50 characters. You have entered ${watch()?.sponsorName?.length || 0} characters.`
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Sponser name (Arabic)",
|
label: "Sponsor name (Arabic)",
|
||||||
name: "sponsorNameArabic",
|
name: "sponsorNameArabic",
|
||||||
placeHolder: " ",
|
placeHolder: " ",
|
||||||
type: "text",
|
type: "text",
|
||||||
isRequired: true,
|
isRequired: true,
|
||||||
section: "Add Details",
|
section: "",
|
||||||
arabic: true,
|
arabic: true,
|
||||||
right: true,
|
right: true,
|
||||||
maxLength:255
|
maxLength:55,
|
||||||
|
helperText:`Maximum length should be 55 characters. You have entered ${watch()?.sponsorNameArabic?.length || 0} characters.`
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Email address",
|
label: "Email address",
|
||||||
@@ -189,7 +203,7 @@ const AddSponser = () => {
|
|||||||
placeHolder: " ",
|
placeHolder: " ",
|
||||||
type: "email",
|
type: "email",
|
||||||
// isRequired: true,
|
// isRequired: true,
|
||||||
section: "Add Details",
|
section: "",
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -197,23 +211,25 @@ const AddSponser = () => {
|
|||||||
|
|
||||||
const formEditFields = [
|
const formEditFields = [
|
||||||
{
|
{
|
||||||
label: "Sponser name",
|
label: "Sponsor name",
|
||||||
placeHolder: " ",
|
placeHolder: " ",
|
||||||
name: "sponsorName",
|
name: "sponsorName",
|
||||||
type: "text",
|
type: "text",
|
||||||
isRequired: true,
|
isRequired: true,
|
||||||
section: "Add Details",
|
section: "",
|
||||||
maxLength:50
|
maxLength:55,
|
||||||
|
helperText:`Maximum length should be 55 characters. You have entered ${watch()?.sponsorName?.length || 0} characters.`
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Sponser name (Arabic)",
|
label: "Sponsor name (Arabic)",
|
||||||
name: "sponsorNameArabic",
|
name: "sponsorNameArabic",
|
||||||
placeHolder: " ",
|
placeHolder: " ",
|
||||||
type: "text",
|
type: "text",
|
||||||
isRequired: true,
|
isRequired: true,
|
||||||
section: "Add Details",
|
section: "",
|
||||||
arabic: true,
|
arabic: true,
|
||||||
maxLength:255
|
maxLength:55,
|
||||||
|
helperText:`Maximum length should be 55 characters. You have entered ${watch()?.sponsorNameArabic?.length || 0} characters.`
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Email adress",
|
label: "Email adress",
|
||||||
@@ -221,7 +237,7 @@ const AddSponser = () => {
|
|||||||
placeHolder: " ",
|
placeHolder: " ",
|
||||||
type: "email",
|
type: "email",
|
||||||
// isRequired: true,
|
// isRequired: true,
|
||||||
section: "Add Details",
|
section: "",
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -257,14 +273,16 @@ const AddSponser = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
isLoading?<FullscreenLoaders/>:
|
||||||
<Box {...OPACITY_ON_LOAD} overflowY={"scroll"} height={"100vh"} pb={14}>
|
<Box {...OPACITY_ON_LOAD} overflowY={"scroll"} height={"100vh"} pb={14}>
|
||||||
|
|
||||||
{/* ===================== [Switch Button] ======================== */}
|
{/* ===================== [Switch Button] ======================== */}
|
||||||
|
|
||||||
<Box mt={5} display={"flex"} justifyContent={"right"} mr={5}>
|
<Box mt={5} display={"flex"} justifyContent={"right"} mr={5}>
|
||||||
<SwitchButton isSwitchOn={isSwitchOn} setIsSwitchOn={setIsSwitchOn} />
|
<SwitchButton isSwitchOn={isSwitchOn} setIsSwitchOn={setIsSwitchOn} />
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
|
|
||||||
{/* ====================== [Form Input] ====================== */}
|
{/* ====================== [Form Input] ====================== */}
|
||||||
|
|
||||||
<FormInputMain
|
<FormInputMain
|
||||||
@@ -284,6 +302,8 @@ const AddSponser = () => {
|
|||||||
message={"Are you sure you want to add this?"}
|
message={"Are you sure you want to add this?"}
|
||||||
isLoading={isLoadingBtn}
|
isLoading={isLoadingBtn}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
{/* <DummyComponent /> */}
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ export const formatDate = (date) => {
|
|||||||
const month = String(d.getMonth() + 1).padStart(2, '0'); // Months are 0-indexed
|
const month = String(d.getMonth() + 1).padStart(2, '0'); // Months are 0-indexed
|
||||||
const day = String(d.getDate()).padStart(2, '0');
|
const day = String(d.getDate()).padStart(2, '0');
|
||||||
|
|
||||||
return `${day}-${month}-${year}`;
|
return `${day}/${month}/${year}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
const Sponser = () => {
|
const Sponser = () => {
|
||||||
@@ -158,14 +158,28 @@ const Sponser = () => {
|
|||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
try {
|
try {
|
||||||
const response = await deleteSponser(actionId);
|
const response = await deleteSponser(actionId);
|
||||||
console.log(response);
|
console.log(response?.data);
|
||||||
setIsLoading(false);
|
if(response?.error?.data?.code === 400){
|
||||||
setDeleteAlert(false);
|
toast({
|
||||||
|
render: () => <ToastBox message={response?.error?.data?.message} status={'error'} />,
|
||||||
|
});
|
||||||
|
setIsLoading(false);
|
||||||
|
setDeleteAlert(false);
|
||||||
|
} else if(response?.data?.statusCode === 201 || response?.data?.statusCode === 200){
|
||||||
|
toast({
|
||||||
|
render: () => <ToastBox message={response?.data?.message} status={'error'} />,
|
||||||
|
});
|
||||||
|
setIsLoading(false);
|
||||||
|
setDeleteAlert(false);
|
||||||
|
|
||||||
|
}
|
||||||
} catch (error) {}
|
} catch (error) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log(isSponserLoading);
|
console.log(isSponserLoading);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
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">
|
<Box bg="white.500">
|
||||||
|
|||||||
@@ -13,7 +13,17 @@ const SplashScreen = () => {
|
|||||||
gap={10}
|
gap={10}
|
||||||
>
|
>
|
||||||
<Image src={logo} />
|
<Image src={logo} />
|
||||||
<Spinner color='green.900' size='md' />
|
{/* <Spinner color='green.900' size='md' /> */}
|
||||||
|
<div className="dot-spinner">
|
||||||
|
<div className="dot-spinner__dot"></div>
|
||||||
|
<div className="dot-spinner__dot"></div>
|
||||||
|
<div className="dot-spinner__dot"></div>
|
||||||
|
<div className="dot-spinner__dot"></div>
|
||||||
|
<div className="dot-spinner__dot"></div>
|
||||||
|
<div className="dot-spinner__dot"></div>
|
||||||
|
<div className="dot-spinner__dot"></div>
|
||||||
|
<div className="dot-spinner__dot"></div>
|
||||||
|
</div>
|
||||||
</Box>
|
</Box>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,18 +3,18 @@ import React from 'react'
|
|||||||
// import noInternet from "../assets/Error.svg"
|
// import noInternet from "../assets/Error.svg"
|
||||||
import robot from "../assets/robot.png"
|
import robot from "../assets/robot.png"
|
||||||
|
|
||||||
const UnderConstruction = ({title}) => {
|
const UnderConstruction = ({title, h}) => {
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
h={'100vh'}
|
h={h?h:'100vh'}
|
||||||
display={'flex'}
|
display={'flex'}
|
||||||
justifyContent={'center'}
|
justifyContent={'center'}
|
||||||
alignItems={'center'}
|
alignItems={'center'}
|
||||||
flexDirection={'column'}
|
flexDirection={'column'}
|
||||||
gap={8}
|
gap={8}
|
||||||
>
|
>
|
||||||
<Image src={robot} w={"171px"} />
|
<Image src={robot} w={200} />
|
||||||
{/* <Text color={'green.800'} as={'span'} fontSize={'small'}>The requested URL was not found on this server.</Text> */}
|
<Text color={'green.800'} as={'span'} mt={4} fontSize={'small'}>🚧 Building Something Amazing Just for You! 🚧</Text>
|
||||||
</Box>
|
</Box>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
63
src/Pages/Welcome.jsx
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import welcome from '../assets/welcome.avif';
|
||||||
|
import welcome2 from '../assets/welcome2.avif';
|
||||||
|
import welcome3 from '../assets/welcome3.avif';
|
||||||
|
import welcome4 from '../assets/welcome4.avif';
|
||||||
|
import { Box, Button, Image } from '@chakra-ui/react';
|
||||||
|
import logo from "../../src/assets/logo.png"
|
||||||
|
|
||||||
|
const Welcome = () => {
|
||||||
|
return (
|
||||||
|
<Box position="relative" h="100vh">
|
||||||
|
<div id="carouselExampleSlidesOnly" className="carousel slide" data-bs-ride="carousel">
|
||||||
|
<div className="carousel-inner">
|
||||||
|
<div className="carousel-item active" data-bs-interval="3000">
|
||||||
|
<img src={welcome4} className="d-block w-100" alt="Welcome 2" />
|
||||||
|
</div>
|
||||||
|
<div className="carousel-item" data-bs-interval="3000">
|
||||||
|
<img src={welcome3} className="d-block w-100" alt="Welcome 3" />
|
||||||
|
</div>
|
||||||
|
<div className="carousel-item" data-bs-interval="3000">
|
||||||
|
<img src={welcome2} className="d-block w-100" alt="Welcome 4" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/* <a className="carousel-control-prev" href="#carouselExampleSlidesOnly" role="button" data-bs-slide="prev">
|
||||||
|
<span className="carousel-control-prev-icon" aria-hidden="true"></span>
|
||||||
|
<span className="visually-hidden">Previous</span>
|
||||||
|
</a>
|
||||||
|
<a className="carousel-control-next" href="#carouselExampleSlidesOnly" role="button" data-bs-slide="next">
|
||||||
|
<span className="carousel-control-next-icon" aria-hidden="true"></span>
|
||||||
|
<span className="visually-hidden">Next</span>
|
||||||
|
</a> */}
|
||||||
|
</div>
|
||||||
|
<Box
|
||||||
|
opacity={1}
|
||||||
|
bgGradient="linear(to-b, rgba(0, 0, 0, 0.5), #0047178e 100%)"
|
||||||
|
zIndex={999}
|
||||||
|
position="absolute"
|
||||||
|
top={0}
|
||||||
|
left={0}
|
||||||
|
w="100%"
|
||||||
|
h="100%"
|
||||||
|
display={'flex'}
|
||||||
|
justifyContent={'center'}
|
||||||
|
alignItems={'center'}
|
||||||
|
>
|
||||||
|
<Image src={logo} />
|
||||||
|
|
||||||
|
{/* <Box
|
||||||
|
position="absolute"
|
||||||
|
bottom={12}
|
||||||
|
right={0}
|
||||||
|
p={4} // Adjust padding as needed
|
||||||
|
>
|
||||||
|
<Button color={'#004717'} size={'lg'} bg="white" variant="solid">
|
||||||
|
Let's get started
|
||||||
|
</Button>
|
||||||
|
</Box> */}
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Welcome;
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import { HiOutlineNewspaper } from "react-icons/hi";
|
import { HiOutlineNewspaper } from "react-icons/hi";
|
||||||
import { TbBrandMedium, TbChartHistogram, TbReportMoney } from "react-icons/tb";
|
import { TbBrandMedium, TbChartHistogram, TbLayoutDashboard, TbReportMoney } from "react-icons/tb";
|
||||||
import {
|
import {
|
||||||
RiBankLine,
|
RiBankLine,
|
||||||
RiFileUserLine,
|
RiFileUserLine,
|
||||||
@@ -26,6 +26,12 @@ import { LiaCrownSolid } from "react-icons/lia";
|
|||||||
import { PiCrownDuotone } from "react-icons/pi";
|
import { PiCrownDuotone } from "react-icons/pi";
|
||||||
|
|
||||||
export const nav = [
|
export const nav = [
|
||||||
|
// {
|
||||||
|
// title: "Dashboard",
|
||||||
|
// type: "single",
|
||||||
|
// path: "/",
|
||||||
|
// Icon: TbLayoutDashboard,
|
||||||
|
// },
|
||||||
{
|
{
|
||||||
title: "MASTER MENU",
|
title: "MASTER MENU",
|
||||||
type: "title",
|
type: "title",
|
||||||
|
|||||||
@@ -31,6 +31,9 @@ import InvestmentType from "../Pages/Master/InvestmentType/InvestmentType";
|
|||||||
import DepositRequest from "../Pages/Deposit/DepositRequest/DepositRequest";
|
import DepositRequest from "../Pages/Deposit/DepositRequest/DepositRequest";
|
||||||
import EditBankDetails from "../Pages/Admin/BankDetails/EditBankDetails";
|
import EditBankDetails from "../Pages/Admin/BankDetails/EditBankDetails";
|
||||||
import ExchangeHistory from "../Pages/Master/ExchangeRate/ExchangeHistroy";
|
import ExchangeHistory from "../Pages/Master/ExchangeRate/ExchangeHistroy";
|
||||||
|
import Welcome from "../Pages/Welcome";
|
||||||
|
import Dashbaord from "../Pages/Dashbaord";
|
||||||
|
import UnderConstruction from "../Pages/UnderConstruction";
|
||||||
|
|
||||||
export const RouteLink = [
|
export const RouteLink = [
|
||||||
// =============[ Tanami ]================
|
// =============[ Tanami ]================
|
||||||
@@ -46,10 +49,6 @@ export const RouteLink = [
|
|||||||
{ path: "/exchange-rate", Component: ExchangeRate },
|
{ path: "/exchange-rate", Component: ExchangeRate },
|
||||||
{ path: "/exchange-rate/currency-history/:id", Component: ExchangeHistory },
|
{ path: "/exchange-rate/currency-history/:id", Component: ExchangeHistory },
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{ path: "/investment-type", Component: InvestmentType },
|
{ path: "/investment-type", Component: InvestmentType },
|
||||||
{ path: "/investment-type/add-investment/:id", Component: AddInvestmentType },
|
{ path: "/investment-type/add-investment/:id", Component: AddInvestmentType },
|
||||||
{ path: "/investment-type/add-investment", Component: AddInvestmentType },
|
{ path: "/investment-type/add-investment", Component: AddInvestmentType },
|
||||||
@@ -66,30 +65,43 @@ export const RouteLink = [
|
|||||||
{ path: "/investor-details", Component: InvestorDetails },
|
{ path: "/investor-details", Component: InvestorDetails },
|
||||||
{ path: "/investor-details/profile-view/:id", Component: ProfileView },
|
{ path: "/investor-details/profile-view/:id", Component: ProfileView },
|
||||||
{ path: "/investor-details/view-investor-details", Component: ViewInvestorDetails },
|
{ path: "/investor-details/view-investor-details", Component: ViewInvestorDetails },
|
||||||
{ path: "/investor-transactions", Component: InvestorTransactions },
|
// { path: "/investor-transactions", Component: InvestorTransactions },
|
||||||
|
{ path: "/investor-transactions", Component: UnderConstruction },
|
||||||
|
|
||||||
// ===============[ Deposit ]===============
|
// ===============[ Deposit ]===============
|
||||||
{ path: "/deposit-request", Component: DepositRequest },
|
{ path: "/deposit-request", Component: DepositRequest },
|
||||||
{ path: "/deposit-history", Component: DepositHistory },
|
{ path: "/deposit-history", Component: DepositHistory },
|
||||||
|
|
||||||
// ===============[ Withdrawal]===============
|
// ===============[ Withdrawal]===============
|
||||||
{ path: "/withdraw-request", Component: PendingRequest },
|
// { path: "/withdraw-request", Component: PendingRequest },
|
||||||
{ path: "/withdraw-history", Component: ViewHistory },
|
{ path: "/withdraw-request", Component: UnderConstruction },
|
||||||
|
// { path: "/withdraw-history", Component: ViewHistory },
|
||||||
|
{ path: "/withdraw-history", Component: UnderConstruction },
|
||||||
|
|
||||||
// ===============[ Withdrawal]===============
|
// ===============[ Withdrawal]===============
|
||||||
{ path: "/investor-history", Component: UpgradeHistory },
|
// { path: "/investor-history", Component: UpgradeHistory },
|
||||||
{ path: "/investor-request", Component: InvestorPendingRequest },
|
{ path: "/investor-history", Component: UnderConstruction },
|
||||||
|
// { path: "/investor-request", Component: InvestorPendingRequest },
|
||||||
|
{ path: "/investor-request", Component: UnderConstruction },
|
||||||
|
|
||||||
// ===============[ Deletion]===============
|
// ===============[ Deletion]===============
|
||||||
{ path: "/deletion-request", Component: DeletionRequest },
|
// { path: "/deletion-request", Component: DeletionRequest },
|
||||||
{ path: "/deletion-history", Component: DeletionHistory },
|
{ path: "/deletion-request", Component: UnderConstruction },
|
||||||
|
// { path: "/deletion-history", Component: DeletionHistory },
|
||||||
|
{ path: "/deletion-history", Component: UnderConstruction },
|
||||||
|
|
||||||
// ===============[ Admin]===============
|
// ===============[ Admin]===============
|
||||||
{ path: "/bank-investor", Component: BankInvestor },
|
// { path: "/bank-investor", Component: BankInvestor },
|
||||||
{ path: "/academy", Component: Academy },
|
{ path: "/bank-investor", Component: UnderConstruction },
|
||||||
{ path: "/notification", Component: Notification },
|
// { path: "/academy", Component: Academy },
|
||||||
{ path: "/contact", Component: Contact },
|
{ path: "/academy", Component: UnderConstruction },
|
||||||
{ path: "/users", Component: Users },
|
// { path: "/notification", Component: Notification },
|
||||||
{ path: "/bank-details", Component: BankDetails },
|
{ path: "/notification", Component: UnderConstruction },
|
||||||
|
// { path: "/contact", Component: Contact },
|
||||||
|
{ path: "/contact", Component: UnderConstruction },
|
||||||
|
// { path: "/users", Component: Users },
|
||||||
|
{ path: "/users", Component: UnderConstruction },
|
||||||
|
// { path: "/bank-details", Component: BankDetails },
|
||||||
|
{ path: "/bank-details", Component: UnderConstruction },
|
||||||
{ path: "/bank-details/edit-bank-details/:id", Component: EditBankDetails },
|
{ path: "/bank-details/edit-bank-details/:id", Component: EditBankDetails },
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
// io.service.js
|
// io.service.js
|
||||||
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
|
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
|
||||||
import { api } from "./api.service";
|
// import { api } from "./api.service";
|
||||||
|
import { baseQuery } from "./token.serivce";
|
||||||
|
|
||||||
const baseUrl = api?.defaults.baseURL;
|
// const baseUrl = api?.defaults.baseURL;
|
||||||
|
|
||||||
export const keyMerits = createApi({
|
export const keyMerits = createApi({
|
||||||
reducerPath: "ioService",
|
reducerPath: "ioService",
|
||||||
baseQuery: fetchBaseQuery({ baseUrl }),
|
baseQuery: baseQuery,
|
||||||
tagTypes: ["getKeyMerits"],
|
tagTypes: ["getKeyMerits"],
|
||||||
endpoints: (builder) => ({
|
endpoints: (builder) => ({
|
||||||
// =====[get]
|
// =====[get]
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import axios from "axios";
|
|||||||
// Create an Axios instance for API calls
|
// Create an Axios instance for API calls
|
||||||
export const api = axios.create({
|
export const api = axios.create({
|
||||||
// baseURL: `https://tanami.betadelivery.com/api/v1`,
|
// baseURL: `https://tanami.betadelivery.com/api/v1`,
|
||||||
baseURL: `https://tanami.betadelivery.com/api/v1`, // Replace with your API base URL
|
baseURL: import.meta.env.VITE_BAS_URL, // Replace with your API base URL
|
||||||
timeout: 10000, // Adjust timeout as needed
|
timeout: 10000, // Adjust timeout as needed
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
@@ -49,8 +49,8 @@ api.interceptors.response.use(
|
|||||||
|
|
||||||
if (response.status === 200) {
|
if (response.status === 200) {
|
||||||
// Update tokens in local storage
|
// Update tokens in local storage
|
||||||
localStorage.setItem("accessToken", response.data.accessToken);
|
localStorage.setItem("accessTokenn", response.data.accessToken);
|
||||||
localStorage.setItem("refreshToken", response.data.refreshToken);
|
localStorage.setItem("refreshTokenn", response.data.refreshToken);
|
||||||
|
|
||||||
// Retry the original request with the new tokens
|
// Retry the original request with the new tokens
|
||||||
return api(originalRequest);
|
return api(originalRequest);
|
||||||
|
|||||||
@@ -1,14 +1,16 @@
|
|||||||
// investorDetails.service.js
|
// investorDetails.service.js
|
||||||
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
|
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
|
||||||
import { api } from "./api.service";
|
// import { api } from "./api.service";
|
||||||
|
import { baseQuery } from "./token.serivce";
|
||||||
|
|
||||||
const baseUrl = api?.defaults.baseURL;
|
// const baseUrl = api?.defaults.baseURL;
|
||||||
|
|
||||||
// Define a service using a base URL and expected endpoints
|
// Define a service using a base URL and expected endpoints
|
||||||
export const bankDetails = createApi({
|
export const bankDetails = createApi({
|
||||||
reducerPath: "bankDetails",
|
reducerPath: "bankDetails",
|
||||||
baseQuery: fetchBaseQuery({ baseUrl }),
|
baseQuery: baseQuery,
|
||||||
tagTypes: [],
|
tagTypes: ["getBank"],
|
||||||
|
|
||||||
endpoints: (builder) => ({
|
endpoints: (builder) => ({
|
||||||
|
|
||||||
getBank: builder.query({
|
getBank: builder.query({
|
||||||
@@ -25,7 +27,7 @@ export const bankDetails = createApi({
|
|||||||
method: "PATCH",
|
method: "PATCH",
|
||||||
body: data,
|
body: data,
|
||||||
}),
|
}),
|
||||||
invalidatesTags: ["getBankDetails"],
|
invalidatesTags: ["getBank"],
|
||||||
}),
|
}),
|
||||||
|
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -1,24 +1,37 @@
|
|||||||
// investorDetails.service.js
|
// investorDetails.service.js
|
||||||
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
|
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
|
||||||
import { api } from "./api.service";
|
// import { api } from "./api.service";
|
||||||
|
import { baseQuery } from "./token.serivce";
|
||||||
|
|
||||||
const baseUrl = api?.defaults.baseURL;
|
// const baseUrl = api?.defaults.baseURL;
|
||||||
|
|
||||||
// Define a service using a base URL and expected endpoints
|
// Define a service using a base URL and expected endpoints
|
||||||
export const contact = createApi({
|
export const contact = createApi({
|
||||||
reducerPath: "contact",
|
reducerPath: "contact",
|
||||||
baseQuery: fetchBaseQuery({ baseUrl }),
|
baseQuery: baseQuery,
|
||||||
tagTypes: [],
|
tagTypes: ["getContact"],
|
||||||
endpoints: (builder) => ({
|
endpoints: (builder) => ({
|
||||||
|
|
||||||
getContact: builder.query({
|
getContact: builder.query({
|
||||||
query: ({ page, size }) =>
|
query: () =>
|
||||||
`/contactDetails/admin/?page=${page}&size=${size}`,
|
`/contactDetails/admin`,
|
||||||
providesTags: ["getContact"],
|
providesTags: ["getContact"],
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
|
||||||
|
// ========[Update Investment]=======
|
||||||
|
|
||||||
|
updateContact: builder.mutation({
|
||||||
|
query: (data) => ({
|
||||||
|
url: `/contactDetails/admin/`,
|
||||||
|
method: "PATCH",
|
||||||
|
body: data,
|
||||||
|
}),
|
||||||
|
invalidatesTags: ["getContact"],
|
||||||
|
}),
|
||||||
|
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
// Export hooks for usage in functional components
|
// Export hooks for usage in functional components
|
||||||
export const { useGetContactQuery } = contact;
|
export const { useGetContactQuery, useUpdateContactMutation } = contact;
|
||||||
|
|||||||
55
src/Services/deposit.request.service.js
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
// investorDetails.service.js
|
||||||
|
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
|
||||||
|
// import { api } from "./api.service";
|
||||||
|
import { baseQuery } from "./token.serivce";
|
||||||
|
|
||||||
|
// const baseUrl = api?.defaults.baseURL;
|
||||||
|
|
||||||
|
// Define a service using a base URL and expected endpoints
|
||||||
|
export const depositRequest = createApi({
|
||||||
|
reducerPath: "depositRequest",
|
||||||
|
baseQuery: baseQuery,
|
||||||
|
tagTypes: ["getDepositRequest", "getDepositHistory"],
|
||||||
|
endpoints: (builder) => ({
|
||||||
|
getDepositRequest: builder.query({
|
||||||
|
query: () => `/deposit/admin/pending-requests`,
|
||||||
|
providesTags: ["getDepositRequest"],
|
||||||
|
}),
|
||||||
|
|
||||||
|
getDepositRequestById: builder.query({
|
||||||
|
query: (id) => `/deposit/admin/getById/${id}`,
|
||||||
|
}),
|
||||||
|
|
||||||
|
updateDepositRequest: builder.mutation({
|
||||||
|
query: ({ id, data }) => ({
|
||||||
|
url: `/deposit/admin/approved/${id}`,
|
||||||
|
method: "PATCH",
|
||||||
|
body: data,
|
||||||
|
}),
|
||||||
|
invalidatesTags: ["getDepositRequest", "getDepositHistory"],
|
||||||
|
}),
|
||||||
|
|
||||||
|
depositReject: builder.mutation({
|
||||||
|
query: ({ id, data }) => ({
|
||||||
|
url: `/deposit/admin/rejected/${id}`,
|
||||||
|
method: "PATCH",
|
||||||
|
body: data,
|
||||||
|
}),
|
||||||
|
invalidatesTags: ["getDepositRequest", "getDepositHistory"],
|
||||||
|
}),
|
||||||
|
|
||||||
|
getDepositHistory: builder.query({
|
||||||
|
query: () => `/deposit/admin/history`,
|
||||||
|
providesTags: ["getDepositHistory"],
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
// Export hooks for usage in functional components
|
||||||
|
export const {
|
||||||
|
useGetDepositRequestQuery,
|
||||||
|
useGetDepositRequestByIdQuery,
|
||||||
|
useUpdateDepositRequestMutation,
|
||||||
|
useDepositRejectMutation,
|
||||||
|
useGetDepositHistoryQuery,
|
||||||
|
} = depositRequest;
|
||||||
101
src/Services/deposite.service.js
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
//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 = api?.defaults.baseURL;
|
||||||
|
|
||||||
|
// const baseUrl = `${import.meta.env.VITE_API_BASE_URL}/${import.meta.env.VITE_API_VERSION}`
|
||||||
|
|
||||||
|
// Define a service using a base URL and expected endpoints
|
||||||
|
export const deposite = createApi({
|
||||||
|
reducerPath: "deposite",
|
||||||
|
baseQuery: fetchBaseQuery({ baseUrl: baseUrl }),
|
||||||
|
tagTypes: ["gtDeposite"],
|
||||||
|
endpoints: (builder) => ({
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ======[Get All]=====
|
||||||
|
|
||||||
|
getSponserMaster: builder.query({
|
||||||
|
query: ({ page, size }) => `/sponsor/admin?page=${page}&size=${size}`,
|
||||||
|
providesTags: ["getSponser"],
|
||||||
|
}),
|
||||||
|
|
||||||
|
|
||||||
|
// ========[Get Active]========
|
||||||
|
|
||||||
|
getActiveSponserMaster: builder.query({
|
||||||
|
query: () => `/sponsor/admin/active`,
|
||||||
|
providesTags: ["getSponser"],
|
||||||
|
}),
|
||||||
|
|
||||||
|
getSponserMasterActive: builder.query({
|
||||||
|
query: () => "/sponsor/admin/active",
|
||||||
|
}),
|
||||||
|
|
||||||
|
|
||||||
|
// ======[Get ID]=====
|
||||||
|
|
||||||
|
getSponserById: builder.query({
|
||||||
|
query: (id) => `/sponsor/admin/${id}`,
|
||||||
|
providesTags: ["getSponser"],
|
||||||
|
}),
|
||||||
|
|
||||||
|
// ========[Toggle Status]========
|
||||||
|
|
||||||
|
toggleStatus: builder.mutation({
|
||||||
|
query: ({ id }) => ({
|
||||||
|
url: `/sponsor/admin/toggle-status/${id}`,
|
||||||
|
method: "PATCH",
|
||||||
|
}),
|
||||||
|
invalidatesTags: ["getSponser"],
|
||||||
|
}),
|
||||||
|
|
||||||
|
// ========[Create Sponser]========
|
||||||
|
|
||||||
|
createSponser: builder.mutation({
|
||||||
|
query: (data) => ({
|
||||||
|
url: `/sponsor/admin`,
|
||||||
|
method: "POST",
|
||||||
|
body: data,
|
||||||
|
}),
|
||||||
|
invalidatesTags: ["getSponser"],
|
||||||
|
}),
|
||||||
|
|
||||||
|
// ========[Update Sponser]========
|
||||||
|
|
||||||
|
updateSponser: builder.mutation({
|
||||||
|
query: ({ data, id }) => ({
|
||||||
|
url: `/sponsor/admin/${id}`,
|
||||||
|
method: "PATCH",
|
||||||
|
body: data,
|
||||||
|
}),
|
||||||
|
invalidatesTags: ["getSponser"],
|
||||||
|
}),
|
||||||
|
|
||||||
|
// ========[Delete Sponser]========
|
||||||
|
|
||||||
|
deleteSponser: builder.mutation({
|
||||||
|
query: (id) => ({
|
||||||
|
url: `/sponsor/admin/delete/${id}`,
|
||||||
|
method: "DELETE",
|
||||||
|
}),
|
||||||
|
invalidatesTags: ["getSponser"],
|
||||||
|
}),
|
||||||
|
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
// Export hooks for usage in functional components
|
||||||
|
export const {
|
||||||
|
useGetSponserMasterQuery,
|
||||||
|
useGetSponserMasterActiveQuery,
|
||||||
|
useToggleStatusMutation,
|
||||||
|
useCreateSponserMutation,
|
||||||
|
useUpdateSponserMutation,
|
||||||
|
useGetSponserByIdQuery,
|
||||||
|
useDeleteSponserMutation,
|
||||||
|
useGetActiveSponserMasterQuery
|
||||||
|
} = sponserMaster;
|
||||||
@@ -1,13 +1,14 @@
|
|||||||
// exchangeRate.service.js
|
// exchangeRate.service.js
|
||||||
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
|
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
|
||||||
import { api } from "./api.service";
|
// import { api } from "./api.service";
|
||||||
|
import { baseQuery } from "./token.serivce";
|
||||||
|
|
||||||
const baseUrl = api?.defaults.baseURL;
|
// const baseUrl = api?.defaults.baseURL;
|
||||||
|
|
||||||
// Define a service using a base URL and expected endpoints
|
// Define a service using a base URL and expected endpoints
|
||||||
export const exchangeRate = createApi({
|
export const exchangeRate = createApi({
|
||||||
reducerPath: "exchangeRate",
|
reducerPath: "exchangeRate",
|
||||||
baseQuery: fetchBaseQuery({ baseUrl }),
|
baseQuery: baseQuery,
|
||||||
tagTypes: ["getAllExchangeRate", "getExchangeById"],
|
tagTypes: ["getAllExchangeRate", "getExchangeById"],
|
||||||
|
|
||||||
endpoints: (builder) => ({
|
endpoints: (builder) => ({
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
// io.service.js
|
// io.service.js
|
||||||
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
|
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
|
||||||
import { api } from "./api.service";
|
// import { api } from "./api.service";
|
||||||
|
import { baseQuery } from "./token.serivce";
|
||||||
|
|
||||||
const baseUrl = api?.defaults.baseURL;
|
// const baseUrl = api?.defaults.baseURL;
|
||||||
|
|
||||||
export const ioService = createApi({
|
export const ioService = createApi({
|
||||||
reducerPath: "ioService",
|
reducerPath: "ioService",
|
||||||
baseQuery: fetchBaseQuery({ baseUrl }),
|
baseQuery: baseQuery,
|
||||||
tagTypes: ["getInvestmentDocuments"],
|
tagTypes: ["getInvestmentDocuments"],
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
// investmentType.service.js
|
// investmentType.service.js
|
||||||
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
|
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
|
||||||
import { api } from "./api.service";
|
// import { api } from "./api.service";
|
||||||
|
import { baseQuery } from "./token.serivce";
|
||||||
|
|
||||||
const baseUrl = api?.defaults.baseURL;
|
// const baseUrl = api?.defaults.baseURL;
|
||||||
|
|
||||||
// Define a service using a base URL and expected endpoints
|
// Define a service using a base URL and expected endpoints
|
||||||
export const investmentType = createApi({
|
export const investmentType = createApi({
|
||||||
reducerPath: "investmentType",
|
reducerPath: "investmentType",
|
||||||
baseQuery: fetchBaseQuery({ baseUrl }),
|
baseQuery: baseQuery,
|
||||||
tagTypes: ["getInvestmentType", "getInvestmentTypeID"],
|
tagTypes: ["getInvestmentType", "getInvestmentTypeID"],
|
||||||
endpoints: (builder) => ({
|
endpoints: (builder) => ({
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
// investorDetails.service.js
|
// investorDetails.service.js
|
||||||
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
|
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
|
||||||
import { api } from "./api.service";
|
// import { api } from "./api.service";
|
||||||
|
import { baseQuery } from "./token.serivce";
|
||||||
|
|
||||||
const baseUrl = api?.defaults.baseURL;
|
// const baseUrl = api?.defaults.baseURL;
|
||||||
|
|
||||||
// Define a service using a base URL and expected endpoints
|
// Define a service using a base URL and expected endpoints
|
||||||
export const investorDetails = createApi({
|
export const investorDetails = createApi({
|
||||||
reducerPath: "investorDetails",
|
reducerPath: "investorDetails",
|
||||||
baseQuery: fetchBaseQuery({ baseUrl }),
|
baseQuery: baseQuery,
|
||||||
tagTypes: [],
|
tagTypes: [],
|
||||||
endpoints: (builder) => ({
|
endpoints: (builder) => ({
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
// investorTransaction.service.js
|
// investorTransaction.service.js
|
||||||
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
|
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
|
||||||
|
import { baseQuery } from "./token.serivce";
|
||||||
|
|
||||||
const baseUrl = import.meta.env.VITE_API_BASE_URL + "/api";
|
// const baseUrl = import.meta.env.VITE_API_BASE_URL + "/api";
|
||||||
|
|
||||||
// Define a service using a base URL and expected endpoints
|
// Define a service using a base URL and expected endpoints
|
||||||
export const investorTransaction = createApi({
|
export const investorTransaction = createApi({
|
||||||
reducerPath: "investorTransaction",
|
reducerPath: "investorTransaction",
|
||||||
baseQuery: fetchBaseQuery({ baseUrl }),
|
baseQuery: baseQuery,
|
||||||
tagTypes: [],
|
tagTypes: [],
|
||||||
endpoints: (builder) => ({
|
endpoints: (builder) => ({
|
||||||
getTransactions: builder.query({
|
getTransactions: builder.query({
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
// io.service.js
|
// io.service.js
|
||||||
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
|
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
|
||||||
import { api } from "./api.service";
|
// import { api } from "./api.service";
|
||||||
|
import { baseQuery } from "./token.serivce";
|
||||||
|
|
||||||
const baseUrl = api?.defaults.baseURL;
|
// const baseUrl = api?.defaults.baseURL;
|
||||||
// Define a service using a base URL and expected endpoints
|
// Define a service using a base URL and expected endpoints
|
||||||
export const ioService = createApi({
|
export const ioService = createApi({
|
||||||
reducerPath: "ioService",
|
reducerPath: "ioService",
|
||||||
baseQuery: fetchBaseQuery({ baseUrl }),
|
baseQuery: baseQuery,
|
||||||
tagTypes: [
|
tagTypes: [
|
||||||
"prePopulate",
|
"prePopulate",
|
||||||
"getIO",
|
"getIO",
|
||||||
@@ -49,7 +50,7 @@ export const ioService = createApi({
|
|||||||
method: "PATCH",
|
method: "PATCH",
|
||||||
body: data,
|
body: data,
|
||||||
}),
|
}),
|
||||||
invalidatesTags: ["getIOById"],
|
invalidatesTags: ["getIOById", "getIO","prePopulate"],
|
||||||
}),
|
}),
|
||||||
|
|
||||||
// =====[Key Merits]
|
// =====[Key Merits]
|
||||||
@@ -57,6 +58,7 @@ export const ioService = createApi({
|
|||||||
query: (id) => `/io/admin/key-merits/${id}`,
|
query: (id) => `/io/admin/key-merits/${id}`,
|
||||||
providesTags: ["getKeyMerits"],
|
providesTags: ["getKeyMerits"],
|
||||||
}),
|
}),
|
||||||
|
|
||||||
createKeyMerits: builder.mutation({
|
createKeyMerits: builder.mutation({
|
||||||
query: ({ data, id }) => ({
|
query: ({ data, id }) => ({
|
||||||
url: `/io/admin/key-merits/${id}`,
|
url: `/io/admin/key-merits/${id}`,
|
||||||
@@ -64,7 +66,7 @@ export const ioService = createApi({
|
|||||||
body: data,
|
body: data,
|
||||||
// No need to manually set 'Content-Type'
|
// No need to manually set 'Content-Type'
|
||||||
}),
|
}),
|
||||||
invalidatesTags: ["getKeyMerits"],
|
invalidatesTags: ["getIOById"],
|
||||||
}),
|
}),
|
||||||
|
|
||||||
deleteKeyMerits: builder.mutation({
|
deleteKeyMerits: builder.mutation({
|
||||||
@@ -72,15 +74,16 @@ export const ioService = createApi({
|
|||||||
url: `/io/admin/key-merits/hard-delete/${id}`,
|
url: `/io/admin/key-merits/hard-delete/${id}`,
|
||||||
method: "DELETE",
|
method: "DELETE",
|
||||||
}),
|
}),
|
||||||
invalidatesTags: ["getKeyMerits"],
|
invalidatesTags: ["getIOById"],
|
||||||
}),
|
}),
|
||||||
|
|
||||||
updateKeyMerits: builder.mutation({
|
updateKeyMerits: builder.mutation({
|
||||||
query: ({ data, id }) => ({
|
query: ({ data, id }) => ({
|
||||||
url: `/io/admin/key-merits/byId/${id}`,
|
url: `/io/admin/key-merits/byId/${id}`,
|
||||||
method: "PATCH",
|
method: "PATCH",
|
||||||
body: data,
|
body: data,
|
||||||
}),
|
}),
|
||||||
invalidatesTags: ["getKeyMerits"],
|
invalidatesTags: ["getIOById"],
|
||||||
}),
|
}),
|
||||||
|
|
||||||
// =====[getIODocument]
|
// =====[getIODocument]
|
||||||
@@ -91,7 +94,7 @@ export const ioService = createApi({
|
|||||||
body: data,
|
body: data,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
invalidatesTags: ["getInvestmentDocuments"],
|
invalidatesTags: ["getIOById"],
|
||||||
}),
|
}),
|
||||||
|
|
||||||
updateInvestmentDocuments: builder.mutation({
|
updateInvestmentDocuments: builder.mutation({
|
||||||
@@ -100,7 +103,7 @@ export const ioService = createApi({
|
|||||||
method: "PATCH",
|
method: "PATCH",
|
||||||
body: data,
|
body: data,
|
||||||
}),
|
}),
|
||||||
invalidatesTags: ["getInvestmentDocuments"],
|
invalidatesTags: ["getIOById"],
|
||||||
}),
|
}),
|
||||||
|
|
||||||
getInvestmentDocuments: builder.query({
|
getInvestmentDocuments: builder.query({
|
||||||
@@ -113,7 +116,7 @@ export const ioService = createApi({
|
|||||||
url: `/io/admin/document/hard-delete/${id}`,
|
url: `/io/admin/document/hard-delete/${id}`,
|
||||||
method: "DELETE",
|
method: "DELETE",
|
||||||
}),
|
}),
|
||||||
invalidatesTags: ["getInvestmentDocuments"],
|
invalidatesTags: ["getIOById"],
|
||||||
}),
|
}),
|
||||||
|
|
||||||
// =====[Artifacts]
|
// =====[Artifacts]
|
||||||
@@ -125,23 +128,23 @@ export const ioService = createApi({
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
// =====[createImageArtifacts]
|
// =====[createImageArtifacts]
|
||||||
createImageArtifacts: builder.mutation({
|
createImageArtifacts: builder.mutation({
|
||||||
query: ({ data, id }) => ({
|
query: ({ data, id }) => ({
|
||||||
url: `/io/artifact/artifactImage/${id}`,
|
url: `/io/admin/artifact/image/${id}`,
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: data,
|
body: data,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
invalidatesTags: ["getIOById"],
|
invalidatesTags: ["getIOById"],
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
updateImageArtifacts: builder.mutation({
|
updateImageArtifacts: builder.mutation({
|
||||||
query: ({ data, id }) => ({
|
query: ({ data, id }) => ({
|
||||||
url: `/io/artifact/image/${id}`,
|
url: `/io/admin/artifact/image/byId/${id}`,
|
||||||
method: "PATCH",
|
method: "PATCH",
|
||||||
body: data,
|
body: data,
|
||||||
}),
|
}),
|
||||||
@@ -154,7 +157,7 @@ export const ioService = createApi({
|
|||||||
// =====[createVideoArtifacts]
|
// =====[createVideoArtifacts]
|
||||||
createVideoArtifacts: builder.mutation({
|
createVideoArtifacts: builder.mutation({
|
||||||
query: ({ data, id }) => ({
|
query: ({ data, id }) => ({
|
||||||
url: `/io/artifact/artifactVideo/${id}`,
|
url: `/io/admin/artifact/video/${id}`,
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: data,
|
body: data,
|
||||||
}),
|
}),
|
||||||
@@ -162,10 +165,9 @@ export const ioService = createApi({
|
|||||||
invalidatesTags: ["getIOById"],
|
invalidatesTags: ["getIOById"],
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
|
||||||
deleteVideoArtifacts: builder.mutation({
|
deleteVideoArtifacts: builder.mutation({
|
||||||
query: (id) => ({
|
query: (id) => ({
|
||||||
url: `/io/artifact/video/${id}`,
|
url: `/io/admin/artifact/video/byId/${id}`,
|
||||||
method: "DELETE",
|
method: "DELETE",
|
||||||
}),
|
}),
|
||||||
invalidatesTags: ["getIOById"],
|
invalidatesTags: ["getIOById"],
|
||||||
@@ -173,17 +175,15 @@ export const ioService = createApi({
|
|||||||
|
|
||||||
deleteImageArtifacts: builder.mutation({
|
deleteImageArtifacts: builder.mutation({
|
||||||
query: (id) => ({
|
query: (id) => ({
|
||||||
url: `/io/artifact/image/${id}`,
|
url: `/io/admin/artifact/image/byId/${id}`,
|
||||||
method: "DELETE",
|
method: "DELETE",
|
||||||
}),
|
}),
|
||||||
invalidatesTags: ["getIOById"],
|
invalidatesTags: ["getIOById"],
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
updateVideoArtifacts: builder.mutation({
|
updateVideoArtifacts: builder.mutation({
|
||||||
query: ({ data, id }) => ({
|
query: ({ data, id }) => ({
|
||||||
url: `/io/artifact/video/${id}`,
|
url: `/io/admin/artifact/video/byId/${id}`,
|
||||||
method: "PATCH",
|
method: "PATCH",
|
||||||
body: data,
|
body: data,
|
||||||
}),
|
}),
|
||||||
@@ -208,6 +208,52 @@ export const ioService = createApi({
|
|||||||
invalidatesTags: ["getIOById", 'getIO'],
|
invalidatesTags: ["getIOById", 'getIO'],
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
createIoCash: builder.mutation({
|
||||||
|
query: ({ data, id }) => ({
|
||||||
|
url: `/io/admin/io-cash/${id}`,
|
||||||
|
method: "POST",
|
||||||
|
body: data,
|
||||||
|
}),
|
||||||
|
|
||||||
|
invalidatesTags: ["getIOById"],
|
||||||
|
}),
|
||||||
|
|
||||||
|
|
||||||
|
createIoNav: builder.mutation({
|
||||||
|
query: ({ data, id }) => ({
|
||||||
|
url: `/io/admin/io-nav/${id}`,
|
||||||
|
method: "POST",
|
||||||
|
body: data,
|
||||||
|
}),
|
||||||
|
|
||||||
|
invalidatesTags: ["getIOById"],
|
||||||
|
}),
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// =====[ Amount Investment ] ======
|
||||||
|
amountIvestment : builder.mutation({
|
||||||
|
query: ({ data, id }) => ({
|
||||||
|
url: `/io/admin/amount-invested/${id}`,
|
||||||
|
method: "POST",
|
||||||
|
body: data,
|
||||||
|
}),
|
||||||
|
invalidatesTags: ["getIOById"],
|
||||||
|
}),
|
||||||
|
|
||||||
|
|
||||||
|
// ======== [ Distribution Transaction ] ========
|
||||||
|
|
||||||
|
|
||||||
|
getDistributionInvestor : builder.mutation({
|
||||||
|
query: ({id,data}) => ({
|
||||||
|
url: `/io/admin/io-distribution/pre-populate/${id}`,
|
||||||
|
method: "POST",
|
||||||
|
body: data,
|
||||||
|
}),
|
||||||
|
invalidatesTags: ["getIOById"],
|
||||||
|
}),
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -250,6 +296,16 @@ export const {
|
|||||||
useSetDisplayOrderMutation,
|
useSetDisplayOrderMutation,
|
||||||
|
|
||||||
|
|
||||||
|
useCreateIoCashMutation,
|
||||||
|
useCreateIoNavMutation,
|
||||||
|
|
||||||
useUpdateStatusIoMutation
|
|
||||||
|
|
||||||
|
useUpdateStatusIoMutation,
|
||||||
|
|
||||||
|
|
||||||
|
useAmountIvestmentMutation,
|
||||||
|
|
||||||
|
|
||||||
|
useGetDistributionInvestorMutation,
|
||||||
} = ioService;
|
} = ioService;
|
||||||
|
|||||||
@@ -1,17 +1,23 @@
|
|||||||
//sponser.service
|
//sponser.service
|
||||||
// Need to use the React-specific entry point to import createApi
|
// Need to use the React-specific entry point to import createApi
|
||||||
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
|
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
|
||||||
import { api } from "./api.service";
|
// import { api } from "./api.service";
|
||||||
|
import { baseQuery } from "./token.serivce";
|
||||||
|
import { ioService } from "./io.service";
|
||||||
|
|
||||||
|
// const baseUrl = api?.defaults.baseURL;
|
||||||
|
|
||||||
|
|
||||||
const baseUrl = api?.defaults.baseURL;
|
|
||||||
|
|
||||||
// const baseUrl = `${import.meta.env.VITE_API_BASE_URL}/${import.meta.env.VITE_API_VERSION}`
|
// const baseUrl = `${import.meta.env.VITE_API_BASE_URL}/${import.meta.env.VITE_API_VERSION}`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Define a service using a base URL and expected endpoints
|
// Define a service using a base URL and expected endpoints
|
||||||
export const sponserMaster = createApi({
|
export const sponserMaster = createApi({
|
||||||
reducerPath: "sponserMaster",
|
reducerPath: "sponserMaster",
|
||||||
baseQuery: fetchBaseQuery({ baseUrl: baseUrl }),
|
baseQuery: baseQuery,
|
||||||
tagTypes: ["getSponser"],
|
tagTypes: ["getSponser", "prePopulate"],
|
||||||
endpoints: (builder) => ({
|
endpoints: (builder) => ({
|
||||||
|
|
||||||
|
|
||||||
@@ -28,7 +34,6 @@ export const sponserMaster = createApi({
|
|||||||
|
|
||||||
getActiveSponserMaster: builder.query({
|
getActiveSponserMaster: builder.query({
|
||||||
query: () => `/sponsor/admin/active`,
|
query: () => `/sponsor/admin/active`,
|
||||||
providesTags: ["getSponser"],
|
|
||||||
}),
|
}),
|
||||||
|
|
||||||
getSponserMasterActive: builder.query({
|
getSponserMasterActive: builder.query({
|
||||||
@@ -40,7 +45,6 @@ export const sponserMaster = createApi({
|
|||||||
|
|
||||||
getSponserById: builder.query({
|
getSponserById: builder.query({
|
||||||
query: (id) => `/sponsor/admin/${id}`,
|
query: (id) => `/sponsor/admin/${id}`,
|
||||||
providesTags: ["getSponser"],
|
|
||||||
}),
|
}),
|
||||||
|
|
||||||
// ========[Toggle Status]========
|
// ========[Toggle Status]========
|
||||||
@@ -61,7 +65,7 @@ export const sponserMaster = createApi({
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
body: data,
|
body: data,
|
||||||
}),
|
}),
|
||||||
invalidatesTags: ["getSponser"],
|
invalidatesTags: ["getSponser","prePopulate"],
|
||||||
}),
|
}),
|
||||||
|
|
||||||
// ========[Update Sponser]========
|
// ========[Update Sponser]========
|
||||||
|
|||||||
113
src/Services/token.serivce.js
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
|
||||||
|
|
||||||
|
// Define a base query function with RTK Query
|
||||||
|
// export const baseQuery = fetchBaseQuery({
|
||||||
|
// baseUrl: 'https://sprint4.tanami.betadelivery.com/api/v1',
|
||||||
|
// prepareHeaders: (headers) => {
|
||||||
|
// const token = localStorage.getItem('accessToken');
|
||||||
|
// if (token) {
|
||||||
|
// headers.set('x-auth-token', `${token}`);
|
||||||
|
// }
|
||||||
|
// return headers;
|
||||||
|
// },
|
||||||
|
// });
|
||||||
|
|
||||||
|
// Define a base query function with token refresh logic
|
||||||
|
export const baseQuery = async (args, api, extraOptions) => {
|
||||||
|
let result = await fetchBaseQuery({
|
||||||
|
baseUrl: import.meta.env.VITE_BAS_URL,
|
||||||
|
prepareHeaders: (headers) => {
|
||||||
|
const token = localStorage.getItem("accessToken");
|
||||||
|
if (token) {
|
||||||
|
headers.set("x-auth-token", token);
|
||||||
|
}
|
||||||
|
return headers;
|
||||||
|
},
|
||||||
|
})(args, api, extraOptions);
|
||||||
|
|
||||||
|
if (result.error && result.error.status === 401) {
|
||||||
|
// Handle token refresh
|
||||||
|
const refreshToken = localStorage.getItem("refreshToken");
|
||||||
|
if (refreshToken) {
|
||||||
|
try {
|
||||||
|
const refreshResult = await fetchBaseQuery({
|
||||||
|
baseUrl: import.meta.env.VITE_BAS_URL,
|
||||||
|
})(
|
||||||
|
{
|
||||||
|
url: "/auth/user/regenerate-token",
|
||||||
|
method: "POST",
|
||||||
|
body: { refreshToken },
|
||||||
|
},
|
||||||
|
api,
|
||||||
|
extraOptions
|
||||||
|
);
|
||||||
|
|
||||||
|
if (refreshResult.data) {
|
||||||
|
// Save new tokens
|
||||||
|
localStorage.setItem("accessToken", refreshResult.data.access.token);
|
||||||
|
localStorage.setItem(
|
||||||
|
"refreshToken",
|
||||||
|
refreshResult.data.refresh.token
|
||||||
|
);
|
||||||
|
localStorage.setItem(
|
||||||
|
"refreshTokenExp",
|
||||||
|
refreshResult.data.refresh.expires
|
||||||
|
);
|
||||||
|
|
||||||
|
// Retry the original request with the new token
|
||||||
|
result = await fetchBaseQuery({
|
||||||
|
baseUrl: import.meta.env.VITE_BAS_URL,
|
||||||
|
prepareHeaders: (headers) => {
|
||||||
|
const token = localStorage.getItem("accessToken");
|
||||||
|
if (token) {
|
||||||
|
headers.set("x-auth-token", token);
|
||||||
|
}
|
||||||
|
return headers;
|
||||||
|
},
|
||||||
|
})(args, api, extraOptions);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Failed to refresh token:", err);
|
||||||
|
// Handle refresh failure (e.g., redirect to login)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create an RTK Query API slice
|
||||||
|
export const apiSlice = createApi({
|
||||||
|
reducerPath: "api",
|
||||||
|
baseQuery: baseQuery,
|
||||||
|
endpoints: (builder) => ({
|
||||||
|
login: builder.mutation({
|
||||||
|
query: (credentials) => ({
|
||||||
|
url: "/auth/admin",
|
||||||
|
method: "POST",
|
||||||
|
body: credentials,
|
||||||
|
}),
|
||||||
|
async onQueryStarted(arg, { dispatch, queryFulfilled }) {
|
||||||
|
try {
|
||||||
|
const { data } = await queryFulfilled;
|
||||||
|
// Store tokens in local storage
|
||||||
|
localStorage.setItem("accessToken", data?.data?.access?.token);
|
||||||
|
localStorage.setItem("refreshToken", data?.data?.refresh?.token);
|
||||||
|
// localStorage.setItem('refreshTokenExp', data?.data?.refresh?.expires);
|
||||||
|
localStorage.setItem("accessTokenExp", data?.data?.access?.expires);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Login failed:", error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
refreshToken: builder.mutation({
|
||||||
|
query: (refreshToken) => ({
|
||||||
|
url: "/auth/user/regenerate-token",
|
||||||
|
method: "POST",
|
||||||
|
body: { refreshToken },
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const { useLoginMutation, useRefreshTokenMutation } = apiSlice;
|
||||||
@@ -6,13 +6,16 @@ import { exchangeRate } from "../Services/exchange.rate.service";
|
|||||||
import { ioService } from "../Services/io.service";
|
import { ioService } from "../Services/io.service";
|
||||||
import { investorDetails } from "../Services/investor.details.service";
|
import { investorDetails } from "../Services/investor.details.service";
|
||||||
import { investorTransaction } from "../Services/investor.transaction.service";
|
import { investorTransaction } from "../Services/investor.transaction.service";
|
||||||
import { api } from "../Services/api.service";
|
// import { api } from "../Services/api.service";
|
||||||
import { keyMerits } from "../Services/Key.merits.service";
|
// import { keyMerits } from "../Services/Key.merits.service";
|
||||||
import { bankDetails } from "../Services/bank.details.service";
|
import { bankDetails } from "../Services/bank.details.service";
|
||||||
import { contact } from "../Services/contact.service";
|
import { contact } from "../Services/contact.service";
|
||||||
|
import { depositRequest } from "../Services/deposit.request.service";
|
||||||
|
import { apiSlice, baseQuery } from "../Services/token.serivce";
|
||||||
|
|
||||||
export const store = configureStore({
|
export const store = configureStore({
|
||||||
reducer: {
|
reducer: {
|
||||||
|
[apiSlice.reducerPath]: apiSlice.reducer,
|
||||||
[sponserMaster.reducerPath]: sponserMaster.reducer,
|
[sponserMaster.reducerPath]: sponserMaster.reducer,
|
||||||
[investmentType.reducerPath]: investmentType.reducer,
|
[investmentType.reducerPath]: investmentType.reducer,
|
||||||
[exchangeRate.reducerPath]: exchangeRate.reducer,
|
[exchangeRate.reducerPath]: exchangeRate.reducer,
|
||||||
@@ -21,14 +24,16 @@ export const store = configureStore({
|
|||||||
[investorTransaction.reducerPath]: investorTransaction.reducer,
|
[investorTransaction.reducerPath]: investorTransaction.reducer,
|
||||||
[bankDetails.reducerPath]: bankDetails.reducer,
|
[bankDetails.reducerPath]: bankDetails.reducer,
|
||||||
[contact.reducerPath]: contact.reducer,
|
[contact.reducerPath]: contact.reducer,
|
||||||
|
[depositRequest.reducerPath]: depositRequest.reducer,
|
||||||
// Add other reducers as needed
|
// Add other reducers as needed
|
||||||
},
|
},
|
||||||
middleware: (getDefaultMiddleware) =>
|
middleware: (getDefaultMiddleware) =>
|
||||||
getDefaultMiddleware({
|
getDefaultMiddleware({
|
||||||
thunk: {
|
thunk: {
|
||||||
extraArgument: api, // Pass Axios instance as extra argument
|
extraArgument: baseQuery, // Pass Axios instance as extra argument
|
||||||
},
|
},
|
||||||
}).concat(
|
}).concat(
|
||||||
|
apiSlice.middleware,
|
||||||
sponserMaster.middleware,
|
sponserMaster.middleware,
|
||||||
investmentType.middleware,
|
investmentType.middleware,
|
||||||
exchangeRate.middleware,
|
exchangeRate.middleware,
|
||||||
@@ -37,6 +42,7 @@ export const store = configureStore({
|
|||||||
investorTransaction.middleware,
|
investorTransaction.middleware,
|
||||||
bankDetails.middleware,
|
bankDetails.middleware,
|
||||||
contact.middleware,
|
contact.middleware,
|
||||||
|
depositRequest.middleware,
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import * as Yup from "yup";
|
import * as Yup from "yup";
|
||||||
|
|
||||||
export const validationSchema = Yup.object().shape({
|
export const validationSchema = Yup.object().shape({
|
||||||
name: Yup.string().required("Owner name is required"),
|
name: Yup.string().required("Email name is required"),
|
||||||
password: Yup.string().required("Password is required"),
|
password: Yup.string().required("Password is required"),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
BIN
src/assets/click-151673.mp3
Normal file
BIN
src/assets/commingsoon.png
Normal file
|
After Width: | Height: | Size: 88 KiB |
BIN
src/assets/mobileImg.png
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
BIN
src/assets/mobileWing.png
Normal file
|
After Width: | Height: | Size: 7.3 KiB |
BIN
src/assets/mouse-click-104737.mp3
Normal file
BIN
src/assets/under-construction.png
Normal file
|
After Width: | Height: | Size: 563 KiB |
BIN
src/assets/welcome.avif
Normal file
|
After Width: | Height: | Size: 1.5 MiB |
BIN
src/assets/welcome2.avif
Normal file
|
After Width: | Height: | Size: 743 KiB |
BIN
src/assets/welcome3.avif
Normal file
|
After Width: | Height: | Size: 698 KiB |
BIN
src/assets/welcome4.avif
Normal file
|
After Width: | Height: | Size: 313 KiB |
@@ -1,6 +1,9 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import ReactDOM from "react-dom/client";
|
import ReactDOM from "react-dom/client";
|
||||||
import App from "./App.jsx";
|
import App from "./App.jsx";
|
||||||
|
import 'bootstrap/dist/css/bootstrap.min.css';
|
||||||
|
import 'bootstrap/dist/js/bootstrap.bundle.min';
|
||||||
|
|
||||||
// import { persistor, store } from "./Redux/Store.js";
|
// import { persistor, store } from "./Redux/Store.js";
|
||||||
|
|
||||||
import { Provider } from "react-redux";
|
import { Provider } from "react-redux";
|
||||||
|
|||||||