diff --git a/src/Pages/Admin/BankDetails.jsx b/src/Pages/Admin/BankDetails.jsx deleted file mode 100644 index 08859f6..0000000 --- a/src/Pages/Admin/BankDetails.jsx +++ /dev/null @@ -1,22 +0,0 @@ -import { Box, Image, Text } from "@chakra-ui/react" -// import error from "../assets/Error.svg" -import robot from "../../assets/robot.png" -// import robot from "../assets/robot.png" -const BankDetails = () => { - return ( - - - - {/* The requested URL was not found on this server. */} - - ) -} - -export default BankDetails \ No newline at end of file diff --git a/src/Pages/Admin/BankDetails/BankDetails.jsx b/src/Pages/Admin/BankDetails/BankDetails.jsx new file mode 100644 index 0000000..8266930 --- /dev/null +++ b/src/Pages/Admin/BankDetails/BankDetails.jsx @@ -0,0 +1,254 @@ +import { + Avatar, + Badge, + Box, + Button, + HStack, + Input, + Menu, + MenuButton, + MenuItem, + MenuList, + Portal, + Select, + Switch, + Tag, + Text, + Tooltip, + useDisclosure, + useToast, +} from "@chakra-ui/react"; +import React, { useContext, useEffect, useState, useRef } from "react"; +import { HiDotsVertical } from "react-icons/hi"; +import { Link, Link as RouterLink, useNavigate } from "react-router-dom"; +import { + AddIcon, + DeleteIcon, + EditIcon, + EmailIcon, + ViewIcon, +} from "@chakra-ui/icons"; +import { OPACITY_ON_LOAD } from "../../../Layout/animations"; +import DataTable from "../../../Components/DataTable/DataTable"; +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 { useGetBankQuery } from "../../../Services/bank.details.service"; + +const formatDate = (date) => new Date(date).toLocaleDateString(); // Simple date formatter + +const BankDetails = () => { + const navigate = useNavigate(); + const toast = useToast(); + const thirdField = useRef(); + const { InvestorDetails, setInvestorDetails, slideFromRight } = + useContext(GlobalStateContext); + const [searchTerm, setSearchTerm] = useState(""); + const [isLoading, setIsLoading] = useState(true); + const [deleteAlert, setDeleteAlert] = useState(false); + const [actionId, setActionId] = useState(false); + const [mouseEntered, setMouseEntered] = useState(false); + const [mouseEnteredId, setMouseEnteredId] = useState(""); + const { + isOpen: isEditOpen, + onOpen: onEditOpen, + onClose: onEditClose, + } = useDisclosure(); + const btnRef = React.useRef(); + + const { + data: bankDetails, + isLoading: bankDetailsLoading, + error, + } = useGetBankQuery({ page: 1, size: 10 }); + + console.log(bankDetails?.data); + + 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", + "Country name", + "Account Name", + "Account No", + "Bank Name", + "Action", + ]; + + const handleUpdateStatus = debounce((id) => { + setInvestorDetails((prevData) => + prevData.map((InvestorDetails) => + InvestorDetails.id === id ? { ...InvestorDetails } : InvestorDetails + ) + ); + toast({ + render: () => , + }); + }, 300); + + // ====================================================[Table Filter]================================================================ + const filteredData = bankDetails?.data?.filter((item) => { + // Filter by name (case insensitive) + const name = item.accountName; + const searchLower = searchTerm.toLowerCase(); + const nameMatches = name?.toLowerCase().includes(searchLower); + + // Filter by status + // const status = item.status; + // const statusLower = status ? "active" : "inactive"; + + // const statusMatches = + // statusFilter === "all" || + // (statusFilter === "active" && status === true) || + // (statusFilter === "inactive" && status === false); + + return nameMatches; + }); + + console.log(bankDetails); + + const extractedArray = filteredData?.map((item) => ({ + id: item?.id, + "Sr N/O": ( + + {item.id} + + ), + "Country name": ( + + + {item.country_xid} + + + ), + "Account Name": ( + + + {item.accountName} + + + ), + "Account No ": ( + + + {item?.accountNumber} + + + ), + "Bank Name": ( + + + {item.bankName} + + + ), + Action: ( + + + + + + ), + })); + + const handleDelete = () => { + const updatedInvestorDetails = InvestorDetails.filter( + (sponsor) => sponsor.id !== actionId + ); + + setTimeout(() => { + setInvestorDetails(updatedInvestorDetails); + setDeleteAlert(false); + setIsLoading(false); + }, 100); + setIsLoading(true); + }; + + const handleEdit = (id) => { + setActionId(id); + onEditOpen(); + }; + + return ( + + + + setSearchTerm(e.target.value)} + /> + + + + + + setDeleteAlert(false)} + isOpen={deleteAlert} + message={"Are you sure you want to delete sponers?"} + alertHandler={handleDelete} + isLoading={isLoading} + /> + + ); +}; + +export default BankDetails; diff --git a/src/Pages/Admin/BankDetails/EditBankDetails.jsx b/src/Pages/Admin/BankDetails/EditBankDetails.jsx new file mode 100644 index 0000000..fe08a64 --- /dev/null +++ b/src/Pages/Admin/BankDetails/EditBankDetails.jsx @@ -0,0 +1,194 @@ +import React, { useEffect, useState } from "react"; +import { OPACITY_ON_LOAD } from "../../../Layout/animations"; +import { Box, useToast } from "@chakra-ui/react"; +import { useForm } from "react-hook-form"; +import { yupResolver } from "@hookform/resolvers/yup"; +import { useNavigate, useParams } from "react-router-dom"; +import FormInputMain from "../../../Components/FormInputMain"; +import ToastBox from "../../../Components/ToastBox"; +import FullscreenLoaders from "../../../Components/Loaders/FullscreenLoaders"; +import CustomAlertDialog from "../../../Components/CustomAlertDialog"; +import SwitchButton from "../../../Components/SwitchButton"; +import * as yup from "yup"; +import { useGetBankQuery, useUpdateBankDetailsMutation } from "../../../Services/bank.details.service"; +// import { useUpdateBankDetailsMutation, useGetBankQuery } from "../../../Services/investorDetails.service"; + +const editBankSchema = yup.object().shape({ + accountNumber: yup.string().required("Account number is required"), + swiftCode: yup.string().required("SWIFT code is required"), + bankName: yup.string().required("Bank name is required"), + bankAddress: yup.string().required("Bank address is required"), + IBANnumber: yup.string().required("IBAN number is required"), +}); + +const EditBankDetails = () => { + const toast = useToast(); + const params = useParams(); + const navigate = useNavigate(); + const id = params?.id; + + const [isLoadingBtn, setIsLoadingBtn] = useState(false); + const [alert, setAlert] = useState(false); + const [form, setForm] = useState({}); + const [isSwitchOn, setIsSwitchOn] = useState(false); + + const [updateBankDetails] = useUpdateBankDetailsMutation(); + const { data: bankDetails, error, isLoading } = useGetBankQuery({ id }, { skip: !id }); + + const { + control, + handleSubmit, + formState: { errors }, + reset, + } = useForm({ + resolver: yupResolver(editBankSchema), + }); + + useEffect(() => { + if (bankDetails) { + reset({ + accountNumber: bankDetails.accountNumber, + swiftCode: bankDetails.swiftCode, + bankName: bankDetails.bankName, + bankAddress: bankDetails.bankAddress, + IBANnumber: bankDetails.IBANnumber, + }); + } + }, [bankDetails, reset]); + + if (isLoading) { + return ; + } + + const handleConfirm = async () => { + setIsLoadingBtn(true); + + try { + const formData = { + ...form, + isActive: isSwitchOn, + }; + + const response = await updateBankDetails({ data: formData, id }); + if (response?.data?.statusCode) { + toast({ + render: () => , + }); + + setIsLoadingBtn(false); + setAlert(false); + navigate("/bank-details"); + } else { + throw new Error("Something went wrong"); + } + } catch (error) { + toast({ + render: () => , + }); + + setIsLoadingBtn(false); + navigate("/bank-details"); + } + }; + + const formEditFields = [ + { + label: "Country Name", + placeHolder: "Enter country name", + name: "countryName", + type: "text", + isRequired: true, + section: "Add Details", + maxLength: 50, + width: "32%", + }, + { + label: "Account Name", + name: "accountName", + placeHolder: "Enter account name", + type: "text", + isRequired: true, + section: "Add Details", + maxLength: 255, + width: "32%", + }, + { + label: "Account Number *", + name: "accountNumber", + placeHolder: "Enter account number", + type: "text", + section: "Add Details", + width: "32%", + }, + { + label: "IBAN Number", + name: "IBANnumber", + placeHolder: "Enter IBAN number", + type: "text", + section: "Add Details", + width: "32%", + }, + { + label: "SWIFT Code", + name: "swiftCode", + placeHolder: "Enter SWIFT code", + type: "text", + section: "Add Details", + width: "32%", + }, + { + label: "Bank Name", + name: "bankName", + placeHolder: "Enter bank name", + type: "text", + section: "Add Details", + width: "32%", + }, + { + label: "Bank Address", + name: "bankAddress", + placeHolder: "Enter bank address", + type: "text", + section: "Add Details", + width: "32%", + }, + ]; + + const groupedEditFields = formEditFields.reduce((groups, field) => { + const { section } = field; + if (!groups[section]) { + groups[section] = []; + } + groups[section].push(field); + return groups; + }, {}); + + const onSubmit = (data) => { + if (!Object.keys(errors).length) { + setForm(data); + setAlert(true); + } + }; + + return ( + + + + setAlert(false)} + alertHandler={handleConfirm} + message="Are you sure you want to update these details?" + isLoading={isLoadingBtn} + /> + + ); +}; + +export default EditBankDetails; diff --git a/src/Pages/Admin/Contact.jsx b/src/Pages/Admin/Contact.jsx index ebc52ce..d83021b 100644 --- a/src/Pages/Admin/Contact.jsx +++ b/src/Pages/Admin/Contact.jsx @@ -19,11 +19,12 @@ import { v4 as uuidv4 } from "uuid"; import GlobalStateContext from "../../Contexts/GlobalStateContext"; import { OPACITY_ON_LOAD } from "../../Layout/animations"; import FormInputMain from "../../Components/FormInputMain"; +import { useGetContactQuery } from "../../Services/contact.service"; export const addSponser = yup.object().shape({ phoneNumber: yup.string().required("Phone Number is required"), - emailId: yup.string().required("E-mail ID is required"), - WebsiteURL: yup.string().required("Website URL is required"), + emailAddress: yup.string().required("E-mail ID is required"), + websiteUrl: yup.string().required("Website URL is required"), }); export function debounce(func, delay) { @@ -50,6 +51,13 @@ const Contact = () => { console.log(errors); + const { + data: contact, + isLoading: contactLoading, + error, + } = useGetContactQuery({ page: 1, size: 10 }); + + console.log(contact?.data); const formFields = [ { @@ -62,7 +70,7 @@ const Contact = () => { }, { label: "E-mail ID ", - name: "emailId", + name: "emailAddress", placeHolder:" ", type: "text", isRequired: true, @@ -70,7 +78,7 @@ const Contact = () => { }, { label: "Website URL", - name: "WebsiteURL", + name: "websiteUrl", placeHolder:" ", type: "text", isRequired: true, diff --git a/src/Pages/Master/Sponser/EditSponser.jsx b/src/Pages/Master/Sponser/EditSponser.jsx index e1de7c5..bb7389a 100644 --- a/src/Pages/Master/Sponser/EditSponser.jsx +++ b/src/Pages/Master/Sponser/EditSponser.jsx @@ -95,7 +95,7 @@ const EditSponser = () => { }, { label: "Address (Arabic)", - name: "sponserAddressArabic", + name: "sponserAddressArabic", placeHolder: " ", type: "text", isRequired: true, @@ -106,7 +106,7 @@ const EditSponser = () => { label: "Bank Name (English)", name: "bankName", placeHolder: " ", - type: "text", + type: "text", isRequired: true, section: "Add Details", }, diff --git a/src/Routes/Routes.js b/src/Routes/Routes.js index 05388bb..647ed06 100644 --- a/src/Routes/Routes.js +++ b/src/Routes/Routes.js @@ -2,7 +2,7 @@ import DeletionHistory from "../Pages/AccountDeletion/DeletionHistory"; import DeletionRequest from "../Pages/AccountDeletion/DeletionRequest"; // import Academy from "../Pages/Admin/Academy"; -import BankDetails from "../Pages/Admin/BankDetails"; +import BankDetails from "../Pages/Admin/BankDetails/BankDetails"; import BankInvestor from "../Pages/Admin/BankInvestor"; import Contact from "../Pages/Admin/Contact"; import Notification from "../Pages/Admin/Notification"; @@ -37,6 +37,7 @@ import DepositHistory from "../Pages/Deposit/DepositViewHistory/DepositHistory"; import Academy from "../Pages/Admin/ManageAcademy/Academy"; import InvestmentType from "../Pages/Master/InvestmentType/InvestmentType"; import DepositRequest from "../Pages/Deposit/DepositRequest/DepositRequest"; +import EditBankDetails from "../Pages/Admin/BankDetails/EditBankDetails"; export const RouteLink = [ // =============[ Tanami ]================ @@ -94,4 +95,5 @@ export const RouteLink = [ { path: "/contact", Component: Contact }, { path: "/users", Component: Users }, { path: "/bank-details", Component: BankDetails }, + { path: "/bank-details/edit-bank-details/:id", Component: EditBankDetails }, ]; diff --git a/src/Services/bank.details.service.js b/src/Services/bank.details.service.js new file mode 100644 index 0000000..45aaddb --- /dev/null +++ b/src/Services/bank.details.service.js @@ -0,0 +1,35 @@ +// investorDetails.service.js +import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; +import { api } from "./api.service"; + +const baseUrl = api?.defaults.baseURL; + +// Define a service using a base URL and expected endpoints +export const bankDetails = createApi({ + reducerPath: "bankDetails", + baseQuery: fetchBaseQuery({ baseUrl }), + tagTypes: [], + endpoints: (builder) => ({ + + getBank: builder.query({ + query: ({ page, size }) => + `/bankDetails/admin/?page=${page}&size=${size}`, + providesTags: ["getBank"], + }), + + // ========[Update Sponser]======== + + updateBankDetails: builder.mutation({ + query: ({ data, id }) => ({ + url: `/bankDetails/admin/${id}`, + method: "PATCH", + body: data, + }), + invalidatesTags: ["getBankDetails"], + }), + + }), +}); + +// Export hooks for usage in functional components +export const { useGetBankQuery,useUpdateBankDetailsMutation } = bankDetails; diff --git a/src/Services/contact.service.js b/src/Services/contact.service.js new file mode 100644 index 0000000..d165202 --- /dev/null +++ b/src/Services/contact.service.js @@ -0,0 +1,24 @@ +// investorDetails.service.js +import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; +import { api } from "./api.service"; + +const baseUrl = api?.defaults.baseURL; + +// Define a service using a base URL and expected endpoints +export const contact = createApi({ + reducerPath: "contact", + baseQuery: fetchBaseQuery({ baseUrl }), + tagTypes: [], + endpoints: (builder) => ({ + + getContact: builder.query({ + query: ({ page, size }) => + `/contactDetails/admin/?page=${page}&size=${size}`, + providesTags: ["getContact"], + }), + + }), +}); + +// Export hooks for usage in functional components +export const { useGetContactQuery } = contact; diff --git a/src/Store/Store.js b/src/Store/Store.js index a99ad3e..e0399f6 100644 --- a/src/Store/Store.js +++ b/src/Store/Store.js @@ -8,6 +8,8 @@ import { investorDetails } from "../Services/investor.details.service"; import { investorTransaction } from "../Services/investor.transaction.service"; import { api } from "../Services/api.service"; import { keyMerits } from "../Services/Key.merits.service"; +import { bankDetails } from "../Services/bank.details.service"; +import { contact } from "../Services/contact.service"; export const store = configureStore({ reducer: { @@ -17,6 +19,8 @@ export const store = configureStore({ [ioService.reducerPath]: ioService.reducer, [investorDetails.reducerPath]: investorDetails.reducer, [investorTransaction.reducerPath]: investorTransaction.reducer, + [bankDetails.reducerPath]: bankDetails.reducer, + [contact.reducerPath]: contact.reducer, // Add other reducers as needed }, middleware: (getDefaultMiddleware) => @@ -31,6 +35,8 @@ export const store = configureStore({ ioService.middleware, investorDetails.middleware, investorTransaction.middleware, + bankDetails.middleware, + contact.middleware, ), });