Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9c0b231e62 | ||
|
|
fed5125660 | ||
|
|
8a297d02ef | ||
|
|
2c8965c16a | ||
| 9d4d5301e5 | |||
|
|
d567acfec8 | ||
|
|
463325e603 | ||
| 84f869d9bd | |||
| 272e94caf0 | |||
| cd95aa35a7 | |||
| 95c629533e |
@@ -13,8 +13,9 @@ import {
|
|||||||
Portal,
|
Portal,
|
||||||
Text,
|
Text,
|
||||||
useColorMode,
|
useColorMode,
|
||||||
|
useDisclosure,
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import React, { useContext } from "react";
|
import React, { useContext, useRef } from "react";
|
||||||
import { Link, useNavigate } from "react-router-dom";
|
import { Link, useNavigate } from "react-router-dom";
|
||||||
import { IoMdDownload } from "react-icons/io";
|
import { IoMdDownload } from "react-icons/io";
|
||||||
import * as XLSX from "xlsx";
|
import * as XLSX from "xlsx";
|
||||||
@@ -23,6 +24,7 @@ import GlobalStateContext from "../Contexts/GlobalStateContext";
|
|||||||
import { MdOutlineDarkMode, MdOutlineLightMode } from "react-icons/md";
|
import { MdOutlineDarkMode, MdOutlineLightMode } from "react-icons/md";
|
||||||
import logoMini from "../assets/propic.png";
|
import logoMini from "../assets/propic.png";
|
||||||
import { BsBack } from "react-icons/bs";
|
import { BsBack } from "react-icons/bs";
|
||||||
|
import ChangePassword from "../Pages/ChangePassword";
|
||||||
|
|
||||||
const HeaderMain = ({
|
const HeaderMain = ({
|
||||||
link,
|
link,
|
||||||
@@ -35,6 +37,8 @@ const HeaderMain = ({
|
|||||||
}) => {
|
}) => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { colorMode, toggleColorMode } = useContext(GlobalStateContext);
|
const { colorMode, toggleColorMode } = useContext(GlobalStateContext);
|
||||||
|
const { isOpen, onOpen, onClose } = useDisclosure();
|
||||||
|
const firstField = useRef();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
@@ -66,11 +70,11 @@ const HeaderMain = ({
|
|||||||
<PopoverBody onClick={()=> navigate('/profile')} className="web-text-medium pointer link">
|
<PopoverBody onClick={()=> navigate('/profile')} className="web-text-medium pointer link">
|
||||||
Profile
|
Profile
|
||||||
</PopoverBody>
|
</PopoverBody>
|
||||||
<Link to={"/help-and-support"}>
|
<Box onClick={onOpen}>
|
||||||
<PopoverBody className="web-text-medium pointer ">
|
<PopoverBody className="web-text-medium pointer ">
|
||||||
Help & Support
|
Change Password
|
||||||
</PopoverBody>
|
</PopoverBody>
|
||||||
</Link>
|
</Box>
|
||||||
<PopoverFooter
|
<PopoverFooter
|
||||||
onClick={logOutHandler}
|
onClick={logOutHandler}
|
||||||
className="web-text-medium pointer link"
|
className="web-text-medium pointer link"
|
||||||
@@ -112,6 +116,11 @@ const HeaderMain = ({
|
|||||||
{/* <Box onClick={() => toggleColorMode()} as="span" p={2} rounded={'lg'} className="link pointer">
|
{/* <Box onClick={() => toggleColorMode()} as="span" p={2} rounded={'lg'} className="link pointer">
|
||||||
{colorMode === "light"? <MdOutlineDarkMode /> :<MdOutlineLightMode />}
|
{colorMode === "light"? <MdOutlineDarkMode /> :<MdOutlineLightMode />}
|
||||||
</Box> */}
|
</Box> */}
|
||||||
|
<ChangePassword
|
||||||
|
isOpen={isOpen}
|
||||||
|
onClose={onClose}
|
||||||
|
firstField={firstField}
|
||||||
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
import { Box, Spinner, Text } from "@chakra-ui/react";
|
import { Box, Spinner, Text } from "@chakra-ui/react";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import './FullscreenLoaders.css'
|
import "./FullscreenLoaders.css";
|
||||||
|
|
||||||
const FullscreenLoaders = ({height}) => {
|
const FullscreenLoaders = ({ height }) => {
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
display={"flex"}
|
display={"flex"}
|
||||||
justifyContent={"center"}
|
justifyContent={"center"}
|
||||||
flexDirection={'column'}
|
flexDirection={"column"}
|
||||||
alignItems={"center"}
|
alignItems={"center"}
|
||||||
w={"100%"}
|
w={"100%"}
|
||||||
h={height ? height: "100vh"}
|
h={height ? height : "100vh"}
|
||||||
gap={4}
|
gap={4}
|
||||||
>
|
>
|
||||||
{/* <div className="dot-spinner">
|
{/* <div className="dot-spinner">
|
||||||
@@ -23,8 +23,16 @@ const FullscreenLoaders = ({height}) => {
|
|||||||
<div className="dot-spinner__dot"></div>
|
<div className="dot-spinner__dot"></div>
|
||||||
<div className="dot-spinner__dot"></div>
|
<div className="dot-spinner__dot"></div>
|
||||||
</div> */}
|
</div> */}
|
||||||
{/* <Text color='#004717' fontSize={'md'} fontWeight={500}>Loading...</Text> */}
|
{/* <Text color='#004717' fontSize={'md'} fontWeight={500}>Loading...</Text> */}
|
||||||
<Spinner />
|
{/* <div className="spinner-grow" style={{backgroundColor:"#004118"}} role="status" /> */}
|
||||||
|
|
||||||
|
<Spinner
|
||||||
|
thickness="4px"
|
||||||
|
speed="0.65s"
|
||||||
|
emptyColor="#fff"
|
||||||
|
color="#004118"
|
||||||
|
size="lg"
|
||||||
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -4,6 +4,16 @@ import { Spinner } from "@chakra-ui/react";
|
|||||||
|
|
||||||
const Loader01 = () => {
|
const Loader01 = () => {
|
||||||
return (
|
return (
|
||||||
|
// <div className="dot-spinner">
|
||||||
|
// <div className="dot-spinner__dot"></div>
|
||||||
|
// <div className="dot-spinner__dot"></div>
|
||||||
|
// <div className="dot-spinner__dot"></div>
|
||||||
|
// <div className="dot-spinner__dot"></div>
|
||||||
|
// <div className="dot-spinner__dot"></div>
|
||||||
|
// <div className="dot-spinner__dot"></div>
|
||||||
|
// <div className="dot-spinner__dot"></div>
|
||||||
|
// <div className="dot-spinner__dot"></div>
|
||||||
|
// </div>
|
||||||
|
|
||||||
// <div className="dot-spinner">
|
// <div className="dot-spinner">
|
||||||
// <div className="dot-spinner__dot"></div>
|
// <div className="dot-spinner__dot"></div>
|
||||||
|
|||||||
66
src/Components/RoleSwitchButton.jsx
Normal file
66
src/Components/RoleSwitchButton.jsx
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
import { Box, Text } from "@chakra-ui/react";
|
||||||
|
import React, { useRef } from "react";
|
||||||
|
import audioClick from "../assets/click-151673.mp3";
|
||||||
|
|
||||||
|
const RoleSwitchButton = ({ isSwitchOn, setIsSwitchOn }) => {
|
||||||
|
|
||||||
|
// const [isSwitchOn, setIsSwitchOn] = useState(false);
|
||||||
|
|
||||||
|
// const audio = useRef();
|
||||||
|
|
||||||
|
const switchOnChangeHandle = () => {
|
||||||
|
setIsSwitchOn(!isSwitchOn);
|
||||||
|
// if (audio.current) {
|
||||||
|
// audio.current.play();
|
||||||
|
// }
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box display="flex" alignItems="center">
|
||||||
|
<Box
|
||||||
|
as="button"
|
||||||
|
display="flex"
|
||||||
|
justifyContent="normal"
|
||||||
|
alignItems="center"
|
||||||
|
// justifyContent={isSwitchOn ? "flex-end" : "flex-start"}
|
||||||
|
width="85px"
|
||||||
|
height="24px"
|
||||||
|
borderRadius="20px"
|
||||||
|
backgroundColor={isSwitchOn ? "#00ffcc" : "#b3ff99"}
|
||||||
|
onClick={switchOnChangeHandle}
|
||||||
|
position="relative"
|
||||||
|
fontSize="12px"
|
||||||
|
fontWeight="100"
|
||||||
|
transition="background-color 0.2s"
|
||||||
|
_before={{
|
||||||
|
content: '""',
|
||||||
|
position: "absolute",
|
||||||
|
width: "20px",
|
||||||
|
height: "20px",
|
||||||
|
borderRadius: "50%",
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
boxShadow: "0 2px 4px rgba(0, 0, 0, 0.2)",
|
||||||
|
transform: isSwitchOn ? "translateX(61px)" : "translateX(0)",
|
||||||
|
transition: "transform 0.2s",
|
||||||
|
left:'2px',
|
||||||
|
top:'2px'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
fontWeight="500"
|
||||||
|
zIndex={1}
|
||||||
|
position="absolute"
|
||||||
|
mb={0}
|
||||||
|
color={isSwitchOn ? "#000" : "#000"}
|
||||||
|
left={isSwitchOn ? "10px" : "auto"}
|
||||||
|
right={isSwitchOn ? "auto" : "10px"}
|
||||||
|
>
|
||||||
|
{isSwitchOn ? "Maker" : "Checker"}
|
||||||
|
</Text>
|
||||||
|
</Box>
|
||||||
|
{/* <audio ref={audio} src={audioClick} /> */}
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default RoleSwitchButton;
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
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";
|
||||||
|
|
||||||
|
|
||||||
export const generateSerialNumber = (index, currentPage, pageSize) => {
|
export const generateSerialNumber = (index, currentPage, pageSize) => {
|
||||||
@@ -218,4 +219,18 @@ export function formatDateToYYYYMMDD(dateString) {
|
|||||||
|
|
||||||
// Combine the formatted parts
|
// Combine the formatted parts
|
||||||
return `${year}-${month}-${day}`;
|
return `${year}-${month}-${day}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Encrypt a string
|
||||||
|
export const encryptString = (text) => {
|
||||||
|
const ciphertext = CryptoJS.AES.encrypt(text, import.meta.env.VITE_ROLE_ENCRYPTION_KEY).toString();
|
||||||
|
return ciphertext;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Decrypt a string
|
||||||
|
export const decryptString = (ciphertext) => {
|
||||||
|
const bytes = CryptoJS.AES.decrypt(ciphertext, import.meta.env.VITE_ROLE_ENCRYPTION_KEY);
|
||||||
|
const originalText = bytes.toString(CryptoJS.enc.Utf8);
|
||||||
|
return originalText;
|
||||||
|
};
|
||||||
@@ -15,7 +15,12 @@ import {
|
|||||||
TbTransactionDollar,
|
TbTransactionDollar,
|
||||||
} from "react-icons/tb";
|
} from "react-icons/tb";
|
||||||
import { TbArrowBadgeRightFilled } from "react-icons/tb";
|
import { TbArrowBadgeRightFilled } from "react-icons/tb";
|
||||||
import { ArrowBackIcon, ArrowLeftIcon, ArrowRightIcon, AtSignIcon } from "@chakra-ui/icons";
|
import {
|
||||||
|
ArrowBackIcon,
|
||||||
|
ArrowLeftIcon,
|
||||||
|
ArrowRightIcon,
|
||||||
|
AtSignIcon,
|
||||||
|
} from "@chakra-ui/icons";
|
||||||
import {
|
import {
|
||||||
Link,
|
Link,
|
||||||
NavLink,
|
NavLink,
|
||||||
@@ -83,6 +88,7 @@ import ApproveRequest from "../Pages/FawateerChecker/ApproveRequest/ApproveReque
|
|||||||
import ApproveHistoryMaker from "../Pages/FawateerChecker/ApproveHistory/ApproveHistoryMaker";
|
import ApproveHistoryMaker from "../Pages/FawateerChecker/ApproveHistory/ApproveHistoryMaker";
|
||||||
import ApproveHistory from "../Pages/FawateerChecker/ApproveHistory/ApproveHistoryChecker";
|
import ApproveHistory from "../Pages/FawateerChecker/ApproveHistory/ApproveHistoryChecker";
|
||||||
import { useProfileQuery } from "../Services/io.service";
|
import { useProfileQuery } from "../Services/io.service";
|
||||||
|
import SubAdmin from "../Pages/SubAdmin/SubAdmin";
|
||||||
|
|
||||||
const DashboardLayout = ({ isOnline }) => {
|
const DashboardLayout = ({ isOnline }) => {
|
||||||
const userRole = localStorage.getItem("role");
|
const userRole = localStorage.getItem("role");
|
||||||
@@ -165,24 +171,24 @@ const DashboardLayout = ({ isOnline }) => {
|
|||||||
<RiMoneyDollarBoxLine className="h4 m-0" /> Sponsor
|
<RiMoneyDollarBoxLine className="h4 m-0" /> Sponsor
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
case path.startsWith("/email"):
|
case path.startsWith("/email"):
|
||||||
return (
|
return (
|
||||||
<span className="d-flex align-items-end gap-2">
|
<span className="d-flex align-items-end gap-2">
|
||||||
<AtSignIcon className="h4 m-0" /> Email Notifiation
|
<AtSignIcon className="h4 m-0" /> Email Notifiation
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
case path.startsWith("/investment-type"):
|
case path.startsWith("/investment-type"):
|
||||||
return (
|
return (
|
||||||
<span className="d-flex align-items-end gap-2">
|
<span className="d-flex align-items-end gap-2">
|
||||||
<VscSymbolClass className="h4 m-0" /> Investment Type
|
<VscSymbolClass className="h4 m-0" /> Investment Type
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
case path.startsWith("/profile"):
|
case path.startsWith("/profile"):
|
||||||
return (
|
return (
|
||||||
<span className="d-flex align-items-end gap-2">
|
<span className="d-flex align-items-end gap-2">
|
||||||
<CgProfile className="h4 m-0" /> Profile
|
<CgProfile className="h4 m-0" /> Profile
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
case path.startsWith("/exchange-rate"):
|
case path.startsWith("/exchange-rate"):
|
||||||
return (
|
return (
|
||||||
<span className="d-flex align-items-end gap-2">
|
<span className="d-flex align-items-end gap-2">
|
||||||
@@ -241,7 +247,7 @@ const DashboardLayout = ({ isOnline }) => {
|
|||||||
Deposite Request
|
Deposite Request
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
|
|
||||||
case path.startsWith("/fawateer"):
|
case path.startsWith("/fawateer"):
|
||||||
return (
|
return (
|
||||||
<span className="d-flex align-items-end gap-2">
|
<span className="d-flex align-items-end gap-2">
|
||||||
@@ -249,13 +255,13 @@ const DashboardLayout = ({ isOnline }) => {
|
|||||||
Fawateer Deposit
|
Fawateer Deposit
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
case path.startsWith("/fawateer-history"):
|
case path.startsWith("/fawateer-history"):
|
||||||
return (
|
return (
|
||||||
<span className="d-flex align-items-end gap-2">
|
<span className="d-flex align-items-end gap-2">
|
||||||
<RiMoneyDollarBoxLine className="h4 m-0 fw-normal" />
|
<RiMoneyDollarBoxLine className="h4 m-0 fw-normal" />
|
||||||
Fawateer Deposit
|
Fawateer Deposit
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
|
|
||||||
case path.startsWith("/withdraw-request"):
|
case path.startsWith("/withdraw-request"):
|
||||||
return (
|
return (
|
||||||
@@ -398,6 +404,19 @@ const DashboardLayout = ({ isOnline }) => {
|
|||||||
return <SplashScreen />;
|
return <SplashScreen />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const filteredNav = nav.map((item) => {
|
||||||
|
if (item.submenu) {
|
||||||
|
return {
|
||||||
|
...item,
|
||||||
|
submenu: item.submenu.filter(
|
||||||
|
(submenuItem) =>
|
||||||
|
!(!data?.data?.superAdmin && submenuItem.title === "Sub Admin")
|
||||||
|
),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
style={{
|
style={{
|
||||||
@@ -515,7 +534,7 @@ const DashboardLayout = ({ isOnline }) => {
|
|||||||
index={openIndex}
|
index={openIndex}
|
||||||
onChange={handleAccordionChange}
|
onChange={handleAccordionChange}
|
||||||
>
|
>
|
||||||
{nav.map(({ title, type, Icon, submenu, path }, index) => {
|
{filteredNav.map(({ title, type, Icon, submenu, path }, index) => {
|
||||||
if (type === "accordion") {
|
if (type === "accordion") {
|
||||||
return (
|
return (
|
||||||
<AccordionItem key={index} border={"none"}>
|
<AccordionItem key={index} border={"none"}>
|
||||||
@@ -788,6 +807,7 @@ const AppContent = ({ data }) => {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Route path="*" element={<NotFound />} />
|
<Route path="*" element={<NotFound />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
);
|
);
|
||||||
|
|||||||
233
src/Pages/ChangePassword.jsx
Normal file
233
src/Pages/ChangePassword.jsx
Normal file
@@ -0,0 +1,233 @@
|
|||||||
|
import {
|
||||||
|
Button,
|
||||||
|
DrawerFooter,
|
||||||
|
FormControl,
|
||||||
|
FormErrorMessage,
|
||||||
|
FormLabel,
|
||||||
|
Input,
|
||||||
|
InputGroup,
|
||||||
|
InputRightElement,
|
||||||
|
Modal,
|
||||||
|
ModalBody,
|
||||||
|
ModalCloseButton,
|
||||||
|
ModalContent,
|
||||||
|
ModalHeader,
|
||||||
|
ModalOverlay,
|
||||||
|
Stack,
|
||||||
|
useToast,
|
||||||
|
} 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 CustomAlertDialog from "../Components/CustomAlertDialog";
|
||||||
|
import ToastBox from "../Components/ToastBox";
|
||||||
|
import { useUpdatePasswordMutation } from "../Services/change.password.service";
|
||||||
|
import { all } from "axios";
|
||||||
|
|
||||||
|
// Validation schema
|
||||||
|
const passwordSchema = yup.object().shape({
|
||||||
|
oldPassword: yup.string().required("Current Password is required"),
|
||||||
|
newPassword: yup
|
||||||
|
.string()
|
||||||
|
.required("New Password is required")
|
||||||
|
.min(8, "Password must be at least 8 characters long")
|
||||||
|
.max(16, "Password must be at most 50 characters long")
|
||||||
|
.matches(/[A-Z]/, "Password must contain at least one uppercase letter")
|
||||||
|
.matches(/[a-z]/, "Password must contain at least one lowercase letter")
|
||||||
|
.matches(/[0-9]/, "Password must contain at least one number")
|
||||||
|
.matches(
|
||||||
|
/[@$!%*?&#]/,
|
||||||
|
"Password must contain at least one special character"
|
||||||
|
),
|
||||||
|
confirmNewPassword: yup
|
||||||
|
.string()
|
||||||
|
.required("Confirm Password is required")
|
||||||
|
.oneOf([yup.ref("newPassword")], "Passwords must match"),
|
||||||
|
});
|
||||||
|
|
||||||
|
const ChangePassword = ({
|
||||||
|
isOpen,
|
||||||
|
onClose,
|
||||||
|
firstField,
|
||||||
|
actionId,
|
||||||
|
setActionId,
|
||||||
|
}) => {
|
||||||
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
const [alert, setAlert] = useState(false);
|
||||||
|
const [showCurrentPassword, setShowCurrentPassword] = useState(false);
|
||||||
|
const [showNewPassword, setShowNewPassword] = useState(false);
|
||||||
|
const [showConfirmPassword, setShowConfirmPassword] = useState(false);
|
||||||
|
const toast = useToast();
|
||||||
|
|
||||||
|
const [updatePassword] = useUpdatePasswordMutation();
|
||||||
|
|
||||||
|
// Form handling
|
||||||
|
const {
|
||||||
|
register,
|
||||||
|
handleSubmit,
|
||||||
|
reset,
|
||||||
|
formState: { errors },
|
||||||
|
} = useForm({
|
||||||
|
resolver: yupResolver(passwordSchema),
|
||||||
|
mode: "all",
|
||||||
|
});
|
||||||
|
|
||||||
|
// Form submit handler
|
||||||
|
const onSubmit = async (data) => {
|
||||||
|
setIsLoading(true);
|
||||||
|
try {
|
||||||
|
const res = await updatePassword(data); // Assuming API request works as expected
|
||||||
|
if (res?.data?.statusCode === 200) {
|
||||||
|
toast({
|
||||||
|
render: () => <ToastBox message={res?.data?.message} />,
|
||||||
|
});
|
||||||
|
handleClose();
|
||||||
|
} else if (res?.error) {
|
||||||
|
toast({
|
||||||
|
render: () => (
|
||||||
|
<ToastBox message={res?.error?.data?.message} status={"error"} />
|
||||||
|
),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
} finally {
|
||||||
|
setIsLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Handle modal close
|
||||||
|
const handleClose = () => {
|
||||||
|
setAlert(false);
|
||||||
|
onClose();
|
||||||
|
reset();
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Modal isOpen={isOpen} onClose={onClose} initialFocusRef={firstField}>
|
||||||
|
<ModalOverlay />
|
||||||
|
<ModalContent>
|
||||||
|
<ModalHeader fontSize="md">Change Password</ModalHeader>
|
||||||
|
<ModalCloseButton />
|
||||||
|
<ModalBody pb={6}>
|
||||||
|
<Stack spacing={4}>
|
||||||
|
{/* Current Password */}
|
||||||
|
<FormControl isInvalid={errors.oldPassword}>
|
||||||
|
<FormLabel fontSize="sm" mb={1} fontWeight={500}>
|
||||||
|
Current Password
|
||||||
|
</FormLabel>
|
||||||
|
<InputGroup size="sm">
|
||||||
|
<Input
|
||||||
|
{...register("oldPassword")}
|
||||||
|
fontSize="sm"
|
||||||
|
type={showCurrentPassword ? "text" : "password"}
|
||||||
|
focusBorderColor="forestGreen.300"
|
||||||
|
/>
|
||||||
|
<InputRightElement width="4.5rem">
|
||||||
|
<Button
|
||||||
|
h="1.5rem"
|
||||||
|
size="xs"
|
||||||
|
onClick={() => setShowCurrentPassword((prev) => !prev)}
|
||||||
|
>
|
||||||
|
{showCurrentPassword ? "Hide" : "Show"}
|
||||||
|
</Button>
|
||||||
|
</InputRightElement>
|
||||||
|
</InputGroup>
|
||||||
|
<FormErrorMessage>
|
||||||
|
{errors.oldPassword?.message}
|
||||||
|
</FormErrorMessage>
|
||||||
|
</FormControl>
|
||||||
|
|
||||||
|
{/* New Password */}
|
||||||
|
<FormControl isInvalid={errors.newPassword}>
|
||||||
|
<FormLabel fontSize="sm" mb={1}>
|
||||||
|
New Password
|
||||||
|
</FormLabel>
|
||||||
|
<InputGroup size="sm">
|
||||||
|
<Input
|
||||||
|
{...register("newPassword")}
|
||||||
|
fontSize="sm"
|
||||||
|
type={showNewPassword ? "text" : "password"}
|
||||||
|
focusBorderColor="forestGreen.300"
|
||||||
|
/>
|
||||||
|
<InputRightElement width="4.5rem">
|
||||||
|
<Button
|
||||||
|
h="1.5rem"
|
||||||
|
size="xs"
|
||||||
|
onClick={() => setShowNewPassword((prev) => !prev)}
|
||||||
|
>
|
||||||
|
{showNewPassword ? "Hide" : "Show"}
|
||||||
|
</Button>
|
||||||
|
</InputRightElement>
|
||||||
|
</InputGroup>
|
||||||
|
<FormErrorMessage>
|
||||||
|
{errors.newPassword?.message}
|
||||||
|
</FormErrorMessage>
|
||||||
|
</FormControl>
|
||||||
|
|
||||||
|
{/* Confirm Password */}
|
||||||
|
<FormControl isInvalid={errors.confirmNewPassword}>
|
||||||
|
<FormLabel fontSize="sm" mb={1}>
|
||||||
|
Confirm New Password
|
||||||
|
</FormLabel>
|
||||||
|
<InputGroup size="sm">
|
||||||
|
<Input
|
||||||
|
{...register("confirmNewPassword")}
|
||||||
|
fontSize="sm"
|
||||||
|
type={showConfirmPassword ? "text" : "password"}
|
||||||
|
focusBorderColor="forestGreen.300"
|
||||||
|
/>
|
||||||
|
<InputRightElement width="4.5rem">
|
||||||
|
<Button
|
||||||
|
h="1.5rem"
|
||||||
|
size="xs"
|
||||||
|
onClick={() => setShowConfirmPassword((prev) => !prev)}
|
||||||
|
>
|
||||||
|
{showConfirmPassword ? "Hide" : "Show"}
|
||||||
|
</Button>
|
||||||
|
</InputRightElement>
|
||||||
|
</InputGroup>
|
||||||
|
<FormErrorMessage>
|
||||||
|
{errors.confirmNewPassword?.message}
|
||||||
|
</FormErrorMessage>
|
||||||
|
</FormControl>
|
||||||
|
</Stack>
|
||||||
|
</ModalBody>
|
||||||
|
|
||||||
|
<DrawerFooter mb={5}>
|
||||||
|
<Button
|
||||||
|
onClick={handleClose}
|
||||||
|
bg="#e0ebeb"
|
||||||
|
size="sm"
|
||||||
|
mr={3}
|
||||||
|
rounded={"sm"}
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
rounded={"sm"}
|
||||||
|
colorScheme="forestGreen"
|
||||||
|
size="sm"
|
||||||
|
onClick={() => setAlert(true)}
|
||||||
|
isLoading={isLoading}
|
||||||
|
>
|
||||||
|
Save
|
||||||
|
</Button>
|
||||||
|
</DrawerFooter>
|
||||||
|
</ModalContent>
|
||||||
|
</Modal>
|
||||||
|
|
||||||
|
<CustomAlertDialog
|
||||||
|
isOpen={alert}
|
||||||
|
onClose={() => setAlert(false)}
|
||||||
|
alertHandler={handleSubmit(onSubmit)}
|
||||||
|
message={"Are you sure you want to change the password?"}
|
||||||
|
isLoading={isLoading}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ChangePassword;
|
||||||
134
src/Pages/ForgetPassword.jsx
Normal file
134
src/Pages/ForgetPassword.jsx
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
import {
|
||||||
|
Button,
|
||||||
|
DrawerFooter,
|
||||||
|
FormControl,
|
||||||
|
FormErrorMessage,
|
||||||
|
FormLabel,
|
||||||
|
Input,
|
||||||
|
Modal,
|
||||||
|
ModalBody,
|
||||||
|
ModalCloseButton,
|
||||||
|
ModalContent,
|
||||||
|
ModalHeader,
|
||||||
|
ModalOverlay,
|
||||||
|
Stack,
|
||||||
|
useToast,
|
||||||
|
} from "@chakra-ui/react";
|
||||||
|
import * as yup from "yup";
|
||||||
|
import React, { useState} from "react";
|
||||||
|
import { useForm, Controller } from "react-hook-form";
|
||||||
|
import { yupResolver } from "@hookform/resolvers/yup";
|
||||||
|
import { useForgetPasswordMutation } from "../Services/forget.password.service";
|
||||||
|
import ToastBox from "../Components/ToastBox";
|
||||||
|
|
||||||
|
const validationSchema = yup.object().shape({
|
||||||
|
emailAddress: yup
|
||||||
|
.string()
|
||||||
|
.email("Invalid email format")
|
||||||
|
.required("Email, Phone, or Username is required"),
|
||||||
|
});
|
||||||
|
|
||||||
|
const ForgetPassword = ({ isOpen, onClose, firstField }) => {
|
||||||
|
const toast = useToast();
|
||||||
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
|
||||||
|
const [forgetPassword] = useForgetPasswordMutation();
|
||||||
|
|
||||||
|
const {
|
||||||
|
control,
|
||||||
|
handleSubmit,
|
||||||
|
formState: { errors },
|
||||||
|
} = useForm({
|
||||||
|
resolver: yupResolver(validationSchema),
|
||||||
|
});
|
||||||
|
|
||||||
|
const onSubmit = async (formData) => {
|
||||||
|
|
||||||
|
setIsLoading(true);
|
||||||
|
try {
|
||||||
|
const res = await forgetPassword(formData);
|
||||||
|
if (res?.data?.statusCode === 200) {
|
||||||
|
toast({
|
||||||
|
render: () => <ToastBox message={res?.data?.message} />,
|
||||||
|
});
|
||||||
|
handleClose();
|
||||||
|
} else if (res?.error?.status === 401) {
|
||||||
|
toast({
|
||||||
|
render: () => (
|
||||||
|
<ToastBox message={res?.error?.data?.message} status="error" />
|
||||||
|
),
|
||||||
|
});
|
||||||
|
handleClose();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
} finally {
|
||||||
|
setIsLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleClose = () => {
|
||||||
|
setIsLoading(false);
|
||||||
|
onClose();
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
isCentered
|
||||||
|
isOpen={isOpen}
|
||||||
|
onClose={handleClose}
|
||||||
|
initialFocusRef={firstField}
|
||||||
|
>
|
||||||
|
<ModalOverlay />
|
||||||
|
<ModalContent>
|
||||||
|
<form onSubmit={handleSubmit(onSubmit)}>
|
||||||
|
<ModalHeader fontSize="md">Forget Password</ModalHeader>
|
||||||
|
<ModalCloseButton />
|
||||||
|
<ModalBody pb={4}>
|
||||||
|
<Stack spacing={4}>
|
||||||
|
<FormControl isInvalid={errors.emailAddress}>
|
||||||
|
<FormLabel fontSize="sm" mb={3} fontWeight={500}>
|
||||||
|
Email, Phone, or Username
|
||||||
|
</FormLabel>
|
||||||
|
<Controller
|
||||||
|
name="emailAddress"
|
||||||
|
control={control}
|
||||||
|
render={({ field }) => (
|
||||||
|
<Input
|
||||||
|
{...field}
|
||||||
|
size="md"
|
||||||
|
fontSize="sm"
|
||||||
|
focusBorderColor="forestGreen.300"
|
||||||
|
rounded={4}
|
||||||
|
type="text"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<FormErrorMessage fontSize="xs" fontWeight={500}>
|
||||||
|
{errors.emailAddress?.message}
|
||||||
|
</FormErrorMessage>
|
||||||
|
</FormControl>
|
||||||
|
</Stack>
|
||||||
|
</ModalBody>
|
||||||
|
|
||||||
|
<DrawerFooter mb={5}>
|
||||||
|
<Button
|
||||||
|
w="100%"
|
||||||
|
colorScheme="forestGreen"
|
||||||
|
rounded="md"
|
||||||
|
size="md"
|
||||||
|
type="submit"
|
||||||
|
isLoading={isLoading}
|
||||||
|
fontWeight={400}
|
||||||
|
fontSize="sm"
|
||||||
|
>
|
||||||
|
Send Login Link
|
||||||
|
</Button>
|
||||||
|
</DrawerFooter>
|
||||||
|
</form>
|
||||||
|
</ModalContent>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ForgetPassword;
|
||||||
@@ -20,6 +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";
|
||||||
|
|
||||||
const IOCashDetails = () => {
|
const IOCashDetails = () => {
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
@@ -105,7 +106,7 @@ const IOCashDetails = () => {
|
|||||||
</Tab>
|
</Tab>
|
||||||
</TabList>
|
</TabList>
|
||||||
{IODetails?.isInvestedAmount
|
{IODetails?.isInvestedAmount
|
||||||
? localStorage?.getItem("role") === "Maker" && (
|
? localStorage?.getItem("role") === encryptString(import.meta.env.VITE_VITE_MAKER) && (
|
||||||
<Button
|
<Button
|
||||||
onClick={handleAdd}
|
onClick={handleAdd}
|
||||||
leftIcon={<AddIcon />}
|
leftIcon={<AddIcon />}
|
||||||
|
|||||||
@@ -38,6 +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";
|
||||||
|
|
||||||
const formatDate = (date) => new Date(date).toLocaleDateString();
|
const formatDate = (date) => new Date(date).toLocaleDateString();
|
||||||
|
|
||||||
@@ -104,7 +105,7 @@ const Pending = () => {
|
|||||||
"Comments",
|
"Comments",
|
||||||
"Update By",
|
"Update By",
|
||||||
"Update On",
|
"Update On",
|
||||||
...(localStorage?.getItem('role')!=="Maker" ? ["Actions"] : []),
|
...(localStorage?.getItem('role')!==encryptString(import.meta.env.VITE_VITE_MAKER) ? ["Actions"] : []),
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -166,7 +167,7 @@ const Pending = () => {
|
|||||||
),
|
),
|
||||||
Actions: (
|
Actions: (
|
||||||
<Box display={"flex"} justifyContent={"center"}>
|
<Box display={"flex"} justifyContent={"center"}>
|
||||||
{localStorage?.getItem("role") !== "Maker" ? <Box>
|
{localStorage?.getItem("role") !== encryptString(import.meta.env.VITE_VITE_MAKER) ? <Box>
|
||||||
{index===0&&<Box display={"flex"} justifyContent={"center"} gap={2}>
|
{index===0&&<Box display={"flex"} justifyContent={"center"} gap={2}>
|
||||||
<Tooltip
|
<Tooltip
|
||||||
rounded={"sm"}
|
rounded={"sm"}
|
||||||
|
|||||||
@@ -4,10 +4,7 @@ import {
|
|||||||
Box,
|
Box,
|
||||||
Button,
|
Button,
|
||||||
HStack,
|
HStack,
|
||||||
Input,
|
Input,
|
||||||
Table,
|
|
||||||
Tag,
|
|
||||||
Tbody,
|
|
||||||
Text,
|
Text,
|
||||||
Th,
|
Th,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
@@ -22,7 +19,7 @@ import { OPACITY_ON_LOAD } from "../../../../Layout/animations";
|
|||||||
import NormalTable from "../../../../Components/DataTable/NormalTable";
|
import NormalTable from "../../../../Components/DataTable/NormalTable";
|
||||||
import GlobalStateContext from "../../../../Contexts/GlobalStateContext";
|
import GlobalStateContext from "../../../../Contexts/GlobalStateContext";
|
||||||
import CustomAlertDialog from "../../../../Components/CustomAlertDialog";
|
import CustomAlertDialog from "../../../../Components/CustomAlertDialog";
|
||||||
import * as XLSX from "xlsx";
|
import * as XLSX from "xlsx";
|
||||||
import ToastBox from "../../../../Components/ToastBox";
|
import ToastBox from "../../../../Components/ToastBox";
|
||||||
import AddCashDetails from "../AddCashDetails";
|
import AddCashDetails from "../AddCashDetails";
|
||||||
import { debounce } from "../../../Admin/Contact";
|
import { debounce } from "../../../Admin/Contact";
|
||||||
|
|||||||
@@ -75,6 +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";
|
||||||
|
|
||||||
const IONAVDetails = () => {
|
const IONAVDetails = () => {
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
@@ -152,7 +153,7 @@ const IONAVDetails = () => {
|
|||||||
</Tab>
|
</Tab>
|
||||||
</TabList>
|
</TabList>
|
||||||
{IODetails?.isInvestedAmount
|
{IODetails?.isInvestedAmount
|
||||||
? localStorage?.getItem("role") === "Maker" && (
|
? localStorage?.getItem("role") === encryptString(import.meta.env.VITE_VITE_MAKER) && (
|
||||||
<Button
|
<Button
|
||||||
onClick={handleAdd}
|
onClick={handleAdd}
|
||||||
leftIcon={<AddIcon />}
|
leftIcon={<AddIcon />}
|
||||||
|
|||||||
@@ -22,6 +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";
|
||||||
|
|
||||||
const formatDate = (date) => new Date(date).toLocaleDateString();
|
const formatDate = (date) => new Date(date).toLocaleDateString();
|
||||||
|
|
||||||
@@ -90,7 +91,7 @@ const Pending = () => {
|
|||||||
"Investment Closed",
|
"Investment Closed",
|
||||||
"Comments",
|
"Comments",
|
||||||
"Updated By",
|
"Updated By",
|
||||||
...(localStorage?.getItem("role") !== "Maker" ? ["Status"] : []),
|
...(localStorage?.getItem("role") !== encryptString(import.meta.env.VITE_VITE_MAKER) ? ["Status"] : []),
|
||||||
];
|
];
|
||||||
|
|
||||||
const extractedArray = filteredData?.map((item, index) => ({
|
const extractedArray = filteredData?.map((item, index) => ({
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import ViewAmountInvested from "./ViewAmountInvested";
|
|||||||
import ViewDistributionInvestor from "./ViewDistributionInvestor";
|
import ViewDistributionInvestor from "./ViewDistributionInvestor";
|
||||||
import ViewExit from "./ViewExit";
|
import ViewExit from "./ViewExit";
|
||||||
import ViewCancel from "./ViewCancel";
|
import ViewCancel from "./ViewCancel";
|
||||||
|
import { encryptString } from "../../../../Constants/Constants";
|
||||||
|
|
||||||
const formatDate = (date) => new Date(date).toLocaleDateString();
|
const formatDate = (date) => new Date(date).toLocaleDateString();
|
||||||
|
|
||||||
@@ -195,7 +196,7 @@ const Pending = () => {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{localStorage?.getItem("role") === "Maker" ? <ViewIcon me={"4px"} /> : null} {localStorage?.getItem("role") === "Maker" ? "View" : "Approve / Reject"}
|
{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"}
|
||||||
</Button>
|
</Button>
|
||||||
</Box>
|
</Box>
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -27,6 +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";
|
||||||
|
|
||||||
// Validation schema
|
// Validation schema
|
||||||
const validationSchema = yup.object().shape({
|
const validationSchema = yup.object().shape({
|
||||||
@@ -236,7 +237,7 @@ const ViewAmountInvested = ({ isOpen, onClose, id: investorId }) => {
|
|||||||
/>
|
/>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
|
|
||||||
{localStorage?.getItem("role") !== "Maker" && <ModalFooter>
|
{localStorage?.getItem("role") !== encryptString(import.meta.env.VITE_VITE_MAKER) && <ModalFooter>
|
||||||
<Box display={"flex"} justifyContent={"center"} gap={2}>
|
<Box display={"flex"} justifyContent={"center"} gap={2}>
|
||||||
<Button
|
<Button
|
||||||
rounded={"sm"}
|
rounded={"sm"}
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ import {
|
|||||||
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";
|
||||||
|
|
||||||
const ViewCancel = ({ isOpen, onClose,id:cancleId }) => {
|
const ViewCancel = ({ isOpen, onClose,id:cancleId }) => {
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
@@ -311,7 +312,7 @@ import RequestRejectModal from "./RequestRejectModal";
|
|||||||
data={extractedArray}
|
data={extractedArray}
|
||||||
/>
|
/>
|
||||||
</ModalBody>
|
</ModalBody>
|
||||||
{localStorage?.getItem("role") !== "Maker" && <ModalFooter pt={0}>
|
{localStorage?.getItem("role") !== encryptString(import.meta.env.VITE_VITE_MAKER) && <ModalFooter pt={0}>
|
||||||
<Box display={"flex"} justifyContent={"center"} gap={2}>
|
<Box display={"flex"} justifyContent={"center"} gap={2}>
|
||||||
<Button
|
<Button
|
||||||
rounded={"sm"}
|
rounded={"sm"}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ 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";
|
||||||
|
|
||||||
const ViewDistributionInvestor = ({ isOpen, onClose,id:exitId }) => {
|
const ViewDistributionInvestor = ({ isOpen, onClose,id:exitId }) => {
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
@@ -218,7 +219,7 @@ const ViewDistributionInvestor = ({ isOpen, onClose,id:exitId }) => {
|
|||||||
/>
|
/>
|
||||||
</ModalBody>
|
</ModalBody>
|
||||||
{/* ...(localStorage?.getItem("role") !== "Maker" ? ["Status"] : []), */}
|
{/* ...(localStorage?.getItem("role") !== "Maker" ? ["Status"] : []), */}
|
||||||
{localStorage?.getItem("role") !== "Maker" &&<ModalFooter pt={0}>
|
{localStorage?.getItem("role") !== encryptString(import.meta.env.VITE_VITE_MAKER) &&<ModalFooter pt={0}>
|
||||||
<Box display={"flex"} justifyContent={"center"} gap={2}>
|
<Box display={"flex"} justifyContent={"center"} gap={2}>
|
||||||
<Button
|
<Button
|
||||||
rounded={"sm"}
|
rounded={"sm"}
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ import {
|
|||||||
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";
|
||||||
|
|
||||||
const ViewExit = ({ isOpen, onClose ,id:investerId}) => {
|
const ViewExit = ({ isOpen, onClose ,id:investerId}) => {
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
@@ -273,7 +274,7 @@ import RequestRejectModal from "./RequestRejectModal";
|
|||||||
/>
|
/>
|
||||||
{/* ) } */}
|
{/* ) } */}
|
||||||
</ModalBody>
|
</ModalBody>
|
||||||
{localStorage?.getItem("role") !== "Maker" && <ModalFooter pt={0}>
|
{localStorage?.getItem("role") !== encryptString(import.meta.env.VITE_VITE_MAKER) && <ModalFooter pt={0}>
|
||||||
<Box display={"flex"} justifyContent={"center"} gap={2}>
|
<Box display={"flex"} justifyContent={"center"} gap={2}>
|
||||||
<Button
|
<Button
|
||||||
rounded={"sm"}
|
rounded={"sm"}
|
||||||
|
|||||||
@@ -182,7 +182,7 @@ const Investors = ({ data }) => {
|
|||||||
{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"}
|
||||||
@@ -193,7 +193,7 @@ const Investors = ({ data }) => {
|
|||||||
{item.firstName}
|
{item.firstName}
|
||||||
</Text>
|
</Text>
|
||||||
),
|
),
|
||||||
"Last name": (
|
"Last Name": (
|
||||||
<Text
|
<Text
|
||||||
justifyContent={slideFromRight ? "right" : "center"}
|
justifyContent={slideFromRight ? "right" : "center"}
|
||||||
as={"span"}
|
as={"span"}
|
||||||
@@ -204,7 +204,7 @@ const Investors = ({ data }) => {
|
|||||||
{item.lastName}
|
{item.lastName}
|
||||||
</Text>
|
</Text>
|
||||||
),
|
),
|
||||||
"Investment amount": (
|
"Investment Amount": (
|
||||||
<Text
|
<Text
|
||||||
justifyContent={slideFromRight ? "right" : "left"}
|
justifyContent={slideFromRight ? "right" : "left"}
|
||||||
as={"span"}
|
as={"span"}
|
||||||
@@ -313,7 +313,7 @@ const Investors = ({ data }) => {
|
|||||||
})}`}
|
})}`}
|
||||||
</Text>
|
</Text>
|
||||||
),
|
),
|
||||||
"Total return on Investment": (
|
"Total Return on Investment": (
|
||||||
<Text
|
<Text
|
||||||
justifyContent={slideFromRight ? "right" : "center"}
|
justifyContent={slideFromRight ? "right" : "center"}
|
||||||
as={"span"}
|
as={"span"}
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ import { GrGallery } from "react-icons/gr";
|
|||||||
import Loader01 from "../../../Components/Loaders/Loader01";
|
import Loader01 from "../../../Components/Loaders/Loader01";
|
||||||
import { useUpdateTransactionMutation } from "../../../Services/io.service";
|
import { useUpdateTransactionMutation } from "../../../Services/io.service";
|
||||||
import ToastBox from "../../../Components/ToastBox";
|
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";
|
||||||
|
|
||||||
@@ -532,7 +533,7 @@ const ViewIOdataHeader = ({ data, isLoading }) => {
|
|||||||
alignItems={"start"}
|
alignItems={"start"}
|
||||||
height={"95px"}
|
height={"95px"}
|
||||||
>
|
>
|
||||||
{localStorage?.getItem("role") === "Maker" && <Menu>
|
{localStorage?.getItem("role") === encryptString(import.meta.env.VITE_VITE_MAKER) && <Menu>
|
||||||
<MenuButton
|
<MenuButton
|
||||||
className="link p-1 rounded-1 "
|
className="link p-1 rounded-1 "
|
||||||
bg={"#fff"}
|
bg={"#fff"}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import Input01 from "../Components/Inputs/Input01";
|
|||||||
import logo from "../assets/logo2.png";
|
import logo from "../assets/logo2.png";
|
||||||
import { useDispatch, useSelector } from "react-redux";
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
import { loginUser } from "../Redux/Slice/auth";
|
import { loginUser } from "../Redux/Slice/auth";
|
||||||
import { useContext, useEffect, useState } from "react";
|
import { useContext, useEffect, useRef, useState } from "react";
|
||||||
import Button01 from "../Components/Buttons/Button01";
|
import Button01 from "../Components/Buttons/Button01";
|
||||||
import { yupResolver } from "@hookform/resolvers/yup";
|
import { yupResolver } from "@hookform/resolvers/yup";
|
||||||
import { useForm } from "react-hook-form";
|
import { useForm } from "react-hook-form";
|
||||||
@@ -12,12 +12,15 @@ import Loader01 from "../Components/Loaders/Loader01";
|
|||||||
import Asset1 from "../assets/asset1.png";
|
import Asset1 from "../assets/asset1.png";
|
||||||
import Asset2 from "../assets/asset2.png";
|
import Asset2 from "../assets/asset2.png";
|
||||||
import {
|
import {
|
||||||
|
Box,
|
||||||
Button,
|
Button,
|
||||||
FormControl,
|
FormControl,
|
||||||
FormLabel,
|
FormLabel,
|
||||||
Input,
|
Input,
|
||||||
InputGroup,
|
InputGroup,
|
||||||
InputRightElement,
|
InputRightElement,
|
||||||
|
Text,
|
||||||
|
useDisclosure,
|
||||||
useToast,
|
useToast,
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import GlobalStateContext from "../Contexts/GlobalStateContext";
|
import GlobalStateContext from "../Contexts/GlobalStateContext";
|
||||||
@@ -28,6 +31,7 @@ import { useLoginMutation } from "../Services/token.serivce";
|
|||||||
|
|
||||||
// import { yupResolver } from "@hookform/resolvers/yup";
|
// import { yupResolver } from "@hookform/resolvers/yup";
|
||||||
import * as Yup from "yup";
|
import * as Yup from "yup";
|
||||||
|
import ForgetPassword from "./ForgetPassword";
|
||||||
|
|
||||||
|
|
||||||
const validationSchema = Yup.object().shape({
|
const validationSchema = Yup.object().shape({
|
||||||
@@ -50,6 +54,8 @@ const Login = () => {
|
|||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
const [login] = useLoginMutation()
|
const [login] = useLoginMutation()
|
||||||
|
const { isOpen, onOpen, onClose } = useDisclosure();
|
||||||
|
const firstField = useRef();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
||||||
@@ -205,7 +211,7 @@ const Login = () => {
|
|||||||
)}
|
)}
|
||||||
</FormControl>
|
</FormControl>
|
||||||
|
|
||||||
<FormControl className="mb-4">
|
<FormControl className="mb-2">
|
||||||
<FormLabel className="rubix-text-dark ps-1 web-text-medium fw-bold">
|
<FormLabel className="rubix-text-dark ps-1 web-text-medium fw-bold">
|
||||||
Password <span className="text-danger">*</span>
|
Password <span className="text-danger">*</span>
|
||||||
</FormLabel>
|
</FormLabel>
|
||||||
@@ -238,6 +244,9 @@ const Login = () => {
|
|||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</FormControl>
|
</FormControl>
|
||||||
|
<Box fontSize={"sm"} display={"flex"} justifyContent={"end"} mt={0}>
|
||||||
|
<Text fontWeight={500} cursor={"pointer"} onClick={onOpen}>Forget Password?</Text>
|
||||||
|
</Box>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
@@ -247,6 +256,8 @@ const Login = () => {
|
|||||||
color={"whitesmoke"}
|
color={"whitesmoke"}
|
||||||
colorScheme="green.500"
|
colorScheme="green.500"
|
||||||
size="lg"
|
size="lg"
|
||||||
|
fontWeight={500}
|
||||||
|
fontSize={"md"}
|
||||||
>
|
>
|
||||||
Log In
|
Log In
|
||||||
</Button>
|
</Button>
|
||||||
@@ -317,6 +328,11 @@ const Login = () => {
|
|||||||
src={Asset2}
|
src={Asset2}
|
||||||
alt="bg-img"
|
alt="bg-img"
|
||||||
/>
|
/>
|
||||||
|
<ForgetPassword
|
||||||
|
isOpen={isOpen}
|
||||||
|
onClose={onClose}
|
||||||
|
firstField={firstField}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
377
src/Pages/SubAdmin/SubAdmin.jsx
Normal file
377
src/Pages/SubAdmin/SubAdmin.jsx
Normal file
@@ -0,0 +1,377 @@
|
|||||||
|
import {
|
||||||
|
Badge,
|
||||||
|
Box,
|
||||||
|
Button,
|
||||||
|
HStack,
|
||||||
|
Input,
|
||||||
|
Switch,
|
||||||
|
Text,
|
||||||
|
Tooltip,
|
||||||
|
useToast,
|
||||||
|
} from "@chakra-ui/react";
|
||||||
|
import React, { useContext, useEffect, useState } from "react";
|
||||||
|
import { Link, Link as RouterLink } 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 ToastBox from "../../Components/ToastBox";
|
||||||
|
import { TABLE_PAGINATION } from "../../Constants/Paginations";
|
||||||
|
import { generateSerialNumber } from "../../Constants/Constants";
|
||||||
|
import { useGetSponserMasterQuery } from "../../Services/io.service";
|
||||||
|
import {
|
||||||
|
useGetSubAdminMasterQuery,
|
||||||
|
useToggleStatusMutation,
|
||||||
|
} from "../../Services/subadmin.service";
|
||||||
|
import RoleSwitchButton from "../../Components/RoleSwitchButton";
|
||||||
|
|
||||||
|
export const formatDate = (date) => {
|
||||||
|
const d = new Date(date);
|
||||||
|
const year = d.getFullYear();
|
||||||
|
const month = String(d.getMonth() + 1).padStart(2, "0"); // Months are 0-indexed
|
||||||
|
const day = String(d.getDate()).padStart(2, "0");
|
||||||
|
|
||||||
|
return `${day}/${month}/${year}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
const SubAdmin = () => {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const toast = useToast();
|
||||||
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
const [deleteAlert, setDeleteAlert] = useState(false);
|
||||||
|
const [actionId, setActionId] = useState(false);
|
||||||
|
const [mouseEntered, setMouseEntered] = useState(false);
|
||||||
|
const [mouseEnteredId, setMouseEnteredId] = useState("");
|
||||||
|
// const [deleteSponser] = useDeleteSponserMutation();
|
||||||
|
const { sponser, setSponser, slideFromRight } =
|
||||||
|
useContext(GlobalStateContext);
|
||||||
|
|
||||||
|
// =========================== [Use State] =============================
|
||||||
|
const [pageSize, setPageSize] = useState(TABLE_PAGINATION?.size);
|
||||||
|
const [currentPage, setCurrentPage] = useState(TABLE_PAGINATION?.page);
|
||||||
|
const [searchTerm, setSearchTerm] = useState("");
|
||||||
|
const [debouncedSearchTerm, setDebouncedSearchTerm] = useState("");
|
||||||
|
const [isSwitchOn, setIsSwitchOn] = useState(true);
|
||||||
|
|
||||||
|
// 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: subAdmin,
|
||||||
|
error,
|
||||||
|
isLoading: isSponserLoading,
|
||||||
|
} = useGetSubAdminMasterQuery();
|
||||||
|
|
||||||
|
const [toggleStatus] = useToggleStatusMutation();
|
||||||
|
|
||||||
|
// useEffect(() => {
|
||||||
|
// if (subAdmin?.data) {
|
||||||
|
// setIsSwitchOn(subAdmin?.role?.role);
|
||||||
|
// console.log(subAdmin);
|
||||||
|
// }
|
||||||
|
// }, [subAdmin]);
|
||||||
|
|
||||||
|
// ==============================[Table Filter]========================
|
||||||
|
|
||||||
|
const filteredData = subAdmin?.data?.filter((item) => {
|
||||||
|
const name = item.firstName;
|
||||||
|
const searchLower = searchTerm?.toLowerCase();
|
||||||
|
const nameMatches = name?.toLowerCase().includes(searchLower);
|
||||||
|
return nameMatches;
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleToggleStatus = async (isMaker, id) => {
|
||||||
|
console.log("hit");
|
||||||
|
const data = {
|
||||||
|
role_xid: isMaker ? "2" : "1",
|
||||||
|
};
|
||||||
|
console.log("=======================",data)
|
||||||
|
try {
|
||||||
|
const res = await toggleStatus({id, data});
|
||||||
|
if (res?.error) {
|
||||||
|
toast({
|
||||||
|
render: () => (
|
||||||
|
<ToastBox status={"error"} message={res?.error?.data?.message} />
|
||||||
|
),
|
||||||
|
});
|
||||||
|
} else if (res) {
|
||||||
|
toast({
|
||||||
|
render: () => (
|
||||||
|
<ToastBox
|
||||||
|
status={"success"}
|
||||||
|
message={res?.message || "Status updated successfully!"}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
toast({
|
||||||
|
render: () => (
|
||||||
|
<ToastBox
|
||||||
|
status={"error"}
|
||||||
|
message={error?.data?.message || "Something went wrong"}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// ====================================================[Table Setup]================================================================
|
||||||
|
|
||||||
|
const tableHeadRow = [
|
||||||
|
"Sr No",
|
||||||
|
"First Name",
|
||||||
|
"Last Name",
|
||||||
|
"Email Address",
|
||||||
|
"Role",
|
||||||
|
"Action",
|
||||||
|
];
|
||||||
|
|
||||||
|
const extractedArray = subAdmin?.data?.map((item, index) => ({
|
||||||
|
"Sr No": (
|
||||||
|
<Text
|
||||||
|
w={"24px"}
|
||||||
|
justifyContent={slideFromRight ? "right" : "left"}
|
||||||
|
as={"span"}
|
||||||
|
color={"gray.600"}
|
||||||
|
className="d-flex align-items-center fw-bold web-text-small"
|
||||||
|
>
|
||||||
|
{/* {item.id} */}
|
||||||
|
{generateSerialNumber(index, currentPage, pageSize)}
|
||||||
|
</Text>
|
||||||
|
),
|
||||||
|
"First Name": (
|
||||||
|
<Text
|
||||||
|
justifyContent={slideFromRight ? "right" : "left"}
|
||||||
|
as={"span"}
|
||||||
|
color={"teal.900"}
|
||||||
|
fontWeight={"500"}
|
||||||
|
className="d-flex align-items-center web-text-small"
|
||||||
|
>
|
||||||
|
{item?.firstName}
|
||||||
|
</Text>
|
||||||
|
),
|
||||||
|
"Last Name": (
|
||||||
|
<Text
|
||||||
|
justifyContent={slideFromRight ? "right" : "left"}
|
||||||
|
as={"span"}
|
||||||
|
color={"teal.900"}
|
||||||
|
fontWeight={"500"}
|
||||||
|
className="d-flex align-items-center web-text-small"
|
||||||
|
>
|
||||||
|
{item?.lastName}
|
||||||
|
</Text>
|
||||||
|
),
|
||||||
|
"Email Address": (
|
||||||
|
<Box isTruncated={true}>
|
||||||
|
<Text as={"span"} color={"teal.900"} fontWeight={"500"}>
|
||||||
|
{item?.emailAddress}
|
||||||
|
</Text>
|
||||||
|
</Box>
|
||||||
|
),
|
||||||
|
Role: (
|
||||||
|
<Box isTruncated={true} >
|
||||||
|
<Badge
|
||||||
|
py={"2px"}
|
||||||
|
me={2}
|
||||||
|
fontWeight={600}
|
||||||
|
bg={item?.role[0]?.role === "Maker" ? "#00ffcc" : "#b3ff99"}
|
||||||
|
px={item?.role[0]?.role === "Maker" ? "12px" : "5px"}
|
||||||
|
>
|
||||||
|
{item?.role[0]?.role}
|
||||||
|
</Badge>
|
||||||
|
<Switch
|
||||||
|
onChange={() =>
|
||||||
|
handleToggleStatus(item?.role[0]?.role === "Maker", item?.id)
|
||||||
|
}
|
||||||
|
isChecked={item?.role[0]?.role === "Maker"}
|
||||||
|
// colorScheme={item?.role[0]?.role === "Maker" ? "green" : "teal"}
|
||||||
|
sx={{
|
||||||
|
".chakra-switch__track": {
|
||||||
|
bg: item?.role[0]?.role === "Maker" ? "#00ffcc" : "#b3ff99", // "Off" state color
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
{/* <RoleSwitchButton
|
||||||
|
setIsSwitchOn={setIsSwitchOn}
|
||||||
|
isSwitchOn={item?.role[0]?.role === "Maker"}
|
||||||
|
onClick={() => handleToggleStatus(item?.role[0]?.role=== "Maker")}
|
||||||
|
/> */}
|
||||||
|
</Box>
|
||||||
|
),
|
||||||
|
Action: (
|
||||||
|
<Box display={"flex"} justifyContent={"center"} gap={2}>
|
||||||
|
<Tooltip
|
||||||
|
rounded={"sm"}
|
||||||
|
fontSize={"xs"}
|
||||||
|
label="Edit"
|
||||||
|
bg="#fff"
|
||||||
|
color={"blue.500"}
|
||||||
|
placement="top"
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
onClick={() => navigate(`/subadmin/subadmin-update/${item.id}`)}
|
||||||
|
// _hover={{ color: "blue.500" }}
|
||||||
|
// color="blue.400"
|
||||||
|
rounded={"sm"}
|
||||||
|
size={"xs"}
|
||||||
|
colorScheme="blue"
|
||||||
|
>
|
||||||
|
<EditIcon />
|
||||||
|
</Button>
|
||||||
|
</Tooltip>
|
||||||
|
|
||||||
|
{/* <Tooltip
|
||||||
|
rounded={"sm"}
|
||||||
|
fontSize={"xs"}
|
||||||
|
label="Delete"
|
||||||
|
bg="#fff"
|
||||||
|
color={"red.500"}
|
||||||
|
placement="top"
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
onClick={() => {
|
||||||
|
setActionId(item?.id);
|
||||||
|
setDeleteAlert(true);
|
||||||
|
}}
|
||||||
|
// _hover={{ color: "red.500" }}
|
||||||
|
// color="red"
|
||||||
|
rounded={"sm"}
|
||||||
|
size={"xs"}
|
||||||
|
colorScheme="red"
|
||||||
|
variant={"solid"}
|
||||||
|
>
|
||||||
|
<DeleteIcon />
|
||||||
|
</Button>
|
||||||
|
</Tooltip> */}
|
||||||
|
</Box>
|
||||||
|
),
|
||||||
|
}));
|
||||||
|
|
||||||
|
// =========================== [ Delete Function ] =================================
|
||||||
|
|
||||||
|
// const handleDelete = async () => {
|
||||||
|
// console.log(actionId);
|
||||||
|
// setIsLoading(true);
|
||||||
|
// try {
|
||||||
|
// const response = await deleteSponser(actionId);
|
||||||
|
// console.log(response?.data);
|
||||||
|
// if (response?.error?.data?.code === 400) {
|
||||||
|
// toast({
|
||||||
|
// render: () => (
|
||||||
|
// <ToastBox
|
||||||
|
// message={response?.error?.data?.message}
|
||||||
|
// status={"error"}
|
||||||
|
// />
|
||||||
|
// ),
|
||||||
|
// });
|
||||||
|
// setIsLoading(false);
|
||||||
|
// setDeleteAlert(false);
|
||||||
|
// } else if (
|
||||||
|
// response?.data?.statusCode === 201 ||
|
||||||
|
// response?.data?.statusCode === 200
|
||||||
|
// ) {
|
||||||
|
// toast({
|
||||||
|
// render: () => (
|
||||||
|
// <ToastBox message={response?.data?.message} status={"success"} />
|
||||||
|
// ),
|
||||||
|
// });
|
||||||
|
// setIsLoading(false);
|
||||||
|
// setDeleteAlert(false);
|
||||||
|
// }
|
||||||
|
// } catch (error) {}
|
||||||
|
// };
|
||||||
|
|
||||||
|
console.log(isSponserLoading);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box {...OPACITY_ON_LOAD} overflowY={"scroll"} height={"100vh"} pb={38}>
|
||||||
|
<Box bg="white.500">
|
||||||
|
<HStack
|
||||||
|
display={"flex"}
|
||||||
|
justifyContent={"space-between"}
|
||||||
|
ps={1}
|
||||||
|
pe={1}
|
||||||
|
pb={4}
|
||||||
|
pt={4}
|
||||||
|
spacing="24px"
|
||||||
|
>
|
||||||
|
{/* =======================[Search Input]======================== */}
|
||||||
|
|
||||||
|
<Input
|
||||||
|
type="search"
|
||||||
|
width={300}
|
||||||
|
placeholder="Search..."
|
||||||
|
size="sm"
|
||||||
|
rounded="sm"
|
||||||
|
focusBorderColor="green.500"
|
||||||
|
value={searchTerm}
|
||||||
|
onChange={(e) => setSearchTerm(e.target.value)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<HStack display={"flex"} alignItems={"center"}>
|
||||||
|
{/* ====================[Pagination]===================== */}
|
||||||
|
|
||||||
|
<Pagination
|
||||||
|
isLoading={isSponserLoading}
|
||||||
|
pageSize={pageSize}
|
||||||
|
setPageSize={setPageSize}
|
||||||
|
currentPage={currentPage}
|
||||||
|
setCurrentPage={setCurrentPage}
|
||||||
|
totalItems={subAdmin?.data?.totalItems}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* =====================[Add Button]===================== */}
|
||||||
|
|
||||||
|
<Link to={"/subadmin/subadmin-update"}>
|
||||||
|
<Button
|
||||||
|
leftIcon={<AddIcon />}
|
||||||
|
colorScheme={"forestGreen"}
|
||||||
|
rounded={"sm"}
|
||||||
|
fontSize={"xs"}
|
||||||
|
size={"sm"}
|
||||||
|
>
|
||||||
|
Add
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
</HStack>
|
||||||
|
</HStack>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
{/* =================== [Data Table] ===================== */}
|
||||||
|
|
||||||
|
<NormalTable
|
||||||
|
emptyMessage={`We don't have any Sponers `}
|
||||||
|
tableHeadRow={tableHeadRow}
|
||||||
|
data={extractedArray}
|
||||||
|
isLoading={isSponserLoading}
|
||||||
|
viewActionId={actionId}
|
||||||
|
setViewActionId={setActionId}
|
||||||
|
setMouseEnteredId={setMouseEnteredId}
|
||||||
|
setMouseEntered={setMouseEntered}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* ======================== [Modal] ======================== */}
|
||||||
|
|
||||||
|
<CustomAlertDialog
|
||||||
|
onClose={() => setDeleteAlert(false)}
|
||||||
|
isOpen={deleteAlert}
|
||||||
|
message={"Are you sure you want to delete sponers?"}
|
||||||
|
// alertHandler={handleDelete}
|
||||||
|
isLoading={isLoading}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SubAdmin;
|
||||||
355
src/Pages/SubAdmin/SubAdminUpdateCreate.jsx
Normal file
355
src/Pages/SubAdmin/SubAdminUpdateCreate.jsx
Normal file
@@ -0,0 +1,355 @@
|
|||||||
|
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 { OPACITY_ON_LOAD } from "../../Layout/animations";
|
||||||
|
import FormInputMain from "../../Components/FormInputMain";
|
||||||
|
import ToastBox from "../../Components/ToastBox";
|
||||||
|
import FullscreenLoaders from "../../Components/Loaders/FullscreenLoaders";
|
||||||
|
import CustomAlertDialog from "../../Components/CustomAlertDialog";
|
||||||
|
import RoleSwitchButton from "../../Components/RoleSwitchButton";
|
||||||
|
import {
|
||||||
|
useCreateSubAdminMutation,
|
||||||
|
useGetSubAdminByIdQuery,
|
||||||
|
useUpdateSubAdminMutation,
|
||||||
|
} from "../../Services/subadmin.service";
|
||||||
|
import { useGetSponserByIdQuery } from "../../Services/io.service";
|
||||||
|
import { encryptString } from "../../Constants/Constants";
|
||||||
|
// ======================= [validation] =========================
|
||||||
|
|
||||||
|
export const addSubAdmin = yup.object().shape({
|
||||||
|
firstName: yup
|
||||||
|
.string()
|
||||||
|
.required("First Name is required")
|
||||||
|
.min(3, "First Name must be at least 3 characters long")
|
||||||
|
.max(50, "First Name cannot exceed 50 characters")
|
||||||
|
.matches(/^[^\d]+$/, "First Name cannot contain numbers"),
|
||||||
|
|
||||||
|
lastName: yup.string().required("Last Name name in arabic is required"),
|
||||||
|
emailAddress: yup.string().email("Invalid email address").notRequired(),
|
||||||
|
// .test("emailValidity", "Email address is invalid", async function (value) {
|
||||||
|
// if (!value) {
|
||||||
|
// return true; // Allow if the field is empty
|
||||||
|
// }
|
||||||
|
// return await checkEmailValidity(value);
|
||||||
|
// }),
|
||||||
|
});
|
||||||
|
|
||||||
|
// ==================== [debounce] ========================
|
||||||
|
|
||||||
|
export function debounce(func, delay) {
|
||||||
|
let debounceTimer;
|
||||||
|
return function (...args) {
|
||||||
|
clearTimeout(debounceTimer);
|
||||||
|
debounceTimer = setTimeout(() => func.apply(this, args), delay);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const SubAdminUpdateCreate = () => {
|
||||||
|
const toast = useToast();
|
||||||
|
const params = useParams();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const id = params?.id;
|
||||||
|
|
||||||
|
// =====================[useState]=======================
|
||||||
|
|
||||||
|
const [isLoadingBtn, setIsLoadingBtn] = useState(false);
|
||||||
|
const [alert, setAlert] = useState(false);
|
||||||
|
const [form, setForm] = useState();
|
||||||
|
const [isSwitchOn, setIsSwitchOn] = useState(true);
|
||||||
|
|
||||||
|
const [createSubAdmin] = useCreateSubAdminMutation();
|
||||||
|
const [updateSubAdmin] = useUpdateSubAdminMutation();
|
||||||
|
|
||||||
|
// Fetch sponsor data only if id exists
|
||||||
|
const {
|
||||||
|
data: subAdminByIdData,
|
||||||
|
error,
|
||||||
|
isLoading,
|
||||||
|
} = useGetSubAdminByIdQuery(id, { skip: !id });
|
||||||
|
|
||||||
|
// ======================== [validators] ===========================
|
||||||
|
|
||||||
|
const {
|
||||||
|
control,
|
||||||
|
watch,
|
||||||
|
handleSubmit,
|
||||||
|
formState: { errors },
|
||||||
|
reset,
|
||||||
|
} = useForm({
|
||||||
|
resolver: yupResolver(addSubAdmin),
|
||||||
|
});
|
||||||
|
|
||||||
|
// ========================== [useEffect] ================================
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (subAdminByIdData?.data) {
|
||||||
|
reset({
|
||||||
|
firstName: subAdminByIdData?.data?.firstName,
|
||||||
|
lastName: subAdminByIdData?.data?.lastName,
|
||||||
|
emailAddress: subAdminByIdData?.data?.emailAddress,
|
||||||
|
});
|
||||||
|
setIsSwitchOn(
|
||||||
|
subAdminByIdData?.data?.role[0]?.role ===
|
||||||
|
encryptString(import.meta.env.VITE_VITE_MAKER)
|
||||||
|
);
|
||||||
|
console.log(subAdminByIdData?.data?.role);
|
||||||
|
}
|
||||||
|
}, [subAdminByIdData, reset]);
|
||||||
|
|
||||||
|
if (false) {
|
||||||
|
return <FullscreenLoaders />;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================ [API]===============================
|
||||||
|
|
||||||
|
const handleConfirm = async () => {
|
||||||
|
setIsLoadingBtn(true);
|
||||||
|
const id = params?.id;
|
||||||
|
console.log(isSwitchOn);
|
||||||
|
|
||||||
|
if (id) {
|
||||||
|
try {
|
||||||
|
const formData = {
|
||||||
|
...form,
|
||||||
|
// role_xid: !isSwitchOn ? 1 : 2,
|
||||||
|
};
|
||||||
|
await updateSubAdmin({ data: formData, id }).then((response) => {
|
||||||
|
if (response?.data?.statusCode) {
|
||||||
|
toast({
|
||||||
|
render: () => <ToastBox message={response?.data?.message} />,
|
||||||
|
});
|
||||||
|
|
||||||
|
setIsLoadingBtn(false);
|
||||||
|
setAlert(false);
|
||||||
|
navigate("/subadmin");
|
||||||
|
} else if (response?.error?.status === 400) {
|
||||||
|
toast({
|
||||||
|
render: () => (
|
||||||
|
<ToastBox
|
||||||
|
message={response?.error?.data?.message}
|
||||||
|
status={"error"}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
});
|
||||||
|
|
||||||
|
setIsLoadingBtn(false);
|
||||||
|
setAlert(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
setIsLoadingBtn(false);
|
||||||
|
navigate("/subadmin");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
const formData = {
|
||||||
|
...form,
|
||||||
|
role_xid: isSwitchOn ? 1 : 2,
|
||||||
|
};
|
||||||
|
await createSubAdmin(formData).then((response) => {
|
||||||
|
console.log(response);
|
||||||
|
if (response?.data?.statusCode === 201) {
|
||||||
|
toast({
|
||||||
|
render: () => <ToastBox message={response?.data?.message} />,
|
||||||
|
});
|
||||||
|
|
||||||
|
setIsLoadingBtn(false);
|
||||||
|
navigate("/subadmin");
|
||||||
|
} else if (response?.error?.status === 400) {
|
||||||
|
toast({
|
||||||
|
render: () => (
|
||||||
|
<ToastBox
|
||||||
|
message={response?.error?.data?.message}
|
||||||
|
status={"error"}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
});
|
||||||
|
|
||||||
|
setIsLoadingBtn(false);
|
||||||
|
setAlert(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
|
||||||
|
setIsLoadingBtn(false);
|
||||||
|
navigate("/subadmin");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// ====================== [Update Form Object] =========================
|
||||||
|
|
||||||
|
const formFields = [
|
||||||
|
{
|
||||||
|
label: "First Name",
|
||||||
|
placeHolder: " ",
|
||||||
|
name: "firstName",
|
||||||
|
type: "text",
|
||||||
|
isRequired: true,
|
||||||
|
section: "",
|
||||||
|
maxLength: 50,
|
||||||
|
helperText: `Maximum length should be 50 characters. You have entered ${
|
||||||
|
watch()?.firstName?.length || 0
|
||||||
|
} characters.`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Last Name",
|
||||||
|
name: "lastName",
|
||||||
|
placeHolder: " ",
|
||||||
|
type: "text",
|
||||||
|
isRequired: true,
|
||||||
|
section: "",
|
||||||
|
maxLength: 55,
|
||||||
|
helperText: `Maximum length should be 55 characters. You have entered ${
|
||||||
|
watch()?.lastName?.length || 0
|
||||||
|
} characters.`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Email address",
|
||||||
|
name: "emailAddress",
|
||||||
|
placeHolder: " ",
|
||||||
|
type: "email",
|
||||||
|
// isRequired: true,
|
||||||
|
section: "",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
// ==================== [Create Form Object] =======================
|
||||||
|
|
||||||
|
const formEditFields = [
|
||||||
|
{
|
||||||
|
label: "First Name",
|
||||||
|
placeHolder: " ",
|
||||||
|
name: "firstName",
|
||||||
|
type: "text",
|
||||||
|
isRequired: true,
|
||||||
|
section: "",
|
||||||
|
maxLength: 55,
|
||||||
|
helperText: `Maximum length should be 55 characters. You have entered ${
|
||||||
|
watch()?.firstName?.length || 0
|
||||||
|
} characters.`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Last Name",
|
||||||
|
name: "lastName",
|
||||||
|
placeHolder: " ",
|
||||||
|
type: "text",
|
||||||
|
isRequired: true,
|
||||||
|
section: "",
|
||||||
|
maxLength: 55,
|
||||||
|
helperText: `Maximum length should be 55 characters. You have entered ${
|
||||||
|
watch()?.lastName?.length || 0
|
||||||
|
} characters.`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Email Address",
|
||||||
|
name: "emailAddress",
|
||||||
|
placeHolder: " ",
|
||||||
|
type: "email",
|
||||||
|
// isRequired: true,
|
||||||
|
section: "",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
// ====================== [Group Create Fields] =========================
|
||||||
|
|
||||||
|
const groupedEditFields = formEditFields.reduce((groups, field) => {
|
||||||
|
const { section } = field;
|
||||||
|
if (!groups[section]) {
|
||||||
|
groups[section] = [];
|
||||||
|
}
|
||||||
|
groups[section].push(field);
|
||||||
|
return groups;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
// ====================== [Group Update Fields] =======================
|
||||||
|
|
||||||
|
const groupedFields = formFields.reduce((groups, field) => {
|
||||||
|
const { section } = field;
|
||||||
|
if (!groups[section]) {
|
||||||
|
groups[section] = [];
|
||||||
|
}
|
||||||
|
groups[section].push(field);
|
||||||
|
return groups;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
// ==================== [On Submit] ========================
|
||||||
|
console.log(errors);
|
||||||
|
|
||||||
|
const onSubmit = async (data) => {
|
||||||
|
console.log("Hit");
|
||||||
|
|
||||||
|
if (Object.keys(errors).length === 0) {
|
||||||
|
setForm(data);
|
||||||
|
setAlert(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return isLoading ? (
|
||||||
|
<FullscreenLoaders />
|
||||||
|
) : (
|
||||||
|
<Box {...OPACITY_ON_LOAD} overflowY={"scroll"} height={"100vh"} pb={14}>
|
||||||
|
{/* ===================== [Switch Button] ======================== */}
|
||||||
|
<Box
|
||||||
|
display={"flex"}
|
||||||
|
justifyContent={"space-between"}
|
||||||
|
alignItems={"center"}
|
||||||
|
mt={5}
|
||||||
|
px={4}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
fontSize={"sm"}
|
||||||
|
mb={0}
|
||||||
|
onClick={() => navigate(-1)}
|
||||||
|
cursor={"pointer"}
|
||||||
|
>
|
||||||
|
<ArrowBackIcon fontSize={"xl"} me={2} />
|
||||||
|
Add Details
|
||||||
|
</Text>
|
||||||
|
{params?.id ? (
|
||||||
|
""
|
||||||
|
) : (
|
||||||
|
<RoleSwitchButton
|
||||||
|
isSwitchOn={isSwitchOn}
|
||||||
|
setIsSwitchOn={setIsSwitchOn}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
{/* ====================== [Form Input] ====================== */}
|
||||||
|
|
||||||
|
<FormInputMain
|
||||||
|
groupedFields={params?.id ? groupedEditFields : groupedFields}
|
||||||
|
control={control}
|
||||||
|
errors={errors}
|
||||||
|
onSubmit={handleSubmit(onSubmit)}
|
||||||
|
submitTitle={params?.id ? "Update" : "Submit"}
|
||||||
|
></FormInputMain>
|
||||||
|
|
||||||
|
{/* ======================= [Modal] =========================== */}
|
||||||
|
|
||||||
|
<CustomAlertDialog
|
||||||
|
isOpen={alert}
|
||||||
|
onClose={() => setAlert(false)}
|
||||||
|
alertHandler={handleConfirm}
|
||||||
|
message={
|
||||||
|
id
|
||||||
|
? "Are you sure you want to update this?"
|
||||||
|
: "Are you sure you want to add this?"
|
||||||
|
}
|
||||||
|
isLoading={isLoadingBtn}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* <DummyComponent /> */}
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SubAdminUpdateCreate;
|
||||||
@@ -104,25 +104,23 @@ export const nav = [
|
|||||||
title: "INVESTORS REQUEST",
|
title: "INVESTORS REQUEST",
|
||||||
type: "title",
|
type: "title",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Fawateer Deposit",
|
title: "Fawateer Deposit",
|
||||||
submenu: [
|
submenu: [
|
||||||
{
|
{
|
||||||
title: "Aprover Request",
|
title: "Aprover Request",
|
||||||
path: "/fawateer",
|
path: "/fawateer",
|
||||||
icon: RiMoneyDollarBoxLine,
|
icon: RiMoneyDollarBoxLine,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "View History",
|
title: "View History",
|
||||||
path: "/fawateer-history",
|
path: "/fawateer-history",
|
||||||
icon: RiExchangeBoxLine,
|
icon: RiExchangeBoxLine,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
type: "accordion",
|
type: "accordion",
|
||||||
Icon: HiOutlineBanknotes,
|
Icon: HiOutlineBanknotes,
|
||||||
}
|
},
|
||||||
,
|
|
||||||
|
|
||||||
{
|
{
|
||||||
title: "Bank Deposit",
|
title: "Bank Deposit",
|
||||||
submenu: [
|
submenu: [
|
||||||
@@ -233,6 +231,11 @@ export const nav = [
|
|||||||
path: "/bank-details",
|
path: "/bank-details",
|
||||||
icon: RiBankLine,
|
icon: RiBankLine,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: "Sub Admin",
|
||||||
|
path: "/subadmin",
|
||||||
|
icon: RiFileUserLine,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
type: "accordion",
|
type: "accordion",
|
||||||
Icon: MdOutlineAdminPanelSettings,
|
Icon: MdOutlineAdminPanelSettings,
|
||||||
|
|||||||
@@ -46,6 +46,8 @@ import EmailNotification from "../Pages/EmailNotification/EmailNotification";
|
|||||||
import User from "../Pages/User/User";
|
import User from "../Pages/User/User";
|
||||||
import AddUser from "../Pages/User/AddUser";
|
import AddUser from "../Pages/User/AddUser";
|
||||||
import Profile from "../Pages/Profile/Profile";
|
import Profile from "../Pages/Profile/Profile";
|
||||||
|
import SubAdmin from "../Pages/SubAdmin/SubAdmin";
|
||||||
|
import SubAdminUpdateCreate from "../Pages/SubAdmin/SubAdminUpdateCreate";
|
||||||
|
|
||||||
export const RouteLink = [
|
export const RouteLink = [
|
||||||
// =============[ Tanami ]================
|
// =============[ Tanami ]================
|
||||||
@@ -123,6 +125,9 @@ export const RouteLink = [
|
|||||||
// { path: "/bank-details", Component: UnderConstruction },
|
// { path: "/bank-details", Component: UnderConstruction },
|
||||||
{ path: "/bank-details/edit-bank-details/:id", Component: EditBankDetails },
|
{ path: "/bank-details/edit-bank-details/:id", Component: EditBankDetails },
|
||||||
{ path: "/profile", Component: Profile },
|
{ path: "/profile", Component: Profile },
|
||||||
|
{ path: "/subadmin", Component: SubAdmin },
|
||||||
|
{ path: "/subadmin/subadmin-update/:id", Component: SubAdminUpdateCreate },
|
||||||
|
{ path: "/subadmin/subadmin-update", Component: SubAdminUpdateCreate },
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -134,8 +139,5 @@ export const RouteLink = [
|
|||||||
// { path: "/fawateer-approver", Component: ApproveRequest },
|
// { path: "/fawateer-approver", Component: ApproveRequest },
|
||||||
// { path: "/approver-history", Component: ApproveHistory },
|
// { path: "/approver-history", Component: ApproveHistory },
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|||||||
30
src/Services/change.password.service.js
Normal file
30
src/Services/change.password.service.js
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
|
||||||
|
// 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 changePasswordMake = createApi({
|
||||||
|
reducerPath: "changePassword",
|
||||||
|
baseQuery: baseQuery,
|
||||||
|
tagTypes: ["getPassword"],
|
||||||
|
endpoints: (builder) => ({
|
||||||
|
// // ========[ update ]========
|
||||||
|
updatePassword: builder.mutation({
|
||||||
|
query: (data) => ({
|
||||||
|
url: `/auth/admin/update-password`,
|
||||||
|
method: "POST",
|
||||||
|
body: data,
|
||||||
|
}),
|
||||||
|
invalidatesTags: ["getPassword"],
|
||||||
|
}),
|
||||||
|
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
// Export hooks for usage in functional components
|
||||||
|
export const {
|
||||||
|
useUpdatePasswordMutation
|
||||||
|
} = changePasswordMake;
|
||||||
30
src/Services/forget.password.service.js
Normal file
30
src/Services/forget.password.service.js
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
|
||||||
|
// Need to use the React-specific entry point to import createApi
|
||||||
|
import { createApi} from "@reduxjs/toolkit/query/react";
|
||||||
|
import { baseQuery } from "./token.serivce";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Define a service using a base URL and expected endpoints
|
||||||
|
export const forgetPasswordMake = createApi({
|
||||||
|
reducerPath: "forgetPassword",
|
||||||
|
baseQuery: baseQuery,
|
||||||
|
tagTypes: ["getPassword"],
|
||||||
|
endpoints: (builder) => ({
|
||||||
|
// // ========[ update ]========
|
||||||
|
forgetPassword: builder.mutation({
|
||||||
|
query: (data) => ({
|
||||||
|
url: `/auth/admin/forget-password`,
|
||||||
|
method: "POST",
|
||||||
|
body: data,
|
||||||
|
}),
|
||||||
|
invalidatesTags: ["getPassword"],
|
||||||
|
}),
|
||||||
|
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
// Export hooks for usage in functional components
|
||||||
|
export const {
|
||||||
|
useForgetPasswordMutation
|
||||||
|
} = forgetPasswordMake;
|
||||||
98
src/Services/subadmin.service.js
Normal file
98
src/Services/subadmin.service.js
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
|
||||||
|
// 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 sabAdminMaster = createApi({
|
||||||
|
reducerPath: "sabAdminMaster",
|
||||||
|
baseQuery: baseQuery,
|
||||||
|
tagTypes: ["getSubAdmin", "prePopulate"],
|
||||||
|
endpoints: (builder) => ({
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ======[Get All]=====
|
||||||
|
|
||||||
|
getSubAdminMaster: builder.query({
|
||||||
|
query: () => `/subadmin/admin/getAll`,
|
||||||
|
providesTags: ["getSubAdmin"],
|
||||||
|
}),
|
||||||
|
|
||||||
|
// // ========[ Create ]========
|
||||||
|
|
||||||
|
createSubAdmin: builder.mutation({
|
||||||
|
query: (data) => ({
|
||||||
|
url: `/subadmin/admin/create`,
|
||||||
|
method: "POST",
|
||||||
|
body: data,
|
||||||
|
}),
|
||||||
|
invalidatesTags: ["getSubAdmin","prePopulate"],
|
||||||
|
}),
|
||||||
|
|
||||||
|
// // ========[Update Sponser]========
|
||||||
|
|
||||||
|
updateSubAdmin: builder.mutation({
|
||||||
|
query: ({ data, id }) => ({
|
||||||
|
url: `/subadmin/admin/${id}`,
|
||||||
|
method: "PATCH",
|
||||||
|
body: data,
|
||||||
|
}),
|
||||||
|
invalidatesTags: ["getSubAdmin"],
|
||||||
|
}),
|
||||||
|
|
||||||
|
getSubAdminById: builder.query({
|
||||||
|
query: (id) => `/subadmin/admin/${id}`,
|
||||||
|
}),
|
||||||
|
|
||||||
|
// // ========[Toggle Status]========
|
||||||
|
|
||||||
|
toggleStatus: builder.mutation({
|
||||||
|
query: ({id, data}) => ({
|
||||||
|
url: `/subadmin/admin/toggle-role/${id}`,
|
||||||
|
method: "PATCH",
|
||||||
|
body: data,
|
||||||
|
}),
|
||||||
|
invalidatesTags: ["getSubAdmin"],
|
||||||
|
}),
|
||||||
|
|
||||||
|
// // ========[Get Active]========
|
||||||
|
|
||||||
|
// getActiveSponserMaster: builder.query({
|
||||||
|
// query: () => `/sponsor/admin/active`,
|
||||||
|
// }),
|
||||||
|
|
||||||
|
// 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 const {
|
||||||
|
useGetSubAdminMasterQuery,
|
||||||
|
useCreateSubAdminMutation,
|
||||||
|
useUpdateSubAdminMutation,
|
||||||
|
useGetSubAdminByIdQuery,
|
||||||
|
useToggleStatusMutation
|
||||||
|
} = sabAdminMaster;
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
|
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
|
||||||
|
import { encryptString } from '../Constants/Constants'
|
||||||
|
|
||||||
// Define a base query function with RTK Query
|
// Define a base query function with RTK Query
|
||||||
// export const baseQuery = fetchBaseQuery({
|
// export const baseQuery = fetchBaseQuery({
|
||||||
@@ -100,7 +101,7 @@ export const apiSlice = createApi({
|
|||||||
localStorage.setItem("refreshToken", data?.data?.refresh?.token);
|
localStorage.setItem("refreshToken", data?.data?.refresh?.token);
|
||||||
// localStorage.setItem('refreshTokenExp', data?.data?.refresh?.expires);
|
// localStorage.setItem('refreshTokenExp', data?.data?.refresh?.expires);
|
||||||
localStorage.setItem("accessTokenExp", data?.data?.access?.expires);
|
localStorage.setItem("accessTokenExp", data?.data?.access?.expires);
|
||||||
localStorage.setItem("role", data?.data?.role);
|
localStorage.setItem("role", encryptString(data?.data?.role));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Login failed:", error);
|
console.error("Login failed:", error);
|
||||||
}
|
}
|
||||||
@@ -126,6 +127,6 @@ export const apiSlice = createApi({
|
|||||||
|
|
||||||
|
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const { useLoginMutation, useRefreshTokenMutation, useLogoutMutation } = apiSlice;
|
export const { useLoginMutation, useRefreshTokenMutation, useLogoutMutation } = apiSlice;
|
||||||
|
|||||||
@@ -17,6 +17,9 @@ import { deleteRequest } from "../Services/delete.request.service";
|
|||||||
import { banInvestorDetails } from "../Services/ban.investor.service";
|
import { banInvestorDetails } from "../Services/ban.investor.service";
|
||||||
import { fawateerRequest } from "../Services/fawateer.request.service";
|
import { fawateerRequest } from "../Services/fawateer.request.service";
|
||||||
import { fawateerMaker } from "../Services/fawateer.maker.service";
|
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";
|
||||||
|
|
||||||
export const store = configureStore({
|
export const store = configureStore({
|
||||||
reducer: {
|
reducer: {
|
||||||
@@ -35,6 +38,9 @@ export const store = configureStore({
|
|||||||
[banInvestorDetails.reducerPath]: banInvestorDetails.reducer,
|
[banInvestorDetails.reducerPath]: banInvestorDetails.reducer,
|
||||||
[fawateerRequest.reducerPath]: fawateerRequest.reducer,
|
[fawateerRequest.reducerPath]: fawateerRequest.reducer,
|
||||||
[fawateerMaker.reducerPath]: fawateerMaker.reducer,
|
[fawateerMaker.reducerPath]: fawateerMaker.reducer,
|
||||||
|
[sabAdminMaster.reducerPath]: sabAdminMaster.reducer,
|
||||||
|
[changePasswordMake.reducerPath]: changePasswordMake.reducer,
|
||||||
|
[forgetPasswordMake.reducerPath]: forgetPasswordMake.reducer,
|
||||||
|
|
||||||
// Add other reducers as needed
|
// Add other reducers as needed
|
||||||
},
|
},
|
||||||
@@ -59,7 +65,9 @@ export const store = configureStore({
|
|||||||
banInvestorDetails.middleware,
|
banInvestorDetails.middleware,
|
||||||
fawateerRequest.middleware,
|
fawateerRequest.middleware,
|
||||||
fawateerMaker.middleware,
|
fawateerMaker.middleware,
|
||||||
|
sabAdminMaster.middleware,
|
||||||
|
changePasswordMake.middleware,
|
||||||
|
forgetPasswordMake.middleware,
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user