From 57c6923784f500f334954396a0f1431a69a5f5f7 Mon Sep 17 00:00:00 2001 From: YasinShaikh123 <123150391+YasinShaikh123@users.noreply.github.com> Date: Thu, 9 Jan 2025 17:40:55 +0530 Subject: [PATCH 01/50] =?UTF-8?q?[dashboard=20working=F0=9F=91=B7=E2=80=8D?= =?UTF-8?q?=E2=99=82=EF=B8=8F]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Pages/{Dashbaord.jsx => DashbaordOld.jsx} | 6 -- src/Pages/Dashboard/Dashbaord.jsx | 93 +++++++++++++++++++ src/Routes/Nav.js | 12 +-- src/Routes/Routes.js | 4 +- 4 files changed, 101 insertions(+), 14 deletions(-) rename src/Pages/{Dashbaord.jsx => DashbaordOld.jsx} (99%) create mode 100644 src/Pages/Dashboard/Dashbaord.jsx diff --git a/src/Pages/Dashbaord.jsx b/src/Pages/DashbaordOld.jsx similarity index 99% rename from src/Pages/Dashbaord.jsx rename to src/Pages/DashbaordOld.jsx index 1ed8b29..692892b 100644 --- a/src/Pages/Dashbaord.jsx +++ b/src/Pages/DashbaordOld.jsx @@ -135,9 +135,6 @@ const Dashbaord = () => { - - - IO Status @@ -151,9 +148,6 @@ const Dashbaord = () => { - - - ) diff --git a/src/Pages/Dashboard/Dashbaord.jsx b/src/Pages/Dashboard/Dashbaord.jsx new file mode 100644 index 0000000..4957d33 --- /dev/null +++ b/src/Pages/Dashboard/Dashbaord.jsx @@ -0,0 +1,93 @@ +import { Box, Divider, Flex, Grid, GridItem, Heading, SimpleGrid, Text } from '@chakra-ui/react' +import React from 'react' +import { BsBoxArrowDown, BsBoxArrowUp } from "react-icons/bs"; +import { LuContact } from "react-icons/lu"; +import { FaRegPenToSquare } from "react-icons/fa6"; + +const panddingReguest = [ + { + icon: , + label: "Pending deposit requests", + count: 27, + }, + { + icon: , + label: "Pending withdrawal requests", + count: 27, + }, + { + icon: , + label: "Pending KYC review request", + count: 27, + }, + { + icon: , + label: "Pending Acc modification request", + count: 27, + }, +]; + +const userActivity = [ + { + icon: , + label: "Total number of users", + count: 27, + }, + { + icon: , + label: "Total number of users with completed KYC (%)", + count: 27, + }, + { + icon: , + label: "Total number of Active users", + count: 27, + }, +]; + +const Dashbaord = () => { + return ( + + + + Pending Request + + + {panddingReguest.map((item, index) => ( + + {item.icon} + + {item.label} + + + {item.count} + + + ))} + + + + Pending Request + + + {userActivity.map((item, index) => ( + + + {item.icon} + + {item.label} + + + + {item.count} + + + ))} + + + + + ) +} + +export default Dashbaord diff --git a/src/Routes/Nav.js b/src/Routes/Nav.js index 76bf644..d01b988 100644 --- a/src/Routes/Nav.js +++ b/src/Routes/Nav.js @@ -34,12 +34,12 @@ import { HiOutlineBanknotes } from "react-icons/hi2"; import { AtSignIcon } from "@chakra-ui/icons"; export const nav = [ - // { - // title: "Dashboard", - // type: "single", - // path: "/", - // Icon: TbLayoutDashboard, - // }, + { + title: "Dashboard", + type: "single", + path: "/dashboard", + Icon: TbLayoutDashboard, + }, { title: "MASTER MENU", type: "title", diff --git a/src/Routes/Routes.js b/src/Routes/Routes.js index 5115a51..09bdf6e 100644 --- a/src/Routes/Routes.js +++ b/src/Routes/Routes.js @@ -31,7 +31,7 @@ import DepositRequest from "../Pages/Deposit/DepositRequest/DepositRequest"; import EditBankDetails from "../Pages/Admin/BankDetails/EditBankDetails"; import ExchangeHistory from "../Pages/Master/ExchangeRate/ExchangeHistroy"; import Welcome from "../Pages/PaymentSuccess"; -import Dashbaord from "../Pages/Dashbaord"; +import Dashbaord from "../Pages/Dashboard/Dashbaord"; import UnderConstruction from "../Pages/UnderConstruction"; import PendingRequest from "../Pages/WithDrawal/DrawalRequest/PendingRequest"; import BankInvestor from "../Pages/Admin/Investor/BankInvestor/BankInvestor"; @@ -53,7 +53,7 @@ export const RouteLink = [ // =============[ Tanami ]================ // ===============[ Management]=============== - { path: "/", Component: Sponser }, + { path: "/", Component: Dashbaord }, { path: "/sponser", Component: Sponser }, { path: "/sponser/add-sponser/:id", Component: AddSponser }, { path: "/sponser/add-sponser", Component: AddSponser }, From 96f8c3248338fa8ad1ff35cf327915c3e28ca970 Mon Sep 17 00:00:00 2001 From: YasinShaikh123 <123150391+YasinShaikh123@users.noreply.github.com> Date: Thu, 9 Jan 2025 19:31:52 +0530 Subject: [PATCH 02/50] working --- src/Pages/Dashboard/Dashbaord.jsx | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/Pages/Dashboard/Dashbaord.jsx b/src/Pages/Dashboard/Dashbaord.jsx index 4957d33..91672f7 100644 --- a/src/Pages/Dashboard/Dashbaord.jsx +++ b/src/Pages/Dashboard/Dashbaord.jsx @@ -31,17 +31,18 @@ const userActivity = [ { icon: , label: "Total number of users", - count: 27, + count: 1500, }, { icon: , label: "Total number of users with completed KYC (%)", - count: 27, + count: '320', + percentage:'(50%)', }, { icon: , label: "Total number of Active users", - count: 27, + count: '3,298', }, ]; @@ -55,11 +56,11 @@ const Dashbaord = () => { {panddingReguest.map((item, index) => ( - {item.icon} - + {item.icon} + {item.label} - + {item.count} @@ -74,12 +75,12 @@ const Dashbaord = () => { {item.icon} - + {item.label} - - {item.count} + + {item.count} {item.percentage} ))} From aeb0f25663a1d075798215e6713eae47b721c98a Mon Sep 17 00:00:00 2001 From: YasinShaikh123 <123150391+YasinShaikh123@users.noreply.github.com> Date: Fri, 10 Jan 2025 14:53:55 +0530 Subject: [PATCH 03/50] =?UTF-8?q?kaam=20chalu=20hai=F0=9F=98=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Pages/Dashboard/Dashbaord.jsx | 47 +++++++++++++++++++++++++------ 1 file changed, 39 insertions(+), 8 deletions(-) diff --git a/src/Pages/Dashboard/Dashbaord.jsx b/src/Pages/Dashboard/Dashbaord.jsx index 91672f7..4f51092 100644 --- a/src/Pages/Dashboard/Dashbaord.jsx +++ b/src/Pages/Dashboard/Dashbaord.jsx @@ -1,4 +1,4 @@ -import { Box, Divider, Flex, Grid, GridItem, Heading, SimpleGrid, Text } from '@chakra-ui/react' +import { Box, Divider, Flex, Grid, GridItem, Heading, HStack, Select, SimpleGrid, Stack, Text } from '@chakra-ui/react' import React from 'react' import { BsBoxArrowDown, BsBoxArrowUp } from "react-icons/bs"; import { LuContact } from "react-icons/lu"; @@ -50,14 +50,14 @@ const Dashbaord = () => { return ( - + Pending Request {panddingReguest.map((item, index) => ( - + {item.icon} - + {item.label} @@ -67,15 +67,15 @@ const Dashbaord = () => { ))} - - Pending Request + + Pending Request {userActivity.map((item, index) => ( - + {item.icon} - + {item.label} @@ -85,6 +85,37 @@ const Dashbaord = () => { ))} + + + + 80% + Users that opened the app today + + + + 3,298 + New sign-ups + + + + + + + 80% + New KYC verification + + + + 3,298 + Users who logged in + + + + From 96a302d26281421f447c967beab59bd648ad5a6d Mon Sep 17 00:00:00 2001 From: YasinShaikh123 <123150391+YasinShaikh123@users.noreply.github.com> Date: Mon, 13 Jan 2025 19:09:57 +0530 Subject: [PATCH 04/50] =?UTF-8?q?Dashboard=20Working=F0=9F=91=B7=E2=80=8D?= =?UTF-8?q?=E2=99=82=EF=B8=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Contexts/GlobalStateProvider.jsx | 77 +++++++- src/Layout/DefaultLayout.jsx | 7 + src/Pages/Dashboard/Dashbaord.jsx | 168 ++++++++++++++---- .../Dashboard/InvestmentOpportunities.jsx | 161 +++++++++++++++++ src/Routes/Routes.js | 2 + 5 files changed, 382 insertions(+), 33 deletions(-) create mode 100644 src/Pages/Dashboard/InvestmentOpportunities.jsx diff --git a/src/Contexts/GlobalStateProvider.jsx b/src/Contexts/GlobalStateProvider.jsx index b172727..4ecd2b8 100644 --- a/src/Contexts/GlobalStateProvider.jsx +++ b/src/Contexts/GlobalStateProvider.jsx @@ -6,7 +6,7 @@ import { v4 as uuidv4 } from "uuid"; import { TbClock2 } from "react-icons/tb"; import { CiWallet } from "react-icons/ci"; import { HiOutlineReceiptPercent } from "react-icons/hi2"; -import { IoMdQrScanner } from "react-icons/io"; +import { IoMdQrScanner } from "react-icons/io"; import { GrDocumentPdf } from "react-icons/gr"; import { AiOutlineFileGif } from "react-icons/ai"; @@ -1674,6 +1674,79 @@ const GlobalStateProvider = ({ children }) => { }, ]); + const [opportunities, setOpportunities] = useState([ + { + id: 1, + Investors: "Blackstone", + amountRemaining: "10 %", + totalDealsize: "$ 520", + noViews: "50", + }, + { + id: 2, + Investors: "Blackstone", + amountRemaining: "10 %", + totalDealsize: "$ 520", + noViews: "50", + }, + { + id: 3, + Investors: "Blackstone", + amountRemaining: "10 %", + totalDealsize: "$ 520", + noViews: "50", + }, + { + id: 4, + Investors: "Blackstone", + amountRemaining: "10 %", + totalDealsize: "$ 520", + noViews: "50", + }, + { + id: 5, + Investors: "Blackstone", + amountRemaining: "10 %", + totalDealsize: "$ 520", + noViews: "50", + }, + { + id: 6, + Investors: "Blackstone", + amountRemaining: "10 %", + totalDealsize: "$ 520", + noViews: "50", + }, + { + id: 7, + Investors: "Blackstone", + amountRemaining: "10 %", + totalDealsize: "$ 520", + noViews: "50", + }, + { + id: 8, + Investors: "Blackstone", + amountRemaining: "10 %", + totalDealsize: "$ 520", + noViews: "50", + }, + { + id: 9, + Investors: "Blackstone", + amountRemaining: "10 %", + totalDealsize: "$ 520", + noViews: "50", + }, + { + id: 10, + Investors: "Blackstone", + amountRemaining: "10 %", + totalDealsize: "$ 520", + noViews: "50", + }, + ]); + const [InvestorWallet, setInvestorWallet] = useState(null); // ==============[ prod state ]=============================== @@ -1767,6 +1840,8 @@ const GlobalStateProvider = ({ children }) => { setIONAVDetail, iOTransaction, setIOTransaction, + opportunities, + setOpportunities, }} > {children} diff --git a/src/Layout/DefaultLayout.jsx b/src/Layout/DefaultLayout.jsx index f615b1e..d74a08b 100644 --- a/src/Layout/DefaultLayout.jsx +++ b/src/Layout/DefaultLayout.jsx @@ -38,6 +38,7 @@ import { RiMoneyDollarBoxLine, } from "react-icons/ri"; import { + TbLayoutDashboard, TbListDetails, TbReportMoney, TbTransactionDollar @@ -139,6 +140,12 @@ const DashboardLayout = ({ isOnline }) => { switch (true) { case "/": return "👋🏻 Hi, Admin"; + case path.startsWith("/investment-opportunities"): + return ( + + dashboard / Open Opportunities + + ); case path.startsWith("/sponser"): return ( diff --git a/src/Pages/Dashboard/Dashbaord.jsx b/src/Pages/Dashboard/Dashbaord.jsx index 4f51092..833ff84 100644 --- a/src/Pages/Dashboard/Dashbaord.jsx +++ b/src/Pages/Dashboard/Dashbaord.jsx @@ -1,8 +1,10 @@ import { Box, Divider, Flex, Grid, GridItem, Heading, HStack, Select, SimpleGrid, Stack, Text } from '@chakra-ui/react' import React from 'react' -import { BsBoxArrowDown, BsBoxArrowUp } from "react-icons/bs"; +import { BsArrowsAngleContract, BsBoxArrowDown, BsBoxArrowUp } from "react-icons/bs"; import { LuContact } from "react-icons/lu"; import { FaRegPenToSquare } from "react-icons/fa6"; +import InvestmentOpportunities from './InvestmentOpportunities'; +import { Link } from 'react-router-dom'; const panddingReguest = [ { @@ -46,21 +48,54 @@ const userActivity = [ }, ]; -const Dashbaord = () => { +const closedOpportunities = [ + { + icon: , + label: "Closed Opportunities", + count: 27, + }, + { + icon: , + label: "Total assets under managemnet", + count: 27, + }, + { + icon: , + label: "Total number of investors", + count: 27, + }, + { + icon: , + label: "Total number of unique investors", + count: 27, + }, +]; + +const walletCase = [ + { amount: "$ د. ب. 50,000", currency: "USD" }, + { amount: "$ د. ب. 50,000", currency: "BHD" }, + { amount: "$ ﷼. 50,000", currency: "SAR" }, + { amount: "$ د.ك 50,0000", currency: "KWD" }, + { amount: "$ د.إ 50,000", currency: "AED" }, + { amount: "$ ﷼ 50,000", currency: "OMR" }, + { amount: "$ ر. ق 50,000" , currency: "QAR" }, +]; + +const Dashbaord = ({ showSearch = false }) => { return ( - - + + Pending Request - + {panddingReguest.map((item, index) => ( {item.icon} - + {item.label} - + {item.count} @@ -68,56 +103,125 @@ const Dashbaord = () => { - Pending Request + User Activity - + {userActivity.map((item, index) => ( {item.icon} - + {item.label} - + {item.count} {item.percentage} ))} - - - - 80% - Users that opened the app today - - - - 3,298 - New sign-ups - - - - - + + + + 80% - New KYC verification + Users that opened the app today 3,298 - Users who logged in + New sign-ups + + + + + + + + + + 80% + New KYC verification + + + + 3,298 + Users who logged in + + + Investment Opportunities + + + + Open Opportunities + + + + + + + + {closedOpportunities.map((item, index) => ( + + + {item.icon} + + {item.label} + + + + {item.count} + + + ))} + + + + Wallet Balances + + + $ 50,000 + TOTAL CASH AVAILABLE ACROSS ALL WALLETS USD + + Sum of users available wallet cash in + + {walletCase.slice(0, 4).map((item, index) => ( + + + {item.amount} + + + {item.currency} + + + ))} + + + + {walletCase.slice(4).map((item, index) => ( + + + {item.amount} + + + {item.currency} + + + ))} + + + ) } diff --git a/src/Pages/Dashboard/InvestmentOpportunities.jsx b/src/Pages/Dashboard/InvestmentOpportunities.jsx new file mode 100644 index 0000000..260334a --- /dev/null +++ b/src/Pages/Dashboard/InvestmentOpportunities.jsx @@ -0,0 +1,161 @@ +import { + Box, + HStack, + Input, + Select, + Text, + useToast, + } from "@chakra-ui/react"; + import React, { useContext, useEffect, useState, useRef } from "react"; +import { OPACITY_ON_LOAD } from "../../Layout/animations"; +import GlobalStateContext from "../../Contexts/GlobalStateContext"; +import CustomAlertDialog from "../../Components/CustomAlertDialog"; +import NormalTable from "../../Components/DataTable/NormalTable"; + + const formatDate = (date) => new Date(date).toLocaleDateString(); + + const InvestmentOpportunities = ({ showSearch = true }) => { + const toast = useToast(); + const { opportunities, setOpportunities, slideFromRight } = + useContext(GlobalStateContext); + const [searchTerm, setSearchTerm] = useState(""); + const [isLoading, setIsLoading] = useState(true); + const [deleteAlert, setDeleteAlert] = useState(false); + const [actionId, setActionId] = useState(false); + + // const { + // data: bankDetails, + // isLoading: bankDetailsLoading, + // error, + // } = useGetBankQuery({ page: 1, size: 10 }); + + useEffect(() => { + // Simulate loading + const timer = setTimeout(() => { + setIsLoading(false); + }, 1500); + + // Cleanup the timer on component unmount + return () => clearTimeout(timer); + }, []); + + // ====================================================[Table Setup]================================================================ + const tableHeadRow = [ + "Sr N/O", + "Investors", + "Amount remaining %", + "Total deal size", + // + // Total deal size + // + // , + "No of views", + ]; + + // ====================================================[Table Filter]================================================================ + const filteredData = opportunities?.filter((item) => { + // Filter by name (case insensitive) + const name = item.Investors; + const searchLower = searchTerm.toLowerCase(); + const nameMatches = name?.toLowerCase().includes(searchLower); + + return nameMatches; + }); + + + const extractedArray = filteredData?.map((item,index) => ({ + id: item?.id, + "Sr N/O": ( + + {item.id} + + ), + "Investors": ( + + + {item?.Investors} + + + ), + "Amount remaining %": ( + + + {item?.amountRemaining} + + + ), + "Total deal size": ( + + + {item?.totalDealsize} + + + ), + "No of views": ( + + + {item.noViews} + + + ), + })); + + return ( + + + {showSearch && ( + + setSearchTerm(e.target.value)} + /> + + )} + + + + + setDeleteAlert(false)} + isOpen={deleteAlert} + message={"Are you sure you want to delete sponers?"} + isLoading={isLoading} + /> + + ); + }; + + export default InvestmentOpportunities; + \ No newline at end of file diff --git a/src/Routes/Routes.js b/src/Routes/Routes.js index 09bdf6e..a366cf6 100644 --- a/src/Routes/Routes.js +++ b/src/Routes/Routes.js @@ -48,12 +48,14 @@ import AddUser from "../Pages/User/AddUser"; import Profile from "../Pages/Profile/Profile"; import SubAdmin from "../Pages/SubAdmin/SubAdmin"; import SubAdminUpdateCreate from "../Pages/SubAdmin/SubAdminUpdateCreate"; +import InvestmentOpportunities from "../Pages/Dashboard/InvestmentOpportunities"; export const RouteLink = [ // =============[ Tanami ]================ // ===============[ Management]=============== { path: "/", Component: Dashbaord }, + { path: "/investment-opportunities", Component: InvestmentOpportunities }, { path: "/sponser", Component: Sponser }, { path: "/sponser/add-sponser/:id", Component: AddSponser }, { path: "/sponser/add-sponser", Component: AddSponser }, From 874940ae7c28420a7fbae4864674bb96057066e2 Mon Sep 17 00:00:00 2001 From: YasinShaikh123 <123150391+YasinShaikh123@users.noreply.github.com> Date: Mon, 13 Jan 2025 19:24:03 +0530 Subject: [PATCH 05/50] =?UTF-8?q?Spelling=20=E2=9C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Layout/DefaultLayout.jsx | 2 +- src/Pages/Master/Sponser/AddSponser.jsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Layout/DefaultLayout.jsx b/src/Layout/DefaultLayout.jsx index f615b1e..d2ab662 100644 --- a/src/Layout/DefaultLayout.jsx +++ b/src/Layout/DefaultLayout.jsx @@ -218,7 +218,7 @@ const DashboardLayout = ({ isOnline }) => { return ( - Deposite Request + Deposit Request ); diff --git a/src/Pages/Master/Sponser/AddSponser.jsx b/src/Pages/Master/Sponser/AddSponser.jsx index ed3b276..2a86177 100644 --- a/src/Pages/Master/Sponser/AddSponser.jsx +++ b/src/Pages/Master/Sponser/AddSponser.jsx @@ -254,7 +254,7 @@ const AddSponser = () => { } characters.`, }, { - label: "Email adress", + label: "Email address", name: "email", placeHolder: " ", type: "email", From 5928af4283c396065138c3b4c574306d0a7e7d3e Mon Sep 17 00:00:00 2001 From: YasinShaikh123 <123150391+YasinShaikh123@users.noreply.github.com> Date: Wed, 15 Jan 2025 17:06:00 +0530 Subject: [PATCH 06/50] =?UTF-8?q?[update]=20-=20dashboard=20=E2=9D=A4?= =?UTF-8?q?=EF=B8=8F=E2=9C=85=F0=9F=98=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Components/DataTable/NormalTable.jsx | 1 - src/Layout/DefaultLayout.jsx | 8 + src/Pages/Dashboard/Dashbaord.jsx | 542 +++++++++++++----- .../Dashboard/InvestmentOpportunities.jsx | 269 ++++----- src/Routes/Nav.js | 2 +- src/Services/dashboard.service.js | 20 + src/Store/Store.js | 3 + 7 files changed, 566 insertions(+), 279 deletions(-) create mode 100644 src/Services/dashboard.service.js diff --git a/src/Components/DataTable/NormalTable.jsx b/src/Components/DataTable/NormalTable.jsx index af3155f..a08a134 100644 --- a/src/Components/DataTable/NormalTable.jsx +++ b/src/Components/DataTable/NormalTable.jsx @@ -58,7 +58,6 @@ const NormalTable = ({ }; - const handleCheckboxChange = (value) => { if (radio) { // If radio is true, select only one option diff --git a/src/Layout/DefaultLayout.jsx b/src/Layout/DefaultLayout.jsx index d74a08b..39f6a95 100644 --- a/src/Layout/DefaultLayout.jsx +++ b/src/Layout/DefaultLayout.jsx @@ -140,6 +140,14 @@ const DashboardLayout = ({ isOnline }) => { switch (true) { case "/": return "👋🏻 Hi, Admin"; + + case path.startsWith("/"): + return ( + + Dashboard + + ); + case path.startsWith("/investment-opportunities"): return ( diff --git a/src/Pages/Dashboard/Dashbaord.jsx b/src/Pages/Dashboard/Dashbaord.jsx index 833ff84..bd56825 100644 --- a/src/Pages/Dashboard/Dashbaord.jsx +++ b/src/Pages/Dashboard/Dashbaord.jsx @@ -1,201 +1,455 @@ -import { Box, Divider, Flex, Grid, GridItem, Heading, HStack, Select, SimpleGrid, Stack, Text } from '@chakra-ui/react' -import React from 'react' -import { BsArrowsAngleContract, BsBoxArrowDown, BsBoxArrowUp } from "react-icons/bs"; +import { + Box, + Divider, + Flex, + Heading, + HStack, + Select, + SimpleGrid, + Text, +} from "@chakra-ui/react"; +import React, { useState } from "react"; +import { + BsArrowsAngleContract, + BsBoxArrowDown, + BsBoxArrowUp, +} from "react-icons/bs"; +import { FaRegPenToSquare } from "react-icons/fa6"; import { LuContact } from "react-icons/lu"; -import { FaRegPenToSquare } from "react-icons/fa6"; -import InvestmentOpportunities from './InvestmentOpportunities'; -import { Link } from 'react-router-dom'; +import { Link } from "react-router-dom"; +import { useGetDashboardMasterQuery } from "../../Services/dashboard.service"; +import InvestmentOpportunities from "./InvestmentOpportunities"; -const panddingReguest = [ - { - icon: , - label: "Pending deposit requests", - count: 27, - }, - { - icon: , - label: "Pending withdrawal requests", - count: 27, - }, - { - icon: , - label: "Pending KYC review request", - count: 27, - }, - { - icon: , - label: "Pending Acc modification request", - count: 27, - }, -]; - -const userActivity = [ - { - icon: , - label: "Total number of users", - count: 1500, - }, - { - icon: , - label: "Total number of users with completed KYC (%)", - count: '320', - percentage:'(50%)', - }, - { - icon: , - label: "Total number of Active users", - count: '3,298', - }, -]; - -const closedOpportunities = [ - { - icon: , - label: "Closed Opportunities", - count: 27, - }, - { - icon: , - label: "Total assets under managemnet", - count: 27, - }, - { - icon: , - label: "Total number of investors", - count: 27, - }, - { - icon: , - label: "Total number of unique investors", - count: 27, - }, -]; - -const walletCase = [ - { amount: "$ د. ب. 50,000", currency: "USD" }, - { amount: "$ د. ب. 50,000", currency: "BHD" }, - { amount: "$ ﷼. 50,000", currency: "SAR" }, - { amount: "$ د.ك 50,0000", currency: "KWD" }, - { amount: "$ د.إ 50,000", currency: "AED" }, - { amount: "$ ﷼ 50,000", currency: "OMR" }, - { amount: "$ ر. ق 50,000" , currency: "QAR" }, -]; +// const panddingReguest = [ +// { +// icon: , +// label: "Pending deposit requests", +// count: 27, +// }, +// { +// icon: , +// label: "Pending withdrawal requests", +// count: 27, +// }, +// { +// icon: , +// label: "Pending KYC review request", +// count: 27, +// }, +// { +// icon: , +// label: "Pending Acc modification request", +// count: 27, +// }, +// ]; const Dashbaord = ({ showSearch = false }) => { + const [filter, setFilter] = useState("today"); + const { data, error, isLoading } = useGetDashboardMasterQuery(); + console.log(data); + + const panddingReguest = [ + { + icon: , + label: "Pending deposit requests", + count: parseFloat( + data?.data?.pendingRequests?.pendingDepositReq?.totalDepositReq || 0 + ).toLocaleString(), + }, + { + icon: , + label: "Pending withdrawal requests", + count: parseFloat( + data?.data?.pendingRequests?.pendingWithdrawalReq || 0 + ).toLocaleString(), + }, + { + icon: , + label: "Pending KYC review request", + count: parseFloat( + data?.data?.pendingRequests?.pendingKYCReviewReq || 0 + ).toLocaleString(), + }, + { + icon: , + label: "Pending Acc modification request", + count: parseFloat( + data?.data?.pendingRequests?.pendingAccModReq?.totalAccModReq || 0 + ).toLocaleString(), + }, + ]; + + const userActivity = [ + { + icon: , + label: "Total number of users", + count: data?.data?.userActivity?.totalCount, //totalCount + }, + { + icon: , + label: "Total number of users with completed KYC (%)", + count: data?.data?.userActivity?.KYCCompletedCount, //KYCCompletedCount + percentage: data?.data?.userActivity?.completedKYCPer, //completedKYCPer + }, + { + icon: , + label: "Total number of Active users", + count: data?.data?.userActivity?.ActiveUsers, //ActiveUsers + }, + ]; + + const closedOpportunities = [ + { + icon: , + label: "Closed Opportunities", + count: parseFloat( + data?.data?.investmentOpportunity?.closedOpportunityDetails + ?.numberOfClosedOpportunities || 0 + ).toLocaleString(), + }, + { + icon: , + label: "Total assets under managemnet", + count: `$ ${parseFloat( + data?.data?.investmentOpportunity?.closedOpportunityDetails?.totalAUM || + 0 + ).toLocaleString(undefined, { + minimumFractionDigits: 2, + maximumFractionDigits: 2, + })}`, + }, + { + icon: , + label: "Total number of investors", + count: parseFloat( + data?.data?.investmentOpportunity?.closedOpportunityDetails + ?.totalNumberOfInvestors || 0 + ).toLocaleString(), + }, + { + icon: , + label: "Total number of unique investors", + count: parseFloat( + data?.data?.investmentOpportunity?.closedOpportunityDetails + ?.numberOfUniqueInvestors || 0 + ).toLocaleString(), + }, + ]; + + const walletCase = [ + { + amount: `$ ${parseFloat( + data?.data?.walletBalance?.usersWalletCashInUSD || 0 + ).toLocaleString(undefined, { + minimumFractionDigits: 2, + maximumFractionDigits: 2, + })}`, + currency: "USD", + }, + { + amount: ` د. ب. ${parseFloat( + data?.data?.walletBalance?.usersWalletCashInBHD || 0 + ).toLocaleString(undefined, { + minimumFractionDigits: 2, + maximumFractionDigits: 2, + })}`, + currency: "BHD", + }, + { + amount: ` ﷼. ${parseFloat( + data?.data?.walletBalance?.usersWalletCashInSAR || 0 + ).toLocaleString(undefined, { + minimumFractionDigits: 2, + maximumFractionDigits: 2, + })}`, + currency: "SAR", + }, + { + amount: ` د.ك ${parseFloat( + data?.data?.walletBalance?.usersWalletCashInKWD || 0 + ).toLocaleString(undefined, { + minimumFractionDigits: 2, + maximumFractionDigits: 2, + })}`, + currency: "KWD", + }, + { + amount: ` د.إ ${parseFloat( + data?.data?.walletBalance?.usersWalletCashInAED || 0 + ).toLocaleString(undefined, { + minimumFractionDigits: 2, + maximumFractionDigits: 2, + })}`, + currency: "AED", + }, + { + amount: ` ﷼. ${parseFloat( + data?.data?.walletBalance?.usersWalletCashInOMR || 0 + ).toLocaleString(undefined, { + minimumFractionDigits: 2, + maximumFractionDigits: 2, + })}`, + currency: "OMR", + }, + { + amount: ` ر. ق. ${parseFloat( + data?.data?.walletBalance?.usersWalletCashInQAR || 0 + ).toLocaleString(undefined, { + minimumFractionDigits: 2, + maximumFractionDigits: 2, + })}`, + currency: "QAR", + }, + ]; + return ( - - - - Pending Request + + + + + Pending Request + {panddingReguest.map((item, index) => ( - {item.icon} - + + {item.icon} + + {item.label} - + {item.count} ))} - - User Activity + + + User Activity + {userActivity.map((item, index) => ( - - {item.icon} - - {item.label} - + + {item.icon} + + {item.label} + - - {item.count} {item.percentage} + + {item?.count} + {item?.percentage && ( + + {` (${item?.percentage}) %`} + + )} ))} - - - - - - 80% - Users that opened the app today + + + + + + + {data?.data?.userActivity?.openedAppToday?.percentage} % + + + Users that opened the app today + - - - 3,298 - New sign-ups + + + + {parseFloat( + data?.data?.userActivity?.loggedInWithInLastMonth + ?.number || 0 + ).toLocaleString()} + + + Users who logged in during the last month + - - - setFilter(e.target.value)} + > + + + - - - 80% - New KYC verification + + + + {filter === "today" + ? data?.data?.userActivity?.newSignUps?.today + : filter === "last7days" + ? data?.data?.userActivity?.newSignUps?.last7days + : data?.data?.userActivity?.newSignUps?.last30days} + + + New sign-ups{" "} + - - - 3,298 - Users who logged in + + + + {filter === "today" + ? data?.data?.userActivity?.newKYCVerifications?.today + : filter === "last7days" + ? data?.data?.userActivity?.newKYCVerifications?.last7days + : data?.data?.userActivity?.newKYCVerifications + ?.last30days} + + + New KYC verification + - - - Investment Opportunities + + + + Investment Opportunities + - - - Open Opportunities - + + + + Open Opportunities + + + + - - + + {closedOpportunities.map((item, index) => ( - - {item.icon} - + + + {item.icon} + + {item.label} - + + {/* {parseFloat(item?.count || 0).toLocaleString(undefined, { + minimumFractionDigits: 2, + maximumFractionDigits: 2, + })} */} {item.count} ))} - - Wallet Balances + + + Wallet Balances + - - $ 50,000 - TOTAL CASH AVAILABLE ACROSS ALL WALLETS USD + + + ${" "} + {parseFloat( + data?.data?.walletBalance?.totalCashAvailAcrossAllUSD || 0 + ).toLocaleString(undefined, { + minimumFractionDigits: 2, + maximumFractionDigits: 2, + })} + {/* {data?.data?.walletBalance?.totalCashAvailAcrossAllUSD} */} + + + TOTAL CASH AVAILABLE ACROSS ALL WALLETS USD + - Sum of users available wallet cash in - + + Sum of users available wallet cash in + + {walletCase.slice(0, 4).map((item, index) => ( @@ -223,7 +477,7 @@ const Dashbaord = ({ showSearch = false }) => { - ) -} + ); +}; -export default Dashbaord +export default Dashbaord; diff --git a/src/Pages/Dashboard/InvestmentOpportunities.jsx b/src/Pages/Dashboard/InvestmentOpportunities.jsx index 260334a..1d8ed47 100644 --- a/src/Pages/Dashboard/InvestmentOpportunities.jsx +++ b/src/Pages/Dashboard/InvestmentOpportunities.jsx @@ -1,122 +1,102 @@ -import { - Box, - HStack, - Input, - Select, - Text, - useToast, - } from "@chakra-ui/react"; - import React, { useContext, useEffect, useState, useRef } from "react"; +import { Box, HStack, Input, Select, Text, useToast } from "@chakra-ui/react"; +import React, { useContext, useEffect, useState } from "react"; import { OPACITY_ON_LOAD } from "../../Layout/animations"; import GlobalStateContext from "../../Contexts/GlobalStateContext"; import CustomAlertDialog from "../../Components/CustomAlertDialog"; import NormalTable from "../../Components/DataTable/NormalTable"; - - const formatDate = (date) => new Date(date).toLocaleDateString(); - - const InvestmentOpportunities = ({ showSearch = true }) => { - const toast = useToast(); - const { opportunities, setOpportunities, slideFromRight } = - useContext(GlobalStateContext); - const [searchTerm, setSearchTerm] = useState(""); - const [isLoading, setIsLoading] = useState(true); - const [deleteAlert, setDeleteAlert] = useState(false); - const [actionId, setActionId] = useState(false); - - // const { - // data: bankDetails, - // isLoading: bankDetailsLoading, - // error, - // } = useGetBankQuery({ page: 1, size: 10 }); - - useEffect(() => { - // Simulate loading - const timer = setTimeout(() => { - setIsLoading(false); - }, 1500); - - // Cleanup the timer on component unmount - return () => clearTimeout(timer); - }, []); - - // ====================================================[Table Setup]================================================================ - const tableHeadRow = [ - "Sr N/O", - "Investors", - "Amount remaining %", - "Total deal size", - // - // Total deal size - // - // , - "No of views", - ]; - - // ====================================================[Table Filter]================================================================ - const filteredData = opportunities?.filter((item) => { - // Filter by name (case insensitive) - const name = item.Investors; - const searchLower = searchTerm.toLowerCase(); - const nameMatches = name?.toLowerCase().includes(searchLower); - - return nameMatches; - }); - - - const extractedArray = filteredData?.map((item,index) => ({ - id: item?.id, - "Sr N/O": ( - - {item.id} +import { useGetDashboardMasterQuery } from "../../Services/dashboard.service"; +import { generateSerialNumber } from "../../Constants/Constants"; + +const formatDate = (date) => new Date(date).toLocaleDateString(); + +const InvestmentOpportunities = ({ showSearch = true, selectStyle = {} }) => { + const toast = useToast(); + const { opportunities, setOpportunities, slideFromRight } = + useContext(GlobalStateContext); + const [searchTerm, setSearchTerm] = useState(""); + const [isLoading, setIsLoading] = useState(true); + const [deleteAlert, setDeleteAlert] = useState(false); + const [actionId, setActionId] = useState(null); + const [filter, setFilter] = useState(null); + + const { data, error } = useGetDashboardMasterQuery(); + + useEffect(() => { + const timer = setTimeout(() => setIsLoading(false), 1500); + return () => clearTimeout(timer); + }, []); + + const tableHeadRow = [ + "Sr No", + "Investors", + "Amount Remaining %", + "Total Deal Size", + "No of Views", + ]; + + const filteredData = + data?.data?.investmentOpportunity?.openOpportunityDetails?.filter((item) => + item?.Investment_name?.toLowerCase().includes(searchTerm.toLowerCase()) + ); + + const extractedArray = filteredData?.map((item, index) => ({ + id: item?.id, + "Sr No": ( + + {index + 1} + + ), + Investors: ( + + + {item?.Investment_name} - ), - "Investors": ( - - - {item?.Investors} - - - ), - "Amount remaining %": ( - - - {item?.amountRemaining} - - - ), - "Total deal size": ( - - - {item?.totalDealsize} - - - ), - "No of views": ( - - - {item.noViews} - - - ), - })); - - return ( - - + + ), + "Amount Remaining %": ( + + + {`${parseFloat(item?.Amount_remaining_per || 0).toLocaleString()} %`} + + + ), + "Total Deal Size": ( + + + {`$ ${parseFloat(item?.Deal_size || 0).toLocaleString(undefined, { + minimumFractionDigits: 2, + maximumFractionDigits: 2, + })}`} + + + ), + "No of Views": ( + + + {item?.Views_today} + {filter === "today" + ? item?.Views_today + : filter === "last7days" + ? item?.Views_last_7_days + : item?.Views_mtd} + + + ), + })); + + return ( + + {showSearch && ( )} + + - - - - setDeleteAlert(false)} - isOpen={deleteAlert} - message={"Are you sure you want to delete sponers?"} - isLoading={isLoading} - /> - ); - }; - - export default InvestmentOpportunities; - \ No newline at end of file + + + + setDeleteAlert(false)} + isOpen={deleteAlert} + message={"Are you sure you want to delete this opportunity?"} + isLoading={isLoading} + /> + + ); +}; + +export default InvestmentOpportunities; diff --git a/src/Routes/Nav.js b/src/Routes/Nav.js index d01b988..b7b5f1a 100644 --- a/src/Routes/Nav.js +++ b/src/Routes/Nav.js @@ -37,7 +37,7 @@ export const nav = [ { title: "Dashboard", type: "single", - path: "/dashboard", + path: "/", Icon: TbLayoutDashboard, }, { diff --git a/src/Services/dashboard.service.js b/src/Services/dashboard.service.js new file mode 100644 index 0000000..fa1c88f --- /dev/null +++ b/src/Services/dashboard.service.js @@ -0,0 +1,20 @@ +// Need to use the React-specific entry point to import createApi +import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; +import { baseQuery } from "./token.serivce"; + +// Define a service using a base URL and expected endpoints +export const dashboardMaster = createApi({ + reducerPath: "Dashboard", + baseQuery: baseQuery, + tagTypes: ["getDashboard"], + endpoints: (builder) => ({ + // ======[Get All]===== + + getDashboardMaster: builder.query({ + query: () => `/dashboard/admin/`, + providesTags: ["getDashboard"], + }), + }), +}); + +export const { useGetDashboardMasterQuery } = dashboardMaster; diff --git a/src/Store/Store.js b/src/Store/Store.js index 8d1bc65..f3a101c 100644 --- a/src/Store/Store.js +++ b/src/Store/Store.js @@ -20,6 +20,7 @@ import { fawateerMaker } from "../Services/fawateer.maker.service"; import { sabAdminMaster } from "../Services/subadmin.service"; import { changePasswordMake } from "../Services/change.password.service"; import { forgetPasswordMake } from "../Services/forget.password.service"; +import { dashboardMaster } from "../Services/dashboard.service"; export const store = configureStore({ reducer: { @@ -41,6 +42,7 @@ export const store = configureStore({ [sabAdminMaster.reducerPath]: sabAdminMaster.reducer, [changePasswordMake.reducerPath]: changePasswordMake.reducer, [forgetPasswordMake.reducerPath]: forgetPasswordMake.reducer, + [dashboardMaster.reducerPath]: dashboardMaster.reducer, // Add other reducers as needed }, @@ -68,6 +70,7 @@ export const store = configureStore({ sabAdminMaster.middleware, changePasswordMake.middleware, forgetPasswordMake.middleware, + dashboardMaster.middleware, ), }); From 4e4de8caf577524505d41be3dfb57ea4ebe3df54 Mon Sep 17 00:00:00 2001 From: Swapnil Bendal <84583651+Swapnil155@users.noreply.github.com> Date: Wed, 15 Jan 2025 17:29:17 +0530 Subject: [PATCH 07/50] [update] - format percentage display and adjust navigation path --- .../Dashboard/InvestmentOpportunities.jsx | 19 ++++++++++++------- src/Pages/Login.jsx | 2 +- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/Pages/Dashboard/InvestmentOpportunities.jsx b/src/Pages/Dashboard/InvestmentOpportunities.jsx index 1d8ed47..d11a454 100644 --- a/src/Pages/Dashboard/InvestmentOpportunities.jsx +++ b/src/Pages/Dashboard/InvestmentOpportunities.jsx @@ -62,7 +62,13 @@ const InvestmentOpportunities = ({ showSearch = true, selectStyle = {} }) => { "Amount Remaining %": ( - {`${parseFloat(item?.Amount_remaining_per || 0).toLocaleString()} %`} + {`${parseFloat(item?.Amount_remaining_per || 0).toLocaleString( + undefined, + { + minimumFractionDigits: 2, + maximumFractionDigits: 2, + } + )} %`} ), @@ -79,12 +85,11 @@ const InvestmentOpportunities = ({ showSearch = true, selectStyle = {} }) => { "No of Views": ( - {item?.Views_today} - {filter === "today" - ? item?.Views_today + {filter === "last30days" + ? item?.Views_mtd : filter === "last7days" ? item?.Views_last_7_days - : item?.Views_mtd} + : item?.Views_today} ), @@ -136,8 +141,8 @@ const InvestmentOpportunities = ({ showSearch = true, selectStyle = {} }) => { - - + + diff --git a/src/Pages/Login.jsx b/src/Pages/Login.jsx index 62837f1..d53844c 100644 --- a/src/Pages/Login.jsx +++ b/src/Pages/Login.jsx @@ -78,7 +78,7 @@ const Login = () => { setIsLoading(false); setIsAuthenticate(true); Cookies.set("isAuthenticated", true, { expires: 7 }); - navigate("/sponser"); + navigate("/"); reset(); } From 3d456c3c48070acfa9ceb59d02c46578eba320b2 Mon Sep 17 00:00:00 2001 From: Swapnil Bendal <84583651+Swapnil155@users.noreply.github.com> Date: Wed, 15 Jan 2025 17:55:59 +0530 Subject: [PATCH 08/50] [update] - refactor Notification component for improved readability and adjust message validation --- src/Pages/Admin/Notification.jsx | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/Pages/Admin/Notification.jsx b/src/Pages/Admin/Notification.jsx index 874a28a..1579aa1 100644 --- a/src/Pages/Admin/Notification.jsx +++ b/src/Pages/Admin/Notification.jsx @@ -26,7 +26,10 @@ import ToastBox from "../../Components/ToastBox"; import NormalTable from "../../Components/DataTable/NormalTable"; import GlobalStateContext from "../../Contexts/GlobalStateContext"; import { useGetInvestorsQuery } from "../../Services/investor.details.service"; -import { INVESTOR_TABLE_PAGINATION, TABLE_PAGINATION } from "../../Constants/Paginations"; +import { + INVESTOR_TABLE_PAGINATION, + TABLE_PAGINATION, +} from "../../Constants/Paginations"; import { formatDate, generateSerialNumber } from "../../Constants/Constants"; import { ViewIcon } from "@chakra-ui/icons"; import { useGetUnbanInvestorQuery } from "../../Services/ban.investor.service"; @@ -49,7 +52,7 @@ export const notification = yup.object().shape({ export const notificationNew = yup.object().shape({ title: yup.string().required("Notification Header is required"), - message: yup.string().required("Message is required"), + message: yup.string().notRequired(), }); const Notification = () => { @@ -59,7 +62,9 @@ const Notification = () => { const [isLoading, setIsLoading] = useState(false); const [selectedRadio, setSelectedRadio] = useState([]); const [pageSize, setPageSize] = useState(INVESTOR_TABLE_PAGINATION?.size); - const [currentPage, setCurrentPage] = useState(INVESTOR_TABLE_PAGINATION?.page); + const [currentPage, setCurrentPage] = useState( + INVESTOR_TABLE_PAGINATION?.page + ); const [searchTerm, setSearchTerm] = useState(""); const [debouncedSearchTerm, setDebouncedSearchTerm] = useState(""); const [country, setCountry] = useState(""); @@ -108,16 +113,18 @@ const Notification = () => { }, 300); return () => clearTimeout(handler); }, [searchTerm]); - - const { data: investorDetails, isLoading: investorDetailsLoading, refetch } = - useGetUnbanInvestorQuery( + const { + data: investorDetails, + isLoading: investorDetailsLoading, + refetch, + } = useGetUnbanInvestorQuery( { page: 1, // Omit pagination for search size: 10000, // Omit pagination for search // page: debouncedSearchTerm ? undefined : currentPage, // Disable pagination for search // size: debouncedSearchTerm ? undefined : 10000 || pageSize || 500, // Disable pagination for search - search: debouncedSearchTerm, // Pass search term + search: debouncedSearchTerm, // Pass search term country_xid: country, KYCStatus: kyc, }, @@ -131,10 +138,6 @@ const Notification = () => { // console.log("Debounced Search Term:", debouncedSearchTerm); // console.log("Investor Details:", investorDetails); // }, [searchTerm, debouncedSearchTerm, investorDetails]); - - - - console.log(investorDetails); const [sendNotification] = useSendNotificationMutation(); @@ -190,7 +193,6 @@ const Notification = () => { setIsLoading(true); try { const res = await sendNotification(dataToPass); - console.log(res); if (res?.error) { toast({ @@ -313,7 +315,6 @@ const Notification = () => { ), })); - return ( From 20213408c47cf8d91b12c21636e1a72585fc50ce Mon Sep 17 00:00:00 2001 From: Swapnil Bendal <84583651+Swapnil155@users.noreply.github.com> Date: Wed, 15 Jan 2025 18:00:54 +0530 Subject: [PATCH 09/50] [update] - enforce message requirement for specific status in UpdateIOStatus component --- src/Pages/IO_Management/ViewIO/HeaderModal/UpdateIOStatus.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Pages/IO_Management/ViewIO/HeaderModal/UpdateIOStatus.jsx b/src/Pages/IO_Management/ViewIO/HeaderModal/UpdateIOStatus.jsx index 1db3014..8b36298 100644 --- a/src/Pages/IO_Management/ViewIO/HeaderModal/UpdateIOStatus.jsx +++ b/src/Pages/IO_Management/ViewIO/HeaderModal/UpdateIOStatus.jsx @@ -57,7 +57,7 @@ const UpdateIOStatus = ({ isOpen, onClose, status }) => { setError("Please select status"); return; } - if (!message) { + if (selectedStatusId == 6 && !message) { return setMessageError("message is required"); } setError(""); From d23bf5d7e9d1362e6eab99fc750e72eef2b460f3 Mon Sep 17 00:00:00 2001 From: YasinShaikh123 <123150391+YasinShaikh123@users.noreply.github.com> Date: Wed, 15 Jan 2025 19:02:43 +0530 Subject: [PATCH 10/50] =?UTF-8?q?[=20Change=20Icon=20=F0=9F=A5=B1]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Images/dash_icon_1.svg | 4 ++ src/Images/dash_icon_2.svg | 4 ++ src/Images/dash_icon_3.svg | 7 +++ src/Images/dash_icon_4.svg | 3 ++ src/Images/dash_icon_5.svg | 3 ++ src/Images/dash_icon_6.svg | 5 ++ src/Images/dash_icon_7.svg | 3 ++ src/Pages/Dashboard/Dashbaord.jsx | 54 +++++++++++-------- .../Dashboard/InvestmentOpportunities.jsx | 2 +- 9 files changed, 62 insertions(+), 23 deletions(-) create mode 100644 src/Images/dash_icon_1.svg create mode 100644 src/Images/dash_icon_2.svg create mode 100644 src/Images/dash_icon_3.svg create mode 100644 src/Images/dash_icon_4.svg create mode 100644 src/Images/dash_icon_5.svg create mode 100644 src/Images/dash_icon_6.svg create mode 100644 src/Images/dash_icon_7.svg diff --git a/src/Images/dash_icon_1.svg b/src/Images/dash_icon_1.svg new file mode 100644 index 0000000..d6ddeb7 --- /dev/null +++ b/src/Images/dash_icon_1.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/Images/dash_icon_2.svg b/src/Images/dash_icon_2.svg new file mode 100644 index 0000000..02736d2 --- /dev/null +++ b/src/Images/dash_icon_2.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/Images/dash_icon_3.svg b/src/Images/dash_icon_3.svg new file mode 100644 index 0000000..1592b46 --- /dev/null +++ b/src/Images/dash_icon_3.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/Images/dash_icon_4.svg b/src/Images/dash_icon_4.svg new file mode 100644 index 0000000..9a1efb8 --- /dev/null +++ b/src/Images/dash_icon_4.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/Images/dash_icon_5.svg b/src/Images/dash_icon_5.svg new file mode 100644 index 0000000..d548db0 --- /dev/null +++ b/src/Images/dash_icon_5.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/Images/dash_icon_6.svg b/src/Images/dash_icon_6.svg new file mode 100644 index 0000000..81207ec --- /dev/null +++ b/src/Images/dash_icon_6.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/Images/dash_icon_7.svg b/src/Images/dash_icon_7.svg new file mode 100644 index 0000000..6c9d94b --- /dev/null +++ b/src/Images/dash_icon_7.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/Pages/Dashboard/Dashbaord.jsx b/src/Pages/Dashboard/Dashbaord.jsx index bd56825..55514e6 100644 --- a/src/Pages/Dashboard/Dashbaord.jsx +++ b/src/Pages/Dashboard/Dashbaord.jsx @@ -4,6 +4,7 @@ import { Flex, Heading, HStack, + Image, Select, SimpleGrid, Text, @@ -19,6 +20,13 @@ import { LuContact } from "react-icons/lu"; import { Link } from "react-router-dom"; import { useGetDashboardMasterQuery } from "../../Services/dashboard.service"; import InvestmentOpportunities from "./InvestmentOpportunities"; +import IconOne from '../../Images/dash_icon_1.svg'; +import IconTwo from '../../Images/dash_icon_2.svg'; +import IconThree from '../../Images/dash_icon_3.svg'; +import IconFour from '../../Images/dash_icon_4.svg' +import IconFive from '../../Images/dash_icon_5.svg'; +import IconSix from '../../Images/dash_icon_6.svg'; +import IconSeven from '../../Images/dash_icon_7.svg' // const panddingReguest = [ // { @@ -50,28 +58,28 @@ const Dashbaord = ({ showSearch = false }) => { const panddingReguest = [ { - icon: , + icon: IconOne, label: "Pending deposit requests", count: parseFloat( data?.data?.pendingRequests?.pendingDepositReq?.totalDepositReq || 0 ).toLocaleString(), }, { - icon: , + icon: IconTwo, label: "Pending withdrawal requests", count: parseFloat( data?.data?.pendingRequests?.pendingWithdrawalReq || 0 ).toLocaleString(), }, { - icon: , + icon: IconThree, label: "Pending KYC review request", count: parseFloat( data?.data?.pendingRequests?.pendingKYCReviewReq || 0 ).toLocaleString(), }, { - icon: , + icon: IconFour, label: "Pending Acc modification request", count: parseFloat( data?.data?.pendingRequests?.pendingAccModReq?.totalAccModReq || 0 @@ -81,18 +89,18 @@ const Dashbaord = ({ showSearch = false }) => { const userActivity = [ { - icon: , + icon: IconFive, label: "Total number of users", count: data?.data?.userActivity?.totalCount, //totalCount }, { - icon: , + icon: IconSix, label: "Total number of users with completed KYC (%)", count: data?.data?.userActivity?.KYCCompletedCount, //KYCCompletedCount percentage: data?.data?.userActivity?.completedKYCPer, //completedKYCPer }, { - icon: , + icon: IconSeven, label: "Total number of Active users", count: data?.data?.userActivity?.ActiveUsers, //ActiveUsers }, @@ -100,7 +108,7 @@ const Dashbaord = ({ showSearch = false }) => { const closedOpportunities = [ { - icon: , + icon: IconOne, label: "Closed Opportunities", count: parseFloat( data?.data?.investmentOpportunity?.closedOpportunityDetails @@ -108,7 +116,7 @@ const Dashbaord = ({ showSearch = false }) => { ).toLocaleString(), }, { - icon: , + icon: IconOne, label: "Total assets under managemnet", count: `$ ${parseFloat( data?.data?.investmentOpportunity?.closedOpportunityDetails?.totalAUM || @@ -119,7 +127,7 @@ const Dashbaord = ({ showSearch = false }) => { })}`, }, { - icon: , + icon: IconOne, label: "Total number of investors", count: parseFloat( data?.data?.investmentOpportunity?.closedOpportunityDetails @@ -127,7 +135,7 @@ const Dashbaord = ({ showSearch = false }) => { ).toLocaleString(), }, { - icon: , + icon: IconOne, label: "Total number of unique investors", count: parseFloat( data?.data?.investmentOpportunity?.closedOpportunityDetails @@ -220,9 +228,9 @@ const Dashbaord = ({ showSearch = false }) => { {panddingReguest.map((item, index) => ( - + - {item.icon} + {item.label} @@ -241,9 +249,9 @@ const Dashbaord = ({ showSearch = false }) => { {userActivity.map((item, index) => ( - + - {item.icon} + { ))} - + @@ -313,6 +321,7 @@ const Dashbaord = ({ showSearch = false }) => { p={4} rounded={10} alignItems={"inherit"} + border={'1px solid #0047171f'} > setFilter(e.target.value)} > @@ -355,11 +363,11 @@ const Dashbaord = ({ showSearch = false }) => { ? data?.data?.userActivity?.newSignUps?.last7days : data?.data?.userActivity?.newSignUps?.last30days} - + New sign-ups{" "} - + { : data?.data?.userActivity?.newKYCVerifications ?.last30days} - + New KYC verification @@ -388,7 +396,7 @@ const Dashbaord = ({ showSearch = false }) => { Investment Opportunities - + { {closedOpportunities.map((item, index) => ( - + - + {item.label} @@ -440,7 +448,7 @@ const Dashbaord = ({ showSearch = false }) => { Wallet Balances - + ${" "} @@ -461,7 +469,7 @@ const Dashbaord = ({ showSearch = false }) => { {walletCase.slice(0, 4).map((item, index) => ( - + {item.amount} @@ -474,7 +482,7 @@ const Dashbaord = ({ showSearch = false }) => { {walletCase.slice(4).map((item, index) => ( - + {item.amount} diff --git a/src/Pages/Dashboard/InvestmentOpportunities.jsx b/src/Pages/Dashboard/InvestmentOpportunities.jsx index ac71812..f06e633 100644 --- a/src/Pages/Dashboard/InvestmentOpportunities.jsx +++ b/src/Pages/Dashboard/InvestmentOpportunities.jsx @@ -1,4 +1,4 @@ -import { Box, HStack, Input, Select, Text, useToast } from "@chakra-ui/react"; +import { Badge, Box, HStack, Input, Select, Text, useToast } from "@chakra-ui/react"; import React, { useContext, useEffect, useState } from "react"; import { OPACITY_ON_LOAD } from "../../Layout/animations"; import GlobalStateContext from "../../Contexts/GlobalStateContext"; @@ -60,25 +60,25 @@ const InvestmentOpportunities = ({ showSearch = true, selectStyle = {} }) => { ), "Amount Remaining %": ( - + - {`${parseFloat(item?.Amount_remaining_per || 0).toLocaleString( + {parseFloat(item?.Amount_remaining_per || 0).toLocaleString( undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2, } - )} %`} + )}% ), "Total Deal Size": ( - {`$ ${parseFloat(item?.Deal_size || 0).toLocaleString(undefined, { + ${parseFloat(item?.Deal_size || 0).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2, - })}`} + })} ), From 390ec27e35432ca412ab065b1586ee2144237862 Mon Sep 17 00:00:00 2001 From: YasinShaikh123 <123150391+YasinShaikh123@users.noreply.github.com> Date: Wed, 15 Jan 2025 19:59:53 +0530 Subject: [PATCH 12/50] update icon size --- src/Pages/Dashboard/Dashbaord.jsx | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Pages/Dashboard/Dashbaord.jsx b/src/Pages/Dashboard/Dashbaord.jsx index 21eb122..3ef01e5 100644 --- a/src/Pages/Dashboard/Dashbaord.jsx +++ b/src/Pages/Dashboard/Dashbaord.jsx @@ -228,7 +228,7 @@ const Dashbaord = ({ showSearch = false }) => { {panddingReguest.map((item, index) => ( - + @@ -249,15 +249,18 @@ const Dashbaord = ({ showSearch = false }) => { {userActivity.map((item, index) => ( - + {item.icon === IconSix ? ( - + + ) : item.icon === IconSeven ? ( + ) : ( )} + Date: Thu, 16 Jan 2025 15:47:22 +0530 Subject: [PATCH 13/50] [fixed] - spell correct --- src/Pages/Dashboard/Dashbaord.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Pages/Dashboard/Dashbaord.jsx b/src/Pages/Dashboard/Dashbaord.jsx index 3ef01e5..181dedb 100644 --- a/src/Pages/Dashboard/Dashbaord.jsx +++ b/src/Pages/Dashboard/Dashbaord.jsx @@ -117,7 +117,7 @@ const Dashbaord = ({ showSearch = false }) => { }, { icon: IconOne, - label: "Total assets under managemnet", + label: "Total assets under management", count: `$ ${parseFloat( data?.data?.investmentOpportunity?.closedOpportunityDetails?.totalAUM || 0 @@ -470,7 +470,7 @@ const Dashbaord = ({ showSearch = false }) => { Sum of users available wallet cash in - + {walletCase.slice(0, 4).map((item, index) => ( From f9b1f820c22ec5a842605a0b48b8ff915e017707 Mon Sep 17 00:00:00 2001 From: YasinShaikh123 <123150391+YasinShaikh123@users.noreply.github.com> Date: Thu, 16 Jan 2025 15:55:42 +0530 Subject: [PATCH 14/50] [working Reversal] --- .../BankDepositRequest/BankDepositRequest.jsx | 413 ++++++++++++++++++ src/Pages/BankDepositRequest/ConfirmModal.jsx | 137 ++++++ src/Pages/BankDepositRequest/RejectModal.jsx | 98 +++++ .../Dashboard/InvestmentOpportunities.jsx | 2 +- .../ReversalAccountDeletion/ConfirmModal.jsx | 137 ++++++ .../ReversalAccountDeletion/RejectModal.jsx | 98 +++++ .../ReversalAccountDeletion.jsx | 322 ++++++++++++++ .../ReversalFawateerDeposit/ConfirmModal.jsx | 137 ++++++ .../ReversalFawateerDeposit/RejectModal.jsx | 98 +++++ .../ReversalFawateerDeposit.jsx | 390 +++++++++++++++++ src/Routes/Nav.js | 28 ++ src/Routes/Routes.js | 8 + 12 files changed, 1867 insertions(+), 1 deletion(-) create mode 100644 src/Pages/BankDepositRequest/BankDepositRequest.jsx create mode 100644 src/Pages/BankDepositRequest/ConfirmModal.jsx create mode 100644 src/Pages/BankDepositRequest/RejectModal.jsx create mode 100644 src/Pages/ReversalAccountDeletion/ConfirmModal.jsx create mode 100644 src/Pages/ReversalAccountDeletion/RejectModal.jsx create mode 100644 src/Pages/ReversalAccountDeletion/ReversalAccountDeletion.jsx create mode 100644 src/Pages/ReversalFawateerDeposit/ConfirmModal.jsx create mode 100644 src/Pages/ReversalFawateerDeposit/RejectModal.jsx create mode 100644 src/Pages/ReversalFawateerDeposit/ReversalFawateerDeposit.jsx diff --git a/src/Pages/BankDepositRequest/BankDepositRequest.jsx b/src/Pages/BankDepositRequest/BankDepositRequest.jsx new file mode 100644 index 0000000..f6b3c21 --- /dev/null +++ b/src/Pages/BankDepositRequest/BankDepositRequest.jsx @@ -0,0 +1,413 @@ +import { + Badge, + Box, + Button, + HStack, + Input, + Switch, + Text, + Tooltip, + useToast, + useDisclosure, + Link, +} from "@chakra-ui/react"; +import React, { useContext, useEffect, useState } from "react"; +import { useNavigate } from "react-router-dom"; + +import { CheckIcon, CloseIcon, ExternalLinkIcon } from "@chakra-ui/icons"; +import { debounce } from "../Admin/Contact"; +import { OPACITY_ON_LOAD } from "../../Layout/animations"; +import GlobalStateContext from "../../Contexts/GlobalStateContext"; +import CustomAlertDialog from "../../Components/CustomAlertDialog"; +import ToastBox from "../../Components/ToastBox"; +import NormalTable from "../../Components/DataTable/NormalTable"; +import { TABLE_PAGINATION } from "../../Constants/Paginations"; +import { generateSerialNumber } from "../../Constants/Constants"; +import { useGetDepositHistoryQuery } from "../../Services/deposit.request.service"; +import Pagination from "../../Components/Pagination"; +import ConfirmModal from "./ConfirmModal"; +import RejectModal from "./RejectModal"; + +const formatDate = (date) => { + return new Date(date).toLocaleDateString("en-GB", { + day: "2-digit", + month: "2-digit", + year: "numeric", + }); +}; // Simple date formatter + +const BankDepositRequest = () => { + const navigate = useNavigate(); + const toast = useToast(); + const { depositHistory, setDepositHistory, slideFromRight } = + useContext(GlobalStateContext); + const [isLoading, setIsLoading] = useState(true); + const [deleteAlert, setDeleteAlert] = useState(false); + const [actionId, setActionId] = useState(false); + const [mouseEntered, setMouseEntered] = useState(false); + const [mouseEnteredId, setMouseEnteredId] = useState(""); + const { + isOpen: isConfirmOpen, + onOpen: onConfirmOpen, + onClose: onConfirmClose, + } = useDisclosure(); + const { + isOpen: isRejectOpen, + onOpen: onRejectOpen, + onClose: onRejectClose, + } = useDisclosure(); + + // =========================== [Use State] ============================= + const [pageSize, setPageSize] = useState(TABLE_PAGINATION?.size); + const [currentPage, setCurrentPage] = useState(TABLE_PAGINATION?.page); + const [searchTerm, setSearchTerm] = useState(""); + const [debouncedSearchTerm, setDebouncedSearchTerm] = useState(""); + + // Debounce the search term to avoid making a request on every keystroke + useEffect(() => { + const handler = setTimeout(() => { + setDebouncedSearchTerm(searchTerm); + }, 500); // Adjust delay as needed + return () => { + clearTimeout(handler); + }; + }, [searchTerm]); + + const { + data, + error, + refetch, + isLoading: depositHistoryLoading, + } = useGetDepositHistoryQuery( + { + page: debouncedSearchTerm ? undefined : currentPage, // Omit pagination for search + size: debouncedSearchTerm ? undefined : pageSize, // Omit pagination for search + search: debouncedSearchTerm, + }, + { + skip: debouncedSearchTerm === "" && searchTerm !== "", // Skip if search is empty and it's not the initial request + } + ); + + // Use useEffect to refetch data when the component mounts + useEffect(() => { + refetch(); + }, [refetch]); + + // ====================================================[Table Setup]================================================================ + const tableHeadRow = [ + "Sr.no", + "Request Date", + "Client ID", + "First Name", + "Last Name", + "Country", + "Phone Number", + "Deposit Amount", + "Deposit Date", + "Status", + "Supporting's", + "Action", + ]; + + const handleUpdateStatus = debounce((id) => { + setDepositHistory((prevDepositHistory) => + prevDepositHistory.map((depositHistory) => + depositHistory.id === id + ? { ...depositHistory, status: !depositHistory.status } + : depositHistory + ) + ); + toast({ + render: () => , + }); + }, 300); + + const filteredData = data?.data?.rows + .filter((item) => { + // Filter by name (case insensitive) + const name = [item.firstName, item.lastName, item.countryName] + .filter(Boolean) + .join(" "); + const searchLower = searchTerm.toLowerCase(); + const nameMatches = name.toLowerCase().includes(searchLower); + + // Filter by status (Uncomment and use if needed) + // const status = item.status; + // const statusLower = status ? "active" : "inactive"; + + // const statusMatches = + // statusFilter === "all" || + // (statusFilter === "active" && status === true) || + // (statusFilter === "inactive" && status === false); + + return nameMatches; + }) + .sort((b, a) => new Date(a.createdAt) - new Date(b.createdAt)); + + // const handleView = (id) => { + // setActionId(id); + // onViewOpen(); + // }; + + const extractedArray = data?.data?.rows?.map((item, idx) => ({ + "Sr.no": ( + + {generateSerialNumber(idx, currentPage, pageSize)} + + ), + "Client ID": ( + + {item?.clientReference_id} + + ), + "First Name": ( + + + {item?.firstName} + + + ), + "Last Name": ( + + + {item?.lastName} + + + ), + Country: ( + + + {item?.countryName} + + + ), + "Phone Number": ( + + + {item?.mobileNumber} + + + ), + "Deposit Amount": ( + + + {parseFloat(item?.investorAmount || 0).toLocaleString(undefined, { + minimumFractionDigits: 2, + maximumFractionDigits: 2, + })} + + {item?.currencyCode} + + + + ), + "Deposit Date": ( + + {formatDate(item?.createdAt)} + + ), + Status: ( + + + {item.transactionStatus} + + + ), + "Supporting's": + item.transactionStatus === "Approved" ? ( + + {/* {item?.supporting_FileName} */} + + + + View + + + + {/* + View + */} + + + ) : ( + "" + ), + Action: ( + + + + + + + + + ), + })); + + const handleDelete = () => { + const IOtype = investmentType.filter( + (investmentType) => investmentType.id !== actionId + ); + + setTimeout(() => { + setInvestmentType(IOtype); + setDeleteAlert(false); + setIsLoading(false); + }, 100); + setIsLoading(true); + }; + + return ( + + + + + + setSearchTerm(e.target.value)} + /> + + + + + + + + + + setDeleteAlert(false)} + isOpen={deleteAlert} + message={"Are you sure you want to delete sponers?"} + alertHandler={handleDelete} + isLoading={isLoading} + /> + + ); +}; + +export default BankDepositRequest; diff --git a/src/Pages/BankDepositRequest/ConfirmModal.jsx b/src/Pages/BankDepositRequest/ConfirmModal.jsx new file mode 100644 index 0000000..40bcbdd --- /dev/null +++ b/src/Pages/BankDepositRequest/ConfirmModal.jsx @@ -0,0 +1,137 @@ +import { + Box, + Button, + Checkbox, + FormControl, + FormLabel, + Input, + Modal, + ModalBody, + ModalCloseButton, + ModalContent, + ModalFooter, + ModalHeader, + ModalOverlay, + Text, + Textarea, + useDisclosure, +} from "@chakra-ui/react"; +import React, { useState } from "react"; +import * as yup from "yup"; +import { yupResolver } from "@hookform/resolvers/yup"; +import { useForm } from "react-hook-form"; + +export const conformModalSchema = yup.object().shape({ + fees: yup.string().required("File name is required"), + totalAmount: yup.string().required("File name is required"), +}); + +const ConfirmModal = ({ isOpen, onClose, firstField }) => { + + const [emailApproval,setEmailApproval] = useState(false) + + const { + register, + handleSubmit, + formState: { errors }, + } = useForm({ + resolver: yupResolver(conformModalSchema), + }); + + const onSubmit = (data) => { + setFile(data.document[0]); + + const newDocument = { + ...data, + document: data.document[0].name, // Store the document name + status: true, + id: uuidv4(), + createdAt: new Date().toISOString(), + Type: getFileIcon(file.type), + }; + + setCreate((prevCreate) => [...prevCreate, newDocument]); + onClose(); + }; + + const handleFileChange = (event) => { + const selectedFile = event.target.files[0]; + setFile(selectedFile); + }; + + return ( + + + + Confirm + + + + + Comment +