Compare commits
36 Commits
Yasin
...
bug-fix/9.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9eca3ae9fc | ||
|
|
212f5d4d37 | ||
|
|
84298ff453 | ||
|
|
8eae4222f4 | ||
| 52a987b616 | |||
|
|
2a3c211b56 | ||
| 4d6a8bb472 | |||
|
|
41a60c0892 | ||
|
|
5c05a68bb0 | ||
| f02f9c8b7d | |||
|
|
137912aa11 | ||
| e3fe5a1618 | |||
|
|
edcb4cd7b9 | ||
| c72f3ece4e | |||
|
|
85be7c891e | ||
|
|
e41d6b17b9 | ||
| 3217605a0f | |||
| b4d28387fa | |||
|
|
5411d4cd18 | ||
|
|
6a0aa17e2d | ||
|
|
471e4f32ab | ||
|
|
5d2c28f6ca | ||
|
|
49f39e1c2c | ||
|
|
f9c7bf9d5d | ||
|
|
49beb9539a | ||
|
|
ed27ed6939 | ||
|
|
d84b3a0e35 | ||
|
|
20c0c7840f | ||
|
|
bbfd617b27 | ||
|
|
87e0716383 | ||
|
|
c7d6a0fe36 | ||
|
|
c83aaa411a | ||
|
|
a2fe1435cb | ||
| 6a9e0f9908 | |||
|
|
4ca28fd910 | ||
| 88dc9d14fe |
28
.env.example
Normal file
28
.env.example
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
# Default Value Maker
|
||||||
|
VITE_MAKER="Maker"
|
||||||
|
|
||||||
|
# Default Value Checker
|
||||||
|
VITE_CHECKER="Checker"
|
||||||
|
|
||||||
|
# Role Encryption key
|
||||||
|
VITE_ROLE_ENCRYPTION_KEY="export"
|
||||||
|
|
||||||
|
# Super Admin
|
||||||
|
VITE_SUPER_ADMIN_ID=1
|
||||||
|
|
||||||
|
# BaseURL
|
||||||
|
VITE_BAS_URL="your_base_url"
|
||||||
|
|
||||||
|
# BaseURL for Images
|
||||||
|
VITE_IMAGE_URL="your_base_url"
|
||||||
|
|
||||||
|
# Max try re-genrate token
|
||||||
|
VITE_MAX_TRY_REGENRATE_TOKEN=3
|
||||||
|
|
||||||
|
VITE_STATUS_DRAFT="Draft"
|
||||||
|
VITE_STATUS_PROCESSING="Processing"
|
||||||
|
VITE_STATUS_OPEN="Open"
|
||||||
|
VITE_STATUS_CLOSED="Closed"
|
||||||
|
VITE_STATUS_EXITED="Exited"
|
||||||
|
VITE_STATUS_CANCELLED="Cancelled"
|
||||||
|
VITE_STATUS_DEACTIVATE="DeActivate"
|
||||||
117
README.md
117
README.md
@@ -1,10 +1,113 @@
|
|||||||
# React + Vite
|
# **Tanami Capital**
|
||||||
|
|
||||||
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
|
**Tanami** is a cutting-edge fintech platform designed to streamline investment opportunities for users in the Gulf region. It features two main components:
|
||||||
|
|
||||||
Currently, two official plugins are available:
|
- **Admin Panel:** A web-based dashboard for managing users, monitoring transactions, and overseeing investments efficiently.
|
||||||
|
- **Mobile Application:** A user-friendly app that empowers individuals to invest in diverse asset classes, including real estate, private equity, and other financial instruments located in Gulf countries.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## **Key Features**
|
||||||
|
- **Regional Focus:** Exclusively operational in Gulf countries, offering investment opportunities tailored to the region.
|
||||||
|
- **Diverse Investment Options:** Enables users to invest in financial instruments like real estate and private equity with ease and transparency.
|
||||||
|
- **Comprehensive Admin Tools:** The admin panel offers robust tools for tracking and managing platform activity.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## **Current Status**
|
||||||
|
The project is **live and operational**, catering specifically to the investment needs of users in the Gulf region.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## **Table of Contents**
|
||||||
|
- [Installation](#installation)
|
||||||
|
- [Usage](#usage)
|
||||||
|
- [Environment Variables](#environment-variables)
|
||||||
|
- [Scripts](#scripts)
|
||||||
|
- [License](#license)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## **Installation**
|
||||||
|
|
||||||
|
### **Prerequisites**
|
||||||
|
- [Node.js](https://nodejs.org/) (version 14 or higher recommended)
|
||||||
|
- [npm](https://www.npmjs.com/) (bundled with Node.js)
|
||||||
|
|
||||||
|
### **Steps**
|
||||||
|
1. Clone the repository:
|
||||||
|
```bash
|
||||||
|
git clone http://git.wdipl.com/Siddhesh.More/tanami-admin-panel.git
|
||||||
|
```
|
||||||
|
2. Navigate to the project directory:
|
||||||
|
```bash
|
||||||
|
cd tanami-admin-panel
|
||||||
|
```
|
||||||
|
3. Install dependencies:
|
||||||
|
```bash
|
||||||
|
npm install
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## **Usage**
|
||||||
|
|
||||||
|
### **Development Mode**
|
||||||
|
1. Start the development server:
|
||||||
|
```bash
|
||||||
|
npm run dev
|
||||||
|
```
|
||||||
|
2. Open your browser and navigate to:
|
||||||
|
```
|
||||||
|
http://localhost:5173/
|
||||||
|
```
|
||||||
|
|
||||||
|
### **Production Mode**
|
||||||
|
1. Install [PM2](https://pm2.keymetrics.io/) globally for process management:
|
||||||
|
```bash
|
||||||
|
npm install pm2 -g
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Build the application (if applicable):
|
||||||
|
```bash
|
||||||
|
npm run build
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Serve the application using PM2:
|
||||||
|
```bash
|
||||||
|
pm2 serve ./dist <port_number> --spa --name=<application_name>
|
||||||
|
```
|
||||||
|
Replace:
|
||||||
|
- `./dist` with your build directory.
|
||||||
|
- `<port_number>` with the desired port (e.g., `3000`).
|
||||||
|
- `<application_name>` with the name of your application.
|
||||||
|
|
||||||
|
4. Save the PM2 process list and enable startup on system reboot:
|
||||||
|
```bash
|
||||||
|
pm2 save
|
||||||
|
pm2 startup
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## **Environment Variables**
|
||||||
|
|
||||||
|
Create a `.env` file in the root directory based on the structure of [`.env.example`](.env.example).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## **Scripts**
|
||||||
|
|
||||||
|
| Script | Description |
|
||||||
|
|---------------------|-------------------------------------------------------------|
|
||||||
|
| `npm run dev` | Starts the app in development mode with `Vite` server. |
|
||||||
|
| `npm run build` | Builds the app for production. |
|
||||||
|
| `npm run lint` | Runs ESLint to check for code quality issues. |
|
||||||
|
| `npm run preview` | Previews the production build locally. |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## **License**
|
||||||
|
|
||||||
|
This project is licensed under the [MIT License](LICENSE).
|
||||||
|
|
||||||
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
|
|
||||||
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
|
|
||||||
# rubix-admin-panel
|
|
||||||
# tanami-admin-panel
|
|
||||||
|
|||||||
@@ -63,8 +63,8 @@ const App = () => {
|
|||||||
path="/*"
|
path="/*"
|
||||||
element={
|
element={
|
||||||
// isOnline ? (
|
// isOnline ? (
|
||||||
// isAuthenticate || isAuthenticatedInCookie === "true" ? (
|
isAuthenticate || isAuthenticatedInCookie === "true" ? (
|
||||||
localStorage.getItem('accessToken') && localStorage.getItem('refreshToken') ? (
|
// localStorage.getItem('accessToken') && localStorage.getItem('refreshToken') ? (
|
||||||
// true ? (
|
// true ? (
|
||||||
<DefaultLayout isOnline={isOnline} />
|
<DefaultLayout isOnline={isOnline} />
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { ChevronLeftIcon, ChevronRightIcon } from "@chakra-ui/icons";
|
|||||||
const Pagination = ({
|
const Pagination = ({
|
||||||
pageSize,
|
pageSize,
|
||||||
setPageSize,
|
setPageSize,
|
||||||
totalItems,
|
totalItems = 1,
|
||||||
isLoading,
|
isLoading,
|
||||||
setCurrentPage,
|
setCurrentPage,
|
||||||
currentPage,
|
currentPage,
|
||||||
@@ -49,7 +49,7 @@ const Pagination = ({
|
|||||||
value={pageSize}
|
value={pageSize}
|
||||||
onChange={handlePageSizeChange}
|
onChange={handlePageSizeChange}
|
||||||
>
|
>
|
||||||
{[15, 20, 30]?.map((size) => (
|
{[15, 20, 30, 500]?.map((size) => (
|
||||||
<option key={size} value={size}>
|
<option key={size} value={size}>
|
||||||
{size}
|
{size}
|
||||||
</option>
|
</option>
|
||||||
@@ -84,7 +84,7 @@ const Pagination = ({
|
|||||||
onClick={paginationNext}
|
onClick={paginationNext}
|
||||||
className="link pointer"
|
className="link pointer"
|
||||||
isDisabled={currentPage === totalPages}
|
isDisabled={currentPage === totalPages}
|
||||||
aria-label="Next Page"
|
aria-label="Next Page"
|
||||||
/>
|
/>
|
||||||
</HStack>
|
</HStack>
|
||||||
</HStack>
|
</HStack>
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { Box, Text } from "@chakra-ui/react";
|
import { Box, Text } from "@chakra-ui/react";
|
||||||
import React, { useRef } from "react";
|
import React from "react";
|
||||||
import audioClick from "../assets/click-151673.mp3";
|
|
||||||
|
|
||||||
const RoleSwitchButton = ({ isSwitchOn, setIsSwitchOn }) => {
|
const RoleSwitchButton = ({ isSwitchOn, setIsSwitchOn }) => {
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
|
|
||||||
import dns from "node:dns"
|
import dns from "node:dns"
|
||||||
import * as XLSX from 'xlsx';
|
import * as XLSX from 'xlsx';
|
||||||
import CryptoJS from "crypto-js";
|
import CryptoJS from "crypto-js";
|
||||||
|
|
||||||
|
|
||||||
export const generateSerialNumber = (index, currentPage, pageSize) => {
|
export const generateSerialNumber = (index, currentPage = 1, pageSize = 1) => {
|
||||||
return (currentPage - 1) * pageSize + (index + 1);
|
return (currentPage - 1) * pageSize + (index + 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -34,7 +33,7 @@ export function removeTrailingZeros(value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export function getCountdownTimer(utcDateString) {
|
export function getCountdownTimer(utcDateString) {
|
||||||
// Parse the UTC datetime string into a Date object
|
// Parse the UTC datetime string into a Date object
|
||||||
const targetDate = new Date(utcDateString);
|
const targetDate = new Date(utcDateString);
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
@@ -57,7 +56,7 @@ export function removeTrailingZeros(value) {
|
|||||||
const remainingMinutes = minutes % 60;
|
const remainingMinutes = minutes % 60;
|
||||||
const remainingSeconds = seconds % 60;
|
const remainingSeconds = seconds % 60;
|
||||||
|
|
||||||
return `${remainingDays === 0 ? "": remainingDays+"d"} ${remainingHours === 0 ? "": remainingHours+"h"} ${remainingMinutes}m ${remainingSeconds}s `;
|
return `${remainingDays === 0 ? "" : remainingDays + "d"} ${remainingHours === 0 ? "" : remainingHours + "h"} ${remainingMinutes}m ${remainingSeconds}s `;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -95,30 +94,33 @@ export function debounce(func, delay) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
async function resolveMx(domain, recordType) {
|
async function resolveMx(domain) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
dns.resolveMx(domain, (err, mxRecords) => {
|
dns.resolveMx(domain, (err, mxRecords) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
reject(err);
|
reject(err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const addresses = mxRecords.map((mxRecord) => mxRecord.exchange);
|
const addresses = mxRecords.map((mxRecord) => mxRecord.exchange);
|
||||||
resolve(addresses);
|
resolve(addresses);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// Async function to check email address validity
|
// Async function to check email address validity
|
||||||
export async function checkEmailValidity(email) {
|
export async function checkEmailValidity(email) {
|
||||||
try {
|
try {
|
||||||
const domain = email?.split("@")[1];
|
const domain = email?.split('@')[1];
|
||||||
const addresses = await resolveMx(domain, "MX");
|
const addresses = await resolveMx(domain, 'MX');
|
||||||
|
console.log(addresses);
|
||||||
|
|
||||||
if (addresses && addresses?.length > 0) {
|
if (addresses && addresses?.length > 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false; // No MX record exists
|
return false; // No MX record exists
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return false; // Error occurred
|
console.log(err);
|
||||||
|
|
||||||
|
return false; // Error occurred
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,14 +129,14 @@ export async function checkEmailValidity(email) {
|
|||||||
export function formatTimestampInGulfTimezone(timestamp) {
|
export function formatTimestampInGulfTimezone(timestamp) {
|
||||||
const date = new Date(timestamp);
|
const date = new Date(timestamp);
|
||||||
const options = {
|
const options = {
|
||||||
year: 'numeric',
|
year: 'numeric',
|
||||||
month: 'long',
|
month: 'long',
|
||||||
day: 'numeric',
|
day: 'numeric',
|
||||||
hour: '2-digit',
|
hour: '2-digit',
|
||||||
minute: '2-digit',
|
minute: '2-digit',
|
||||||
second: '2-digit',
|
second: '2-digit',
|
||||||
timeZone: 'Asia/Dubai', // Gulf Standard Time (GST) timezone
|
timeZone: 'Asia/Dubai', // Gulf Standard Time (GST) timezone
|
||||||
timeZoneName: 'short'
|
timeZoneName: 'short'
|
||||||
};
|
};
|
||||||
return date.toLocaleDateString('en-GB', options);
|
return date.toLocaleDateString('en-GB', options);
|
||||||
}
|
}
|
||||||
@@ -234,3 +236,10 @@ export const decryptString = (ciphertext) => {
|
|||||||
const originalText = bytes.toString(CryptoJS.enc.Utf8);
|
const originalText = bytes.toString(CryptoJS.enc.Utf8);
|
||||||
return originalText;
|
return originalText;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const SUPER_ADMIN_ID = Number(import.meta.env.VITE_SUPER_ADMIN_ID) || 1
|
||||||
|
export const MAKER_ID = import.meta.env.VITE_MAKER_ID || 1
|
||||||
|
export const CHECKER_ID = import.meta.env.VITE_CHECKER_ID || 2
|
||||||
|
|
||||||
|
export const isMaker = (role = decryptString(localStorage?.getItem("role"))) => role === import.meta.env.VITE_MAKER;
|
||||||
|
export const isChecker = (role = decryptString(localStorage?.getItem("role"))) => role === import.meta.env.VITE_CHECKER;
|
||||||
|
|||||||
@@ -1,2 +1,3 @@
|
|||||||
export const TABLE_PAGINATION = { page: 1, size:20 }
|
export const TABLE_PAGINATION = { page: 1, size: 20 }
|
||||||
export const IMAGE_URI = import.meta.env.VITE_API_IMAGE_URL
|
export const IMAGE_URI = import.meta.env.VITE_API_IMAGE_URL
|
||||||
|
export const INVESTOR_TABLE_PAGINATION = { page: 1, size: 500 }
|
||||||
@@ -1,26 +1,48 @@
|
|||||||
import React, { useContext, useEffect, useState } from "react";
|
import React, { useContext, useEffect, useState } from "react";
|
||||||
import logo from "../assets/logo2.png";
|
|
||||||
import logoDark from "../assets/logo.png";
|
|
||||||
import logoMini from "../assets/logo-min.png";
|
|
||||||
import logoMiniDark from "../assets/favicon.png";
|
|
||||||
import { useDispatch } from "react-redux";
|
|
||||||
import { loginUser } from "../Redux/Slice/auth";
|
|
||||||
import Button02 from "../Components/Buttons/Button02";
|
|
||||||
import { CgProfile } from "react-icons/cg";
|
import { CgProfile } from "react-icons/cg";
|
||||||
|
import { useDispatch } from "react-redux";
|
||||||
|
import logoMiniDark from "../assets/favicon.png";
|
||||||
|
import logoMini from "../assets/logo-min.png";
|
||||||
|
import logoDark from "../assets/logo.png";
|
||||||
|
import logo from "../assets/logo2.png";
|
||||||
|
|
||||||
import {
|
|
||||||
TbArrowBadgeLeftFilled,
|
|
||||||
TbListDetails,
|
|
||||||
TbReportMoney,
|
|
||||||
TbTransactionDollar,
|
|
||||||
} from "react-icons/tb";
|
|
||||||
import { TbArrowBadgeRightFilled } from "react-icons/tb";
|
|
||||||
import {
|
import {
|
||||||
ArrowBackIcon,
|
ArrowBackIcon,
|
||||||
ArrowLeftIcon,
|
ArrowLeftIcon,
|
||||||
ArrowRightIcon,
|
ArrowRightIcon,
|
||||||
AtSignIcon,
|
AtSignIcon,
|
||||||
} from "@chakra-ui/icons";
|
} from "@chakra-ui/icons";
|
||||||
|
import {
|
||||||
|
Accordion,
|
||||||
|
AccordionButton,
|
||||||
|
AccordionIcon,
|
||||||
|
AccordionItem,
|
||||||
|
AccordionPanel,
|
||||||
|
Alert,
|
||||||
|
AlertIcon,
|
||||||
|
Box,
|
||||||
|
Button,
|
||||||
|
Image,
|
||||||
|
Text,
|
||||||
|
Tooltip
|
||||||
|
} from "@chakra-ui/react";
|
||||||
|
import Cookies from "js-cookie"; // Import the Cookies library
|
||||||
|
import { GrManual } from "react-icons/gr";
|
||||||
|
import { HiOutlineChartSquareBar } from "react-icons/hi";
|
||||||
|
import { LuContact } from "react-icons/lu";
|
||||||
|
import { MdNotificationsNone, MdOutlineAddChart } from "react-icons/md";
|
||||||
|
import {
|
||||||
|
RiBankLine,
|
||||||
|
RiExchangeBoxLine,
|
||||||
|
RiFileUserLine,
|
||||||
|
RiMoneyDollarBoxLine,
|
||||||
|
} from "react-icons/ri";
|
||||||
|
import {
|
||||||
|
TbListDetails,
|
||||||
|
TbReportMoney,
|
||||||
|
TbTransactionDollar
|
||||||
|
} from "react-icons/tb";
|
||||||
|
import { VscSymbolClass } from "react-icons/vsc";
|
||||||
import {
|
import {
|
||||||
Link,
|
Link,
|
||||||
NavLink,
|
NavLink,
|
||||||
@@ -29,71 +51,21 @@ import {
|
|||||||
useLocation,
|
useLocation,
|
||||||
useNavigate,
|
useNavigate,
|
||||||
} from "react-router-dom";
|
} from "react-router-dom";
|
||||||
import { RouteLink } from "../Routes/Routes";
|
|
||||||
import NotFound from "../Pages/NotFound";
|
|
||||||
import { nav } from "../Routes/Nav";
|
|
||||||
import {
|
|
||||||
Avatar,
|
|
||||||
Box,
|
|
||||||
Button,
|
|
||||||
PopoverArrow,
|
|
||||||
PopoverBody,
|
|
||||||
PopoverCloseButton,
|
|
||||||
PopoverContent,
|
|
||||||
PopoverFooter,
|
|
||||||
PopoverHeader,
|
|
||||||
PopoverTrigger,
|
|
||||||
Portal,
|
|
||||||
Text,
|
|
||||||
WrapItem,
|
|
||||||
Popover,
|
|
||||||
Tag,
|
|
||||||
Accordion,
|
|
||||||
AccordionItem,
|
|
||||||
AccordionButton,
|
|
||||||
AccordionIcon,
|
|
||||||
AccordionPanel,
|
|
||||||
Image,
|
|
||||||
Alert,
|
|
||||||
AlertIcon,
|
|
||||||
Breadcrumb,
|
|
||||||
Divider,
|
|
||||||
Tooltip,
|
|
||||||
useRadio,
|
|
||||||
} from "@chakra-ui/react";
|
|
||||||
import GlobalStateContext from "../Contexts/GlobalStateContext";
|
|
||||||
import Cookies from "js-cookie"; // Import the Cookies library
|
|
||||||
import Header from "../Components/Header";
|
|
||||||
import HeaderMain from "../Components/HeaderMain";
|
import HeaderMain from "../Components/HeaderMain";
|
||||||
import { IoMdSwap } from "react-icons/io";
|
import GlobalStateContext from "../Contexts/GlobalStateContext";
|
||||||
import {
|
|
||||||
RiBankLine,
|
|
||||||
RiExchangeBoxLine,
|
|
||||||
RiFileUserLine,
|
|
||||||
RiMoneyDollarBoxLine,
|
|
||||||
} from "react-icons/ri";
|
|
||||||
import { VscSymbolClass } from "react-icons/vsc";
|
|
||||||
import { MdNotificationsNone, MdOutlineAddChart } from "react-icons/md";
|
|
||||||
import { HiOutlineChartSquareBar } from "react-icons/hi";
|
|
||||||
import { GrManual } from "react-icons/gr";
|
|
||||||
import { LuContact } from "react-icons/lu";
|
|
||||||
import shield from "../assets/shield.png";
|
|
||||||
import SplashScreen from "../Pages/SplashScreen";
|
|
||||||
import CutomBreadcrumb from "../Components/CutomBreadcrumb";
|
|
||||||
import CustomBreadcrumb from "../Components/CutomBreadcrumb";
|
|
||||||
import { getCountdownTimer } from "../Constants/Constants";
|
|
||||||
import { useLogoutMutation } from "../Services/token.serivce";
|
|
||||||
import CreateRequest from "../Pages/Fawateer/CreateRequest";
|
import CreateRequest from "../Pages/Fawateer/CreateRequest";
|
||||||
import ApproveRequest from "../Pages/FawateerChecker/ApproveRequest/ApproveRequest";
|
|
||||||
import ApproveHistoryMaker from "../Pages/FawateerChecker/ApproveHistory/ApproveHistoryMaker";
|
|
||||||
import ApproveHistory from "../Pages/FawateerChecker/ApproveHistory/ApproveHistoryChecker";
|
import ApproveHistory from "../Pages/FawateerChecker/ApproveHistory/ApproveHistoryChecker";
|
||||||
|
import ApproveHistoryMaker from "../Pages/FawateerChecker/ApproveHistory/ApproveHistoryMaker";
|
||||||
|
import ApproveRequest from "../Pages/FawateerChecker/ApproveRequest/ApproveRequest";
|
||||||
|
import NotFound from "../Pages/NotFound";
|
||||||
|
import SplashScreen from "../Pages/SplashScreen";
|
||||||
|
import { nav } from "../Routes/Nav";
|
||||||
|
import { RouteLink } from "../Routes/Routes";
|
||||||
import { useProfileQuery } from "../Services/io.service";
|
import { useProfileQuery } from "../Services/io.service";
|
||||||
import SubAdmin from "../Pages/SubAdmin/SubAdmin";
|
import { useLogoutMutation } from "../Services/token.serivce";
|
||||||
|
|
||||||
const DashboardLayout = ({ isOnline }) => {
|
const DashboardLayout = ({ isOnline }) => {
|
||||||
const userRole = localStorage.getItem("role");
|
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const dispach = useDispatch();
|
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const path = location.pathname;
|
const path = location.pathname;
|
||||||
const [isDrawerOpen, setIsDrawerOpen] = useState(false);
|
const [isDrawerOpen, setIsDrawerOpen] = useState(false);
|
||||||
@@ -110,15 +82,15 @@ const DashboardLayout = ({ isOnline }) => {
|
|||||||
|
|
||||||
const { data, refetch } = useProfileQuery();
|
const { data, refetch } = useProfileQuery();
|
||||||
|
|
||||||
useEffect(() => {
|
// useEffect(() => {
|
||||||
if (
|
// if (
|
||||||
!localStorage.getItem("accessToken") &&
|
// !localStorage.getItem("accessToken") &&
|
||||||
!localStorage.getItem("refreshToken")
|
// !localStorage.getItem("refreshToken")
|
||||||
) {
|
// ) {
|
||||||
logOutHandler();
|
// logOutHandler();
|
||||||
return navigate("/login");
|
// return navigate("/login");
|
||||||
}
|
// }
|
||||||
}, []);
|
// }, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const savedIndex = localStorage.getItem("openAccordionIndex");
|
const savedIndex = localStorage.getItem("openAccordionIndex");
|
||||||
@@ -157,7 +129,9 @@ const DashboardLayout = ({ isOnline }) => {
|
|||||||
await logout();
|
await logout();
|
||||||
localStorage.clear();
|
localStorage.clear();
|
||||||
navigate("/login");
|
navigate("/login");
|
||||||
} catch (error) {}
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// // Function to get the title based on the route
|
// // Function to get the title based on the route
|
||||||
@@ -375,6 +349,13 @@ const DashboardLayout = ({ isOnline }) => {
|
|||||||
Deletion request
|
Deletion request
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
|
case path.startsWith("/subadmin"):
|
||||||
|
return (
|
||||||
|
<span className="d-flex align-items-end gap-2">
|
||||||
|
<RiMoneyDollarBoxLine className="h4 m-0 fw-normal" />
|
||||||
|
Manage SubAdmin
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (path.startsWith("/community/view/")) {
|
if (path.startsWith("/community/view/")) {
|
||||||
|
|||||||
@@ -1,27 +1,25 @@
|
|||||||
import {
|
import {
|
||||||
Avatar,
|
|
||||||
Badge,
|
Badge,
|
||||||
Box,
|
Box,
|
||||||
HStack,
|
HStack,
|
||||||
Input,
|
Input,
|
||||||
Select,
|
Select,
|
||||||
Switch,
|
|
||||||
Text,
|
Text,
|
||||||
useDisclosure,
|
useDisclosure,
|
||||||
useToast,
|
useToast,
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import React, { useContext, useEffect, useState, useRef } from "react";
|
import React, { useContext, useEffect, useRef, useState } from "react";
|
||||||
import { Link, Link as RouterLink, useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import GlobalStateContext from "../../../../Contexts/GlobalStateContext";
|
|
||||||
import { debounce } from "../../../Master/Sponser/AddSponser";
|
|
||||||
import { OPACITY_ON_LOAD } from "../../../../Layout/animations";
|
|
||||||
import NormalTable from "../../../../Components/DataTable/NormalTable";
|
|
||||||
import CustomAlertDialog from "../../../../Components/CustomAlertDialog";
|
import CustomAlertDialog from "../../../../Components/CustomAlertDialog";
|
||||||
import Pagination from "../../../../Components/Pagination";
|
import NormalTable from "../../../../Components/DataTable/NormalTable";
|
||||||
import ToastBox from "../../../../Components/ToastBox";
|
import ToastBox from "../../../../Components/ToastBox";
|
||||||
import ReasonBanModal from "./ReasonBanModal";
|
|
||||||
import { useGetbanInvestorQuery } from "../../../../Services/ban.investor.service";
|
|
||||||
import { TABLE_PAGINATION } from "../../../../Constants/Paginations";
|
import { TABLE_PAGINATION } from "../../../../Constants/Paginations";
|
||||||
|
import GlobalStateContext from "../../../../Contexts/GlobalStateContext";
|
||||||
|
import { OPACITY_ON_LOAD } from "../../../../Layout/animations";
|
||||||
|
import { useGetbanInvestorQuery } from "../../../../Services/ban.investor.service";
|
||||||
|
import { debounce } from "../../../Master/Sponser/AddSponser";
|
||||||
|
import ReasonBanModal from "./ReasonBanModal";
|
||||||
|
import Pagination from "../../../../Components/Pagination";
|
||||||
|
|
||||||
const formatDate = (date) => new Date(date).toLocaleDateString(); // Simple date formatter
|
const formatDate = (date) => new Date(date).toLocaleDateString(); // Simple date formatter
|
||||||
|
|
||||||
@@ -233,8 +231,6 @@ const BankInvestor = () => {
|
|||||||
),
|
),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
console.log(extractedArray);
|
|
||||||
|
|
||||||
const handleDelete = () => {
|
const handleDelete = () => {
|
||||||
const updatedInvestorDetails = InvestorDetails.filter(
|
const updatedInvestorDetails = InvestorDetails.filter(
|
||||||
(sponsor) => sponsor.id !== actionId
|
(sponsor) => sponsor.id !== actionId
|
||||||
@@ -278,6 +274,14 @@ const BankInvestor = () => {
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<HStack display={"flex"} alignItems={"center"}>
|
<HStack display={"flex"} alignItems={"center"}>
|
||||||
|
<Pagination
|
||||||
|
isLoading={unbanLoading}
|
||||||
|
pageSize={pageSize}
|
||||||
|
setPageSize={setPageSize}
|
||||||
|
currentPage={currentPage}
|
||||||
|
setCurrentPage={setCurrentPage}
|
||||||
|
totalItems={data?.data?.totalItems}
|
||||||
|
/>
|
||||||
{/* <Select
|
{/* <Select
|
||||||
focusBorderColor="green.500"
|
focusBorderColor="green.500"
|
||||||
size={"sm"}
|
size={"sm"}
|
||||||
|
|||||||
@@ -1,31 +1,26 @@
|
|||||||
import {
|
import {
|
||||||
Avatar,
|
|
||||||
Badge,
|
Badge,
|
||||||
Box,
|
Box,
|
||||||
HStack,
|
HStack,
|
||||||
Input,
|
Input,
|
||||||
Select,
|
Select,
|
||||||
Switch,
|
|
||||||
Text,
|
Text,
|
||||||
useDisclosure,
|
useDisclosure,
|
||||||
useToast,
|
useToast,
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import React, { useContext, useEffect, useState, useRef } from "react";
|
import React, { useContext, useEffect, useRef, useState } from "react";
|
||||||
import { Link, Link as RouterLink, useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import GlobalStateContext from "../../../../Contexts/GlobalStateContext";
|
|
||||||
import { debounce } from "../../../Master/Sponser/AddSponser";
|
|
||||||
import { OPACITY_ON_LOAD } from "../../../../Layout/animations";
|
|
||||||
import DataTable from "../../../../Components/DataTable/NormalTable";
|
|
||||||
import CustomAlertDialog from "../../../../Components/CustomAlertDialog";
|
import CustomAlertDialog from "../../../../Components/CustomAlertDialog";
|
||||||
import Pagination from "../../../../Components/Pagination";
|
import DataTable from "../../../../Components/DataTable/NormalTable";
|
||||||
import ToastBox from "../../../../Components/ToastBox";
|
import ToastBox from "../../../../Components/ToastBox";
|
||||||
import ReasonBanModal from "./ReasonBanModal";
|
|
||||||
import {
|
|
||||||
useGetInvestorQuery,
|
|
||||||
useGetUnbanInvestorQuery,
|
|
||||||
} from "../../../../Services/ban.investor.service";
|
|
||||||
import { generateSerialNumber } from "../../../../Constants/Constants";
|
import { generateSerialNumber } from "../../../../Constants/Constants";
|
||||||
import { TABLE_PAGINATION } from "../../../../Constants/Paginations";
|
import { TABLE_PAGINATION } from "../../../../Constants/Paginations";
|
||||||
|
import GlobalStateContext from "../../../../Contexts/GlobalStateContext";
|
||||||
|
import { OPACITY_ON_LOAD } from "../../../../Layout/animations";
|
||||||
|
import { useGetUnbanInvestorQuery } from "../../../../Services/ban.investor.service";
|
||||||
|
import { debounce } from "../../../Master/Sponser/AddSponser";
|
||||||
|
import ReasonBanModal from "./ReasonBanModal";
|
||||||
|
import Pagination from "../../../../Components/Pagination";
|
||||||
|
|
||||||
const formatDate = (date) => new Date(date).toLocaleDateString(); // Simple date formatter
|
const formatDate = (date) => new Date(date).toLocaleDateString(); // Simple date formatter
|
||||||
|
|
||||||
@@ -270,6 +265,14 @@ const UnbanInvestor = () => {
|
|||||||
onChange={(e) => setSearchTerm(e.target.value)}
|
onChange={(e) => setSearchTerm(e.target.value)}
|
||||||
/>
|
/>
|
||||||
<HStack display={"flex"} alignItems={"center"}>
|
<HStack display={"flex"} alignItems={"center"}>
|
||||||
|
<Pagination
|
||||||
|
isLoading={unbanLoading}
|
||||||
|
pageSize={pageSize}
|
||||||
|
setPageSize={setPageSize}
|
||||||
|
currentPage={currentPage}
|
||||||
|
setCurrentPage={setCurrentPage}
|
||||||
|
totalItems={data?.data?.totalItems}
|
||||||
|
/>
|
||||||
{/* <Select
|
{/* <Select
|
||||||
focusBorderColor="green.500"
|
focusBorderColor="green.500"
|
||||||
size={"sm"}
|
size={"sm"}
|
||||||
|
|||||||
@@ -16,14 +16,13 @@ import {
|
|||||||
Stack,
|
Stack,
|
||||||
useToast,
|
useToast,
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import * as yup from "yup";
|
|
||||||
import React, { useState, useContext } from "react";
|
|
||||||
import { useForm } from "react-hook-form";
|
|
||||||
import { yupResolver } from "@hookform/resolvers/yup";
|
import { yupResolver } from "@hookform/resolvers/yup";
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import { useForm } from "react-hook-form";
|
||||||
|
import * as yup from "yup";
|
||||||
import CustomAlertDialog from "../Components/CustomAlertDialog";
|
import CustomAlertDialog from "../Components/CustomAlertDialog";
|
||||||
import ToastBox from "../Components/ToastBox";
|
import ToastBox from "../Components/ToastBox";
|
||||||
import { useUpdatePasswordMutation } from "../Services/change.password.service";
|
import { useUpdatePasswordMutation } from "../Services/change.password.service";
|
||||||
import { all } from "axios";
|
|
||||||
|
|
||||||
// Validation schema
|
// Validation schema
|
||||||
const passwordSchema = yup.object().shape({
|
const passwordSchema = yup.object().shape({
|
||||||
@@ -42,8 +41,8 @@ const passwordSchema = yup.object().shape({
|
|||||||
),
|
),
|
||||||
confirmNewPassword: yup
|
confirmNewPassword: yup
|
||||||
.string()
|
.string()
|
||||||
.required("Confirm Password is required")
|
.required("Confirm New Password is required")
|
||||||
.oneOf([yup.ref("newPassword")], "Passwords must match"),
|
.oneOf([yup.ref("newPassword")], "Password do not match"),
|
||||||
});
|
});
|
||||||
|
|
||||||
const ChangePassword = ({
|
const ChangePassword = ({
|
||||||
@@ -53,12 +52,18 @@ const ChangePassword = ({
|
|||||||
actionId,
|
actionId,
|
||||||
setActionId,
|
setActionId,
|
||||||
}) => {
|
}) => {
|
||||||
|
const initialValue = {
|
||||||
|
oldPassword: "",
|
||||||
|
newPassword: "",
|
||||||
|
confirmNewPassword: "",
|
||||||
|
};
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
const [alert, setAlert] = useState(false);
|
const [alert, setAlert] = useState(false);
|
||||||
const [showCurrentPassword, setShowCurrentPassword] = useState(false);
|
const [showCurrentPassword, setShowCurrentPassword] = useState(false);
|
||||||
const [showNewPassword, setShowNewPassword] = useState(false);
|
const [showNewPassword, setShowNewPassword] = useState(false);
|
||||||
const [showConfirmPassword, setShowConfirmPassword] = useState(false);
|
const [showConfirmPassword, setShowConfirmPassword] = useState(false);
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
|
const [input, setInput] = useState(initialValue);
|
||||||
|
|
||||||
const [updatePassword] = useUpdatePasswordMutation();
|
const [updatePassword] = useUpdatePasswordMutation();
|
||||||
|
|
||||||
@@ -74,10 +79,10 @@ const ChangePassword = ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Form submit handler
|
// Form submit handler
|
||||||
const onSubmit = async (data) => {
|
const onSubmit = async () => {
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
try {
|
try {
|
||||||
const res = await updatePassword(data); // Assuming API request works as expected
|
const res = await updatePassword(input); // Assuming API request works as expected
|
||||||
if (res?.data?.statusCode === 200) {
|
if (res?.data?.statusCode === 200) {
|
||||||
toast({
|
toast({
|
||||||
render: () => <ToastBox message={res?.data?.message} />,
|
render: () => <ToastBox message={res?.data?.message} />,
|
||||||
@@ -89,6 +94,7 @@ const ChangePassword = ({
|
|||||||
<ToastBox message={res?.error?.data?.message} status={"error"} />
|
<ToastBox message={res?.error?.data?.message} status={"error"} />
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
|
setAlert(false);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
@@ -97,6 +103,11 @@ const ChangePassword = ({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleSubmitFrom = (data) => {
|
||||||
|
setAlert(true);
|
||||||
|
setInput(data);
|
||||||
|
};
|
||||||
|
|
||||||
// Handle modal close
|
// Handle modal close
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
setAlert(false);
|
setAlert(false);
|
||||||
@@ -106,7 +117,7 @@ const ChangePassword = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Modal isOpen={isOpen} onClose={onClose} initialFocusRef={firstField}>
|
<Modal isOpen={isOpen} onClose={handleClose} initialFocusRef={firstField}>
|
||||||
<ModalOverlay />
|
<ModalOverlay />
|
||||||
<ModalContent>
|
<ModalContent>
|
||||||
<ModalHeader fontSize="md">Change Password</ModalHeader>
|
<ModalHeader fontSize="md">Change Password</ModalHeader>
|
||||||
@@ -114,7 +125,7 @@ const ChangePassword = ({
|
|||||||
<ModalBody pb={6}>
|
<ModalBody pb={6}>
|
||||||
<Stack spacing={4}>
|
<Stack spacing={4}>
|
||||||
{/* Current Password */}
|
{/* Current Password */}
|
||||||
<FormControl isInvalid={errors.oldPassword}>
|
<FormControl isInvalid={errors.oldPassword} isRequired>
|
||||||
<FormLabel fontSize="sm" mb={1} fontWeight={500}>
|
<FormLabel fontSize="sm" mb={1} fontWeight={500}>
|
||||||
Current Password
|
Current Password
|
||||||
</FormLabel>
|
</FormLabel>
|
||||||
@@ -141,7 +152,7 @@ const ChangePassword = ({
|
|||||||
</FormControl>
|
</FormControl>
|
||||||
|
|
||||||
{/* New Password */}
|
{/* New Password */}
|
||||||
<FormControl isInvalid={errors.newPassword}>
|
<FormControl isInvalid={errors.newPassword} isRequired>
|
||||||
<FormLabel fontSize="sm" mb={1}>
|
<FormLabel fontSize="sm" mb={1}>
|
||||||
New Password
|
New Password
|
||||||
</FormLabel>
|
</FormLabel>
|
||||||
@@ -168,7 +179,7 @@ const ChangePassword = ({
|
|||||||
</FormControl>
|
</FormControl>
|
||||||
|
|
||||||
{/* Confirm Password */}
|
{/* Confirm Password */}
|
||||||
<FormControl isInvalid={errors.confirmNewPassword}>
|
<FormControl isInvalid={errors.confirmNewPassword} isRequired>
|
||||||
<FormLabel fontSize="sm" mb={1}>
|
<FormLabel fontSize="sm" mb={1}>
|
||||||
Confirm New Password
|
Confirm New Password
|
||||||
</FormLabel>
|
</FormLabel>
|
||||||
@@ -210,7 +221,8 @@ const ChangePassword = ({
|
|||||||
rounded={"sm"}
|
rounded={"sm"}
|
||||||
colorScheme="forestGreen"
|
colorScheme="forestGreen"
|
||||||
size="sm"
|
size="sm"
|
||||||
onClick={() => setAlert(true)}
|
// onClick={() => setAlert(true)}
|
||||||
|
onClick={handleSubmit(handleSubmitFrom)}
|
||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
>
|
>
|
||||||
Save
|
Save
|
||||||
@@ -222,7 +234,7 @@ const ChangePassword = ({
|
|||||||
<CustomAlertDialog
|
<CustomAlertDialog
|
||||||
isOpen={alert}
|
isOpen={alert}
|
||||||
onClose={() => setAlert(false)}
|
onClose={() => setAlert(false)}
|
||||||
alertHandler={handleSubmit(onSubmit)}
|
alertHandler={onSubmit}
|
||||||
message={"Are you sure you want to change the password?"}
|
message={"Are you sure you want to change the password?"}
|
||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import {
|
|||||||
useToast,
|
useToast,
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import * as yup from "yup";
|
import * as yup from "yup";
|
||||||
import React, { useState} from "react";
|
import React, { 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 { useForgetPasswordMutation } from "../Services/forget.password.service";
|
import { useForgetPasswordMutation } from "../Services/forget.password.service";
|
||||||
@@ -25,7 +25,9 @@ const validationSchema = yup.object().shape({
|
|||||||
emailAddress: yup
|
emailAddress: yup
|
||||||
.string()
|
.string()
|
||||||
.email("Invalid email format")
|
.email("Invalid email format")
|
||||||
.required("Email, Phone, or Username is required"),
|
.required("Email address is required")
|
||||||
|
.min(6, "Email address must be at least 6 characters long")
|
||||||
|
.max(255, "Email address can be at most 255 characters long"),
|
||||||
});
|
});
|
||||||
|
|
||||||
const ForgetPassword = ({ isOpen, onClose, firstField }) => {
|
const ForgetPassword = ({ isOpen, onClose, firstField }) => {
|
||||||
@@ -38,12 +40,12 @@ const ForgetPassword = ({ isOpen, onClose, firstField }) => {
|
|||||||
control,
|
control,
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
formState: { errors },
|
formState: { errors },
|
||||||
|
reset, // Add reset from useForm
|
||||||
} = useForm({
|
} = useForm({
|
||||||
resolver: yupResolver(validationSchema),
|
resolver: yupResolver(validationSchema),
|
||||||
});
|
});
|
||||||
|
|
||||||
const onSubmit = async (formData) => {
|
const onSubmit = async (formData) => {
|
||||||
|
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
try {
|
try {
|
||||||
const res = await forgetPassword(formData);
|
const res = await forgetPassword(formData);
|
||||||
@@ -52,13 +54,14 @@ const ForgetPassword = ({ isOpen, onClose, firstField }) => {
|
|||||||
render: () => <ToastBox message={res?.data?.message} />,
|
render: () => <ToastBox message={res?.data?.message} />,
|
||||||
});
|
});
|
||||||
handleClose();
|
handleClose();
|
||||||
} else if (res?.error?.status === 401) {
|
} else if (res?.error?.status === 400) {
|
||||||
toast({
|
toast({
|
||||||
render: () => (
|
render: () => (
|
||||||
<ToastBox message={res?.error?.data?.message} status="error" />
|
<ToastBox message={res?.error?.data?.message} status="error" />
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
handleClose();
|
handleClose();
|
||||||
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
@@ -70,6 +73,7 @@ const ForgetPassword = ({ isOpen, onClose, firstField }) => {
|
|||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
onClose();
|
onClose();
|
||||||
|
reset(); // Reset form state when modal closes
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -82,13 +86,13 @@ const ForgetPassword = ({ isOpen, onClose, firstField }) => {
|
|||||||
<ModalOverlay />
|
<ModalOverlay />
|
||||||
<ModalContent>
|
<ModalContent>
|
||||||
<form onSubmit={handleSubmit(onSubmit)}>
|
<form onSubmit={handleSubmit(onSubmit)}>
|
||||||
<ModalHeader fontSize="md">Forget Password</ModalHeader>
|
<ModalHeader fontSize="md">Forgot Password</ModalHeader>
|
||||||
<ModalCloseButton />
|
<ModalCloseButton />
|
||||||
<ModalBody pb={4}>
|
<ModalBody pb={4}>
|
||||||
<Stack spacing={4}>
|
<Stack spacing={4}>
|
||||||
<FormControl isInvalid={errors.emailAddress}>
|
<FormControl isInvalid={errors.emailAddress} isRequired>
|
||||||
<FormLabel fontSize="sm" mb={3} fontWeight={500}>
|
<FormLabel fontSize="sm" mb={3} fontWeight={500}>
|
||||||
Email, Phone, or Username
|
Please Enter Email Address
|
||||||
</FormLabel>
|
</FormLabel>
|
||||||
<Controller
|
<Controller
|
||||||
name="emailAddress"
|
name="emailAddress"
|
||||||
@@ -98,7 +102,7 @@ const ForgetPassword = ({ isOpen, onClose, firstField }) => {
|
|||||||
{...field}
|
{...field}
|
||||||
size="md"
|
size="md"
|
||||||
fontSize="sm"
|
fontSize="sm"
|
||||||
focusBorderColor="forestGreen.300"
|
focusBorderColor="forestGreen.300"
|
||||||
rounded={4}
|
rounded={4}
|
||||||
type="text"
|
type="text"
|
||||||
/>
|
/>
|
||||||
@@ -122,7 +126,7 @@ const ForgetPassword = ({ isOpen, onClose, firstField }) => {
|
|||||||
fontWeight={400}
|
fontWeight={400}
|
||||||
fontSize="sm"
|
fontSize="sm"
|
||||||
>
|
>
|
||||||
Send Login Link
|
Reset Password
|
||||||
</Button>
|
</Button>
|
||||||
</DrawerFooter>
|
</DrawerFooter>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import AddCaseDetails from "./AddCaseDetails";
|
|||||||
import { useUpdateIOCaseMutation } from "../../../../Services/io.service";
|
import { useUpdateIOCaseMutation } from "../../../../Services/io.service";
|
||||||
import ToastBox from "../../../../Components/ToastBox";
|
import ToastBox from "../../../../Components/ToastBox";
|
||||||
import { useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
import { encryptString } from "../../../../Constants/Constants";
|
import { encryptString, isMaker } from "../../../../Constants/Constants";
|
||||||
|
|
||||||
const IOCashDetails = () => {
|
const IOCashDetails = () => {
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
@@ -88,7 +88,8 @@ const IOCashDetails = () => {
|
|||||||
Pending
|
Pending
|
||||||
{IODetails?.ioCashStatusHistory?.Pending.length > 0 && (
|
{IODetails?.ioCashStatusHistory?.Pending.length > 0 && (
|
||||||
<Badge rounded={"sm"} colorScheme="forestGreen" ms={2}>
|
<Badge rounded={"sm"} colorScheme="forestGreen" ms={2}>
|
||||||
{IODetails?.ioCashStatusHistory?.Pending.length !== 0 && IODetails?.ioCashStatusHistory?.Pending.length}
|
{IODetails?.ioCashStatusHistory?.Pending.length !== 0 &&
|
||||||
|
IODetails?.ioCashStatusHistory?.Pending.length}
|
||||||
</Badge>
|
</Badge>
|
||||||
)}
|
)}
|
||||||
{/* <Badge rounded={"sm"} colorScheme="forestGreen" ms={2}>
|
{/* <Badge rounded={"sm"} colorScheme="forestGreen" ms={2}>
|
||||||
@@ -106,7 +107,7 @@ const IOCashDetails = () => {
|
|||||||
</Tab>
|
</Tab>
|
||||||
</TabList>
|
</TabList>
|
||||||
{IODetails?.isInvestedAmount
|
{IODetails?.isInvestedAmount
|
||||||
? localStorage?.getItem("role") === encryptString(import.meta.env.VITE_VITE_MAKER) && (
|
? isMaker() && (
|
||||||
<Button
|
<Button
|
||||||
onClick={handleAdd}
|
onClick={handleAdd}
|
||||||
leftIcon={<AddIcon />}
|
leftIcon={<AddIcon />}
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ import { useUpdateIOCaseMutation } from "../../../../Services/io.service";
|
|||||||
import RequestApproveModal from "./RequestApproveModal";
|
import RequestApproveModal from "./RequestApproveModal";
|
||||||
import RequestRejectModal from "./RequestRejectModal";
|
import RequestRejectModal from "./RequestRejectModal";
|
||||||
import AddCaseDetails from "./AddCaseDetails";
|
import AddCaseDetails from "./AddCaseDetails";
|
||||||
import { encryptString } from "../../../../Constants/Constants";
|
import { encryptString, isMaker } from "../../../../Constants/Constants";
|
||||||
|
|
||||||
const formatDate = (date) => new Date(date).toLocaleDateString();
|
const formatDate = (date) => new Date(date).toLocaleDateString();
|
||||||
|
|
||||||
@@ -105,8 +105,7 @@ const Pending = () => {
|
|||||||
"Comments",
|
"Comments",
|
||||||
"Update By",
|
"Update By",
|
||||||
"Update On",
|
"Update On",
|
||||||
...(localStorage?.getItem('role')!==encryptString(import.meta.env.VITE_VITE_MAKER) ? ["Actions"] : []),
|
...(!isMaker() ? ["Actions"] : []),
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const extractedArray = filteredData?.map((item, index) => ({
|
const extractedArray = filteredData?.map((item, index) => ({
|
||||||
@@ -132,9 +131,9 @@ const Pending = () => {
|
|||||||
$
|
$
|
||||||
</Badge>
|
</Badge>
|
||||||
{parseFloat(item?.transactionAmount || 0).toLocaleString(undefined, {
|
{parseFloat(item?.transactionAmount || 0).toLocaleString(undefined, {
|
||||||
minimumFractionDigits: 2,
|
minimumFractionDigits: 2,
|
||||||
maximumFractionDigits: 2,
|
maximumFractionDigits: 2,
|
||||||
})}
|
})}
|
||||||
</Text>
|
</Text>
|
||||||
),
|
),
|
||||||
Comments: (
|
Comments: (
|
||||||
@@ -167,64 +166,69 @@ const Pending = () => {
|
|||||||
),
|
),
|
||||||
Actions: (
|
Actions: (
|
||||||
<Box display={"flex"} justifyContent={"center"}>
|
<Box display={"flex"} justifyContent={"center"}>
|
||||||
{localStorage?.getItem("role") !== encryptString(import.meta.env.VITE_VITE_MAKER) ? <Box>
|
{!isMaker() ? (
|
||||||
{index===0&&<Box display={"flex"} justifyContent={"center"} gap={2}>
|
<Box>
|
||||||
<Tooltip
|
{index === 0 && (
|
||||||
rounded={"sm"}
|
<Box display={"flex"} justifyContent={"center"} gap={2}>
|
||||||
fontSize={"xs"}
|
<Tooltip
|
||||||
label="Approve"
|
rounded={"sm"}
|
||||||
bg="#fff"
|
fontSize={"xs"}
|
||||||
color={"green.500"}
|
label="Approve"
|
||||||
placement="left-start"
|
bg="#fff"
|
||||||
>
|
color={"green.500"}
|
||||||
|
placement="left-start"
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
// colorScheme="forestGreen"
|
||||||
|
// color="green.500"
|
||||||
|
rounded={"sm"}
|
||||||
|
size={"xs"}
|
||||||
|
textTransform={"inherit"}
|
||||||
|
fontWeight={500}
|
||||||
|
px={2}
|
||||||
|
py={1}
|
||||||
|
onClick={() => {
|
||||||
|
setActionId(item.id);
|
||||||
|
onConfirmOpen();
|
||||||
|
}}
|
||||||
|
colorScheme="green"
|
||||||
|
variant={"solid"}
|
||||||
|
cursor={"pointer"}
|
||||||
|
>
|
||||||
|
<CheckIcon fontSize={"12px"} />
|
||||||
|
</Button>
|
||||||
|
</Tooltip>
|
||||||
|
<Tooltip
|
||||||
|
rounded={"sm"}
|
||||||
|
fontSize={"xs"}
|
||||||
|
label="Reject"
|
||||||
|
bg="#fff"
|
||||||
|
color={"red.500"}
|
||||||
|
placement="left-start"
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
colorScheme="red"
|
||||||
|
// color="red.500"
|
||||||
|
rounded={"sm"}
|
||||||
|
size={"xs"}
|
||||||
|
textTransform={"inherit"}
|
||||||
|
fontWeight={500}
|
||||||
|
px={2}
|
||||||
|
onClick={() => {
|
||||||
|
setActionId(item.id);
|
||||||
|
onRejectOpen();
|
||||||
|
}}
|
||||||
|
py={1}
|
||||||
|
// variant={"solid"}
|
||||||
|
>
|
||||||
|
<CloseIcon fontSize={"10px"} />
|
||||||
|
</Button>
|
||||||
|
</Tooltip>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
) : (
|
||||||
<Button
|
<Button
|
||||||
// colorScheme="forestGreen"
|
|
||||||
// color="green.500"
|
|
||||||
rounded={"sm"}
|
|
||||||
size={"xs"}
|
|
||||||
textTransform={"inherit"}
|
|
||||||
fontWeight={500}
|
|
||||||
px={2}
|
|
||||||
py={1}
|
|
||||||
onClick={() => {
|
|
||||||
setActionId(item.id);
|
|
||||||
onConfirmOpen();
|
|
||||||
}}
|
|
||||||
colorScheme="green"
|
|
||||||
variant={"solid"}
|
|
||||||
cursor={"pointer"}
|
|
||||||
>
|
|
||||||
<CheckIcon fontSize={"12px"} />
|
|
||||||
</Button>
|
|
||||||
</Tooltip>
|
|
||||||
<Tooltip
|
|
||||||
rounded={"sm"}
|
|
||||||
fontSize={"xs"}
|
|
||||||
label="Reject"
|
|
||||||
bg="#fff"
|
|
||||||
color={"red.500"}
|
|
||||||
placement="left-start"
|
|
||||||
>
|
|
||||||
<Button
|
|
||||||
colorScheme="red"
|
|
||||||
// color="red.500"
|
|
||||||
rounded={"sm"}
|
|
||||||
size={"xs"}
|
|
||||||
textTransform={"inherit"}
|
|
||||||
fontWeight={500}
|
|
||||||
px={2}
|
|
||||||
onClick={() => {
|
|
||||||
setActionId(item.id);
|
|
||||||
onRejectOpen();
|
|
||||||
}}
|
|
||||||
py={1}
|
|
||||||
// variant={"solid"}
|
|
||||||
>
|
|
||||||
<CloseIcon fontSize={"10px"} />
|
|
||||||
</Button>
|
|
||||||
</Tooltip></Box>}
|
|
||||||
|
|
||||||
</Box> : <Button
|
|
||||||
colorScheme="green"
|
colorScheme="green"
|
||||||
rounded={"sm"}
|
rounded={"sm"}
|
||||||
size={"xs"}
|
size={"xs"}
|
||||||
@@ -236,7 +240,8 @@ const Pending = () => {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<ViewIcon me={"4px"} /> View
|
<ViewIcon me={"4px"} /> View
|
||||||
</Button>}
|
</Button>
|
||||||
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
),
|
),
|
||||||
}));
|
}));
|
||||||
@@ -314,9 +319,9 @@ const Pending = () => {
|
|||||||
$
|
$
|
||||||
</Badge>
|
</Badge>
|
||||||
{parseFloat(IODetails?.ioCash || 0).toLocaleString(undefined, {
|
{parseFloat(IODetails?.ioCash || 0).toLocaleString(undefined, {
|
||||||
minimumFractionDigits: 2,
|
minimumFractionDigits: 2,
|
||||||
maximumFractionDigits: 2,
|
maximumFractionDigits: 2,
|
||||||
})}
|
})}
|
||||||
</Th>
|
</Th>
|
||||||
<Th
|
<Th
|
||||||
textAlign={"center"}
|
textAlign={"center"}
|
||||||
|
|||||||
@@ -235,7 +235,6 @@ const IODetails = ({ enableNextTab, index, data }) => {
|
|||||||
|
|
||||||
const [values, setValues] = useState(id?minInvestmentById:miniValue);
|
const [values, setValues] = useState(id?minInvestmentById:miniValue);
|
||||||
|
|
||||||
console.log(values);
|
|
||||||
|
|
||||||
const formatNumber = (num) => {
|
const formatNumber = (num) => {
|
||||||
// Remove non-numeric characters and format with commas
|
// Remove non-numeric characters and format with commas
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ import ToastBox from "../../../../Components/ToastBox";
|
|||||||
import { useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
import AddNavDetails from "./AddNavDetails";
|
import AddNavDetails from "./AddNavDetails";
|
||||||
import { useUpdateIOCaseMutation } from "../../../../Services/io.service";
|
import { useUpdateIOCaseMutation } from "../../../../Services/io.service";
|
||||||
import { encryptString } from "../../../../Constants/Constants";
|
import { encryptString, isMaker } from "../../../../Constants/Constants";
|
||||||
|
|
||||||
const IONAVDetails = () => {
|
const IONAVDetails = () => {
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
@@ -153,7 +153,7 @@ const IONAVDetails = () => {
|
|||||||
</Tab>
|
</Tab>
|
||||||
</TabList>
|
</TabList>
|
||||||
{IODetails?.isInvestedAmount
|
{IODetails?.isInvestedAmount
|
||||||
? localStorage?.getItem("role") === encryptString(import.meta.env.VITE_VITE_MAKER) && (
|
? isMaker() && (
|
||||||
<Button
|
<Button
|
||||||
onClick={handleAdd}
|
onClick={handleAdd}
|
||||||
leftIcon={<AddIcon />}
|
leftIcon={<AddIcon />}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import ToastBox from "../../../../Components/ToastBox";
|
|||||||
import AddNavDetails from "./AddNavDetails";
|
import AddNavDetails from "./AddNavDetails";
|
||||||
import RequestApproveModal from "./RequestApproveModal";
|
import RequestApproveModal from "./RequestApproveModal";
|
||||||
import RequestRejectModal from "./RequestRejectModal";
|
import RequestRejectModal from "./RequestRejectModal";
|
||||||
import { encryptString } from "../../../../Constants/Constants";
|
import { encryptString, isMaker } from "../../../../Constants/Constants";
|
||||||
|
|
||||||
const formatDate = (date) => new Date(date).toLocaleDateString();
|
const formatDate = (date) => new Date(date).toLocaleDateString();
|
||||||
|
|
||||||
@@ -91,7 +91,7 @@ const Pending = () => {
|
|||||||
"Investment Closed",
|
"Investment Closed",
|
||||||
"Comments",
|
"Comments",
|
||||||
"Updated By",
|
"Updated By",
|
||||||
...(localStorage?.getItem("role") !== encryptString(import.meta.env.VITE_VITE_MAKER) ? ["Status"] : []),
|
...(!isMaker() ? ["Status"] : []),
|
||||||
];
|
];
|
||||||
|
|
||||||
const extractedArray = filteredData?.map((item, index) => ({
|
const extractedArray = filteredData?.map((item, index) => ({
|
||||||
@@ -112,9 +112,9 @@ const Pending = () => {
|
|||||||
$
|
$
|
||||||
</Badge>
|
</Badge>
|
||||||
{parseFloat(item?.transactionAmount || 0).toLocaleString(undefined, {
|
{parseFloat(item?.transactionAmount || 0).toLocaleString(undefined, {
|
||||||
minimumFractionDigits: 2,
|
minimumFractionDigits: 2,
|
||||||
maximumFractionDigits: 2,
|
maximumFractionDigits: 2,
|
||||||
})}
|
})}
|
||||||
</Text>
|
</Text>
|
||||||
),
|
),
|
||||||
"Last Nav Update": (
|
"Last Nav Update": (
|
||||||
@@ -162,65 +162,79 @@ const Pending = () => {
|
|||||||
{item?.modifier?.firstName}
|
{item?.modifier?.firstName}
|
||||||
</Text>
|
</Text>
|
||||||
),
|
),
|
||||||
Status: (
|
Status: isMaker() ? (
|
||||||
|
<Button
|
||||||
|
colorScheme="green"
|
||||||
|
rounded={"sm"}
|
||||||
|
size={"xs"}
|
||||||
|
px={2}
|
||||||
|
py={1}
|
||||||
|
fontWeight={500}
|
||||||
|
onClick={() => {
|
||||||
|
setActionId(item.id);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ViewIcon me={"4px"} /> View
|
||||||
|
</Button>
|
||||||
|
) : (
|
||||||
<Box display={"flex"} justifyContent={"center"}>
|
<Box display={"flex"} justifyContent={"center"}>
|
||||||
<Box>
|
<Box>
|
||||||
<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="Approve"
|
label="Approve"
|
||||||
bg="#fff"
|
bg="#fff"
|
||||||
color={"green.500"}
|
color={"green.500"}
|
||||||
placement="left-start"
|
placement="left-start"
|
||||||
>
|
>
|
||||||
<Button
|
<Button
|
||||||
// colorScheme="forestGreen"
|
// colorScheme="forestGreen"
|
||||||
// color="green.500"
|
// color="green.500"
|
||||||
rounded={"sm"}
|
rounded={"sm"}
|
||||||
size={"xs"}
|
size={"xs"}
|
||||||
textTransform={"inherit"}
|
textTransform={"inherit"}
|
||||||
fontWeight={500}
|
fontWeight={500}
|
||||||
px={2}
|
px={2}
|
||||||
py={1}
|
py={1}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setActionId(item.id);
|
setActionId(item.id);
|
||||||
onConfirmOpen();
|
onConfirmOpen();
|
||||||
}}
|
}}
|
||||||
colorScheme="green"
|
colorScheme="green"
|
||||||
variant={"solid"}
|
variant={"solid"}
|
||||||
cursor={"pointer"}
|
cursor={"pointer"}
|
||||||
>
|
>
|
||||||
<CheckIcon fontSize={"12px"} />
|
<CheckIcon fontSize={"12px"} />
|
||||||
</Button>
|
</Button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Tooltip
|
<Tooltip
|
||||||
rounded={"sm"}
|
rounded={"sm"}
|
||||||
fontSize={"xs"}
|
fontSize={"xs"}
|
||||||
label="Reject"
|
label="Reject"
|
||||||
bg="#fff"
|
bg="#fff"
|
||||||
color={"red.500"}
|
color={"red.500"}
|
||||||
placement="left-start"
|
placement="left-start"
|
||||||
>
|
>
|
||||||
<Button
|
<Button
|
||||||
colorScheme="red"
|
colorScheme="red"
|
||||||
// color="red.500"
|
// color="red.500"
|
||||||
rounded={"sm"}
|
rounded={"sm"}
|
||||||
size={"xs"}
|
size={"xs"}
|
||||||
textTransform={"inherit"}
|
textTransform={"inherit"}
|
||||||
fontWeight={500}
|
fontWeight={500}
|
||||||
px={2}
|
px={2}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setActionId(item.id);
|
setActionId(item.id);
|
||||||
onRejectOpen();
|
onRejectOpen();
|
||||||
}}
|
}}
|
||||||
py={1}
|
py={1}
|
||||||
// variant={"solid"}
|
// variant={"solid"}
|
||||||
>
|
>
|
||||||
<CloseIcon fontSize={"10px"} />
|
<CloseIcon fontSize={"10px"} />
|
||||||
</Button>
|
</Button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -1,33 +1,26 @@
|
|||||||
|
import { ViewIcon } from "@chakra-ui/icons";
|
||||||
import {
|
import {
|
||||||
Avatar,
|
|
||||||
Badge,
|
Badge,
|
||||||
Box,
|
Box,
|
||||||
Button,
|
Button,
|
||||||
HStack,
|
HStack,
|
||||||
Input,
|
Input,
|
||||||
Table,
|
|
||||||
Tag,
|
|
||||||
Tbody,
|
|
||||||
Text,
|
Text,
|
||||||
Th,
|
|
||||||
Tooltip,
|
|
||||||
Tr,
|
|
||||||
useDisclosure,
|
useDisclosure,
|
||||||
useToast,
|
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 { OPACITY_ON_LOAD } from "../../../../Layout/animations";
|
|
||||||
import NormalTable from "../../../../Components/DataTable/NormalTable";
|
|
||||||
import GlobalStateContext from "../../../../Contexts/GlobalStateContext";
|
|
||||||
import CustomAlertDialog from "../../../../Components/CustomAlertDialog";
|
import CustomAlertDialog from "../../../../Components/CustomAlertDialog";
|
||||||
import { CheckIcon, CloseIcon, ViewIcon } from "@chakra-ui/icons";
|
import NormalTable from "../../../../Components/DataTable/NormalTable";
|
||||||
|
import { isMaker } from "../../../../Constants/Constants";
|
||||||
|
import GlobalStateContext from "../../../../Contexts/GlobalStateContext";
|
||||||
|
import { OPACITY_ON_LOAD } from "../../../../Layout/animations";
|
||||||
import RequestApproveModal from "./RequestApproveModal";
|
import RequestApproveModal from "./RequestApproveModal";
|
||||||
import RequestRejectModal from "./RequestRejectModal";
|
import RequestRejectModal from "./RequestRejectModal";
|
||||||
import ViewAmountInvested from "./ViewAmountInvested";
|
import ViewAmountInvested from "./ViewAmountInvested";
|
||||||
|
import ViewCancel from "./ViewCancel";
|
||||||
import ViewDistributionInvestor from "./ViewDistributionInvestor";
|
import ViewDistributionInvestor from "./ViewDistributionInvestor";
|
||||||
import ViewExit from "./ViewExit";
|
import ViewExit from "./ViewExit";
|
||||||
import ViewCancel from "./ViewCancel";
|
|
||||||
import { encryptString } from "../../../../Constants/Constants";
|
|
||||||
|
|
||||||
const formatDate = (date) => new Date(date).toLocaleDateString();
|
const formatDate = (date) => new Date(date).toLocaleDateString();
|
||||||
|
|
||||||
@@ -43,6 +36,7 @@ const Pending = () => {
|
|||||||
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 [distributedAmt, setDistributedAmt] = useState();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
isOpen: isConfirmOpen,
|
isOpen: isConfirmOpen,
|
||||||
@@ -93,11 +87,6 @@ const Pending = () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log(
|
|
||||||
"==============panding",
|
|
||||||
IODetails?.ioTransactionRecords?.Pending
|
|
||||||
);
|
|
||||||
|
|
||||||
// Table filter
|
// Table filter
|
||||||
// const filteredData = IODetails?.ioTransactionRecords?.Pending?.filter((item) => {
|
// const filteredData = IODetails?.ioTransactionRecords?.Pending?.filter((item) => {
|
||||||
// // Filter by name (case insensitive)
|
// // Filter by name (case insensitive)
|
||||||
@@ -128,11 +117,7 @@ const Pending = () => {
|
|||||||
</Text>
|
</Text>
|
||||||
),
|
),
|
||||||
"Transaction Date": (
|
"Transaction Date": (
|
||||||
<Text
|
<Text as={"span"} color={"gray.600"} fontWeight={"500"}>
|
||||||
as={"span"}
|
|
||||||
color={"gray.600"}
|
|
||||||
fontWeight={"500"}
|
|
||||||
>
|
|
||||||
{formatDate(item?.transactionDate)}
|
{formatDate(item?.transactionDate)}
|
||||||
</Text>
|
</Text>
|
||||||
),
|
),
|
||||||
@@ -154,7 +139,12 @@ const Pending = () => {
|
|||||||
),
|
),
|
||||||
"Created By": (
|
"Created By": (
|
||||||
<Text
|
<Text
|
||||||
textTransform={'capitalize'} w={"100px"} as={"span"} color={"gray.800"} fontWeight={"500"}>
|
textTransform={"capitalize"}
|
||||||
|
w={"100px"}
|
||||||
|
as={"span"}
|
||||||
|
color={"gray.800"}
|
||||||
|
fontWeight={"500"}
|
||||||
|
>
|
||||||
{item?.creator?.firstName}
|
{item?.creator?.firstName}
|
||||||
</Text>
|
</Text>
|
||||||
),
|
),
|
||||||
@@ -165,7 +155,12 @@ const Pending = () => {
|
|||||||
),
|
),
|
||||||
"Approved By": (
|
"Approved By": (
|
||||||
<Text
|
<Text
|
||||||
textTransform={'capitalize'} w={"100px"} as={"span"} color={"gray.800"} fontWeight={"500"}>
|
textTransform={"capitalize"}
|
||||||
|
w={"100px"}
|
||||||
|
as={"span"}
|
||||||
|
color={"gray.800"}
|
||||||
|
fontWeight={"500"}
|
||||||
|
>
|
||||||
{item?.modifier?.firstName}
|
{item?.modifier?.firstName}
|
||||||
</Text>
|
</Text>
|
||||||
),
|
),
|
||||||
@@ -189,6 +184,7 @@ const Pending = () => {
|
|||||||
onInvestmentOpen();
|
onInvestmentOpen();
|
||||||
} else if (item?.transactionType === "Distribution To Investor") {
|
} else if (item?.transactionType === "Distribution To Investor") {
|
||||||
onDistInvestorOpen();
|
onDistInvestorOpen();
|
||||||
|
setDistributedAmt(item?.transactionAmount);
|
||||||
} else if (item?.transactionType === "Exit") {
|
} else if (item?.transactionType === "Exit") {
|
||||||
onExitOpen();
|
onExitOpen();
|
||||||
} else if (item?.transactionType === "Cancel") {
|
} else if (item?.transactionType === "Cancel") {
|
||||||
@@ -196,7 +192,8 @@ const Pending = () => {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{localStorage?.getItem("role") === encryptString(import.meta.env.VITE_VITE_MAKER) ? <ViewIcon me={"4px"} /> : null} {localStorage?.getItem("role") === encryptString(import.meta.env.VITE_VITE_MAKER) ? "View" : "Approve / Reject"}
|
{isMaker() ? <ViewIcon me={"4px"} /> : null}{" "}
|
||||||
|
{isMaker() ? "View" : "Approve / Reject"}
|
||||||
</Button>
|
</Button>
|
||||||
</Box>
|
</Box>
|
||||||
),
|
),
|
||||||
@@ -263,20 +260,13 @@ const Pending = () => {
|
|||||||
id={actionId}
|
id={actionId}
|
||||||
/>
|
/>
|
||||||
<ViewDistributionInvestor
|
<ViewDistributionInvestor
|
||||||
isOpen={isDistInvestorOpen}
|
isOpen={isDistInvestorOpen}
|
||||||
onClose={onDistInvestorClose}
|
onClose={onDistInvestorClose}
|
||||||
id={actionId}
|
|
||||||
/>
|
|
||||||
<ViewExit
|
|
||||||
isOpen={isExitOpen}
|
|
||||||
onClose={onExitClose}
|
|
||||||
id={actionId}
|
|
||||||
/>
|
|
||||||
<ViewCancel
|
|
||||||
isOpen={isCancelOpen}
|
|
||||||
onClose={onCancelClose}
|
|
||||||
id={actionId}
|
id={actionId}
|
||||||
|
amount={distributedAmt}
|
||||||
/>
|
/>
|
||||||
|
<ViewExit isOpen={isExitOpen} onClose={onExitClose} id={actionId} />
|
||||||
|
<ViewCancel isOpen={isCancelOpen} onClose={onCancelClose} id={actionId} />
|
||||||
<RequestApproveModal
|
<RequestApproveModal
|
||||||
// data={data?.data?.rows}
|
// data={data?.data?.rows}
|
||||||
isOpen={isConfirmOpen}
|
isOpen={isConfirmOpen}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ import CurrencyInput from "../../../../Components/CurrencyInput";
|
|||||||
import RequestRejectModal from "./RequestRejectModal";
|
import RequestRejectModal from "./RequestRejectModal";
|
||||||
import ApproveInvestedModal from "./ApproveInvestedModal";
|
import ApproveInvestedModal from "./ApproveInvestedModal";
|
||||||
import { formatDate } from "../../../Master/Sponser/Sponsers";
|
import { formatDate } from "../../../Master/Sponser/Sponsers";
|
||||||
import { encryptString } from "../../../../Constants/Constants";
|
import { encryptString, isMaker } from "../../../../Constants/Constants";
|
||||||
|
|
||||||
// Validation schema
|
// Validation schema
|
||||||
const validationSchema = yup.object().shape({
|
const validationSchema = yup.object().shape({
|
||||||
@@ -118,7 +118,6 @@ const ViewAmountInvested = ({ isOpen, onClose, id: investorId }) => {
|
|||||||
|
|
||||||
// const formatDate = (date) => new Date(date).toLocaleDateString();
|
// const formatDate = (date) => new Date(date).toLocaleDateString();
|
||||||
|
|
||||||
|
|
||||||
const handleAmountChange = (e) => {
|
const handleAmountChange = (e) => {
|
||||||
// e might be an object or just a value, handle both cases
|
// e might be an object or just a value, handle both cases
|
||||||
const amount =
|
const amount =
|
||||||
@@ -237,41 +236,43 @@ const ViewAmountInvested = ({ isOpen, onClose, id: investorId }) => {
|
|||||||
/>
|
/>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
|
|
||||||
{localStorage?.getItem("role") !== encryptString(import.meta.env.VITE_VITE_MAKER) && <ModalFooter>
|
{!isMaker() && (
|
||||||
<Box display={"flex"} justifyContent={"center"} gap={2}>
|
<ModalFooter>
|
||||||
<Button
|
<Box display={"flex"} justifyContent={"center"} gap={2}>
|
||||||
rounded={"sm"}
|
<Button
|
||||||
size={"xs"}
|
rounded={"sm"}
|
||||||
textTransform={"inherit"}
|
size={"xs"}
|
||||||
fontWeight={500}
|
textTransform={"inherit"}
|
||||||
px={3}
|
fontWeight={500}
|
||||||
py={2}
|
px={3}
|
||||||
onClick={() => {
|
py={2}
|
||||||
setActionId(id); // Use the `id` variable from params
|
onClick={() => {
|
||||||
onConfirmOpen();
|
setActionId(id); // Use the `id` variable from params
|
||||||
}}
|
onConfirmOpen();
|
||||||
colorScheme="forestGreen"
|
}}
|
||||||
variant={"solid"}
|
colorScheme="forestGreen"
|
||||||
cursor={"pointer"}
|
variant={"solid"}
|
||||||
>
|
cursor={"pointer"}
|
||||||
Approve
|
>
|
||||||
</Button>
|
Approve
|
||||||
<Button
|
</Button>
|
||||||
rounded={"sm"}
|
<Button
|
||||||
size={"xs"}
|
rounded={"sm"}
|
||||||
textTransform={"inherit"}
|
size={"xs"}
|
||||||
fontWeight={500}
|
textTransform={"inherit"}
|
||||||
px={3}
|
fontWeight={500}
|
||||||
py={2}
|
px={3}
|
||||||
onClick={() => {
|
py={2}
|
||||||
setActionId(id); // Use the `id` variable from params
|
onClick={() => {
|
||||||
onRejectOpen();
|
setActionId(id); // Use the `id` variable from params
|
||||||
}}
|
onRejectOpen();
|
||||||
>
|
}}
|
||||||
Reject
|
>
|
||||||
</Button>
|
Reject
|
||||||
</Box>
|
</Button>
|
||||||
</ModalFooter>}
|
</Box>
|
||||||
|
</ModalFooter>
|
||||||
|
)}
|
||||||
</form>
|
</form>
|
||||||
</ModalBody>
|
</ModalBody>
|
||||||
</ModalContent>
|
</ModalContent>
|
||||||
|
|||||||
@@ -1,128 +1,128 @@
|
|||||||
import {
|
import {
|
||||||
Badge,
|
Badge,
|
||||||
Box,
|
Box,
|
||||||
Button,
|
Button,
|
||||||
HStack,
|
HStack,
|
||||||
Modal,
|
Modal,
|
||||||
ModalBody,
|
ModalBody,
|
||||||
ModalCloseButton,
|
ModalCloseButton,
|
||||||
ModalContent,
|
ModalContent,
|
||||||
ModalFooter,
|
ModalFooter,
|
||||||
ModalHeader,
|
ModalHeader,
|
||||||
ModalOverlay,
|
ModalOverlay,
|
||||||
Table,
|
Table,
|
||||||
Tbody,
|
Tbody,
|
||||||
Text,
|
Text,
|
||||||
Th,
|
Th,
|
||||||
Tr,
|
Tr,
|
||||||
useDisclosure,
|
useDisclosure,
|
||||||
useToast,
|
useToast,
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import NormalData from "../../../../Components/DataTable/NormalTable";
|
import NormalData from "../../../../Components/DataTable/NormalTable";
|
||||||
import { useContext, useState } from "react";
|
import { useContext, useState } from "react";
|
||||||
import {
|
import {
|
||||||
useExitIOTransactionMutation,
|
useExitIOTransactionMutation,
|
||||||
useGetDistributedToInvestorMutation,
|
useGetDistributedToInvestorMutation,
|
||||||
useGetDistributionInvestorMutation,
|
useGetDistributionInvestorMutation,
|
||||||
useGetIOByIdQuery,
|
useGetIOByIdQuery,
|
||||||
} from "../../../../Services/io.service";
|
} from "../../../../Services/io.service";
|
||||||
import { useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
import { useForm } from "react-hook-form";
|
import { useForm } from "react-hook-form";
|
||||||
import * as yup from "yup";
|
import * as yup from "yup";
|
||||||
import { yupResolver } from "@hookform/resolvers/yup";
|
import { yupResolver } from "@hookform/resolvers/yup";
|
||||||
import ToastBox from "../../../../Components/ToastBox";
|
import ToastBox from "../../../../Components/ToastBox";
|
||||||
import GlobalStateContext from "../../../../Contexts/GlobalStateContext";
|
import GlobalStateContext from "../../../../Contexts/GlobalStateContext";
|
||||||
import ApprovedCancelTransaction from "./ApprovedCancelTransaction";
|
import ApprovedCancelTransaction from "./ApprovedCancelTransaction";
|
||||||
import RequestRejectModal from "./RequestRejectModal";
|
import RequestRejectModal from "./RequestRejectModal";
|
||||||
import { encryptString } from "../../../../Constants/Constants";
|
import { encryptString, isMaker } from "../../../../Constants/Constants";
|
||||||
|
|
||||||
const ViewCancel = ({ isOpen, onClose,id:cancleId }) => {
|
const ViewCancel = ({ isOpen, onClose, id: cancleId }) => {
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
const id = params?.id;
|
const id = params?.id;
|
||||||
const [isCalculateLoading, setIsCalculateLoading] = useState(false);
|
const [isCalculateLoading, setIsCalculateLoading] = useState(false);
|
||||||
const [isFinalCalculateLoading, setIsFinalCalculateLoading] = useState(false);
|
const [isFinalCalculateLoading, setIsFinalCalculateLoading] = useState(false);
|
||||||
const [calcualtedData, setCalculatedDate] = useState(null);
|
const [calcualtedData, setCalculatedDate] = useState(null);
|
||||||
const [isCalcualtedData, setIsCalcualtedData] = useState(false);
|
const [isCalcualtedData, setIsCalcualtedData] = useState(false);
|
||||||
const { investors, setInvestors, slideFromRight, IODetails } =
|
const { investors, setInvestors, slideFromRight, IODetails } =
|
||||||
useContext(GlobalStateContext);
|
useContext(GlobalStateContext);
|
||||||
|
|
||||||
const [actionId, setActionId] = useState(false);
|
const [actionId, setActionId] = useState(false);
|
||||||
|
|
||||||
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 investorExit = yup.object().shape({
|
const investorExit = yup.object().shape({
|
||||||
amount: yup
|
amount: yup
|
||||||
.string()
|
.string()
|
||||||
.required("Amount is required")
|
.required("Amount is required")
|
||||||
.test(
|
.test(
|
||||||
"max",
|
"max",
|
||||||
`Distribution amount should not be greater than IO cash amount ${IODetails?.ioCash}`,
|
`Distribution amount should not be greater than IO cash amount ${IODetails?.ioCash}`,
|
||||||
function (value) {
|
function (value) {
|
||||||
const { ioCash } = IODetails || {}; // Safely get ioCash
|
const { ioCash } = IODetails || {}; // Safely get ioCash
|
||||||
if (value && ioCash) {
|
if (value && ioCash) {
|
||||||
return parseFloat(value) <= parseFloat(ioCash); // Ensure both are compared as numbers
|
return parseFloat(value) <= parseFloat(ioCash); // Ensure both are compared as numbers
|
||||||
}
|
|
||||||
return true; // If ioCash is not available, skip validation
|
|
||||||
}
|
}
|
||||||
),
|
return true; // If ioCash is not available, skip validation
|
||||||
});
|
}
|
||||||
|
),
|
||||||
|
});
|
||||||
|
|
||||||
const {
|
const {
|
||||||
control,
|
control,
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
formState: { errors },
|
formState: { errors },
|
||||||
reset,
|
reset,
|
||||||
} = useForm({
|
} = useForm({
|
||||||
resolver: yupResolver(investorExit),
|
resolver: yupResolver(investorExit),
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.log("hiit useEffectc");
|
console.log("hiit useEffectc");
|
||||||
if (id && IODetails) {
|
if (id && IODetails) {
|
||||||
handleCalculate(id, {
|
handleCalculate(id, {
|
||||||
amount: IODetails?.ioMVNAV,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
reset({
|
|
||||||
amount: IODetails?.ioMVNAV,
|
amount: IODetails?.ioMVNAV,
|
||||||
});
|
});
|
||||||
}, [IODetails, id]);
|
}
|
||||||
|
reset({
|
||||||
const handleCalculate = async (id, data) => {
|
amount: IODetails?.ioMVNAV,
|
||||||
try {
|
|
||||||
const res = await getDistributionInvestment({ id, data });
|
|
||||||
console.log(res?.data?.data);
|
|
||||||
|
|
||||||
if (res?.error?.status === 401) {
|
|
||||||
setIsCalculateLoading(false);
|
|
||||||
setIsCalcualtedData(false);
|
|
||||||
} else if (res?.data?.statusCode === 200) {
|
|
||||||
setCalculatedDate(res?.data?.data);
|
|
||||||
setIsCalculateLoading(false);
|
|
||||||
setIsCalcualtedData(true);
|
|
||||||
}
|
|
||||||
} catch (error) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
const [getDistributionInvestment] = useGetDistributionInvestorMutation();
|
|
||||||
|
|
||||||
const investor = yup.object().shape({
|
|
||||||
amount: yup.string().required("Amount is required"),
|
|
||||||
});
|
});
|
||||||
|
}, [IODetails, id]);
|
||||||
|
|
||||||
// ====================================================[Table Setup]================================================================
|
const handleCalculate = async (id, data) => {
|
||||||
const tableHeadRow = [
|
try {
|
||||||
|
const res = await getDistributionInvestment({ id, data });
|
||||||
|
console.log(res?.data?.data);
|
||||||
|
|
||||||
|
if (res?.error?.status === 401) {
|
||||||
|
setIsCalculateLoading(false);
|
||||||
|
setIsCalcualtedData(false);
|
||||||
|
} else if (res?.data?.statusCode === 200) {
|
||||||
|
setCalculatedDate(res?.data?.data);
|
||||||
|
setIsCalculateLoading(false);
|
||||||
|
setIsCalcualtedData(true);
|
||||||
|
}
|
||||||
|
} catch (error) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
const [getDistributionInvestment] = useGetDistributionInvestorMutation();
|
||||||
|
|
||||||
|
const investor = yup.object().shape({
|
||||||
|
amount: yup.string().required("Amount is required"),
|
||||||
|
});
|
||||||
|
|
||||||
|
// ====================================================[Table Setup]================================================================
|
||||||
|
const tableHeadRow = [
|
||||||
"Client ID",
|
"Client ID",
|
||||||
"First name",
|
"First name",
|
||||||
"Last name",
|
"Last name",
|
||||||
@@ -134,221 +134,223 @@ import { encryptString } from "../../../../Constants/Constants";
|
|||||||
"Distribution Percent",
|
"Distribution Percent",
|
||||||
"Total Return",
|
"Total Return",
|
||||||
"Total return on Investment",
|
"Total return on Investment",
|
||||||
];
|
];
|
||||||
|
|
||||||
const extractedArray = IODetails?.investors?.map((item, index) => ({
|
const extractedArray = IODetails?.investors?.map((item, index) => ({
|
||||||
id: item?.id,
|
id: item?.id,
|
||||||
"Client ID": (
|
"Client ID": (
|
||||||
<Text
|
<Text
|
||||||
justifyContent={slideFromRight ? "right" : "center"}
|
justifyContent={slideFromRight ? "right" : "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?.clientReference_id}
|
{item?.clientReference_id}
|
||||||
</Text>
|
</Text>
|
||||||
),
|
),
|
||||||
"First name": (
|
"First name": (
|
||||||
<Text
|
<Text
|
||||||
justifyContent={slideFromRight ? "right" : "center"}
|
justifyContent={slideFromRight ? "right" : "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.firstName}
|
{item.firstName}
|
||||||
</Text>
|
</Text>
|
||||||
),
|
),
|
||||||
"Last name": (
|
"Last name": (
|
||||||
<Text
|
<Text
|
||||||
justifyContent={slideFromRight ? "right" : "center"}
|
justifyContent={slideFromRight ? "right" : "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.lastName}
|
{item.lastName}
|
||||||
</Text>
|
</Text>
|
||||||
),
|
),
|
||||||
"Investment amount": (
|
"Investment amount": (
|
||||||
<Text
|
<Text
|
||||||
justifyContent={slideFromRight ? "right" : "left"}
|
justifyContent={slideFromRight ? "right" : "left"}
|
||||||
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"
|
||||||
>
|
>
|
||||||
<Badge ms={1} colorScheme="green" me={1}>
|
<Badge ms={1} colorScheme="green" me={1}>
|
||||||
$
|
$
|
||||||
</Badge>
|
</Badge>
|
||||||
{/* {`$${formatCurrency(item.InvestedAmount_USD)}`} */}
|
{/* {`$${formatCurrency(item.InvestedAmount_USD)}`} */}
|
||||||
{`${parseFloat(item.InvestedAmount_USD || 0).toLocaleString(undefined, {
|
{`${parseFloat(item.InvestedAmount_USD || 0).toLocaleString(undefined, {
|
||||||
minimumFractionDigits: 2,
|
minimumFractionDigits: 2,
|
||||||
maximumFractionDigits: 2,
|
maximumFractionDigits: 2,
|
||||||
})}`}
|
})}`}
|
||||||
</Text>
|
</Text>
|
||||||
),
|
),
|
||||||
Percentage: (
|
Percentage: (
|
||||||
<Text
|
<Text
|
||||||
justifyContent={slideFromRight ? "right" : "center"}
|
justifyContent={slideFromRight ? "right" : "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.Investor_Holidings} %
|
{item.Investor_Holidings} %
|
||||||
</Text>
|
</Text>
|
||||||
),
|
),
|
||||||
"Market Value": (
|
"Market Value": (
|
||||||
<Text
|
<Text
|
||||||
justifyContent={slideFromRight ? "right" : "left"}
|
justifyContent={slideFromRight ? "right" : "left"}
|
||||||
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"
|
||||||
>
|
>
|
||||||
<Badge ms={1} colorScheme="green" me={1}>
|
<Badge ms={1} colorScheme="green" me={1}>
|
||||||
$
|
$
|
||||||
</Badge>
|
</Badge>
|
||||||
{`${parseFloat(item.Market_Value || 0).toLocaleString(undefined, {
|
{`${parseFloat(item.Market_Value || 0).toLocaleString(undefined, {
|
||||||
minimumFractionDigits: 2,
|
minimumFractionDigits: 2,
|
||||||
maximumFractionDigits: 2,
|
maximumFractionDigits: 2,
|
||||||
})}`}
|
})}`}
|
||||||
</Text>
|
</Text>
|
||||||
),
|
),
|
||||||
"Return on Investment": (
|
"Return on Investment": (
|
||||||
<Text
|
<Text
|
||||||
justifyContent={slideFromRight ? "right" : "center"}
|
justifyContent={slideFromRight ? "right" : "center"}
|
||||||
as={"span"}
|
as={"span"}
|
||||||
color={"teal.900"}
|
color={"teal.900"}
|
||||||
fontWeight={"500"}
|
fontWeight={"500"}
|
||||||
h={6}
|
h={6}
|
||||||
className="d-flex align-items-center web-text-small"
|
className="d-flex align-items-center web-text-small"
|
||||||
>
|
>
|
||||||
{item.Return_On_Investment || 0} %
|
{item.Return_On_Investment || 0} %
|
||||||
</Text>
|
</Text>
|
||||||
),
|
),
|
||||||
Distribution: (
|
Distribution: (
|
||||||
<Text
|
<Text
|
||||||
justifyContent={slideFromRight ? "right" : "left"}
|
justifyContent={slideFromRight ? "right" : "left"}
|
||||||
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"
|
||||||
>
|
>
|
||||||
<Badge ms={1} colorScheme="green" me={1}>
|
<Badge ms={1} colorScheme="green" me={1}>
|
||||||
$
|
$
|
||||||
</Badge>
|
</Badge>
|
||||||
{/* {`$${item.Distribution_Amt}`} */}
|
{/* {`$${item.Distribution_Amt}`} */}
|
||||||
{`${parseFloat(item.Distribution_Amt || 0).toLocaleString(undefined, {
|
{`${parseFloat(item.Distribution_Amt || 0).toLocaleString(undefined, {
|
||||||
minimumFractionDigits: 2,
|
minimumFractionDigits: 2,
|
||||||
maximumFractionDigits: 2,
|
maximumFractionDigits: 2,
|
||||||
})}`}
|
})}`}
|
||||||
</Text>
|
</Text>
|
||||||
),
|
),
|
||||||
"Distribution Percent": (
|
"Distribution Percent": (
|
||||||
<Text
|
<Text
|
||||||
justifyContent={slideFromRight ? "right" : "center"}
|
justifyContent={slideFromRight ? "right" : "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.Distribution_Amt}`} */}
|
{/* {`$${item.Distribution_Amt}`} */}
|
||||||
{`${parseFloat(item.Distribution_Per || 0).toLocaleString(undefined, {
|
{`${parseFloat(item.Distribution_Per || 0).toLocaleString(undefined, {
|
||||||
minimumFractionDigits: 2,
|
minimumFractionDigits: 2,
|
||||||
maximumFractionDigits: 2,
|
maximumFractionDigits: 2,
|
||||||
})} %`}
|
})} %`}
|
||||||
</Text>
|
</Text>
|
||||||
),
|
),
|
||||||
"Total Return": (
|
"Total Return": (
|
||||||
<Text
|
<Text
|
||||||
justifyContent={slideFromRight ? "right" : "left"}
|
justifyContent={slideFromRight ? "right" : "left"}
|
||||||
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"
|
||||||
>
|
>
|
||||||
<Badge ms={1} colorScheme="green" me={1}>
|
<Badge ms={1} colorScheme="green" me={1}>
|
||||||
$
|
$
|
||||||
</Badge>
|
</Badge>
|
||||||
{/* {`$${formatCurrency(item.Total_Return) || 0}`} */}
|
{/* {`$${formatCurrency(item.Total_Return) || 0}`} */}
|
||||||
{`${parseFloat(item.Total_Return || 0).toLocaleString(undefined, {
|
{`${parseFloat(item.Total_Return || 0).toLocaleString(undefined, {
|
||||||
minimumFractionDigits: 2,
|
minimumFractionDigits: 2,
|
||||||
maximumFractionDigits: 2,
|
maximumFractionDigits: 2,
|
||||||
})}`}
|
})}`}
|
||||||
</Text>
|
</Text>
|
||||||
),
|
),
|
||||||
"Total return on Investment": (
|
"Total return on Investment": (
|
||||||
<Text
|
<Text
|
||||||
justifyContent={slideFromRight ? "right" : "center"}
|
justifyContent={slideFromRight ? "right" : "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.Total_Return_On_Investment || 0} %
|
{item.Total_Return_On_Investment || 0} %
|
||||||
</Text>
|
</Text>
|
||||||
),
|
),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
onClose();
|
onClose();
|
||||||
setIsFinalCalculateLoading(false);
|
setIsFinalCalculateLoading(false);
|
||||||
setIsCalcualtedData(false);
|
setIsCalcualtedData(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal size={"xl"} isOpen={isOpen} onClose={handleClose} >
|
<Modal size={"xl"} isOpen={isOpen} onClose={handleClose}>
|
||||||
<ModalOverlay />
|
<ModalOverlay />
|
||||||
<ModalContent maxW={1000}>
|
<ModalContent maxW={1000}>
|
||||||
<ModalHeader fontSize={"md"}>Cancel Transaction</ModalHeader>
|
<ModalHeader fontSize={"md"}>Cancel Transaction</ModalHeader>
|
||||||
<ModalCloseButton />
|
<ModalCloseButton />
|
||||||
<ModalBody>
|
<ModalBody>
|
||||||
<NormalData
|
<NormalData
|
||||||
emptyMessage={`We don't have any Sponers `}
|
emptyMessage={`We don't have any Sponers `}
|
||||||
tableHeadRow={tableHeadRow}
|
tableHeadRow={tableHeadRow}
|
||||||
data={extractedArray}
|
data={extractedArray}
|
||||||
/>
|
/>
|
||||||
</ModalBody>
|
</ModalBody>
|
||||||
{localStorage?.getItem("role") !== encryptString(import.meta.env.VITE_VITE_MAKER) && <ModalFooter pt={0}>
|
{!isMaker() && (
|
||||||
|
<ModalFooter pt={0}>
|
||||||
<Box display={"flex"} justifyContent={"center"} gap={2}>
|
<Box display={"flex"} justifyContent={"center"} gap={2}>
|
||||||
<Button
|
<Button
|
||||||
rounded={"sm"}
|
rounded={"sm"}
|
||||||
size={"xs"}
|
size={"xs"}
|
||||||
textTransform={"inherit"}
|
textTransform={"inherit"}
|
||||||
fontWeight={500}
|
fontWeight={500}
|
||||||
px={3}
|
px={3}
|
||||||
py={2}
|
py={2}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setActionId(id); // Use the `id` variable from params
|
setActionId(id); // Use the `id` variable from params
|
||||||
onConfirmOpen();
|
onConfirmOpen();
|
||||||
}}
|
}}
|
||||||
colorScheme="forestGreen"
|
colorScheme="forestGreen"
|
||||||
variant={"solid"}
|
variant={"solid"}
|
||||||
cursor={"pointer"}
|
cursor={"pointer"}
|
||||||
>
|
>
|
||||||
Approve
|
Approve
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
rounded={"sm"}
|
rounded={"sm"}
|
||||||
size={"xs"}
|
size={"xs"}
|
||||||
textTransform={"inherit"}
|
textTransform={"inherit"}
|
||||||
fontWeight={500}
|
fontWeight={500}
|
||||||
px={3}
|
px={3}
|
||||||
py={2}
|
py={2}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setActionId(id); // Use the `id` variable from params
|
setActionId(id); // Use the `id` variable from params
|
||||||
onRejectOpen();
|
onRejectOpen();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Reject
|
Reject
|
||||||
</Button>
|
</Button>
|
||||||
</Box>
|
</Box>
|
||||||
</ModalFooter>}
|
</ModalFooter>
|
||||||
</ModalContent>
|
)}
|
||||||
<ApprovedCancelTransaction
|
</ModalContent>
|
||||||
|
<ApprovedCancelTransaction
|
||||||
isOpen={isConfirmOpen}
|
isOpen={isConfirmOpen}
|
||||||
onClose={onConfirmClose}
|
onClose={onConfirmClose}
|
||||||
onBigModalClose={onClose}
|
onBigModalClose={onClose}
|
||||||
@@ -360,9 +362,8 @@ import { encryptString } from "../../../../Constants/Constants";
|
|||||||
onBigModalClose={onClose}
|
onBigModalClose={onClose}
|
||||||
id={cancleId}
|
id={cancleId}
|
||||||
/>
|
/>
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ViewCancel;
|
|
||||||
|
|
||||||
|
export default ViewCancel;
|
||||||
|
|||||||
@@ -23,9 +23,9 @@ import { yupResolver } from "@hookform/resolvers/yup";
|
|||||||
import GlobalStateContext from "../../../../Contexts/GlobalStateContext";
|
import GlobalStateContext from "../../../../Contexts/GlobalStateContext";
|
||||||
import ApproveDistrubationModal from "./ApproveDistrubationModal";
|
import ApproveDistrubationModal from "./ApproveDistrubationModal";
|
||||||
import RequestRejectModal from "./RequestRejectModal";
|
import RequestRejectModal from "./RequestRejectModal";
|
||||||
import { encryptString } from "../../../../Constants/Constants";
|
import { encryptString, isMaker } from "../../../../Constants/Constants";
|
||||||
|
|
||||||
const ViewDistributionInvestor = ({ isOpen, onClose,id:exitId }) => {
|
const ViewDistributionInvestor = ({ isOpen, onClose, id: exitId, amount }) => {
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
const id = params?.id;
|
const id = params?.id;
|
||||||
@@ -72,19 +72,15 @@ const ViewDistributionInvestor = ({ isOpen, onClose,id:exitId }) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.log("hiit useEffectc");
|
|
||||||
// handleCalculate(id, {
|
|
||||||
// amount: IODetails?.ioMVNAV,
|
|
||||||
// });
|
|
||||||
if (id && IODetails) {
|
if (id && IODetails) {
|
||||||
handleCalculate(id, {
|
handleCalculate(id, {
|
||||||
amount: IODetails?.ioMVNAV,
|
amount: Math.abs(amount),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
reset({
|
reset({
|
||||||
amount: IODetails?.ioMVNAV,
|
amount: amount,
|
||||||
});
|
});
|
||||||
}, [IODetails, id]);
|
}, [IODetails, id, amount]);
|
||||||
|
|
||||||
const handleCalculate = async (id, data) => {
|
const handleCalculate = async (id, data) => {
|
||||||
try {
|
try {
|
||||||
@@ -202,7 +198,6 @@ const ViewDistributionInvestor = ({ isOpen, onClose,id:exitId }) => {
|
|||||||
setIsCalcualtedData(false);
|
setIsCalcualtedData(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal size={"xl"} isOpen={isOpen} onClose={handleClose}>
|
<Modal size={"xl"} isOpen={isOpen} onClose={handleClose}>
|
||||||
<ModalOverlay />
|
<ModalOverlay />
|
||||||
@@ -219,41 +214,43 @@ const ViewDistributionInvestor = ({ isOpen, onClose,id:exitId }) => {
|
|||||||
/>
|
/>
|
||||||
</ModalBody>
|
</ModalBody>
|
||||||
{/* ...(localStorage?.getItem("role") !== "Maker" ? ["Status"] : []), */}
|
{/* ...(localStorage?.getItem("role") !== "Maker" ? ["Status"] : []), */}
|
||||||
{localStorage?.getItem("role") !== encryptString(import.meta.env.VITE_VITE_MAKER) &&<ModalFooter pt={0}>
|
{!isMaker() && (
|
||||||
<Box display={"flex"} justifyContent={"center"} gap={2}>
|
<ModalFooter pt={0}>
|
||||||
<Button
|
<Box display={"flex"} justifyContent={"center"} gap={2}>
|
||||||
rounded={"sm"}
|
<Button
|
||||||
size={"xs"}
|
rounded={"sm"}
|
||||||
textTransform={"inherit"}
|
size={"xs"}
|
||||||
fontWeight={500}
|
textTransform={"inherit"}
|
||||||
px={3}
|
fontWeight={500}
|
||||||
py={2}
|
px={3}
|
||||||
onClick={() => {
|
py={2}
|
||||||
setActionId(id); // Use the `id` variable from params
|
onClick={() => {
|
||||||
onConfirmOpen();
|
setActionId(id); // Use the `id` variable from params
|
||||||
}}
|
onConfirmOpen();
|
||||||
colorScheme="forestGreen"
|
}}
|
||||||
variant={"solid"}
|
colorScheme="forestGreen"
|
||||||
cursor={"pointer"}
|
variant={"solid"}
|
||||||
>
|
cursor={"pointer"}
|
||||||
Approve
|
>
|
||||||
</Button>
|
Approve
|
||||||
<Button
|
</Button>
|
||||||
rounded={"sm"}
|
<Button
|
||||||
size={"xs"}
|
rounded={"sm"}
|
||||||
textTransform={"inherit"}
|
size={"xs"}
|
||||||
fontWeight={500}
|
textTransform={"inherit"}
|
||||||
px={3}
|
fontWeight={500}
|
||||||
py={2}
|
px={3}
|
||||||
onClick={() => {
|
py={2}
|
||||||
setActionId(id); // Use the `id` variable from params
|
onClick={() => {
|
||||||
onRejectOpen();
|
setActionId(id); // Use the `id` variable from params
|
||||||
}}
|
onRejectOpen();
|
||||||
>
|
}}
|
||||||
Reject
|
>
|
||||||
</Button>
|
Reject
|
||||||
</Box>
|
</Button>
|
||||||
</ModalFooter>}
|
</Box>
|
||||||
|
</ModalFooter>
|
||||||
|
)}
|
||||||
</ModalContent>
|
</ModalContent>
|
||||||
<ApproveDistrubationModal
|
<ApproveDistrubationModal
|
||||||
isOpen={isConfirmOpen}
|
isOpen={isConfirmOpen}
|
||||||
|
|||||||
@@ -1,330 +1,332 @@
|
|||||||
import {
|
import {
|
||||||
Alert,
|
Alert,
|
||||||
AlertIcon,
|
AlertIcon,
|
||||||
Box,
|
Box,
|
||||||
Button,
|
Button,
|
||||||
FormControl,
|
FormControl,
|
||||||
FormErrorMessage,
|
FormErrorMessage,
|
||||||
FormLabel,
|
FormLabel,
|
||||||
HStack,
|
HStack,
|
||||||
Input,
|
Input,
|
||||||
Modal,
|
Modal,
|
||||||
ModalBody,
|
ModalBody,
|
||||||
ModalCloseButton,
|
ModalCloseButton,
|
||||||
ModalContent,
|
ModalContent,
|
||||||
ModalFooter,
|
ModalFooter,
|
||||||
ModalHeader,
|
ModalHeader,
|
||||||
ModalOverlay,
|
ModalOverlay,
|
||||||
Switch,
|
Switch,
|
||||||
Table,
|
Table,
|
||||||
Tbody,
|
Tbody,
|
||||||
Text,
|
Text,
|
||||||
Textarea,
|
Textarea,
|
||||||
Th,
|
Th,
|
||||||
Tr,
|
Tr,
|
||||||
useDisclosure,
|
useDisclosure,
|
||||||
useToast,
|
useToast,
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import NormalData from "../../../../Components/DataTable/NormalTable";
|
import NormalData from "../../../../Components/DataTable/NormalTable";
|
||||||
import { useContext, useState } from "react";
|
import { useContext, useState } from "react";
|
||||||
import { AddIcon } from "@chakra-ui/icons";
|
import { AddIcon } from "@chakra-ui/icons";
|
||||||
import {
|
import {
|
||||||
useExitIOTransactionMutation,
|
useExitIOTransactionMutation,
|
||||||
useGetDistributedToInvestorMutation,
|
useGetDistributedToInvestorMutation,
|
||||||
useGetDistributionInvestorMutation,
|
useGetDistributionInvestorMutation,
|
||||||
useUpdateExitToInvestorMutation,
|
useUpdateExitToInvestorMutation,
|
||||||
} from "../../../../Services/io.service";
|
} from "../../../../Services/io.service";
|
||||||
import { useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
import { Controller, useForm } from "react-hook-form";
|
import { Controller, useForm } from "react-hook-form";
|
||||||
import * as yup from "yup";
|
import * as yup from "yup";
|
||||||
import { yupResolver } from "@hookform/resolvers/yup";
|
import { yupResolver } from "@hookform/resolvers/yup";
|
||||||
import ToastBox from "../../../../Components/ToastBox";
|
import ToastBox from "../../../../Components/ToastBox";
|
||||||
import GlobalStateContext from "../../../../Contexts/GlobalStateContext";
|
import GlobalStateContext from "../../../../Contexts/GlobalStateContext";
|
||||||
import ApprovedExit from "./ApprovedExit";
|
import ApprovedExit from "./ApprovedExit";
|
||||||
import RequestRejectModal from "./RequestRejectModal";
|
import RequestRejectModal from "./RequestRejectModal";
|
||||||
import { encryptString } from "../../../../Constants/Constants";
|
import { encryptString, isMaker } from "../../../../Constants/Constants";
|
||||||
|
|
||||||
const ViewExit = ({ isOpen, onClose ,id:investerId}) => {
|
const ViewExit = ({ isOpen, onClose, id: investerId }) => {
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
const id = params?.id;
|
const id = params?.id;
|
||||||
const [isCalculateLoading, setIsCalculateLoading] = useState(false);
|
const [isCalculateLoading, setIsCalculateLoading] = useState(false);
|
||||||
const [isFinalCalculateLoading, setIsFinalCalculateLoading] = useState(false);
|
const [isFinalCalculateLoading, setIsFinalCalculateLoading] = useState(false);
|
||||||
const [calcualtedData, setCalculatedDate] = useState(null);
|
const [calcualtedData, setCalculatedDate] = useState(null);
|
||||||
const [isCalcualtedData, setIsCalcualtedData] = useState(false);
|
const [isCalcualtedData, setIsCalcualtedData] = useState(false);
|
||||||
const { IODetails } = useContext(GlobalStateContext);
|
const { IODetails } = useContext(GlobalStateContext);
|
||||||
const [actionId, setActionId] = useState(false);
|
const [actionId, setActionId] = useState(false);
|
||||||
|
|
||||||
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 {
|
||||||
|
control,
|
||||||
|
handleSubmit,
|
||||||
|
formState: { errors },
|
||||||
|
reset,
|
||||||
|
} = useForm({
|
||||||
|
resolver: yupResolver(),
|
||||||
|
});
|
||||||
|
|
||||||
const {
|
useEffect(() => {
|
||||||
control,
|
console.log("hiit useEffectc");
|
||||||
handleSubmit,
|
if (id && IODetails) {
|
||||||
formState: { errors },
|
|
||||||
reset,
|
|
||||||
} = useForm({
|
|
||||||
resolver: yupResolver(),
|
|
||||||
});
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
console.log("hiit useEffectc");
|
|
||||||
if (id && IODetails) {
|
|
||||||
handleCalculate(id, {
|
handleCalculate(id, {
|
||||||
amount: IODetails?.ioMVNAV,
|
amount: IODetails?.ioMVNAV,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
reset({
|
reset({
|
||||||
amount: IODetails?.ioMVNAV,
|
amount: IODetails?.ioMVNAV,
|
||||||
});
|
|
||||||
}, [IODetails, id]);
|
|
||||||
|
|
||||||
const handleCalculate = async (id, data) => {
|
|
||||||
try {
|
|
||||||
|
|
||||||
const res = await getDistributionInvestment({ id, data });
|
|
||||||
console.log(res?.data?.data);
|
|
||||||
|
|
||||||
if (res?.error?.status === 401) {
|
|
||||||
setIsCalculateLoading(false);
|
|
||||||
setIsCalcualtedData(false);
|
|
||||||
} else if (res?.data?.statusCode === 200) {
|
|
||||||
setCalculatedDate(res?.data?.data);
|
|
||||||
setIsCalculateLoading(false);
|
|
||||||
setIsCalcualtedData(true);
|
|
||||||
}
|
|
||||||
} catch (error) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
const [getDistributionInvestment] = useGetDistributionInvestorMutation();
|
|
||||||
|
|
||||||
const investor = yup.object().shape({
|
|
||||||
amount: yup.string().required("Amount is required"),
|
|
||||||
});
|
});
|
||||||
|
}, [IODetails, id]);
|
||||||
|
|
||||||
// ====================================================[Table Setup]================================================================
|
const handleCalculate = async (id, data) => {
|
||||||
const tableHeadRow = [
|
try {
|
||||||
"Sr No.",
|
const res = await getDistributionInvestment({ id, data });
|
||||||
"Client Id",
|
console.log(res?.data?.data);
|
||||||
"First name",
|
|
||||||
"Last Name",
|
|
||||||
"Amount",
|
|
||||||
"Holding (%)",
|
|
||||||
"Exit Amt($)",
|
|
||||||
];
|
|
||||||
|
|
||||||
|
if (res?.error?.status === 401) {
|
||||||
|
setIsCalculateLoading(false);
|
||||||
const extractedArray = calcualtedData?.data?.map((item, index) => ({
|
setIsCalcualtedData(false);
|
||||||
id: item?.id,
|
} else if (res?.data?.statusCode === 200) {
|
||||||
"Sr No.": (
|
setCalculatedDate(res?.data?.data);
|
||||||
<Box
|
setIsCalculateLoading(false);
|
||||||
w={9}
|
setIsCalcualtedData(true);
|
||||||
display={"flex"}
|
}
|
||||||
alignItems={"center"}
|
} catch (error) {}
|
||||||
isTruncated={true}
|
|
||||||
h={25}
|
|
||||||
>
|
|
||||||
<Text as={"span"} color={"teal.900"} fontWeight={"500"}>
|
|
||||||
{index + 1}
|
|
||||||
</Text>
|
|
||||||
</Box>
|
|
||||||
),
|
|
||||||
"Client Id": (
|
|
||||||
<Box w={100} isTruncated={true}>
|
|
||||||
<Text as={"span"} color={"teal.900"} fontWeight={"500"}>
|
|
||||||
{item?.clientId}
|
|
||||||
</Text>
|
|
||||||
</Box>
|
|
||||||
),
|
|
||||||
"First name": (
|
|
||||||
<Box minW={24} isTruncated={true}>
|
|
||||||
<Text as={"span"} color={"teal.900"} fontWeight={"500"}>
|
|
||||||
{item?.firstName}
|
|
||||||
</Text>
|
|
||||||
</Box>
|
|
||||||
),
|
|
||||||
"Last Name": (
|
|
||||||
<Box minW={24} isTruncated={true}>
|
|
||||||
<Text as={"span"} color={"teal.900"} fontWeight={"500"}>
|
|
||||||
{item?.lastName}
|
|
||||||
</Text>
|
|
||||||
</Box>
|
|
||||||
),
|
|
||||||
Amount: (
|
|
||||||
<Box minW={24} isTruncated={true}>
|
|
||||||
<Text as={"span"} color={"teal.900"} fontWeight={"500"}>
|
|
||||||
{item?.amount?.toLocaleString(undefined, {
|
|
||||||
minimumFractionDigits: 2,
|
|
||||||
maximumFractionDigits: 2,
|
|
||||||
})}
|
|
||||||
</Text>
|
|
||||||
</Box>
|
|
||||||
),
|
|
||||||
"Holding (%)": (
|
|
||||||
<Box minW={24} isTruncated={true}>
|
|
||||||
<Text as={"span"} color={"teal.900"} fontWeight={"500"}>
|
|
||||||
{item?.investor_holidings?.toLocaleString(undefined, {
|
|
||||||
minimumFractionDigits: 2,
|
|
||||||
maximumFractionDigits: 2,
|
|
||||||
})}%
|
|
||||||
</Text>
|
|
||||||
</Box>
|
|
||||||
),
|
|
||||||
"Exit Amt($)": (
|
|
||||||
<Box minW={24} isTruncated={true}>
|
|
||||||
<Text as={"span"} color={"teal.900"} fontWeight={"500"}>
|
|
||||||
{item?.distribution_amt?.toLocaleString(undefined, {
|
|
||||||
minimumFractionDigits: 2,
|
|
||||||
maximumFractionDigits: 2,
|
|
||||||
})}
|
|
||||||
</Text>
|
|
||||||
</Box>
|
|
||||||
),
|
|
||||||
}));
|
|
||||||
|
|
||||||
const onSubmit = async (data) => {
|
|
||||||
setIsCalculateLoading(true);
|
|
||||||
|
|
||||||
try {
|
|
||||||
const res = await getDistributionInvestment({ id, data });
|
|
||||||
console.log(res?.data?.data);
|
|
||||||
|
|
||||||
if (res?.error?.status === 401) {
|
|
||||||
toast({
|
|
||||||
render: () => (
|
|
||||||
<ToastBox message={res?.error?.data?.message} status={"error"} />
|
|
||||||
),
|
|
||||||
});
|
|
||||||
setIsCalculateLoading(false);
|
|
||||||
setIsCalcualtedData(false);
|
|
||||||
} else if (res?.data?.statusCode === 200) {
|
|
||||||
setCalculatedDate(res?.data?.data);
|
|
||||||
toast({
|
|
||||||
render: () => <ToastBox message={res?.data?.message} />,
|
|
||||||
});
|
|
||||||
setIsCalculateLoading(false);
|
|
||||||
setIsCalcualtedData(true);
|
|
||||||
}
|
|
||||||
} catch (error) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleClose = () => {
|
|
||||||
onClose();
|
|
||||||
setIsFinalCalculateLoading(false);
|
|
||||||
setIsCalcualtedData(false);
|
|
||||||
};
|
|
||||||
|
|
||||||
console.log(id);
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Modal size={"xl"} isOpen={isOpen} onClose={handleClose} >
|
|
||||||
<ModalOverlay />
|
|
||||||
<ModalContent maxW={1000}>
|
|
||||||
<ModalHeader fontSize={"md"}>Exit Transaction</ModalHeader>
|
|
||||||
<ModalCloseButton />
|
|
||||||
<ModalBody>
|
|
||||||
{/* <Text as="label" mb="5px" fontSize="sm" fontWeight={500}>
|
|
||||||
Amount to Distribute
|
|
||||||
</Text> */}
|
|
||||||
<HStack onSubmit={handleSubmit(onSubmit)} as={"form"} mb={4} alignItems={'center'}>
|
|
||||||
{/* <Input placeholder="$00.00" size={"sm"} className="col" /> */}
|
|
||||||
{/* <FormControl isInvalid={errors.amount} isRequired>*/}
|
|
||||||
<Text textAlign={"right"} fontSize={"sm"}>
|
|
||||||
Exit Amount :
|
|
||||||
</Text>
|
|
||||||
<Text
|
|
||||||
textAlign={"start"}
|
|
||||||
bg={"green.100"}
|
|
||||||
p={2}
|
|
||||||
rounded={"md"}
|
|
||||||
fontSize={"sm"}
|
|
||||||
pt={1}
|
|
||||||
pb={1}
|
|
||||||
fontWeight={600}
|
|
||||||
>
|
|
||||||
${" "}
|
|
||||||
{parseFloat(IODetails?.ioMVNAV || 0).toLocaleString(undefined, {
|
|
||||||
minimumFractionDigits: 2,
|
|
||||||
maximumFractionDigits: 2,
|
|
||||||
})}
|
|
||||||
</Text>
|
|
||||||
|
|
||||||
{/* </FormControl> */}
|
|
||||||
</HStack>
|
|
||||||
|
|
||||||
{/* {calcualtedData && ( */}
|
|
||||||
<NormalData
|
|
||||||
emptyMessage={`We don't have any Sponers `}
|
|
||||||
tableHeadRow={tableHeadRow}
|
|
||||||
data={extractedArray}
|
|
||||||
// total={<Total />}
|
|
||||||
// isLoading={isLoading}
|
|
||||||
/>
|
|
||||||
{/* ) } */}
|
|
||||||
</ModalBody>
|
|
||||||
{localStorage?.getItem("role") !== encryptString(import.meta.env.VITE_VITE_MAKER) && <ModalFooter pt={0}>
|
|
||||||
<Box display={"flex"} justifyContent={"center"} gap={2}>
|
|
||||||
<Button
|
|
||||||
rounded={"sm"}
|
|
||||||
size={"xs"}
|
|
||||||
textTransform={"inherit"}
|
|
||||||
fontWeight={500}
|
|
||||||
px={3}
|
|
||||||
py={2}
|
|
||||||
onClick={() => {
|
|
||||||
setActionId(id); // Use the `id` variable from params
|
|
||||||
onConfirmOpen();
|
|
||||||
}}
|
|
||||||
colorScheme="forestGreen"
|
|
||||||
variant={"solid"}
|
|
||||||
cursor={"pointer"}
|
|
||||||
>
|
|
||||||
Approve
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
rounded={"sm"}
|
|
||||||
size={"xs"}
|
|
||||||
textTransform={"inherit"}
|
|
||||||
fontWeight={500}
|
|
||||||
px={3}
|
|
||||||
py={2}
|
|
||||||
onClick={() => {
|
|
||||||
setActionId(id); // Use the `id` variable from params
|
|
||||||
onRejectOpen();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Reject
|
|
||||||
</Button>
|
|
||||||
</Box>
|
|
||||||
</ModalFooter>}
|
|
||||||
</ModalContent>
|
|
||||||
<ApprovedExit
|
|
||||||
isOpen={isConfirmOpen}
|
|
||||||
onClose={onConfirmClose}
|
|
||||||
onBigModalClose={onClose}
|
|
||||||
id={investerId}
|
|
||||||
/>
|
|
||||||
<RequestRejectModal
|
|
||||||
isOpen={isRejectOpen}
|
|
||||||
onClose={onRejectClose}
|
|
||||||
onBigModalClose={onClose}
|
|
||||||
id={investerId}
|
|
||||||
/>
|
|
||||||
</Modal>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ViewExit;
|
const [getDistributionInvestment] = useGetDistributionInvestorMutation();
|
||||||
|
|
||||||
|
const investor = yup.object().shape({
|
||||||
|
amount: yup.string().required("Amount is required"),
|
||||||
|
});
|
||||||
|
|
||||||
|
// ====================================================[Table Setup]================================================================
|
||||||
|
const tableHeadRow = [
|
||||||
|
"Sr No.",
|
||||||
|
"Client Id",
|
||||||
|
"First name",
|
||||||
|
"Last Name",
|
||||||
|
"Amount",
|
||||||
|
"Holding (%)",
|
||||||
|
"Exit Amt($)",
|
||||||
|
];
|
||||||
|
|
||||||
|
const extractedArray = calcualtedData?.data?.map((item, index) => ({
|
||||||
|
id: item?.id,
|
||||||
|
"Sr No.": (
|
||||||
|
<Box
|
||||||
|
w={9}
|
||||||
|
display={"flex"}
|
||||||
|
alignItems={"center"}
|
||||||
|
isTruncated={true}
|
||||||
|
h={25}
|
||||||
|
>
|
||||||
|
<Text as={"span"} color={"teal.900"} fontWeight={"500"}>
|
||||||
|
{index + 1}
|
||||||
|
</Text>
|
||||||
|
</Box>
|
||||||
|
),
|
||||||
|
"Client Id": (
|
||||||
|
<Box w={100} isTruncated={true}>
|
||||||
|
<Text as={"span"} color={"teal.900"} fontWeight={"500"}>
|
||||||
|
{item?.clientId}
|
||||||
|
</Text>
|
||||||
|
</Box>
|
||||||
|
),
|
||||||
|
"First name": (
|
||||||
|
<Box minW={24} isTruncated={true}>
|
||||||
|
<Text as={"span"} color={"teal.900"} fontWeight={"500"}>
|
||||||
|
{item?.firstName}
|
||||||
|
</Text>
|
||||||
|
</Box>
|
||||||
|
),
|
||||||
|
"Last Name": (
|
||||||
|
<Box minW={24} isTruncated={true}>
|
||||||
|
<Text as={"span"} color={"teal.900"} fontWeight={"500"}>
|
||||||
|
{item?.lastName}
|
||||||
|
</Text>
|
||||||
|
</Box>
|
||||||
|
),
|
||||||
|
Amount: (
|
||||||
|
<Box minW={24} isTruncated={true}>
|
||||||
|
<Text as={"span"} color={"teal.900"} fontWeight={"500"}>
|
||||||
|
{item?.amount?.toLocaleString(undefined, {
|
||||||
|
minimumFractionDigits: 2,
|
||||||
|
maximumFractionDigits: 2,
|
||||||
|
})}
|
||||||
|
</Text>
|
||||||
|
</Box>
|
||||||
|
),
|
||||||
|
"Holding (%)": (
|
||||||
|
<Box minW={24} isTruncated={true}>
|
||||||
|
<Text as={"span"} color={"teal.900"} fontWeight={"500"}>
|
||||||
|
{item?.investor_holidings?.toLocaleString(undefined, {
|
||||||
|
minimumFractionDigits: 2,
|
||||||
|
maximumFractionDigits: 2,
|
||||||
|
})}
|
||||||
|
%
|
||||||
|
</Text>
|
||||||
|
</Box>
|
||||||
|
),
|
||||||
|
"Exit Amt($)": (
|
||||||
|
<Box minW={24} isTruncated={true}>
|
||||||
|
<Text as={"span"} color={"teal.900"} fontWeight={"500"}>
|
||||||
|
{item?.distribution_amt?.toLocaleString(undefined, {
|
||||||
|
minimumFractionDigits: 2,
|
||||||
|
maximumFractionDigits: 2,
|
||||||
|
})}
|
||||||
|
</Text>
|
||||||
|
</Box>
|
||||||
|
),
|
||||||
|
}));
|
||||||
|
|
||||||
|
const onSubmit = async (data) => {
|
||||||
|
setIsCalculateLoading(true);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await getDistributionInvestment({ id, data });
|
||||||
|
console.log(res?.data?.data);
|
||||||
|
|
||||||
|
if (res?.error?.status === 401) {
|
||||||
|
toast({
|
||||||
|
render: () => (
|
||||||
|
<ToastBox message={res?.error?.data?.message} status={"error"} />
|
||||||
|
),
|
||||||
|
});
|
||||||
|
setIsCalculateLoading(false);
|
||||||
|
setIsCalcualtedData(false);
|
||||||
|
} else if (res?.data?.statusCode === 200) {
|
||||||
|
setCalculatedDate(res?.data?.data);
|
||||||
|
toast({
|
||||||
|
render: () => <ToastBox message={res?.data?.message} />,
|
||||||
|
});
|
||||||
|
setIsCalculateLoading(false);
|
||||||
|
setIsCalcualtedData(true);
|
||||||
|
}
|
||||||
|
} catch (error) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleClose = () => {
|
||||||
|
onClose();
|
||||||
|
setIsFinalCalculateLoading(false);
|
||||||
|
setIsCalcualtedData(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log(id);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal size={"xl"} isOpen={isOpen} onClose={handleClose}>
|
||||||
|
<ModalOverlay />
|
||||||
|
<ModalContent maxW={1000}>
|
||||||
|
<ModalHeader fontSize={"md"}>Exit Transaction</ModalHeader>
|
||||||
|
<ModalCloseButton />
|
||||||
|
<ModalBody>
|
||||||
|
{/* <Text as="label" mb="5px" fontSize="sm" fontWeight={500}>
|
||||||
|
Amount to Distribute
|
||||||
|
</Text> */}
|
||||||
|
<HStack
|
||||||
|
onSubmit={handleSubmit(onSubmit)}
|
||||||
|
as={"form"}
|
||||||
|
mb={4}
|
||||||
|
alignItems={"center"}
|
||||||
|
>
|
||||||
|
{/* <Input placeholder="$00.00" size={"sm"} className="col" /> */}
|
||||||
|
{/* <FormControl isInvalid={errors.amount} isRequired>*/}
|
||||||
|
<Text textAlign={"right"} fontSize={"sm"}>
|
||||||
|
Exit Amount :
|
||||||
|
</Text>
|
||||||
|
<Text
|
||||||
|
textAlign={"start"}
|
||||||
|
bg={"green.100"}
|
||||||
|
p={2}
|
||||||
|
rounded={"md"}
|
||||||
|
fontSize={"sm"}
|
||||||
|
pt={1}
|
||||||
|
pb={1}
|
||||||
|
fontWeight={600}
|
||||||
|
>
|
||||||
|
${" "}
|
||||||
|
{parseFloat(IODetails?.ioMVNAV || 0).toLocaleString(undefined, {
|
||||||
|
minimumFractionDigits: 2,
|
||||||
|
maximumFractionDigits: 2,
|
||||||
|
})}
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
{/* </FormControl> */}
|
||||||
|
</HStack>
|
||||||
|
|
||||||
|
{/* {calcualtedData && ( */}
|
||||||
|
<NormalData
|
||||||
|
emptyMessage={`We don't have any Sponers `}
|
||||||
|
tableHeadRow={tableHeadRow}
|
||||||
|
data={extractedArray}
|
||||||
|
// total={<Total />}
|
||||||
|
// isLoading={isLoading}
|
||||||
|
/>
|
||||||
|
{/* ) } */}
|
||||||
|
</ModalBody>
|
||||||
|
{!isMaker() && (
|
||||||
|
<ModalFooter pt={0}>
|
||||||
|
<Box display={"flex"} justifyContent={"center"} gap={2}>
|
||||||
|
<Button
|
||||||
|
rounded={"sm"}
|
||||||
|
size={"xs"}
|
||||||
|
textTransform={"inherit"}
|
||||||
|
fontWeight={500}
|
||||||
|
px={3}
|
||||||
|
py={2}
|
||||||
|
onClick={() => {
|
||||||
|
setActionId(id); // Use the `id` variable from params
|
||||||
|
onConfirmOpen();
|
||||||
|
}}
|
||||||
|
colorScheme="forestGreen"
|
||||||
|
variant={"solid"}
|
||||||
|
cursor={"pointer"}
|
||||||
|
>
|
||||||
|
Approve
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
rounded={"sm"}
|
||||||
|
size={"xs"}
|
||||||
|
textTransform={"inherit"}
|
||||||
|
fontWeight={500}
|
||||||
|
px={3}
|
||||||
|
py={2}
|
||||||
|
onClick={() => {
|
||||||
|
setActionId(id); // Use the `id` variable from params
|
||||||
|
onRejectOpen();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Reject
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
</ModalFooter>
|
||||||
|
)}
|
||||||
|
</ModalContent>
|
||||||
|
<ApprovedExit
|
||||||
|
isOpen={isConfirmOpen}
|
||||||
|
onClose={onConfirmClose}
|
||||||
|
onBigModalClose={onClose}
|
||||||
|
id={investerId}
|
||||||
|
/>
|
||||||
|
<RequestRejectModal
|
||||||
|
isOpen={isRejectOpen}
|
||||||
|
onClose={onRejectClose}
|
||||||
|
onBigModalClose={onClose}
|
||||||
|
id={investerId}
|
||||||
|
/>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ViewExit;
|
||||||
|
|||||||
@@ -1,57 +1,29 @@
|
|||||||
import React, { useContext, useEffect, useState } from "react";
|
|
||||||
import { OPACITY_ON_LOAD } from "../../../Layout/animations";
|
|
||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
Divider,
|
|
||||||
FormControl,
|
|
||||||
FormLabel,
|
|
||||||
Heading,
|
|
||||||
Input,
|
|
||||||
Select,
|
|
||||||
Textarea,
|
|
||||||
Button,
|
|
||||||
Text,
|
|
||||||
Image,
|
|
||||||
Tabs,
|
|
||||||
TabList,
|
|
||||||
Tab,
|
Tab,
|
||||||
|
TabList,
|
||||||
TabPanel,
|
TabPanel,
|
||||||
TabPanels,
|
TabPanels,
|
||||||
Tooltip,
|
Tabs,
|
||||||
Switch,
|
|
||||||
useDisclosure,
|
useDisclosure,
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import { useForm, Controller } from "react-hook-form";
|
|
||||||
import { yupResolver } from "@hookform/resolvers/yup";
|
import { yupResolver } from "@hookform/resolvers/yup";
|
||||||
import * as yup from "yup";
|
import React, { useContext, useEffect, useState } from "react";
|
||||||
import {
|
import { useForm } from "react-hook-form";
|
||||||
AddIcon,
|
|
||||||
CloseIcon,
|
|
||||||
DeleteIcon,
|
|
||||||
EditIcon,
|
|
||||||
ViewIcon,
|
|
||||||
WarningTwoIcon,
|
|
||||||
} from "@chakra-ui/icons";
|
|
||||||
import { TiWarning } from "react-icons/ti";
|
|
||||||
import GlobalStateContext from "../../../Contexts/GlobalStateContext";
|
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import FormField from "../../../Components/FormField";
|
import * as yup from "yup";
|
||||||
import { v4 as uuidv4 } from "uuid";
|
import GlobalStateContext from "../../../Contexts/GlobalStateContext";
|
||||||
import AddIOCharges from "../AddIOCharges";
|
import { OPACITY_ON_LOAD } from "../../../Layout/animations";
|
||||||
import FormInputMain from "../../../Components/FormInputMain";
|
|
||||||
import DataTable from "../../../Components/DataTable/DataTable";
|
|
||||||
import { debounce } from "../../Master/Sponser/AddSponser";
|
|
||||||
import CustomAlertDialog from "../../../Components/CustomAlertDialog";
|
|
||||||
import { formatDate } from "../../../Components/Functions/UTCConvertor";
|
|
||||||
import IODetails from "./IODetails";
|
|
||||||
import KeyMerits from "./KeyMerits";
|
|
||||||
import IOArtifacts from "./IOArtifacts";
|
|
||||||
import Investors from "./Investors";
|
|
||||||
import IOCashDetails from "./IOCashDetails";
|
|
||||||
import IONAVDetails from "./IONAVDetails";
|
|
||||||
import Distribution from "./Destribution";
|
import Distribution from "./Destribution";
|
||||||
import InvestmentDocuments from "../InvestmentDocuments";
|
|
||||||
import InvestmentDocument from "./InvestmentDocument";
|
import InvestmentDocument from "./InvestmentDocument";
|
||||||
|
import Investors from "./Investors";
|
||||||
|
import IOArtifacts from "./IOArtifacts";
|
||||||
|
import IOCashDetails from "./IOCashDetails";
|
||||||
|
import IODetails from "./IODetails";
|
||||||
|
import IONAVDetails from "./IONAVDetails";
|
||||||
|
import KeyMerits from "./KeyMerits";
|
||||||
|
import { useAuthProfileQuery } from "../../Services/token.serivce";
|
||||||
|
import { encryptString } from "../../Constants/Constants";
|
||||||
|
|
||||||
const schema = yup.object().shape({
|
const schema = yup.object().shape({
|
||||||
ioName: yup.string().required("Arabic name is required"),
|
ioName: yup.string().required("Arabic name is required"),
|
||||||
@@ -59,7 +31,9 @@ const schema = yup.object().shape({
|
|||||||
discription: yup.string().required("Description is required"),
|
discription: yup.string().required("Description is required"),
|
||||||
discriptionArabic: yup.string().required("Arabic Description is required"),
|
discriptionArabic: yup.string().required("Arabic Description is required"),
|
||||||
typeName: yup.string().required("Investment type is required"),
|
typeName: yup.string().required("Investment type is required"),
|
||||||
typeNameArabic: yup.string().required("Investment type arabic name is required"),
|
typeNameArabic: yup
|
||||||
|
.string()
|
||||||
|
.required("Investment type arabic name is required"),
|
||||||
sponserName: yup.string().required("Sponsorer name is required"),
|
sponserName: yup.string().required("Sponsorer name is required"),
|
||||||
sponserNameArabic: yup
|
sponserNameArabic: yup
|
||||||
.string()
|
.string()
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ const UpdateIOStatus = ({ isOpen, onClose, status }) => {
|
|||||||
let res;
|
let res;
|
||||||
|
|
||||||
// If selectedItem is 'Cancelled', make the updateCancelStatus API call
|
// If selectedItem is 'Cancelled', make the updateCancelStatus API call
|
||||||
if (selectedItem === "Cancelled") {
|
if (selectedItem === import.meta.env.VITE_STATUS_CANCELLED) {
|
||||||
res = await updateCancleStatus({
|
res = await updateCancleStatus({
|
||||||
id
|
id
|
||||||
});
|
});
|
||||||
@@ -119,17 +119,17 @@ const UpdateIOStatus = ({ isOpen, onClose, status }) => {
|
|||||||
mb={1.5}
|
mb={1.5}
|
||||||
textTransform={"none"}
|
textTransform={"none"}
|
||||||
colorScheme={
|
colorScheme={
|
||||||
selectedItem === "Draft"
|
selectedItem === import.meta.env.VITE_STATUS_DRAFT
|
||||||
? "gray"
|
? "gray"
|
||||||
: selectedItem === "Processing"
|
: selectedItem === import.meta.env.VITE_STATUS_PROCESSING
|
||||||
? "yellow"
|
? "yellow"
|
||||||
: selectedItem === "Open"
|
: selectedItem === import.meta.env.VITE_STATUS_OPEN
|
||||||
? "blue"
|
? "blue"
|
||||||
: selectedItem === "Closed"
|
: selectedItem === import.meta.env.VITE_STATUS_CLOSED
|
||||||
? "green"
|
? "green"
|
||||||
: selectedItem === "Exited"
|
: selectedItem === import.meta.env.VITE_STATUS_EXITED
|
||||||
? "red"
|
? "red"
|
||||||
: selectedItem === "Cancelled"
|
: selectedItem === import.meta.env.VITE_STATUS_CANCELLED
|
||||||
? "orange"
|
? "orange"
|
||||||
: "purple"
|
: "purple"
|
||||||
}
|
}
|
||||||
@@ -161,17 +161,17 @@ const UpdateIOStatus = ({ isOpen, onClose, status }) => {
|
|||||||
mb={1.5}
|
mb={1.5}
|
||||||
textTransform={"none"}
|
textTransform={"none"}
|
||||||
colorScheme={
|
colorScheme={
|
||||||
statusAdmin === "Draft"
|
statusAdmin === import.meta.env.VITE_STATUS_DRAFT
|
||||||
? "gray"
|
? "gray"
|
||||||
: statusAdmin === "Processing"
|
: statusAdmin === import.meta.env.VITE_STATUS_PROCESSING
|
||||||
? "yellow"
|
? "yellow"
|
||||||
: statusAdmin === "Open"
|
: statusAdmin === import.meta.env.VITE_STATUS_OPEN
|
||||||
? "blue"
|
? "blue"
|
||||||
: statusAdmin === "Closed"
|
: statusAdmin === import.meta.env.VITE_STATUS_CLOSED
|
||||||
? "green"
|
? "green"
|
||||||
: statusAdmin === "Exited"
|
: statusAdmin === import.meta.env.VITE_STATUS_EXITED
|
||||||
? "red"
|
? "red"
|
||||||
: statusAdmin === "Cancelled"
|
: statusAdmin === import.meta.env.VITE_STATUS_CANCELLED
|
||||||
? "orange"
|
? "orange"
|
||||||
: "purple"
|
: "purple"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -97,7 +97,6 @@ const ViewIOTable = () => {
|
|||||||
skip: debouncedSearchTerm === "" && searchTerm !== "", // Skip if search is empty and it's not the initial request
|
skip: debouncedSearchTerm === "" && searchTerm !== "", // Skip if search is empty and it's not the initial request
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(data);
|
|
||||||
|
|
||||||
// ===============================[ Table Header ]
|
// ===============================[ Table Header ]
|
||||||
const tableHeadRow = [
|
const tableHeadRow = [
|
||||||
@@ -242,17 +241,17 @@ const ViewIOTable = () => {
|
|||||||
textTransform={"none"}
|
textTransform={"none"}
|
||||||
// variant={"solid"}
|
// variant={"solid"}
|
||||||
colorScheme={
|
colorScheme={
|
||||||
item?.ioStatus?.statusAdmin === "Draft"
|
item?.ioStatus?.statusAdmin === import.meta.env.VITE_STATUS_DRAFT
|
||||||
? "gray"
|
? "gray"
|
||||||
: item?.ioStatus?.statusAdmin === "Processing"
|
: item?.ioStatus?.statusAdmin === import.meta.env.VITE_STATUS_PROCESSING
|
||||||
? "yellow"
|
? "yellow"
|
||||||
: item?.ioStatus?.statusAdmin === "Open"
|
: item?.ioStatus?.statusAdmin === import.meta.env.VITE_STATUS_OPEN
|
||||||
? "blue"
|
? "blue"
|
||||||
: item?.ioStatus?.statusAdmin === "Closed"
|
: item?.ioStatus?.statusAdmin === import.meta.env.VITE_STATUS_CLOSED
|
||||||
? "green"
|
? "green"
|
||||||
: item?.ioStatus?.statusAdmin === "Exited"
|
: item?.ioStatus?.statusAdmin === import.meta.env.VITE_STATUS_EXITED
|
||||||
? "red"
|
? "red"
|
||||||
: item?.ioStatus?.statusAdmin === "Canclled"
|
: item?.ioStatus?.statusAdmin === import.meta.env.VITE_STATUS_CANCELLED
|
||||||
? "orange"
|
? "orange"
|
||||||
: "purple"
|
: "purple"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
Button,
|
Button,
|
||||||
Icon,
|
|
||||||
Input,
|
|
||||||
keyframes,
|
keyframes,
|
||||||
Stack,
|
Stack,
|
||||||
Tab,
|
Tab,
|
||||||
@@ -10,40 +8,29 @@ import {
|
|||||||
TabPanel,
|
TabPanel,
|
||||||
TabPanels,
|
TabPanels,
|
||||||
Tabs,
|
Tabs,
|
||||||
Text,
|
useDisclosure
|
||||||
useDisclosure,
|
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
|
import { useContext, useState } from "react";
|
||||||
import { useNavigate, useParams } from "react-router-dom";
|
import { useNavigate, useParams } from "react-router-dom";
|
||||||
import GlobalStateContext from "../../../Contexts/GlobalStateContext";
|
import GlobalStateContext from "../../../Contexts/GlobalStateContext";
|
||||||
import { useContext, useEffect, useState } from "react";
|
|
||||||
import FormInputView from "../../../Components/FormInputView";
|
|
||||||
import { useForm } from "react-hook-form"; // assuming react-hook-form is used
|
|
||||||
import { OPACITY_ON_LOAD } from "../../../Layout/animations";
|
import { OPACITY_ON_LOAD } from "../../../Layout/animations";
|
||||||
import { ArrowBackIcon, RepeatIcon } from "@chakra-ui/icons";
|
import InvestmentDocument from "../CreateIO/InvestmentDocument";
|
||||||
import CustomAlertDialog from "../../../Components/CustomAlertDialog";
|
import Investors from "../CreateIO/Investors";
|
||||||
|
import IOArtifacts from "../CreateIO/IOArtifacts";
|
||||||
|
import KeyMerits from "../CreateIO/KeyMerits";
|
||||||
import ViewIOdataHeader from "./ViewIOdataHeader";
|
import ViewIOdataHeader from "./ViewIOdataHeader";
|
||||||
import ViewIOdetails from "./ViewIOdetails";
|
import ViewIOdetails from "./ViewIOdetails";
|
||||||
import ViewIOdocs from "./ViewIOdocs";
|
|
||||||
import ViewKeyMerits from "./ViewKeyMerits";
|
|
||||||
import ViewIOartifacts from "./ViewIOartifacts";
|
|
||||||
import ViewInvestors from "./ViewInvestors";
|
|
||||||
import ViewIOcash from "./ViewIOcash";
|
|
||||||
import ViewIOnav from "./ViewIOnav";
|
|
||||||
import ViewDistribution from "./ViewDistribution";
|
|
||||||
import InvestmentDocument from "../CreateIO/InvestmentDocument";
|
|
||||||
import KeyMerits from "../CreateIO/KeyMerits";
|
|
||||||
import Investors from "../CreateIO/Investors";
|
|
||||||
import EditIO from "../EditIO/EditIO";
|
|
||||||
import IOArtifacts from "../CreateIO/IOArtifacts";
|
|
||||||
// import IOCashDetails from "../CreateIO/IOCashDetailsold";
|
// import IOCashDetails from "../CreateIO/IOCashDetailsold";
|
||||||
// import IONAVDetails from "../CreateIO/IONAVDetailsOld";
|
// import IONAVDetails from "../CreateIO/IONAVDetailsOld";
|
||||||
import { useGetIOByIdQuery, useGetIOprepopulateDataQuery } from "../../../Services/io.service";
|
import { GoDotFill } from "react-icons/go";
|
||||||
import UnderConstruction from "../../UnderConstruction";
|
import {
|
||||||
|
useGetIOByIdQuery,
|
||||||
|
useGetIOprepopulateDataQuery,
|
||||||
|
} from "../../../Services/io.service";
|
||||||
import Destribution from "../CreateIO/Destribution";
|
import Destribution from "../CreateIO/Destribution";
|
||||||
import IOCashDetails from "../CreateIO/IOCashDetails/IOCashDetails";
|
import IOCashDetails from "../CreateIO/IOCashDetails/IOCashDetails";
|
||||||
import IONAVDetails from "../CreateIO/IONAVDetails/IONAVDetails";
|
import IONAVDetails from "../CreateIO/IONAVDetails/IONAVDetails";
|
||||||
import IOTransaction from "../CreateIO/IOTransaction/IOTransaction";
|
import IOTransaction from "../CreateIO/IOTransaction/IOTransaction";
|
||||||
import { GoDotFill } from "react-icons/go";
|
|
||||||
|
|
||||||
const rotate = keyframes`
|
const rotate = keyframes`
|
||||||
from {
|
from {
|
||||||
@@ -69,7 +56,6 @@ const ViewIOdata = () => {
|
|||||||
const [isEditing, setIsEditing] = useState(false);
|
const [isEditing, setIsEditing] = useState(false);
|
||||||
const [isRefetchLoading, setIsRefetchLoading] = useState(false);
|
const [isRefetchLoading, setIsRefetchLoading] = useState(false);
|
||||||
const { IODetails, setIODetails } = useContext(GlobalStateContext);
|
const { IODetails, setIODetails } = useContext(GlobalStateContext);
|
||||||
console.log(IODetails?.isInvestedAmount);
|
|
||||||
|
|
||||||
const tabs = [
|
const tabs = [
|
||||||
{ label: "IO Details", content: <ViewIOdetails data={data?.data} /> },
|
{ label: "IO Details", content: <ViewIOdetails data={data?.data} /> },
|
||||||
@@ -193,13 +179,19 @@ const ViewIOdata = () => {
|
|||||||
cursor={"pointer"}
|
cursor={"pointer"}
|
||||||
/>
|
/>
|
||||||
</Box> */}
|
</Box> */}
|
||||||
<Stack position={"absolute"} right={1} bottom={1} direction="row" spacing={4}>
|
<Stack
|
||||||
|
position={"absolute"}
|
||||||
|
right={1}
|
||||||
|
bottom={1}
|
||||||
|
direction="row"
|
||||||
|
spacing={4}
|
||||||
|
>
|
||||||
<Button
|
<Button
|
||||||
isLoading={isRefetchLoading}
|
isLoading={isRefetchLoading}
|
||||||
loadingText="Refresh"
|
loadingText="Refresh"
|
||||||
colorScheme="forestGreen"
|
colorScheme="forestGreen"
|
||||||
variant="solid"
|
variant="solid"
|
||||||
size={'xs'}
|
size={"xs"}
|
||||||
onClick={handleRefresh}
|
onClick={handleRefresh}
|
||||||
fontWeight={400}
|
fontWeight={400}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -1,61 +1,59 @@
|
|||||||
import {
|
import {
|
||||||
Button,
|
Badge,
|
||||||
Divider,
|
Box,
|
||||||
|
HStack,
|
||||||
|
Icon,
|
||||||
Image,
|
Image,
|
||||||
Menu,
|
Menu,
|
||||||
MenuButton,
|
MenuButton,
|
||||||
MenuItem,
|
MenuItem,
|
||||||
MenuList,
|
MenuList,
|
||||||
Modal,
|
|
||||||
ModalBody,
|
|
||||||
ModalCloseButton,
|
|
||||||
ModalContent,
|
|
||||||
ModalFooter,
|
|
||||||
ModalHeader,
|
|
||||||
ModalOverlay,
|
|
||||||
Portal,
|
|
||||||
Text,
|
Text,
|
||||||
useDisclosure,
|
useDisclosure,
|
||||||
MenuItemOption,
|
|
||||||
MenuGroup,
|
|
||||||
MenuOptionGroup,
|
|
||||||
MenuDivider,
|
|
||||||
Badge,
|
|
||||||
Box,
|
|
||||||
Icon,
|
|
||||||
HStack,
|
|
||||||
useToast,
|
useToast,
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import header from "../../../assets/IOheader.png";
|
import { useContext, useRef } from "react";
|
||||||
|
import { GrGallery } from "react-icons/gr";
|
||||||
import { HiDotsVertical } from "react-icons/hi";
|
import { HiDotsVertical } from "react-icons/hi";
|
||||||
import { Link, useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
|
import Loader01 from "../../../Components/Loaders/Loader01";
|
||||||
|
import ToastBox from "../../../Components/ToastBox";
|
||||||
|
import {
|
||||||
|
decryptString,
|
||||||
|
encryptString,
|
||||||
|
isMaker,
|
||||||
|
} from "../../../Constants/Constants";
|
||||||
|
import GlobalStateContext from "../../../Contexts/GlobalStateContext";
|
||||||
|
import { useUpdateTransactionMutation } from "../../../Services/io.service";
|
||||||
import AmountInvested from "./HeaderModal/AmountInvested";
|
import AmountInvested from "./HeaderModal/AmountInvested";
|
||||||
import FeesExpenses from "./HeaderModal/FeesExpenses";
|
import Cancle from "./HeaderModal/Cancle";
|
||||||
import DistributionSponsor from "./HeaderModal/DistributionSponsor";
|
|
||||||
import DistributionInvestor from "./HeaderModal/DistributionInvestor";
|
import DistributionInvestor from "./HeaderModal/DistributionInvestor";
|
||||||
|
import DistributionSponsor from "./HeaderModal/DistributionSponsor";
|
||||||
|
import Exit from "./HeaderModal/Exit";
|
||||||
|
import FeesExpenses from "./HeaderModal/FeesExpenses";
|
||||||
import UpdateIONav from "./HeaderModal/UpdateIONav";
|
import UpdateIONav from "./HeaderModal/UpdateIONav";
|
||||||
import UpdateIOStatus from "./HeaderModal/UpdateIOStatus";
|
import UpdateIOStatus from "./HeaderModal/UpdateIOStatus";
|
||||||
import { useContext, useRef } from "react";
|
import { useAuthProfileQuery } from "../../../Services/token.serivce";
|
||||||
import GlobalStateContext from "../../../Contexts/GlobalStateContext";
|
|
||||||
import Exit from "./HeaderModal/Exit";
|
|
||||||
import Cancle from "./HeaderModal/Cancle";
|
|
||||||
import { AddIcon } from "@chakra-ui/icons";
|
|
||||||
import { GrGallery } from "react-icons/gr";
|
|
||||||
import Loader01 from "../../../Components/Loaders/Loader01";
|
|
||||||
import { useUpdateTransactionMutation } from "../../../Services/io.service";
|
|
||||||
import ToastBox from "../../../Components/ToastBox";
|
|
||||||
import { encryptString } from "../../../Constants/Constants";
|
|
||||||
// import { formatCurrency } from "../../../Components/CurrencyInput";
|
// import { formatCurrency } from "../../../Components/CurrencyInput";
|
||||||
// import { removeTrailingZeros } from "../../../Constants/Constants";
|
// import { removeTrailingZeros } from "../../../Constants/Constants";
|
||||||
|
|
||||||
const ViewIOdataHeader = ({ data, isLoading }) => {
|
const ViewIOdataHeader = ({ data, isLoading }) => {
|
||||||
const params = useParams()
|
const params = useParams();
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
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, isIOloading } = useContext(GlobalStateContext);
|
const { IODetails, isIOloading } = useContext(GlobalStateContext);
|
||||||
|
|
||||||
|
const { data: authProfile } = useAuthProfileQuery();
|
||||||
|
if (authProfile?.data?.role) {
|
||||||
|
localStorage.setItem("role", encryptString(authProfile.data.role));
|
||||||
|
} else {
|
||||||
|
console.warn("Role is undefined or null. Skipping localStorage update.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
isOpen: isInvestmentOpen,
|
isOpen: isInvestmentOpen,
|
||||||
onOpen: onInvestmentOpen,
|
onOpen: onInvestmentOpen,
|
||||||
@@ -108,94 +106,82 @@ const ViewIOdataHeader = ({ data, isLoading }) => {
|
|||||||
fontWeight: "400",
|
fontWeight: "400",
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log(
|
const [updateTransaction] = useUpdateTransactionMutation();
|
||||||
import.meta.env.VITE_IMAGE_URL +
|
|
||||||
IODetails?.artifactsImage?.[0]?.artifactPathName
|
|
||||||
);
|
|
||||||
|
|
||||||
const [updateTransaction] = useUpdateTransactionMutation()
|
|
||||||
|
|
||||||
const handleDistributionInvestors = async () =>{
|
|
||||||
|
|
||||||
|
const handleDistributionInvestors = async () => {
|
||||||
try {
|
try {
|
||||||
const res = await updateTransaction(id)
|
const res = await updateTransaction(id);
|
||||||
|
|
||||||
if (res?.data) {
|
if (res?.data) {
|
||||||
// toast({
|
// toast({
|
||||||
// render: () => (
|
// render: () => (
|
||||||
// <ToastBox status={"success"} message={res?.data?.message} />
|
// <ToastBox status={"success"} message={res?.data?.message} />
|
||||||
// ),
|
// ),
|
||||||
// });
|
// });
|
||||||
// setIsLoading(false);
|
// setIsLoading(false);
|
||||||
onDistInvestorOpen()
|
onDistInvestorOpen();
|
||||||
|
} else if (res?.error) {
|
||||||
} else if (res?.error) {
|
toast({
|
||||||
toast({
|
render: () => (
|
||||||
render: () => (
|
<ToastBox status={"error"} message={res?.error?.data?.message} />
|
||||||
<ToastBox status={"error"} message={res?.error?.data?.message} />
|
),
|
||||||
),
|
});
|
||||||
});
|
|
||||||
// setIsLoading(false);
|
// setIsLoading(false);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
const handleExit = async () =>{
|
|
||||||
|
|
||||||
|
const handleExit = async () => {
|
||||||
try {
|
try {
|
||||||
const res = await updateTransaction(id)
|
const res = await updateTransaction(id);
|
||||||
|
|
||||||
if (res?.data) {
|
if (res?.data) {
|
||||||
// toast({
|
// toast({
|
||||||
// render: () => (
|
// render: () => (
|
||||||
// <ToastBox status={"success"} message={res?.data?.message} />
|
// <ToastBox status={"success"} message={res?.data?.message} />
|
||||||
// ),
|
// ),
|
||||||
// });
|
// });
|
||||||
// setIsLoading(false);
|
// setIsLoading(false);
|
||||||
onExitOpen()
|
onExitOpen();
|
||||||
|
} else if (res?.error) {
|
||||||
} else if (res?.error) {
|
toast({
|
||||||
toast({
|
render: () => (
|
||||||
render: () => (
|
<ToastBox status={"error"} message={res?.error?.data?.message} />
|
||||||
<ToastBox status={"error"} message={res?.error?.data?.message} />
|
),
|
||||||
),
|
});
|
||||||
});
|
|
||||||
// setIsLoading(false);
|
// setIsLoading(false);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
const handleInvestment = async () =>{
|
|
||||||
|
|
||||||
|
const handleInvestment = async () => {
|
||||||
try {
|
try {
|
||||||
const res = await updateTransaction(id)
|
const res = await updateTransaction(id);
|
||||||
|
|
||||||
if (res?.data) {
|
if (res?.data) {
|
||||||
// toast({
|
// toast({
|
||||||
// render: () => (
|
// render: () => (
|
||||||
// <ToastBox status={"success"} message={res?.data?.message} />
|
// <ToastBox status={"success"} message={res?.data?.message} />
|
||||||
// ),
|
// ),
|
||||||
// });
|
// });
|
||||||
// setIsLoading(false);
|
// setIsLoading(false);
|
||||||
onInvestmentOpen()
|
onInvestmentOpen();
|
||||||
|
} else if (res?.error) {
|
||||||
} else if (res?.error) {
|
toast({
|
||||||
toast({
|
render: () => (
|
||||||
render: () => (
|
<ToastBox status={"error"} message={res?.error?.data?.message} />
|
||||||
<ToastBox status={"error"} message={res?.error?.data?.message} />
|
),
|
||||||
),
|
});
|
||||||
});
|
|
||||||
// setIsLoading(false);
|
// setIsLoading(false);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
const menu = [
|
const menu = [
|
||||||
{
|
{
|
||||||
@@ -251,8 +237,8 @@ const ViewIOdataHeader = ({ data, isLoading }) => {
|
|||||||
apiTransactionTitles?.includes(item.id)
|
apiTransactionTitles?.includes(item.id)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const balanceAmount =
|
||||||
const balanceAmount = IODetails?.goalAmount - IODetails?.totalAmtInvestmentInUSD
|
IODetails?.goalAmount - IODetails?.totalAmtInvestmentInUSD;
|
||||||
|
|
||||||
return IODetails?.investmentNameEnglish ? (
|
return IODetails?.investmentNameEnglish ? (
|
||||||
<Box
|
<Box
|
||||||
@@ -261,19 +247,19 @@ const ViewIOdataHeader = ({ data, isLoading }) => {
|
|||||||
justifyContent={"space-between"}
|
justifyContent={"space-between"}
|
||||||
gap={8}
|
gap={8}
|
||||||
bg={
|
bg={
|
||||||
IODetails?.ioStatus?.statusAdmin === "Draft"
|
IODetails?.ioStatus?.statusAdmin === import.meta.env.VITE_STATUS_DRAFT
|
||||||
? "#EDF2F7"
|
? "#EDF2F7"
|
||||||
: IODetails?.ioStatus?.statusAdmin === "Processing"
|
: IODetails?.ioStatus?.statusAdmin === import.meta.env.VITE_STATUS_PROCESSING
|
||||||
? "#FEFBBF"
|
? "#FEFBBF"
|
||||||
: IODetails?.ioStatus?.statusAdmin === "Open"
|
: IODetails?.ioStatus?.statusAdmin === import.meta.env.VITE_STATUS_OPEN
|
||||||
? "#BEE2F8"
|
? "#BEE2F8"
|
||||||
: IODetails?.ioStatus?.statusAdmin === "Closed"
|
: IODetails?.ioStatus?.statusAdmin === import.meta.env.VITE_STATUS_CLOSED
|
||||||
? "#C6F6D5"
|
? "#C6F6D5"
|
||||||
: IODetails?.ioStatus?.statusAdmin === "Exited"
|
: IODetails?.ioStatus?.statusAdmin === import.meta.env.VITE_STATUS_EXITED
|
||||||
? "#FED7D7"
|
? "#FED7D7"
|
||||||
: IODetails?.ioStatus?.statusAdmin === "Cancelled"
|
: IODetails?.ioStatus?.statusAdmin === import.meta.env.VITE_STATUS_CANCELLED
|
||||||
? "#E9D8FD"
|
? "#E9D8FD"
|
||||||
: IODetails?.ioStatus?.statusAdmin === "DeActivate"
|
: IODetails?.ioStatus?.statusAdmin === import.meta.env.VITE_STATUS_DEACTIVATE
|
||||||
? "#E9D8FD"
|
? "#E9D8FD"
|
||||||
: null
|
: null
|
||||||
}
|
}
|
||||||
@@ -318,7 +304,6 @@ const ViewIOdataHeader = ({ data, isLoading }) => {
|
|||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<Box>
|
<Box>
|
||||||
|
|
||||||
<Box display={"flex"} gap={2} pb={1}>
|
<Box display={"flex"} gap={2} pb={1}>
|
||||||
<Text
|
<Text
|
||||||
as={"span"}
|
as={"span"}
|
||||||
@@ -336,7 +321,7 @@ const ViewIOdataHeader = ({ data, isLoading }) => {
|
|||||||
</Text>
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<Box display={"flex"} gap={2} pb={1}>
|
<Box display={"flex"} gap={2} pb={1}>
|
||||||
<Text
|
<Text
|
||||||
as={"span"}
|
as={"span"}
|
||||||
fontSize={"xs"}
|
fontSize={"xs"}
|
||||||
@@ -353,7 +338,7 @@ const ViewIOdataHeader = ({ data, isLoading }) => {
|
|||||||
</Text>
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<Box display={"flex"} gap={2} pb={1}>
|
<Box display={"flex"} gap={2} pb={1}>
|
||||||
<Text
|
<Text
|
||||||
as={"span"}
|
as={"span"}
|
||||||
fontSize={"xs"}
|
fontSize={"xs"}
|
||||||
@@ -364,18 +349,13 @@ const ViewIOdataHeader = ({ data, isLoading }) => {
|
|||||||
IO ID :-
|
IO ID :-
|
||||||
</Text>
|
</Text>
|
||||||
<Text as={"span"} fontSize={"xs"} fontWeight={"500"}>
|
<Text as={"span"} fontSize={"xs"} fontWeight={"500"}>
|
||||||
{IODetails?.io_id
|
{IODetails?.io_id ? IODetails?.io_id : "---"}
|
||||||
? IODetails?.io_id
|
|
||||||
: "---"}
|
|
||||||
</Text>
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
</HStack>
|
</HStack>
|
||||||
|
|
||||||
<Box gap={8} me={12} w={"220px"}>
|
<Box gap={8} me={12} w={"220px"}>
|
||||||
|
|
||||||
<Box display={"flex"} justifyContent={"space-between"} gap={2} pb={1}>
|
<Box display={"flex"} justifyContent={"space-between"} gap={2} pb={1}>
|
||||||
<Text
|
<Text
|
||||||
as={"span"}
|
as={"span"}
|
||||||
@@ -405,10 +385,13 @@ const ViewIOdataHeader = ({ data, isLoading }) => {
|
|||||||
</Text>
|
</Text>
|
||||||
<Text as={"span"} fontSize={"xs"} fontWeight={"500"}>
|
<Text as={"span"} fontSize={"xs"} fontWeight={"500"}>
|
||||||
{/* {IODetails?.ioCash ? formatCurrency(removeTrailingZeros(IODetails?.ioCash)) : "00.00"} */}
|
{/* {IODetails?.ioCash ? formatCurrency(removeTrailingZeros(IODetails?.ioCash)) : "00.00"} */}
|
||||||
{parseFloat(IODetails?.totalAmtInvestmentInUSD || 0).toLocaleString(undefined, {
|
{parseFloat(IODetails?.totalAmtInvestmentInUSD || 0).toLocaleString(
|
||||||
minimumFractionDigits: 2,
|
undefined,
|
||||||
maximumFractionDigits: 2,
|
{
|
||||||
})}
|
minimumFractionDigits: 2,
|
||||||
|
maximumFractionDigits: 2,
|
||||||
|
}
|
||||||
|
)}
|
||||||
</Text>
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
@@ -449,17 +432,17 @@ const ViewIOdataHeader = ({ data, isLoading }) => {
|
|||||||
textTransform={"none"}
|
textTransform={"none"}
|
||||||
// variant={"solid"}
|
// variant={"solid"}
|
||||||
colorScheme={
|
colorScheme={
|
||||||
IODetails?.ioStatus?.statusAdmin === "Draft"
|
IODetails?.ioStatus?.statusAdmin === import.meta.env.VITE_STATUS_DRAFT
|
||||||
? "gray"
|
? "gray"
|
||||||
: IODetails?.ioStatus?.statusAdmin === "Processing"
|
: IODetails?.ioStatus?.statusAdmin === import.meta.env.VITE_STATUS_PROCESSING
|
||||||
? "yellow"
|
? "yellow"
|
||||||
: IODetails?.ioStatus?.statusAdmin === "Open"
|
: IODetails?.ioStatus?.statusAdmin === import.meta.env.VITE_STATUS_OPEN
|
||||||
? "blue"
|
? "blue"
|
||||||
: IODetails?.ioStatus?.statusAdmin === "Closed"
|
: IODetails?.ioStatus?.statusAdmin === import.meta.env.VITE_STATUS_CLOSED
|
||||||
? "green"
|
? "green"
|
||||||
: IODetails?.ioStatus?.statusAdmin === "Exited"
|
: IODetails?.ioStatus?.statusAdmin === import.meta.env.VITE_STATUS_EXITED
|
||||||
? "red"
|
? "red"
|
||||||
: IODetails?.ioStatus?.statusAdmin === "Cancelled"
|
: IODetails?.ioStatus?.statusAdmin === import.meta.env.VITE_STATUS_CANCELLED
|
||||||
? "purple"
|
? "purple"
|
||||||
: "purple"
|
: "purple"
|
||||||
}
|
}
|
||||||
@@ -533,39 +516,41 @@ const ViewIOdataHeader = ({ data, isLoading }) => {
|
|||||||
alignItems={"start"}
|
alignItems={"start"}
|
||||||
height={"95px"}
|
height={"95px"}
|
||||||
>
|
>
|
||||||
{localStorage?.getItem("role") === encryptString(import.meta.env.VITE_VITE_MAKER) && <Menu>
|
{isMaker() && (
|
||||||
<MenuButton
|
<Menu>
|
||||||
className="link p-1 rounded-1 "
|
<MenuButton
|
||||||
bg={"#fff"}
|
className="link p-1 rounded-1 "
|
||||||
_hover={{ backgroundColor: "#fff !important" }}
|
bg={"#fff"}
|
||||||
onClick={onOpen}
|
_hover={{ backgroundColor: "#fff !important" }}
|
||||||
ref={btnRef}
|
onClick={onOpen}
|
||||||
>
|
ref={btnRef}
|
||||||
<HiDotsVertical className="rubix-text-dark fs-6" />
|
|
||||||
</MenuButton>
|
|
||||||
<MenuList fontSize={"sm"}>
|
|
||||||
<MenuItem
|
|
||||||
_hover={{
|
|
||||||
bg: "#fff",
|
|
||||||
}}
|
|
||||||
as={"span"}
|
|
||||||
fontWeight={600}
|
|
||||||
className="border-bottom"
|
|
||||||
>
|
>
|
||||||
Tansaction
|
<HiDotsVertical className="rubix-text-dark fs-6" />
|
||||||
</MenuItem>
|
</MenuButton>
|
||||||
|
<MenuList fontSize={"sm"}>
|
||||||
{filteredMenu?.map(({ id, title, onClickFunction }) => (
|
|
||||||
<MenuItem
|
<MenuItem
|
||||||
key={id}
|
_hover={{
|
||||||
onClick={onClickFunction}
|
bg: "#fff",
|
||||||
|
}}
|
||||||
|
as={"span"}
|
||||||
|
fontWeight={600}
|
||||||
className="border-bottom"
|
className="border-bottom"
|
||||||
>
|
>
|
||||||
{title}
|
Tansaction
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
))}
|
|
||||||
</MenuList>
|
{filteredMenu?.map(({ id, title, onClickFunction }) => (
|
||||||
</Menu>}
|
<MenuItem
|
||||||
|
key={id}
|
||||||
|
onClick={onClickFunction}
|
||||||
|
className="border-bottom"
|
||||||
|
>
|
||||||
|
{title}
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
</MenuList>
|
||||||
|
</Menu>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* Modals */}
|
{/* Modals */}
|
||||||
<AmountInvested isOpen={isInvestmentOpen} onClose={onInvestmentClose} />
|
<AmountInvested isOpen={isInvestmentOpen} onClose={onInvestmentClose} />
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
|
import { ViewIcon } from "@chakra-ui/icons";
|
||||||
import {
|
import {
|
||||||
Avatar,
|
|
||||||
Badge,
|
Badge,
|
||||||
Box,
|
Box,
|
||||||
Button,
|
Button,
|
||||||
@@ -11,23 +11,21 @@ import {
|
|||||||
useDisclosure,
|
useDisclosure,
|
||||||
useToast,
|
useToast,
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import React, { useContext, useEffect, useState, useRef } from "react";
|
import React, { useContext, useEffect, useRef, useState } from "react";
|
||||||
import { OPACITY_ON_LOAD } from "../../../Layout/animations";
|
|
||||||
import NormalTable from "../../../Components/DataTable/NormalTable";
|
|
||||||
import { Link, Link as RouterLink, useNavigate } from "react-router-dom";
|
|
||||||
import {
|
|
||||||
ViewIcon,
|
|
||||||
} from "@chakra-ui/icons";
|
|
||||||
import Pagination from "../../../Components/Pagination";
|
|
||||||
import GlobalStateContext from "../../../Contexts/GlobalStateContext";
|
|
||||||
import CustomAlertDialog from "../../../Components/CustomAlertDialog";
|
|
||||||
import ToastBox from "../../../Components/ToastBox";
|
|
||||||
import { debounce } from "../../Master/Sponser/AddSponser";
|
|
||||||
import InvestmentDetailsEdit from "./InvestmentDetailsEdit";
|
|
||||||
import { useGetInvestorsQuery } from "../../../Services/investor.details.service";
|
|
||||||
import { TABLE_PAGINATION } from "../../../Constants/Paginations";
|
|
||||||
import { exportToExcel, exportToExcelNew, generateSerialNumber } from "../../../Constants/Constants";
|
|
||||||
import { LuFileSpreadsheet } from "react-icons/lu";
|
import { LuFileSpreadsheet } from "react-icons/lu";
|
||||||
|
import { useNavigate } from "react-router-dom";
|
||||||
|
import CustomAlertDialog from "../../../Components/CustomAlertDialog";
|
||||||
|
import NormalTable from "../../../Components/DataTable/NormalTable";
|
||||||
|
import Pagination from "../../../Components/Pagination";
|
||||||
|
import {
|
||||||
|
exportToExcelNew,
|
||||||
|
generateSerialNumber,
|
||||||
|
} from "../../../Constants/Constants";
|
||||||
|
import { INVESTOR_TABLE_PAGINATION } from "../../../Constants/Paginations";
|
||||||
|
import GlobalStateContext from "../../../Contexts/GlobalStateContext";
|
||||||
|
import { OPACITY_ON_LOAD } from "../../../Layout/animations";
|
||||||
|
import { useGetInvestorsQuery } from "../../../Services/investor.details.service";
|
||||||
|
import InvestmentDetailsEdit from "./InvestmentDetailsEdit";
|
||||||
|
|
||||||
const formatDate = (date) => new Date(date).toLocaleDateString(); // Simple date formatter
|
const formatDate = (date) => new Date(date).toLocaleDateString(); // Simple date formatter
|
||||||
|
|
||||||
@@ -49,10 +47,11 @@ const InvestorDetails = () => {
|
|||||||
} = useDisclosure();
|
} = useDisclosure();
|
||||||
const btnRef = React.useRef();
|
const btnRef = React.useRef();
|
||||||
|
|
||||||
|
|
||||||
// =========================== [Use State] =============================
|
// =========================== [Use State] =============================
|
||||||
const [pageSize, setPageSize] = useState(TABLE_PAGINATION?.size);
|
const [pageSize, setPageSize] = useState(INVESTOR_TABLE_PAGINATION?.size);
|
||||||
const [currentPage, setCurrentPage] = useState(TABLE_PAGINATION?.page);
|
const [currentPage, setCurrentPage] = useState(
|
||||||
|
INVESTOR_TABLE_PAGINATION?.page
|
||||||
|
);
|
||||||
const [searchTerm, setSearchTerm] = useState("");
|
const [searchTerm, setSearchTerm] = useState("");
|
||||||
const [debouncedSearchTerm, setDebouncedSearchTerm] = useState("");
|
const [debouncedSearchTerm, setDebouncedSearchTerm] = useState("");
|
||||||
|
|
||||||
@@ -73,20 +72,19 @@ const InvestorDetails = () => {
|
|||||||
data: investorDetails,
|
data: investorDetails,
|
||||||
isLoading: investorDetailsLoading,
|
isLoading: investorDetailsLoading,
|
||||||
error,
|
error,
|
||||||
} = useGetInvestorsQuery({
|
} = useGetInvestorsQuery(
|
||||||
page: debouncedSearchTerm ? undefined : currentPage, // Omit pagination for search
|
{
|
||||||
size: debouncedSearchTerm ? undefined : pageSize, // Omit pagination for search userStatus KYCStatus investorType_xid
|
page: debouncedSearchTerm ? undefined : currentPage, // Omit pagination for search
|
||||||
search: debouncedSearchTerm,
|
size: debouncedSearchTerm ? undefined : pageSize, // Omit pagination for search userStatus KYCStatus investorType_xid
|
||||||
userStatus: status,
|
search: debouncedSearchTerm,
|
||||||
KYCStatus: kyc,
|
userStatus: status,
|
||||||
country_xid: country
|
KYCStatus: kyc,
|
||||||
|
country_xid: country,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
skip: debouncedSearchTerm === "" && searchTerm !== "", // Skip if search is empty and it's not the initial request
|
skip: debouncedSearchTerm === "" && searchTerm !== "", // Skip if search is empty and it's not the initial request
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Simulate loading
|
// Simulate loading
|
||||||
@@ -113,34 +111,32 @@ const InvestorDetails = () => {
|
|||||||
"Action",
|
"Action",
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
// ====================================================[Table Filter]================================================================
|
// ====================================================[Table Filter]================================================================
|
||||||
const exportInvestor = investorDetails?.data?.rows?.map((item, idx) => ({
|
const exportInvestor = investorDetails?.data?.rows?.map((item, idx) => ({
|
||||||
"Id": parseInt(item?.id, 10) || item?.id, // Convert to integer, fallback to string if conversion fails
|
Id: parseInt(item?.id, 10) || item?.id, // Convert to integer, fallback to string if conversion fails
|
||||||
"Client ID": item?.clientReference_id, // This is likely a string
|
"Client ID": item?.clientReference_id, // This is likely a string
|
||||||
"First Name": item?.principal?.firstName,
|
"First Name": item?.principal?.firstName,
|
||||||
"Last Name": item?.principal?.lastName,
|
"Last Name": item?.principal?.lastName,
|
||||||
"Country": item?.country?.countryName,
|
Country: item?.country?.countryName,
|
||||||
"Phone Number": item?.principal?.mobileNumber, // Skipping integer conversion, as this is likely a string
|
"Phone Number": item?.principal?.mobileNumber, // Skipping integer conversion, as this is likely a string
|
||||||
"E-mail ID": item?.principal?.emailAddress,
|
"E-mail ID": item?.principal?.emailAddress,
|
||||||
"Type": item?.investor_type?.investorTypeName,
|
Type: item?.investor_type?.investorTypeName,
|
||||||
"Status": item.ioStatus ? "Ban" : "Unban",
|
Status: item.ioStatus ? "Ban" : "Unban",
|
||||||
"KYC Status": item.KYCStatus ? "Completed" : "Not complete"
|
"KYC Status": item.KYCStatus ? "Completed" : "Not complete",
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const extractedArray = investorDetails?.data?.rows?.map((item, idx) => ({
|
const extractedArray = investorDetails?.data?.rows?.map((item, idx) => ({
|
||||||
id: item?.id,
|
id: item?.id,
|
||||||
"Sr No": (
|
"Sr No": (
|
||||||
<Text
|
<Text
|
||||||
w={'24px'}
|
w={"24px"}
|
||||||
justifyContent={slideFromRight ? "right" : "left"}
|
justifyContent={slideFromRight ? "right" : "left"}
|
||||||
as={"span"}
|
as={"span"}
|
||||||
color={"gray.600"}
|
color={"gray.600"}
|
||||||
className="d-flex align-items-center fw-bold web-text-small"
|
className="d-flex align-items-center fw-bold web-text-small"
|
||||||
>
|
>
|
||||||
{/* {item.id} */}
|
{/* {item.id} */}
|
||||||
{generateSerialNumber(idx,currentPage, pageSize )}
|
{generateSerialNumber(idx, currentPage, pageSize)}
|
||||||
|
|
||||||
</Text>
|
</Text>
|
||||||
),
|
),
|
||||||
"Client ID": (
|
"Client ID": (
|
||||||
@@ -185,39 +181,44 @@ const InvestorDetails = () => {
|
|||||||
</Text>
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
),
|
),
|
||||||
"Type": (
|
Type: (
|
||||||
<Box w={"auto"} isTruncated={true}>
|
<Box w={"auto"} isTruncated={true}>
|
||||||
<Text as={"span"} >
|
<Text as={"span"}>
|
||||||
<Badge color={"forestGreen.500"} variant={'ghost'} fontWeight={"700"} px={2} py={0.5}>
|
<Badge
|
||||||
|
color={"forestGreen.500"}
|
||||||
|
variant={"ghost"}
|
||||||
|
fontWeight={"700"}
|
||||||
|
px={2}
|
||||||
|
py={0.5}
|
||||||
|
>
|
||||||
{item?.investor_type?.investorTypeName}
|
{item?.investor_type?.investorTypeName}
|
||||||
</Badge>
|
</Badge>
|
||||||
</Text>
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
),
|
),
|
||||||
Status: (
|
Status: (
|
||||||
<Box w={"auto"} isTruncated={true}>
|
<Box w={"auto"} isTruncated={true}>
|
||||||
<Badge
|
<Badge
|
||||||
fontWeight={"700"}
|
fontWeight={"700"}
|
||||||
textTransform={"none"}
|
textTransform={"none"}
|
||||||
colorScheme={item.ioStatus ? "red" : "green"}
|
colorScheme={item.ioStatus ? "red" : "green"}
|
||||||
px={2}
|
px={2}
|
||||||
py={0.5}
|
py={0.5}
|
||||||
>
|
>
|
||||||
{item.ioStatus ? "Ban" : "Unban"}
|
{item.ioStatus ? "Ban" : "Unban"}
|
||||||
</Badge>
|
</Badge>
|
||||||
</Box>
|
</Box>
|
||||||
),
|
),
|
||||||
"KYC Status": (
|
"KYC Status": (
|
||||||
<Box w={"auto"} display={'flex'} alignItems={'center'} isTruncated={true}>
|
<Box w={"auto"} display={"flex"} alignItems={"center"} isTruncated={true}>
|
||||||
<Text
|
<Text
|
||||||
as={'span'}
|
as={"span"}
|
||||||
fontWeight={"700"}
|
fontWeight={"700"}
|
||||||
textTransform={"none"}
|
textTransform={"none"}
|
||||||
color={item?.KYCStatus === true ? "green" : "yellow.500"}
|
color={item?.KYCStatus === true ? "green" : "yellow.500"}
|
||||||
px={2}
|
px={2}
|
||||||
py={0.5}
|
py={0.5}
|
||||||
variant={'solid'}
|
variant={"solid"}
|
||||||
|
|
||||||
>
|
>
|
||||||
{/* {item.KYCStatus ? "Completed" : "Not complete"} */}
|
{/* {item.KYCStatus ? "Completed" : "Not complete"} */}
|
||||||
{item?.KYCStatus === true ? "Completed" : "NotCompleted"}
|
{item?.KYCStatus === true ? "Completed" : "NotCompleted"}
|
||||||
@@ -235,7 +236,7 @@ const InvestorDetails = () => {
|
|||||||
placement="top"
|
placement="top"
|
||||||
>
|
>
|
||||||
<Button
|
<Button
|
||||||
isDisabled={item.ioStatus}
|
isDisabled={item.ioStatus}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
navigate(`/investor-details/profile-view/${item.id}`);
|
navigate(`/investor-details/profile-view/${item.id}`);
|
||||||
}}
|
}}
|
||||||
@@ -266,7 +267,6 @@ const InvestorDetails = () => {
|
|||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
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">
|
||||||
@@ -352,29 +352,23 @@ const InvestorDetails = () => {
|
|||||||
currentPage={currentPage}
|
currentPage={currentPage}
|
||||||
setCurrentPage={setCurrentPage}
|
setCurrentPage={setCurrentPage}
|
||||||
totalItems={investorDetails?.data?.totalItems}
|
totalItems={investorDetails?.data?.totalItems}
|
||||||
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
</HStack>
|
</HStack>
|
||||||
|
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
onClick={() =>
|
onClick={() => exportToExcelNew(exportInvestor, "Investor Details")}
|
||||||
exportToExcelNew(exportInvestor, "Investor Details")
|
leftIcon={<LuFileSpreadsheet />}
|
||||||
}
|
colorScheme="forestGreen"
|
||||||
leftIcon={<LuFileSpreadsheet />}
|
size={"sm"}
|
||||||
colorScheme="forestGreen"
|
variant={"outline"}
|
||||||
size={"sm"}
|
rounded={"sm"}
|
||||||
variant={"outline"}
|
fontSize={"xs"}
|
||||||
rounded={"sm"}
|
w={100}
|
||||||
fontSize={"xs"}
|
me={2}
|
||||||
w={100}
|
isDisabled={exportInvestor?.length === 0}
|
||||||
me={2}
|
>
|
||||||
|
Export xls
|
||||||
isDisabled={exportInvestor?.length === 0}
|
</Button>
|
||||||
>
|
|
||||||
Export xls
|
|
||||||
</Button>
|
|
||||||
</HStack>
|
</HStack>
|
||||||
<InvestmentDetailsEdit
|
<InvestmentDetailsEdit
|
||||||
id={actionId}
|
id={actionId}
|
||||||
|
|||||||
@@ -245,7 +245,7 @@ const Login = () => {
|
|||||||
)}
|
)}
|
||||||
</FormControl>
|
</FormControl>
|
||||||
<Box fontSize={"sm"} display={"flex"} justifyContent={"end"} mt={0}>
|
<Box fontSize={"sm"} display={"flex"} justifyContent={"end"} mt={0}>
|
||||||
<Text fontWeight={500} cursor={"pointer"} onClick={onOpen}>Forget Password?</Text>
|
<Text fontWeight={500} cursor={"pointer"} onClick={onOpen}>Forgot Password?</Text>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
@@ -316,7 +316,7 @@ const AddInvestmentType = () => {
|
|||||||
|
|
||||||
<Box display={"flex"} justifyContent={"space-between"} alignItems={"center"} mt={5} px={4} mb={5}>
|
<Box display={"flex"} justifyContent={"space-between"} alignItems={"center"} mt={5} px={4} mb={5}>
|
||||||
<Text fontSize={"sm"} mb={0} onClick={() => navigate(-1)} cursor={"pointer"}>
|
<Text fontSize={"sm"} mb={0} onClick={() => navigate(-1)} cursor={"pointer"}>
|
||||||
<ArrowBackIcon fontSize={"xl"} me={2} />Add Details
|
<ArrowBackIcon fontSize={"xl"} me={2} />{params?.id ? "Edit Details" : "Add Details"}
|
||||||
</Text>
|
</Text>
|
||||||
<SwitchButton isSwitchOn={isSwitchOn} setIsSwitchOn={setIsSwitchOn} />
|
<SwitchButton isSwitchOn={isSwitchOn} setIsSwitchOn={setIsSwitchOn} />
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@@ -301,7 +301,7 @@ const AddSponser = () => {
|
|||||||
{/* ===================== [Switch Button] ======================== */}
|
{/* ===================== [Switch Button] ======================== */}
|
||||||
<Box display={"flex"} justifyContent={"space-between"} alignItems={"center"} mt={5} px={4}>
|
<Box display={"flex"} justifyContent={"space-between"} alignItems={"center"} mt={5} px={4}>
|
||||||
<Text fontSize={"sm"} mb={0} onClick={() => navigate(-1)} cursor={"pointer"}>
|
<Text fontSize={"sm"} mb={0} onClick={() => navigate(-1)} cursor={"pointer"}>
|
||||||
<ArrowBackIcon fontSize={"xl"} me={2} />Add Details
|
<ArrowBackIcon fontSize={"xl"} me={2} />{params?.id ? "Edit Details" : "Add Details"}
|
||||||
</Text>
|
</Text>
|
||||||
<SwitchButton isSwitchOn={isSwitchOn} setIsSwitchOn={setIsSwitchOn} />
|
<SwitchButton isSwitchOn={isSwitchOn} setIsSwitchOn={setIsSwitchOn} />
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@@ -1,26 +1,21 @@
|
|||||||
|
import { CheckIcon, CloseIcon, InfoIcon } from "@chakra-ui/icons";
|
||||||
import {
|
import {
|
||||||
Avatar,
|
Avatar,
|
||||||
Box,
|
Box,
|
||||||
ButtonGroup,
|
ButtonGroup,
|
||||||
Editable,
|
|
||||||
EditableInput,
|
|
||||||
EditablePreview,
|
|
||||||
EditableTextarea,
|
|
||||||
Flex,
|
|
||||||
HStack,
|
HStack,
|
||||||
Heading,
|
Heading,
|
||||||
Icon,
|
Icon,
|
||||||
IconButton,
|
IconButton,
|
||||||
Input,
|
|
||||||
Text,
|
Text,
|
||||||
VStack,
|
VStack,
|
||||||
useEditableControls,
|
useEditableControls
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import React from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { OPACITY_ON_LOAD } from "../../Layout/animations";
|
|
||||||
import { CheckIcon, CloseIcon, EditIcon, InfoIcon } from "@chakra-ui/icons";
|
|
||||||
import { FaEarthAmericas } from "react-icons/fa6";
|
import { FaEarthAmericas } from "react-icons/fa6";
|
||||||
import logoMini from "../../assets/propic.png";
|
import logoMini from "../../assets/propic.png";
|
||||||
|
import { OPACITY_ON_LOAD } from "../../Layout/animations";
|
||||||
|
import { useAuthProfileQuery } from "../../Services/token.serivce";
|
||||||
|
|
||||||
const Profile = () => {
|
const Profile = () => {
|
||||||
/* Here's a custom control */
|
/* Here's a custom control */
|
||||||
@@ -53,19 +48,56 @@ const Profile = () => {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
const { data } = useAuthProfileQuery();
|
||||||
|
|
||||||
|
const [fields, setFields] = useState([
|
||||||
// Array of fields to render
|
{
|
||||||
const fields = [
|
name: "firstName",
|
||||||
{ name: "firstName", label: "First Name", defaultValue: "Faisal" },
|
label: "First Name",
|
||||||
{ name: "lastName", label: "Last Name", defaultValue: "Aljalahma" },
|
defaultValue: null,
|
||||||
{ name: "email", label: "Email Address", defaultValue: "f.aljalahma@tanamicapital.com" },
|
},
|
||||||
{ name: "mobile", label: "Mobile Number", defaultValue: "9898767876" },
|
{
|
||||||
{ name: "role", label: "Role", defaultValue: "Maker" },
|
name: "lastName",
|
||||||
];
|
label: "Last Name",
|
||||||
|
defaultValue: null,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "email",
|
||||||
|
label: "Email Address",
|
||||||
|
defaultValue: null,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "mobile",
|
||||||
|
label: "Mobile Number",
|
||||||
|
defaultValue: null,
|
||||||
|
},
|
||||||
|
{ name: "role", label: "Role", defaultValue: null },
|
||||||
|
]);
|
||||||
|
useEffect(() => {
|
||||||
|
setFields([
|
||||||
|
{
|
||||||
|
name: "firstName",
|
||||||
|
label: "First Name",
|
||||||
|
defaultValue: data?.data?.firstName || null,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastName",
|
||||||
|
label: "Last Name",
|
||||||
|
defaultValue: data?.data?.lastName || null,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "email",
|
||||||
|
label: "Email Address",
|
||||||
|
defaultValue: data?.data?.emailAddress || null,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "mobile",
|
||||||
|
label: "Mobile Number",
|
||||||
|
defaultValue: data?.data?.mobileNumber || null,
|
||||||
|
},
|
||||||
|
{ name: "role", label: "Role", defaultValue: data?.data?.role || null },
|
||||||
|
]);
|
||||||
|
}, [data]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<VStack
|
<VStack
|
||||||
@@ -114,7 +146,7 @@ const Profile = () => {
|
|||||||
color={"gray.700"}
|
color={"gray.700"}
|
||||||
fontWeight={500}
|
fontWeight={500}
|
||||||
>
|
>
|
||||||
Faisal Aljalahma
|
{data?.data?.firstName + " " + data?.data?.lastName}
|
||||||
</Text>
|
</Text>
|
||||||
|
|
||||||
<Text
|
<Text
|
||||||
@@ -123,7 +155,7 @@ const Profile = () => {
|
|||||||
color={"gray.500"}
|
color={"gray.500"}
|
||||||
fontWeight={400}
|
fontWeight={400}
|
||||||
>
|
>
|
||||||
f.aljalahma@tanamicapital.com
|
{data?.data?.emailAddress}
|
||||||
</Text>
|
</Text>
|
||||||
</VStack>
|
</VStack>
|
||||||
</HStack>
|
</HStack>
|
||||||
@@ -150,16 +182,16 @@ const Profile = () => {
|
|||||||
fontWeight={500}
|
fontWeight={500}
|
||||||
>
|
>
|
||||||
{" "}
|
{" "}
|
||||||
<Icon as={FaEarthAmericas} /> Maker
|
<Icon as={FaEarthAmericas} /> {data?.data?.role}
|
||||||
</Text>
|
</Text>
|
||||||
</VStack>
|
</VStack>
|
||||||
</HStack>
|
</HStack>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
|
{/*
|
||||||
<Heading as="h3" size="sm">
|
<Heading as="h3" size="sm">
|
||||||
About you
|
About you
|
||||||
</Heading>
|
</Heading>
|
||||||
|
|
||||||
<Box
|
<Box
|
||||||
rounded="md"
|
rounded="md"
|
||||||
boxShadow="base"
|
boxShadow="base"
|
||||||
@@ -170,55 +202,56 @@ const Profile = () => {
|
|||||||
alignItems="flex-start"
|
alignItems="flex-start"
|
||||||
p={6}
|
p={6}
|
||||||
gap={0}
|
gap={0}
|
||||||
|
|
||||||
pb={6}
|
pb={6}
|
||||||
>
|
>
|
||||||
|
{fields?.map((item) => (
|
||||||
{fields?.map((item) => (
|
<VStack
|
||||||
<VStack alignItems={"flex-start"} w={"100%"} gap={1.5} mb={6} key={item?.label}>
|
alignItems={"flex-start"}
|
||||||
<Text
|
w={"100%"}
|
||||||
as={"span"}
|
gap={1.5}
|
||||||
fontSize="xs"
|
mb={6}
|
||||||
fontWeight="semibold"
|
key={item?.label}
|
||||||
color={"gray.500"}
|
>
|
||||||
>
|
<Text
|
||||||
{item?.label}
|
as={"span"}
|
||||||
</Text>
|
fontSize="xs"
|
||||||
<Editable
|
fontWeight="semibold"
|
||||||
position={"relative"}
|
color={"gray.500"}
|
||||||
gap={0}
|
>
|
||||||
defaultValue={item?.defaultValue}
|
{item?.label}
|
||||||
w="100%"
|
</Text>
|
||||||
>
|
<Editable
|
||||||
<EditablePreview
|
position={"relative"}
|
||||||
cursor={'pointer'}
|
gap={0}
|
||||||
p={2}
|
defaultValue={item?.defaultValue}
|
||||||
rounded={"sm"}
|
w="100%"
|
||||||
w={"100%"}
|
>
|
||||||
_hover={{
|
<EditablePreview
|
||||||
bg: "gray.100",
|
cursor={"pointer"}
|
||||||
}}
|
p={2}
|
||||||
fontSize="sm"
|
rounded={"sm"}
|
||||||
transition={"0.5s"}
|
w={"100%"}
|
||||||
/>
|
_hover={{
|
||||||
<Input
|
bg: "gray.100",
|
||||||
as={EditableInput}
|
}}
|
||||||
ps={2}
|
fontSize="sm"
|
||||||
size={'sm'}
|
transition={"0.5s"}
|
||||||
fontSize="sm"
|
/>
|
||||||
rounded={"sm"}
|
<Input
|
||||||
_focus={{
|
as={EditableInput}
|
||||||
borderColor:"blue.500"
|
ps={2}
|
||||||
}}
|
size={"sm"}
|
||||||
/>
|
fontSize="sm"
|
||||||
<EditableControls />
|
rounded={"sm"}
|
||||||
</Editable>
|
_focus={{
|
||||||
</VStack>
|
borderColor: "blue.500",
|
||||||
))}
|
}}
|
||||||
|
/>
|
||||||
|
<EditableControls />
|
||||||
|
</Editable>
|
||||||
</Box>
|
</VStack>
|
||||||
|
))}
|
||||||
|
</Box> */}
|
||||||
</VStack>
|
</VStack>
|
||||||
</VStack>
|
</VStack>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { AddIcon, DeleteIcon, EditIcon } from "@chakra-ui/icons";
|
||||||
import {
|
import {
|
||||||
Badge,
|
Badge,
|
||||||
Box,
|
Box,
|
||||||
@@ -9,24 +10,24 @@ import {
|
|||||||
Tooltip,
|
Tooltip,
|
||||||
useToast,
|
useToast,
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import React, { useContext, useEffect, useState } from "react";
|
import React, { useContext, useState } from "react";
|
||||||
import { Link, Link as RouterLink } from "react-router-dom";
|
import { Link, useNavigate } from "react-router-dom";
|
||||||
import { AddIcon, DeleteIcon, EditIcon } from "@chakra-ui/icons";
|
|
||||||
import { useNavigate } from "react-router-dom";
|
|
||||||
import { OPACITY_ON_LOAD } from "../../Layout/animations";
|
|
||||||
import NormalTable from "../../Components/DataTable/NormalTable";
|
|
||||||
import Pagination from "../../Components/Pagination";
|
|
||||||
import GlobalStateContext from "../../Contexts/GlobalStateContext";
|
|
||||||
import CustomAlertDialog from "../../Components/CustomAlertDialog";
|
import CustomAlertDialog from "../../Components/CustomAlertDialog";
|
||||||
|
import NormalTable from "../../Components/DataTable/NormalTable";
|
||||||
import ToastBox from "../../Components/ToastBox";
|
import ToastBox from "../../Components/ToastBox";
|
||||||
import { TABLE_PAGINATION } from "../../Constants/Paginations";
|
|
||||||
import { generateSerialNumber } from "../../Constants/Constants";
|
|
||||||
import { useGetSponserMasterQuery } from "../../Services/io.service";
|
|
||||||
import {
|
import {
|
||||||
|
CHECKER_ID,
|
||||||
|
generateSerialNumber,
|
||||||
|
MAKER_ID,
|
||||||
|
SUPER_ADMIN_ID,
|
||||||
|
} from "../../Constants/Constants";
|
||||||
|
import GlobalStateContext from "../../Contexts/GlobalStateContext";
|
||||||
|
import { OPACITY_ON_LOAD } from "../../Layout/animations";
|
||||||
|
import {
|
||||||
|
useDeleteUserMutation,
|
||||||
useGetSubAdminMasterQuery,
|
useGetSubAdminMasterQuery,
|
||||||
useToggleStatusMutation,
|
useToggleStatusMutation,
|
||||||
} from "../../Services/subadmin.service";
|
} from "../../Services/subadmin.service";
|
||||||
import RoleSwitchButton from "../../Components/RoleSwitchButton";
|
|
||||||
|
|
||||||
export const formatDate = (date) => {
|
export const formatDate = (date) => {
|
||||||
const d = new Date(date);
|
const d = new Date(date);
|
||||||
@@ -46,31 +47,28 @@ const SubAdmin = () => {
|
|||||||
const [mouseEntered, setMouseEntered] = useState(false);
|
const [mouseEntered, setMouseEntered] = useState(false);
|
||||||
const [mouseEnteredId, setMouseEnteredId] = useState("");
|
const [mouseEnteredId, setMouseEnteredId] = useState("");
|
||||||
// const [deleteSponser] = useDeleteSponserMutation();
|
// const [deleteSponser] = useDeleteSponserMutation();
|
||||||
const { sponser, setSponser, slideFromRight } =
|
const { slideFromRight } = useContext(GlobalStateContext);
|
||||||
useContext(GlobalStateContext);
|
|
||||||
|
|
||||||
// =========================== [Use State] =============================
|
// =========================== [Use State] =============================
|
||||||
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);
|
||||||
const [searchTerm, setSearchTerm] = useState("");
|
const [searchTerm, setSearchTerm] = useState("");
|
||||||
const [debouncedSearchTerm, setDebouncedSearchTerm] = useState("");
|
// const [debouncedSearchTerm, setDebouncedSearchTerm] = useState("");
|
||||||
const [isSwitchOn, setIsSwitchOn] = useState(true);
|
|
||||||
|
|
||||||
// Debounce the search term to avoid making a request on every keystroke
|
// Debounce the search term to avoid making a request on every keystroke
|
||||||
useEffect(() => {
|
// useEffect(() => {
|
||||||
const handler = setTimeout(() => {
|
// const handler = setTimeout(() => {
|
||||||
setDebouncedSearchTerm(searchTerm);
|
// setDebouncedSearchTerm(searchTerm);
|
||||||
}, 500); // Adjust delay as needed
|
// }, 500); // Adjust delay as needed
|
||||||
return () => {
|
// return () => {
|
||||||
clearTimeout(handler);
|
// clearTimeout(handler);
|
||||||
};
|
// };
|
||||||
}, [searchTerm]);
|
// }, [searchTerm]);
|
||||||
|
|
||||||
const {
|
const { data: subAdmin, isLoading: isSponserLoading } =
|
||||||
data: subAdmin,
|
useGetSubAdminMasterQuery();
|
||||||
error,
|
|
||||||
isLoading: isSponserLoading,
|
const [deleteUser] = useDeleteUserMutation();
|
||||||
} = useGetSubAdminMasterQuery();
|
|
||||||
|
|
||||||
const [toggleStatus] = useToggleStatusMutation();
|
const [toggleStatus] = useToggleStatusMutation();
|
||||||
|
|
||||||
@@ -91,13 +89,13 @@ const SubAdmin = () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const handleToggleStatus = async (isMaker, id) => {
|
const handleToggleStatus = async (isMaker, id) => {
|
||||||
console.log("hit");
|
// console.log("hit");
|
||||||
const data = {
|
const data = {
|
||||||
role_xid: isMaker ? "2" : "1",
|
role_xid: isMaker ? CHECKER_ID : MAKER_ID,
|
||||||
};
|
};
|
||||||
console.log("=======================",data)
|
console.log("=======================", data);
|
||||||
try {
|
try {
|
||||||
const res = await toggleStatus({id, data});
|
const res = await toggleStatus({ id, data });
|
||||||
if (res?.error) {
|
if (res?.error) {
|
||||||
toast({
|
toast({
|
||||||
render: () => (
|
render: () => (
|
||||||
@@ -137,7 +135,7 @@ const SubAdmin = () => {
|
|||||||
"Action",
|
"Action",
|
||||||
];
|
];
|
||||||
|
|
||||||
const extractedArray = subAdmin?.data?.map((item, index) => ({
|
const extractedArray = filteredData?.map((item, index) => ({
|
||||||
"Sr No": (
|
"Sr No": (
|
||||||
<Text
|
<Text
|
||||||
w={"24px"}
|
w={"24px"}
|
||||||
@@ -147,7 +145,7 @@ const SubAdmin = () => {
|
|||||||
className="d-flex align-items-center fw-bold web-text-small"
|
className="d-flex align-items-center fw-bold web-text-small"
|
||||||
>
|
>
|
||||||
{/* {item.id} */}
|
{/* {item.id} */}
|
||||||
{generateSerialNumber(index, currentPage, pageSize)}
|
{generateSerialNumber(index)}
|
||||||
</Text>
|
</Text>
|
||||||
),
|
),
|
||||||
"First Name": (
|
"First Name": (
|
||||||
@@ -180,17 +178,17 @@ const SubAdmin = () => {
|
|||||||
</Box>
|
</Box>
|
||||||
),
|
),
|
||||||
Role: (
|
Role: (
|
||||||
<Box isTruncated={true} >
|
<Box isTruncated={true}>
|
||||||
<Badge
|
<Badge
|
||||||
py={"2px"}
|
py={"2px"}
|
||||||
me={2}
|
me={2}
|
||||||
fontWeight={600}
|
fontWeight={600}
|
||||||
bg={item?.role[0]?.role === "Maker" ? "#00ffcc" : "#b3ff99"}
|
bg={item?.role[0]?.role === "Maker" ? "#00ffcc" : "#b3ff99"}
|
||||||
px={item?.role[0]?.role === "Maker" ? "12px" : "5px"}
|
px={item?.role[0]?.role === "Maker" ? "12px" : "5px"}
|
||||||
>
|
>
|
||||||
{item?.role[0]?.role}
|
{item?.role[0]?.role}
|
||||||
</Badge>
|
</Badge>
|
||||||
<Switch
|
{/* <Switch
|
||||||
onChange={() =>
|
onChange={() =>
|
||||||
handleToggleStatus(item?.role[0]?.role === "Maker", item?.id)
|
handleToggleStatus(item?.role[0]?.role === "Maker", item?.id)
|
||||||
}
|
}
|
||||||
@@ -201,7 +199,7 @@ const SubAdmin = () => {
|
|||||||
bg: item?.role[0]?.role === "Maker" ? "#00ffcc" : "#b3ff99", // "Off" state color
|
bg: item?.role[0]?.role === "Maker" ? "#00ffcc" : "#b3ff99", // "Off" state color
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
/>
|
/> */}
|
||||||
{/* <RoleSwitchButton
|
{/* <RoleSwitchButton
|
||||||
setIsSwitchOn={setIsSwitchOn}
|
setIsSwitchOn={setIsSwitchOn}
|
||||||
isSwitchOn={item?.role[0]?.role === "Maker"}
|
isSwitchOn={item?.role[0]?.role === "Maker"}
|
||||||
@@ -231,7 +229,7 @@ const SubAdmin = () => {
|
|||||||
</Button>
|
</Button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|
||||||
{/* <Tooltip
|
<Tooltip
|
||||||
rounded={"sm"}
|
rounded={"sm"}
|
||||||
fontSize={"xs"}
|
fontSize={"xs"}
|
||||||
label="Delete"
|
label="Delete"
|
||||||
@@ -240,12 +238,14 @@ const SubAdmin = () => {
|
|||||||
placement="top"
|
placement="top"
|
||||||
>
|
>
|
||||||
<Button
|
<Button
|
||||||
|
isDisabled={item?.id === SUPER_ADMIN_ID}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setActionId(item?.id);
|
setActionId(item?.id);
|
||||||
setDeleteAlert(true);
|
setDeleteAlert(true);
|
||||||
}}
|
}}
|
||||||
// _hover={{ color: "red.500" }}
|
// _hover={{ color: "red.500" }}
|
||||||
// color="red"
|
// color="red"
|
||||||
|
// disabled={true}
|
||||||
rounded={"sm"}
|
rounded={"sm"}
|
||||||
size={"xs"}
|
size={"xs"}
|
||||||
colorScheme="red"
|
colorScheme="red"
|
||||||
@@ -253,46 +253,42 @@ const SubAdmin = () => {
|
|||||||
>
|
>
|
||||||
<DeleteIcon />
|
<DeleteIcon />
|
||||||
</Button>
|
</Button>
|
||||||
</Tooltip> */}
|
</Tooltip>
|
||||||
</Box>
|
</Box>
|
||||||
),
|
),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// =========================== [ Delete Function ] =================================
|
// =========================== [ Delete Function ] =================================
|
||||||
|
|
||||||
// const handleDelete = async () => {
|
const handleDelete = async () => {
|
||||||
// console.log(actionId);
|
setIsLoading(true);
|
||||||
// setIsLoading(true);
|
try {
|
||||||
// try {
|
const response = await deleteUser(actionId);
|
||||||
// const response = await deleteSponser(actionId);
|
if (response?.error?.data?.code === 400) {
|
||||||
// console.log(response?.data);
|
toast({
|
||||||
// if (response?.error?.data?.code === 400) {
|
render: () => (
|
||||||
// toast({
|
<ToastBox
|
||||||
// render: () => (
|
message={response?.error?.data?.message}
|
||||||
// <ToastBox
|
status={"error"}
|
||||||
// message={response?.error?.data?.message}
|
/>
|
||||||
// status={"error"}
|
),
|
||||||
// />
|
});
|
||||||
// ),
|
setIsLoading(false);
|
||||||
// });
|
setDeleteAlert(false);
|
||||||
// setIsLoading(false);
|
} else if (
|
||||||
// setDeleteAlert(false);
|
response?.data?.statusCode === 201 ||
|
||||||
// } else if (
|
response?.data?.statusCode === 200
|
||||||
// response?.data?.statusCode === 201 ||
|
) {
|
||||||
// response?.data?.statusCode === 200
|
toast({
|
||||||
// ) {
|
render: () => (
|
||||||
// toast({
|
<ToastBox message={response?.data?.message} status={"success"} />
|
||||||
// render: () => (
|
),
|
||||||
// <ToastBox message={response?.data?.message} status={"success"} />
|
});
|
||||||
// ),
|
setIsLoading(false);
|
||||||
// });
|
setDeleteAlert(false);
|
||||||
// setIsLoading(false);
|
}
|
||||||
// setDeleteAlert(false);
|
} catch (error) {}
|
||||||
// }
|
};
|
||||||
// } catch (error) {}
|
|
||||||
// };
|
|
||||||
|
|
||||||
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}>
|
||||||
@@ -322,14 +318,14 @@ const SubAdmin = () => {
|
|||||||
<HStack display={"flex"} alignItems={"center"}>
|
<HStack display={"flex"} alignItems={"center"}>
|
||||||
{/* ====================[Pagination]===================== */}
|
{/* ====================[Pagination]===================== */}
|
||||||
|
|
||||||
<Pagination
|
{/* <Pagination
|
||||||
isLoading={isSponserLoading}
|
isLoading={isSponserLoading}
|
||||||
pageSize={pageSize}
|
pageSize={pageSize}
|
||||||
setPageSize={setPageSize}
|
setPageSize={setPageSize}
|
||||||
currentPage={currentPage}
|
currentPage={currentPage}
|
||||||
setCurrentPage={setCurrentPage}
|
setCurrentPage={setCurrentPage}
|
||||||
totalItems={subAdmin?.data?.totalItems}
|
totalItems={subAdmin?.data?.totalItems}
|
||||||
/>
|
/> */}
|
||||||
|
|
||||||
{/* =====================[Add Button]===================== */}
|
{/* =====================[Add Button]===================== */}
|
||||||
|
|
||||||
@@ -366,8 +362,8 @@ const SubAdmin = () => {
|
|||||||
<CustomAlertDialog
|
<CustomAlertDialog
|
||||||
onClose={() => setDeleteAlert(false)}
|
onClose={() => setDeleteAlert(false)}
|
||||||
isOpen={deleteAlert}
|
isOpen={deleteAlert}
|
||||||
message={"Are you sure you want to delete sponers?"}
|
message={"Are you sure you want to delete sub-admin?"}
|
||||||
// alertHandler={handleDelete}
|
alertHandler={handleDelete}
|
||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@@ -1,42 +1,42 @@
|
|||||||
import React, { useContext, useEffect, useState } from "react";
|
|
||||||
import { Box, Button, Text, useToast } from "@chakra-ui/react";
|
|
||||||
import { useForm, Controller } from "react-hook-form";
|
|
||||||
import { yupResolver } from "@hookform/resolvers/yup";
|
|
||||||
import * as yup from "yup";
|
|
||||||
import { useNavigate, useParams } from "react-router-dom";
|
|
||||||
import { v4 as uuidv4 } from "uuid";
|
|
||||||
import { ArrowBackIcon } from "@chakra-ui/icons";
|
import { ArrowBackIcon } from "@chakra-ui/icons";
|
||||||
import { OPACITY_ON_LOAD } from "../../Layout/animations";
|
import { Box, Text, useToast } from "@chakra-ui/react";
|
||||||
import FormInputMain from "../../Components/FormInputMain";
|
import { yupResolver } from "@hookform/resolvers/yup";
|
||||||
import ToastBox from "../../Components/ToastBox";
|
import React, { useEffect, useState } from "react";
|
||||||
import FullscreenLoaders from "../../Components/Loaders/FullscreenLoaders";
|
import { useForm } from "react-hook-form";
|
||||||
|
import { useNavigate, useParams } from "react-router-dom";
|
||||||
|
import * as yup from "yup";
|
||||||
import CustomAlertDialog from "../../Components/CustomAlertDialog";
|
import CustomAlertDialog from "../../Components/CustomAlertDialog";
|
||||||
|
import FormInputMain from "../../Components/FormInputMain";
|
||||||
|
import FullscreenLoaders from "../../Components/Loaders/FullscreenLoaders";
|
||||||
import RoleSwitchButton from "../../Components/RoleSwitchButton";
|
import RoleSwitchButton from "../../Components/RoleSwitchButton";
|
||||||
|
import ToastBox from "../../Components/ToastBox";
|
||||||
|
import {
|
||||||
|
isMaker
|
||||||
|
} from "../../Constants/Constants";
|
||||||
|
import { OPACITY_ON_LOAD } from "../../Layout/animations";
|
||||||
import {
|
import {
|
||||||
useCreateSubAdminMutation,
|
useCreateSubAdminMutation,
|
||||||
useGetSubAdminByIdQuery,
|
useGetSubAdminByIdQuery,
|
||||||
useUpdateSubAdminMutation,
|
useUpdateSubAdminMutation,
|
||||||
} from "../../Services/subadmin.service";
|
} from "../../Services/subadmin.service";
|
||||||
import { useGetSponserByIdQuery } from "../../Services/io.service";
|
|
||||||
import { encryptString } from "../../Constants/Constants";
|
|
||||||
// ======================= [validation] =========================
|
// ======================= [validation] =========================
|
||||||
|
const addSubAdminSchema = yup.object().shape({
|
||||||
export const addSubAdmin = yup.object().shape({
|
|
||||||
firstName: yup
|
firstName: yup
|
||||||
.string()
|
.string()
|
||||||
.required("First Name is required")
|
.required("First Name is required")
|
||||||
.min(3, "First Name must be at least 3 characters long")
|
.min(3, "First Name must be at least 3 characters long")
|
||||||
.max(50, "First Name cannot exceed 50 characters")
|
.max(35, "First Name cannot exceed 35 characters")
|
||||||
.matches(/^[^\d]+$/, "First Name cannot contain numbers"),
|
.matches(/^[^\d]+$/, "First Name cannot contain numbers"),
|
||||||
|
|
||||||
lastName: yup.string().required("Last Name name in arabic is required"),
|
lastName: yup.string().required("Last Name is required")
|
||||||
emailAddress: yup.string().email("Invalid email address").notRequired(),
|
.min(3, "Last Name must be at least 3 characters long")
|
||||||
// .test("emailValidity", "Email address is invalid", async function (value) {
|
.max(35, "Last Name cannot exceed 35 characters")
|
||||||
// if (!value) {
|
.matches(/^[^\d]+$/, "Last Name cannot contain numbers"),
|
||||||
// return true; // Allow if the field is empty
|
emailAddress:yup.
|
||||||
// }
|
string()
|
||||||
// return await checkEmailValidity(value);
|
.required("Email address is required")
|
||||||
// }),
|
.min(6, "Email address must be at least 6 characters long")
|
||||||
|
.max(255, "Email address can be at most 255 characters long"),
|
||||||
});
|
});
|
||||||
|
|
||||||
// ==================== [debounce] ========================
|
// ==================== [debounce] ========================
|
||||||
@@ -60,17 +60,15 @@ const SubAdminUpdateCreate = () => {
|
|||||||
const [isLoadingBtn, setIsLoadingBtn] = useState(false);
|
const [isLoadingBtn, setIsLoadingBtn] = useState(false);
|
||||||
const [alert, setAlert] = useState(false);
|
const [alert, setAlert] = useState(false);
|
||||||
const [form, setForm] = useState();
|
const [form, setForm] = useState();
|
||||||
const [isSwitchOn, setIsSwitchOn] = useState(true);
|
const [isSwitchOn, setIsSwitchOn] = useState(false);
|
||||||
|
|
||||||
const [createSubAdmin] = useCreateSubAdminMutation();
|
const [createSubAdmin] = useCreateSubAdminMutation();
|
||||||
const [updateSubAdmin] = useUpdateSubAdminMutation();
|
const [updateSubAdmin] = useUpdateSubAdminMutation();
|
||||||
|
|
||||||
// Fetch sponsor data only if id exists
|
// Fetch sponsor data only if id exists
|
||||||
const {
|
const { data: subAdminByIdData, isLoading } = useGetSubAdminByIdQuery(id, {
|
||||||
data: subAdminByIdData,
|
skip: !id,
|
||||||
error,
|
});
|
||||||
isLoading,
|
|
||||||
} = useGetSubAdminByIdQuery(id, { skip: !id });
|
|
||||||
|
|
||||||
// ======================== [validators] ===========================
|
// ======================== [validators] ===========================
|
||||||
|
|
||||||
@@ -81,7 +79,8 @@ const SubAdminUpdateCreate = () => {
|
|||||||
formState: { errors },
|
formState: { errors },
|
||||||
reset,
|
reset,
|
||||||
} = useForm({
|
} = useForm({
|
||||||
resolver: yupResolver(addSubAdmin),
|
resolver: yupResolver(addSubAdminSchema),
|
||||||
|
mode: "all",
|
||||||
});
|
});
|
||||||
|
|
||||||
// ========================== [useEffect] ================================
|
// ========================== [useEffect] ================================
|
||||||
@@ -93,15 +92,11 @@ const SubAdminUpdateCreate = () => {
|
|||||||
lastName: subAdminByIdData?.data?.lastName,
|
lastName: subAdminByIdData?.data?.lastName,
|
||||||
emailAddress: subAdminByIdData?.data?.emailAddress,
|
emailAddress: subAdminByIdData?.data?.emailAddress,
|
||||||
});
|
});
|
||||||
setIsSwitchOn(
|
setIsSwitchOn(isMaker(subAdminByIdData?.data?.role[0]?.role));
|
||||||
subAdminByIdData?.data?.role[0]?.role ===
|
|
||||||
encryptString(import.meta.env.VITE_VITE_MAKER)
|
|
||||||
);
|
|
||||||
console.log(subAdminByIdData?.data?.role);
|
|
||||||
}
|
}
|
||||||
}, [subAdminByIdData, reset]);
|
}, [subAdminByIdData, reset]);
|
||||||
|
|
||||||
if (false) {
|
if (isLoading) {
|
||||||
return <FullscreenLoaders />;
|
return <FullscreenLoaders />;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,7 +111,7 @@ const SubAdminUpdateCreate = () => {
|
|||||||
try {
|
try {
|
||||||
const formData = {
|
const formData = {
|
||||||
...form,
|
...form,
|
||||||
// role_xid: !isSwitchOn ? 1 : 2,
|
role_xid: !isSwitchOn ? 2 : 1,
|
||||||
};
|
};
|
||||||
await updateSubAdmin({ data: formData, id }).then((response) => {
|
await updateSubAdmin({ data: formData, id }).then((response) => {
|
||||||
if (response?.data?.statusCode) {
|
if (response?.data?.statusCode) {
|
||||||
@@ -194,8 +189,8 @@ const SubAdminUpdateCreate = () => {
|
|||||||
type: "text",
|
type: "text",
|
||||||
isRequired: true,
|
isRequired: true,
|
||||||
section: "",
|
section: "",
|
||||||
maxLength: 50,
|
maxLength: 35,
|
||||||
helperText: `Maximum length should be 50 characters. You have entered ${
|
helperText: `Maximum length should be 35 characters. You have entered ${
|
||||||
watch()?.firstName?.length || 0
|
watch()?.firstName?.length || 0
|
||||||
} characters.`,
|
} characters.`,
|
||||||
},
|
},
|
||||||
@@ -206,8 +201,8 @@ const SubAdminUpdateCreate = () => {
|
|||||||
type: "text",
|
type: "text",
|
||||||
isRequired: true,
|
isRequired: true,
|
||||||
section: "",
|
section: "",
|
||||||
maxLength: 55,
|
maxLength: 35,
|
||||||
helperText: `Maximum length should be 55 characters. You have entered ${
|
helperText: `Maximum length should be 35 characters. You have entered ${
|
||||||
watch()?.lastName?.length || 0
|
watch()?.lastName?.length || 0
|
||||||
} characters.`,
|
} characters.`,
|
||||||
},
|
},
|
||||||
@@ -216,7 +211,7 @@ const SubAdminUpdateCreate = () => {
|
|||||||
name: "emailAddress",
|
name: "emailAddress",
|
||||||
placeHolder: " ",
|
placeHolder: " ",
|
||||||
type: "email",
|
type: "email",
|
||||||
// isRequired: true,
|
isRequired: true,
|
||||||
section: "",
|
section: "",
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
@@ -231,8 +226,8 @@ const SubAdminUpdateCreate = () => {
|
|||||||
type: "text",
|
type: "text",
|
||||||
isRequired: true,
|
isRequired: true,
|
||||||
section: "",
|
section: "",
|
||||||
maxLength: 55,
|
maxLength: 35,
|
||||||
helperText: `Maximum length should be 55 characters. You have entered ${
|
helperText: `Maximum length should be 35 characters. You have entered ${
|
||||||
watch()?.firstName?.length || 0
|
watch()?.firstName?.length || 0
|
||||||
} characters.`,
|
} characters.`,
|
||||||
},
|
},
|
||||||
@@ -243,8 +238,8 @@ const SubAdminUpdateCreate = () => {
|
|||||||
type: "text",
|
type: "text",
|
||||||
isRequired: true,
|
isRequired: true,
|
||||||
section: "",
|
section: "",
|
||||||
maxLength: 55,
|
maxLength: 35,
|
||||||
helperText: `Maximum length should be 55 characters. You have entered ${
|
helperText: `Maximum length should be 35 characters. You have entered ${
|
||||||
watch()?.lastName?.length || 0
|
watch()?.lastName?.length || 0
|
||||||
} characters.`,
|
} characters.`,
|
||||||
},
|
},
|
||||||
@@ -253,7 +248,7 @@ const SubAdminUpdateCreate = () => {
|
|||||||
name: "emailAddress",
|
name: "emailAddress",
|
||||||
placeHolder: " ",
|
placeHolder: " ",
|
||||||
type: "email",
|
type: "email",
|
||||||
// isRequired: true,
|
isRequired: true,
|
||||||
section: "",
|
section: "",
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
@@ -281,7 +276,7 @@ const SubAdminUpdateCreate = () => {
|
|||||||
}, {});
|
}, {});
|
||||||
|
|
||||||
// ==================== [On Submit] ========================
|
// ==================== [On Submit] ========================
|
||||||
console.log(errors);
|
// console.log(errors);
|
||||||
|
|
||||||
const onSubmit = async (data) => {
|
const onSubmit = async (data) => {
|
||||||
console.log("Hit");
|
console.log("Hit");
|
||||||
@@ -311,16 +306,20 @@ const SubAdminUpdateCreate = () => {
|
|||||||
cursor={"pointer"}
|
cursor={"pointer"}
|
||||||
>
|
>
|
||||||
<ArrowBackIcon fontSize={"xl"} me={2} />
|
<ArrowBackIcon fontSize={"xl"} me={2} />
|
||||||
Add Details
|
{params?.id ? "Edit Details" : "Add Details"}
|
||||||
</Text>
|
</Text>
|
||||||
{params?.id ? (
|
{/* {params?.id ? (
|
||||||
""
|
""
|
||||||
) : (
|
) : (
|
||||||
<RoleSwitchButton
|
<RoleSwitchButton
|
||||||
isSwitchOn={isSwitchOn}
|
isSwitchOn={isSwitchOn}
|
||||||
setIsSwitchOn={setIsSwitchOn}
|
setIsSwitchOn={setIsSwitchOn}
|
||||||
/>
|
/>
|
||||||
)}
|
)} */}
|
||||||
|
<RoleSwitchButton
|
||||||
|
isSwitchOn={isSwitchOn}
|
||||||
|
setIsSwitchOn={setIsSwitchOn}
|
||||||
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{/* ====================== [Form Input] ====================== */}
|
{/* ====================== [Form Input] ====================== */}
|
||||||
|
|||||||
@@ -421,7 +421,7 @@ export const ioService = createApi({
|
|||||||
}),
|
}),
|
||||||
|
|
||||||
profile: builder.query({
|
profile: builder.query({
|
||||||
query: (id) => `/auth/admin/profile`,
|
query: () => `/auth/admin/profile`,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
// ========Add Io Details========
|
// ========Add Io Details========
|
||||||
@@ -448,40 +448,40 @@ export const ioService = createApi({
|
|||||||
|
|
||||||
|
|
||||||
addNavDetails: builder.mutation({
|
addNavDetails: builder.mutation({
|
||||||
query: ({id,data}) => ({
|
query: ({ id, data }) => ({
|
||||||
url: `/io/admin/maker-transaction/${id}/io-nav`,
|
url: `/io/admin/maker-transaction/${id}/io-nav`,
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body:data,
|
body: data,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
invalidatesTags: ["getIOById"],
|
invalidatesTags: ["getIOById"],
|
||||||
}),
|
}),
|
||||||
|
|
||||||
addIOTransaction: builder.mutation({
|
addIOTransaction: builder.mutation({
|
||||||
query: ({id,data}) => ({
|
query: ({ id, data }) => ({
|
||||||
url: `/io/admin/maker-transaction/${id}/io-nav`,
|
url: `/io/admin/maker-transaction/${id}/io-nav`,
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body:data,
|
body: data,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
invalidatesTags: ["getIOById"],
|
invalidatesTags: ["getIOById"],
|
||||||
}),
|
}),
|
||||||
|
|
||||||
saveIOTransaction: builder.mutation({
|
saveIOTransaction: builder.mutation({
|
||||||
query: ({id,data}) => ({
|
query: ({ id, data }) => ({
|
||||||
url: `/io/admin/maker-transaction/${id}/io-yeild`,
|
url: `/io/admin/maker-transaction/${id}/io-yeild`,
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body:data,
|
body: data,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
invalidatesTags: ["getIOById"],
|
invalidatesTags: ["getIOById"],
|
||||||
}),
|
}),
|
||||||
|
|
||||||
exitIOTransaction: builder.mutation({
|
exitIOTransaction: builder.mutation({
|
||||||
query: ({id,data}) => ({
|
query: ({ id, data }) => ({
|
||||||
url: `/io/admin/maker-transaction/${id}/io-exit`,
|
url: `/io/admin/maker-transaction/${id}/io-exit`,
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body:data,
|
body: data,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
invalidatesTags: ["getIOById"],
|
invalidatesTags: ["getIOById"],
|
||||||
@@ -499,10 +499,10 @@ export const ioService = createApi({
|
|||||||
|
|
||||||
|
|
||||||
approveIOCase: builder.mutation({
|
approveIOCase: builder.mutation({
|
||||||
query: ({id,data}) => ({
|
query: ({ id, data }) => ({
|
||||||
url: `/io/admin/checker-transaction/approved/io-cash/${id}`,
|
url: `/io/admin/checker-transaction/approved/io-cash/${id}`,
|
||||||
method: "PATCH",
|
method: "PATCH",
|
||||||
body:data,
|
body: data,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
invalidatesTags: ["getIOById"],
|
invalidatesTags: ["getIOById"],
|
||||||
@@ -510,20 +510,20 @@ export const ioService = createApi({
|
|||||||
|
|
||||||
|
|
||||||
approveIONav: builder.mutation({
|
approveIONav: builder.mutation({
|
||||||
query: ({id,data}) => ({
|
query: ({ id, data }) => ({
|
||||||
url: `/io/admin/checker-transaction/approved/io-nav/${id}`,
|
url: `/io/admin/checker-transaction/approved/io-nav/${id}`,
|
||||||
method: "PATCH",
|
method: "PATCH",
|
||||||
body:data,
|
body: data,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
invalidatesTags: ["getIOById"],
|
invalidatesTags: ["getIOById"],
|
||||||
}),
|
}),
|
||||||
|
|
||||||
approveDistribution: builder.mutation({
|
approveDistribution: builder.mutation({
|
||||||
query: ({id,data}) => ({
|
query: ({ id, data }) => ({
|
||||||
url: `/io/admin/checker-transaction/approved/distributed-to-investor/${id}`,
|
url: `/io/admin/checker-transaction/approved/distributed-to-investor/${id}`,
|
||||||
method: "PATCH",
|
method: "PATCH",
|
||||||
body:data,
|
body: data,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
invalidatesTags: ["getIOById"],
|
invalidatesTags: ["getIOById"],
|
||||||
@@ -531,50 +531,50 @@ export const ioService = createApi({
|
|||||||
|
|
||||||
|
|
||||||
approveExit: builder.mutation({
|
approveExit: builder.mutation({
|
||||||
query: ({id,data}) => ({
|
query: ({ id, data }) => ({
|
||||||
url: `/io/admin/checker-transaction/approved/exit/${id}`,
|
url: `/io/admin/checker-transaction/approved/exit/${id}`,
|
||||||
method: "PATCH",
|
method: "PATCH",
|
||||||
body:data,
|
body: data,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
invalidatesTags: ["getIOById"],
|
invalidatesTags: ["getIOById"],
|
||||||
}),
|
}),
|
||||||
|
|
||||||
approveInvested: builder.mutation({
|
approveInvested: builder.mutation({
|
||||||
query: ({id,data}) => ({
|
query: ({ id, data }) => ({
|
||||||
url: `/io/admin/checker-transaction/approved/amount-invested/${id}`,
|
url: `/io/admin/checker-transaction/approved/amount-invested/${id}`,
|
||||||
method: "PATCH",
|
method: "PATCH",
|
||||||
body:data,
|
body: data,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
invalidatesTags: ["getIOById"],
|
invalidatesTags: ["getIOById"],
|
||||||
}),
|
}),
|
||||||
|
|
||||||
approveDistributed: builder.mutation({
|
approveDistributed: builder.mutation({
|
||||||
query: ({id,data}) => ({
|
query: ({ id, data }) => ({
|
||||||
url: `/io/admin/checker-transaction/approved/distributed-to-investor/${id}`,
|
url: `/io/admin/checker-transaction/approved/distributed-to-investor/${id}`,
|
||||||
method: "PATCH",
|
method: "PATCH",
|
||||||
body:data,
|
body: data,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
invalidatesTags: ["getIOById"],
|
invalidatesTags: ["getIOById"],
|
||||||
}),
|
}),
|
||||||
|
|
||||||
approveExitTransaction: builder.mutation({
|
approveExitTransaction: builder.mutation({
|
||||||
query: ({id,data}) => ({
|
query: ({ id, data }) => ({
|
||||||
url: `/io/admin/checker-transaction/approved/exit/${id}`,
|
url: `/io/admin/checker-transaction/approved/exit/${id}`,
|
||||||
method: "PATCH",
|
method: "PATCH",
|
||||||
body:data,
|
body: data,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
invalidatesTags: ["getIOById"],
|
invalidatesTags: ["getIOById"],
|
||||||
}),
|
}),
|
||||||
|
|
||||||
approveCancleTransaction: builder.mutation({
|
approveCancleTransaction: builder.mutation({
|
||||||
query: ({id,data}) => ({
|
query: ({ id, data }) => ({
|
||||||
url: `/io/admin/checker-transaction/approved/cancel/${id}`,
|
url: `/io/admin/checker-transaction/approved/cancel/${id}`,
|
||||||
method: "PATCH",
|
method: "PATCH",
|
||||||
body:data,
|
body: data,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
invalidatesTags: ["getIOById"],
|
invalidatesTags: ["getIOById"],
|
||||||
@@ -582,10 +582,10 @@ export const ioService = createApi({
|
|||||||
|
|
||||||
|
|
||||||
rejectIOCase: builder.mutation({
|
rejectIOCase: builder.mutation({
|
||||||
query: ({id,data}) => ({
|
query: ({ id, data }) => ({
|
||||||
url: `/io/admin/checker-transaction/reject/${id}`,
|
url: `/io/admin/checker-transaction/reject/${id}`,
|
||||||
method: "PATCH",
|
method: "PATCH",
|
||||||
body:data,
|
body: data,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
invalidatesTags: ["getIOById"],
|
invalidatesTags: ["getIOById"],
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import { baseQuery } from "./token.serivce";
|
|||||||
export const sabAdminMaster = createApi({
|
export const sabAdminMaster = createApi({
|
||||||
reducerPath: "sabAdminMaster",
|
reducerPath: "sabAdminMaster",
|
||||||
baseQuery: baseQuery,
|
baseQuery: baseQuery,
|
||||||
tagTypes: ["getSubAdmin", "prePopulate"],
|
tagTypes: ["getSubAdmin", "prePopulate","getSubAdminById"],
|
||||||
endpoints: (builder) => ({
|
endpoints: (builder) => ({
|
||||||
|
|
||||||
|
|
||||||
@@ -29,7 +29,7 @@ export const sabAdminMaster = createApi({
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
body: data,
|
body: data,
|
||||||
}),
|
}),
|
||||||
invalidatesTags: ["getSubAdmin","prePopulate"],
|
invalidatesTags: ["getSubAdmin", "prePopulate"],
|
||||||
}),
|
}),
|
||||||
|
|
||||||
// // ========[Update Sponser]========
|
// // ========[Update Sponser]========
|
||||||
@@ -40,17 +40,18 @@ export const sabAdminMaster = createApi({
|
|||||||
method: "PATCH",
|
method: "PATCH",
|
||||||
body: data,
|
body: data,
|
||||||
}),
|
}),
|
||||||
invalidatesTags: ["getSubAdmin"],
|
invalidatesTags: ["getSubAdmin","getSubAdminById"],
|
||||||
}),
|
}),
|
||||||
|
|
||||||
getSubAdminById: builder.query({
|
getSubAdminById: builder.query({
|
||||||
query: (id) => `/subadmin/admin/${id}`,
|
query: (id) => `/subadmin/admin/${id}`,
|
||||||
|
providesTags: ["getSubAdminById"],
|
||||||
}),
|
}),
|
||||||
|
|
||||||
// // ========[Toggle Status]========
|
// // ========[Toggle Status]========
|
||||||
|
|
||||||
toggleStatus: builder.mutation({
|
toggleStatus: builder.mutation({
|
||||||
query: ({id, data}) => ({
|
query: ({ id, data }) => ({
|
||||||
url: `/subadmin/admin/toggle-role/${id}`,
|
url: `/subadmin/admin/toggle-role/${id}`,
|
||||||
method: "PATCH",
|
method: "PATCH",
|
||||||
body: data,
|
body: data,
|
||||||
@@ -58,41 +59,26 @@ export const sabAdminMaster = createApi({
|
|||||||
invalidatesTags: ["getSubAdmin"],
|
invalidatesTags: ["getSubAdmin"],
|
||||||
}),
|
}),
|
||||||
|
|
||||||
// // ========[Get Active]========
|
|
||||||
|
|
||||||
// getActiveSponserMaster: builder.query({
|
// ==========[Delete User] ==========
|
||||||
// query: () => `/sponsor/admin/active`,
|
deleteUser: builder.mutation({
|
||||||
// }),
|
query: (id) => ({
|
||||||
|
url: `/subadmin/admin/${id}`,
|
||||||
|
method: "DELETE",
|
||||||
|
}),
|
||||||
|
invalidatesTags: ["getSubAdmin"],
|
||||||
|
}),
|
||||||
|
|
||||||
// getSponserMasterActive: builder.query({
|
|
||||||
// query: () => "/sponsor/admin/active",
|
|
||||||
// }),
|
|
||||||
|
|
||||||
// // ======[Get ID]=====
|
|
||||||
|
|
||||||
// getSponserById: builder.query({
|
|
||||||
// query: (id) => `/sponsor/admin/${id}`,
|
|
||||||
// }),
|
|
||||||
|
|
||||||
// // ========[Update Sponser]========
|
|
||||||
|
|
||||||
// updateSponser: builder.mutation({
|
|
||||||
// query: ({ data, id }) => ({
|
|
||||||
// url: `/sponsor/admin/${id}`,
|
|
||||||
// method: "PATCH",
|
|
||||||
// body: data,
|
|
||||||
// }),
|
|
||||||
// invalidatesTags: ["getSponser"],
|
|
||||||
// }),
|
|
||||||
|
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
// Export hooks for usage in functional components
|
// Export hooks for usage in functional components
|
||||||
export const {
|
export const {
|
||||||
useGetSubAdminMasterQuery,
|
useGetSubAdminMasterQuery,
|
||||||
useCreateSubAdminMutation,
|
useCreateSubAdminMutation,
|
||||||
useUpdateSubAdminMutation,
|
useUpdateSubAdminMutation,
|
||||||
useGetSubAdminByIdQuery,
|
useGetSubAdminByIdQuery,
|
||||||
useToggleStatusMutation
|
useToggleStatusMutation,
|
||||||
|
useDeleteUserMutation,
|
||||||
} = sabAdminMaster;
|
} = sabAdminMaster;
|
||||||
|
|||||||
@@ -1,132 +1,122 @@
|
|||||||
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
|
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
|
||||||
import { encryptString } from '../Constants/Constants'
|
import { encryptString } from '../Constants/Constants'
|
||||||
|
|
||||||
// Define a base query function with RTK Query
|
// Define a base query function with token refresh logic, retry mechanism, and AbortController
|
||||||
// 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) => {
|
export const baseQuery = async (args, api, extraOptions) => {
|
||||||
let result = await fetchBaseQuery({
|
const fetchBase = fetchBaseQuery({
|
||||||
baseUrl: import.meta.env.VITE_BAS_URL,
|
baseUrl: import.meta.env.VITE_BAS_URL,
|
||||||
prepareHeaders: (headers) => {
|
credentials: 'include',
|
||||||
const token = localStorage.getItem("accessToken");
|
prepareHeaders: (headers) => {
|
||||||
if (token) {
|
// headers.set('Content-Type', 'application/json');
|
||||||
headers.set("x-auth-token", token);
|
return headers;
|
||||||
}
|
},
|
||||||
return headers;
|
});
|
||||||
},
|
|
||||||
})(args, api, extraOptions);
|
|
||||||
|
|
||||||
if (result.error && result.error.status === 403) {
|
const abortController = new AbortController();
|
||||||
// Handle token refresh
|
extraOptions = {
|
||||||
const refreshToken = localStorage.getItem("refreshToken");
|
...extraOptions,
|
||||||
console.log(refreshToken);
|
signal: abortController.signal,
|
||||||
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) {
|
let result = await fetchBase(args, api, extraOptions);
|
||||||
// Save new tokens
|
|
||||||
localStorage.setItem("accessToken", refreshResult?.data?.data?.access?.token);
|
|
||||||
// localStorage.setItem("role", refreshResult?.data?.data?.role);
|
|
||||||
// console.log(refreshResult?.data?.data?.role);
|
|
||||||
|
|
||||||
|
if (result.error) {
|
||||||
|
if (result.error.status === 403) {
|
||||||
|
let retryCount = 0;
|
||||||
|
const maxRetries = import.meta.env.VITE_MAX_TRY_REGENRATE_TOKEN || 2;
|
||||||
|
|
||||||
// Retry the original request with the new token
|
while (retryCount < maxRetries) {
|
||||||
result = await fetchBaseQuery({
|
try {
|
||||||
baseUrl: import.meta.env.VITE_BAS_URL,
|
const { data, error } = await fetchBase(
|
||||||
prepareHeaders: (headers) => {
|
{
|
||||||
const token = localStorage.getItem("accessToken");
|
url: "/auth/user/regenerate-token",
|
||||||
if (token) {
|
method: "POST",
|
||||||
headers.set("x-auth-token", token);
|
},
|
||||||
}
|
api,
|
||||||
return headers;
|
{ ...extraOptions, signal: abortController.signal }
|
||||||
},
|
);
|
||||||
})(args, api, extraOptions);
|
if (data) {
|
||||||
}else{
|
// Retry the original query after successful token regeneration
|
||||||
|
return await fetchBase(args, api, { ...extraOptions, signal: abortController.signal });
|
||||||
|
}
|
||||||
|
|
||||||
console.log('refresh failed');
|
throw error;
|
||||||
localStorage.clear();
|
} catch (err) {
|
||||||
window.location.href = '/login'; // Redirect to login page
|
retryCount++;
|
||||||
|
if (retryCount >= maxRetries) {
|
||||||
|
console.error("Failed to refresh token after retries:", err);
|
||||||
|
abortController.abort();
|
||||||
|
localStorage.clear();
|
||||||
|
window.location.href = '/login'; // Redirect to login page
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (result.error.status === 401) {
|
||||||
|
abortController.abort();
|
||||||
|
localStorage.clear();
|
||||||
|
window.location.href = '/login';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
return result;
|
||||||
} catch (err) {
|
|
||||||
console.error("Failed to refresh token:", err);
|
|
||||||
localStorage.clear();
|
|
||||||
window.location.href = '/login'; // Redirect to login page
|
|
||||||
// Handle refresh failure (e.g., redirect to login)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create an RTK Query API slice
|
// Create an RTK Query API slice
|
||||||
export const apiSlice = createApi({
|
export const apiSlice = createApi({
|
||||||
reducerPath: "api",
|
reducerPath: "api",
|
||||||
baseQuery: baseQuery,
|
baseQuery: baseQuery,
|
||||||
endpoints: (builder) => ({
|
tagTypes: ["authProfile"],
|
||||||
login: builder.mutation({
|
endpoints: (builder) => ({
|
||||||
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);
|
login: builder.mutation({
|
||||||
// localStorage.setItem('refreshTokenExp', data?.data?.refresh?.expires);
|
query: (credentials) => ({
|
||||||
localStorage.setItem("accessTokenExp", data?.data?.access?.expires);
|
url: "/auth/admin",
|
||||||
localStorage.setItem("role", encryptString(data?.data?.role));
|
method: "POST",
|
||||||
} catch (error) {
|
body: credentials,
|
||||||
console.error("Login failed:", error);
|
}),
|
||||||
}
|
async onQueryStarted(arg, { queryFulfilled }) {
|
||||||
},
|
try {
|
||||||
}),
|
const { data } = await queryFulfilled;
|
||||||
refreshToken: builder.mutation({
|
localStorage.setItem("role", encryptString(data?.data?.role));
|
||||||
query: (refreshToken) => ({
|
} catch (error) {
|
||||||
url: "/auth/user/regenerate-token",
|
console.error("Login failed:", error);
|
||||||
method: "POST",
|
}
|
||||||
body: { refreshToken },
|
},
|
||||||
}),
|
}),
|
||||||
}),
|
|
||||||
|
refreshToken: builder.mutation({
|
||||||
|
query: (refreshToken) => ({
|
||||||
|
url: "/auth/user/regenerate-token",
|
||||||
|
method: "POST",
|
||||||
|
body: { refreshToken },
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
|
||||||
|
logout: builder.mutation({
|
||||||
|
query: () => ({
|
||||||
|
url: "/auth/admin/logout",
|
||||||
|
method: "POST",
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
|
||||||
|
authProfile: builder.query({
|
||||||
|
query: () => `/auth/admin/profile`,
|
||||||
|
providesTags: (result) => result ? [{ type: 'Auth', id: 'profile' }] : [],
|
||||||
|
onQueryStarted: async (args, { queryFulfilled }) => {
|
||||||
|
try {
|
||||||
|
const { data } = await queryFulfilled; // Get the data from the query response
|
||||||
|
if (data?.role) {
|
||||||
|
localStorage.setItem('role', encryptString(data.role));
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error setting role in localStorage:', error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
|
||||||
|
|
||||||
logout: builder.mutation({
|
}),
|
||||||
query: () => ({
|
|
||||||
url: "/auth/admin/logout",
|
|
||||||
method: "POST",
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export const { useLoginMutation, useRefreshTokenMutation, useLogoutMutation } = apiSlice;
|
export const { useLoginMutation, useRefreshTokenMutation, useLogoutMutation, useAuthProfileQuery } = apiSlice;
|
||||||
|
|||||||
Reference in New Issue
Block a user