Merge pull request 'Yasin' (#22) from Yasin into Sprint-9
Reviewed-on: #22
This commit is contained in:
@@ -13,8 +13,9 @@ import {
|
||||
Portal,
|
||||
Text,
|
||||
useColorMode,
|
||||
useDisclosure,
|
||||
} from "@chakra-ui/react";
|
||||
import React, { useContext } from "react";
|
||||
import React, { useContext, useRef } from "react";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
import { IoMdDownload } from "react-icons/io";
|
||||
import * as XLSX from "xlsx";
|
||||
@@ -23,6 +24,7 @@ import GlobalStateContext from "../Contexts/GlobalStateContext";
|
||||
import { MdOutlineDarkMode, MdOutlineLightMode } from "react-icons/md";
|
||||
import logoMini from "../assets/propic.png";
|
||||
import { BsBack } from "react-icons/bs";
|
||||
import ChangePassword from "../Pages/ChangePassword";
|
||||
|
||||
const HeaderMain = ({
|
||||
link,
|
||||
@@ -35,6 +37,8 @@ const HeaderMain = ({
|
||||
}) => {
|
||||
const navigate = useNavigate();
|
||||
const { colorMode, toggleColorMode } = useContext(GlobalStateContext);
|
||||
const { isOpen, onOpen, onClose } = useDisclosure();
|
||||
const firstField = useRef();
|
||||
|
||||
return (
|
||||
<Box
|
||||
@@ -66,11 +70,11 @@ const HeaderMain = ({
|
||||
<PopoverBody onClick={()=> navigate('/profile')} className="web-text-medium pointer link">
|
||||
Profile
|
||||
</PopoverBody>
|
||||
<Link to={"/help-and-support"}>
|
||||
<Box onClick={onOpen}>
|
||||
<PopoverBody className="web-text-medium pointer ">
|
||||
Help & Support
|
||||
Change Password
|
||||
</PopoverBody>
|
||||
</Link>
|
||||
</Box>
|
||||
<PopoverFooter
|
||||
onClick={logOutHandler}
|
||||
className="web-text-medium pointer link"
|
||||
@@ -112,6 +116,11 @@ const HeaderMain = ({
|
||||
{/* <Box onClick={() => toggleColorMode()} as="span" p={2} rounded={'lg'} className="link pointer">
|
||||
{colorMode === "light"? <MdOutlineDarkMode /> :<MdOutlineLightMode />}
|
||||
</Box> */}
|
||||
<ChangePassword
|
||||
isOpen={isOpen}
|
||||
onClose={onClose}
|
||||
firstField={firstField}
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
|
||||
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;
|
||||
202
src/Pages/ChangePassword.jsx
Normal file
202
src/Pages/ChangePassword.jsx
Normal file
@@ -0,0 +1,202 @@
|
||||
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, useEffect, useContext } from "react";
|
||||
import { useForm, Controller } from "react-hook-form";
|
||||
import { yupResolver } from "@hookform/resolvers/yup";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { useParams } from "react-router-dom";
|
||||
import CustomAlertDialog from "../Components/CustomAlertDialog";
|
||||
import ToastBox from "../Components/ToastBox";
|
||||
import GlobalStateContext from "../Contexts/GlobalStateContext";
|
||||
import CurrencyInput from "../Components/CurrencyInput";
|
||||
|
||||
const ioNav = yup.object().shape({
|
||||
transactionDate: yup.string().required("Date is required"),
|
||||
transactionAmount: yup.string().required("New NAV is required"),
|
||||
comments: yup
|
||||
.string()
|
||||
.notRequired()
|
||||
.max(200, "Approve Comment cannot be more than 200 characters"),
|
||||
});
|
||||
|
||||
const ChangePassword = ({
|
||||
isOpen,
|
||||
onClose,
|
||||
firstField,
|
||||
actionId,
|
||||
setActionId,
|
||||
data,
|
||||
}) => {
|
||||
const params = useParams();
|
||||
const id = params?.id;
|
||||
const [file, setFile] = useState("");
|
||||
const [fileName, setFileName] = useState("");
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [alert, setAlert] = useState(false);
|
||||
const toast = useToast();
|
||||
|
||||
const [showPassword, setShowPassword] = useState(false);
|
||||
const [subject, setSubject] = useState("");
|
||||
const togglePasswordVisibility = () => setShowPassword(!showPassword);
|
||||
// ======================[ Cotext Api ]
|
||||
const { IODetails } = useContext(GlobalStateContext);
|
||||
const found = data?.find((item) => item?.id === actionId);
|
||||
|
||||
// const [addNavDetails] = useAddNavDetailsMutation()
|
||||
// const {
|
||||
// data
|
||||
// } = useGetArtifactsQuery(id)
|
||||
|
||||
const {
|
||||
control,
|
||||
handleSubmit,
|
||||
watch,
|
||||
reset,
|
||||
formState: { errors },
|
||||
} = useForm({
|
||||
resolver: yupResolver(ioNav),
|
||||
});
|
||||
|
||||
// const onSubmit = async (data) => {
|
||||
// setIsLoading(true);
|
||||
|
||||
// try {
|
||||
// const res = await addNavDetails({ data, id });
|
||||
// if (res?.data?.statusCode === 201) {
|
||||
// setIsLoading(false);
|
||||
// toast({
|
||||
// render: () => <ToastBox message={res?.data?.message} />,
|
||||
// });
|
||||
// handleClose();
|
||||
// } else if (res?.error?.status === 400) {
|
||||
// toast({
|
||||
// render: () => (
|
||||
// <ToastBox message={res?.error?.data?.message} status={"error"} />
|
||||
// ),
|
||||
// });
|
||||
// handleClose();
|
||||
// }
|
||||
// } catch (error) {
|
||||
// console.log(error);
|
||||
// }
|
||||
// };
|
||||
|
||||
const handleSave = () => {
|
||||
handleSubmit(onSubmit)();
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
setIsLoading(false);
|
||||
setAlert(false);
|
||||
onClose();
|
||||
};
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<Modal
|
||||
// closeOnOverlayClick={false}
|
||||
isOpen={isOpen}
|
||||
onClose={onClose}
|
||||
initialFocusRef={firstField}
|
||||
>
|
||||
<ModalOverlay />
|
||||
<ModalContent>
|
||||
<ModalHeader fontSize={"md"}>Change Password</ModalHeader>
|
||||
<ModalCloseButton />
|
||||
<ModalBody pb={6}>
|
||||
<Stack spacing={4}>
|
||||
<FormControl isInvalid={errors.ChangePassword} isRequired>
|
||||
<FormLabel fontSize={"sm"} mb={1} fontWeight={500}>Current Password</FormLabel>
|
||||
<Input
|
||||
size={"sm"}
|
||||
onChange={(e) => setSubject(e.target.value)}
|
||||
focusBorderColor="forestGreen.300"
|
||||
rounded={4}
|
||||
type={showPassword ? "text" : "password"}
|
||||
/>
|
||||
<FormErrorMessage fontSize={"xs"} fontWeight={500}>
|
||||
{errors.ChangePassword?.message}
|
||||
</FormErrorMessage>
|
||||
</FormControl>
|
||||
<FormControl isInvalid={errors.newPassword} isRequired>
|
||||
<FormLabel fontSize={"sm"} mb={1}>New Password</FormLabel>
|
||||
<Input
|
||||
size={"sm"}
|
||||
onChange={(e) => setSubject(e.target.value)}
|
||||
focusBorderColor="forestGreen.300"
|
||||
rounded={4}
|
||||
type="text"
|
||||
/>
|
||||
<FormErrorMessage fontSize={"xs"} fontWeight={500}>
|
||||
{errors.newPassword?.message}
|
||||
</FormErrorMessage>
|
||||
</FormControl>
|
||||
<FormControl isInvalid={errors.conformPassword} isRequired>
|
||||
<FormLabel fontSize={"sm"} mb={1}>Re-Type New Password</FormLabel>
|
||||
<Input
|
||||
size={"sm"}
|
||||
onChange={(e) => setSubject(e.target.value)}
|
||||
focusBorderColor="forestGreen.300"
|
||||
rounded={4}
|
||||
type="text"
|
||||
/>
|
||||
<FormErrorMessage fontSize={"xs"} fontWeight={500}>
|
||||
{errors.conformPassword?.message}
|
||||
</FormErrorMessage>
|
||||
</FormControl>
|
||||
</Stack>
|
||||
</ModalBody>
|
||||
|
||||
<DrawerFooter mb={5}>
|
||||
<Button
|
||||
// variant="outline"
|
||||
bg={"#e0ebeb"}
|
||||
rounded={"sm"}
|
||||
size={"sm"}
|
||||
mr={3}
|
||||
onClick={handleClose}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
colorScheme={"forestGreen"}
|
||||
rounded={"sm"}
|
||||
size={"sm"}
|
||||
onClick={() => setAlert(true)}
|
||||
fontWeight={400}
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
</DrawerFooter>
|
||||
</ModalContent>
|
||||
</Modal>
|
||||
|
||||
<CustomAlertDialog
|
||||
isOpen={alert}
|
||||
onClose={() => setAlert(false)}
|
||||
alertHandler={handleSave}
|
||||
message={"Are you sure you want to change password?"}
|
||||
isLoading={isLoading}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default ChangePassword;
|
||||
178
src/Pages/ForgetPassword.jsx
Normal file
178
src/Pages/ForgetPassword.jsx
Normal file
@@ -0,0 +1,178 @@
|
||||
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, useEffect, useContext } from "react";
|
||||
import { useForm, Controller } from "react-hook-form";
|
||||
import { yupResolver } from "@hookform/resolvers/yup";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { useParams } from "react-router-dom";
|
||||
import CustomAlertDialog from "../Components/CustomAlertDialog";
|
||||
import ToastBox from "../Components/ToastBox";
|
||||
import GlobalStateContext from "../Contexts/GlobalStateContext";
|
||||
import CurrencyInput from "../Components/CurrencyInput";
|
||||
|
||||
const ioNav = yup.object().shape({
|
||||
transactionDate: yup.string().required("Date is required"),
|
||||
transactionAmount: yup.string().required("New NAV is required"),
|
||||
comments: yup
|
||||
.string()
|
||||
.notRequired()
|
||||
.max(200, "Approve Comment cannot be more than 200 characters"),
|
||||
});
|
||||
|
||||
const ForgetPassword = ({
|
||||
isOpen,
|
||||
onClose,
|
||||
firstField,
|
||||
actionId,
|
||||
setActionId,
|
||||
data,
|
||||
}) => {
|
||||
const params = useParams();
|
||||
const id = params?.id;
|
||||
const [file, setFile] = useState("");
|
||||
const [fileName, setFileName] = useState("");
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [alert, setAlert] = useState(false);
|
||||
const toast = useToast();
|
||||
|
||||
const [showPassword, setShowPassword] = useState(false);
|
||||
const [subject, setSubject] = useState("");
|
||||
// ======================[ Cotext Api ]
|
||||
const { IODetails } = useContext(GlobalStateContext);
|
||||
const found = data?.find((item) => item?.id === actionId);
|
||||
|
||||
// const [addNavDetails] = useAddNavDetailsMutation()
|
||||
// const {
|
||||
// data
|
||||
// } = useGetArtifactsQuery(id)
|
||||
|
||||
const {
|
||||
control,
|
||||
handleSubmit,
|
||||
watch,
|
||||
reset,
|
||||
formState: { errors },
|
||||
} = useForm({
|
||||
resolver: yupResolver(ioNav),
|
||||
});
|
||||
|
||||
// const onSubmit = async (data) => {
|
||||
// setIsLoading(true);
|
||||
|
||||
// try {
|
||||
// const res = await addNavDetails({ data, id });
|
||||
// if (res?.data?.statusCode === 201) {
|
||||
// setIsLoading(false);
|
||||
// toast({
|
||||
// render: () => <ToastBox message={res?.data?.message} />,
|
||||
// });
|
||||
// handleClose();
|
||||
// } else if (res?.error?.status === 400) {
|
||||
// toast({
|
||||
// render: () => (
|
||||
// <ToastBox message={res?.error?.data?.message} status={"error"} />
|
||||
// ),
|
||||
// });
|
||||
// handleClose();
|
||||
// }
|
||||
// } catch (error) {
|
||||
// console.log(error);
|
||||
// }
|
||||
// };
|
||||
|
||||
const handleSave = () => {
|
||||
handleSubmit(onSubmit)();
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
setIsLoading(false);
|
||||
setAlert(false);
|
||||
onClose();
|
||||
};
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<Modal
|
||||
// closeOnOverlayClick={false}
|
||||
isOpen={isOpen}
|
||||
onClose={onClose}
|
||||
initialFocusRef={firstField}
|
||||
>
|
||||
<ModalOverlay />
|
||||
<ModalContent>
|
||||
<ModalHeader fontSize={"md"}>Forget Password</ModalHeader>
|
||||
<ModalCloseButton />
|
||||
<ModalBody pb={4}>
|
||||
<Stack spacing={4}>
|
||||
<FormControl isInvalid={errors.ChangePassword}>
|
||||
<FormLabel fontSize={"sm"} mb={3} fontWeight={500}>Email, Phone, or UserName</FormLabel>
|
||||
<Input
|
||||
size={"md"}
|
||||
onChange={(e) => setSubject(e.target.value)}
|
||||
focusBorderColor="forestGreen.300"
|
||||
rounded={4}
|
||||
// type={showPassword ? "text" : "password"}
|
||||
type="text"
|
||||
/>
|
||||
<FormErrorMessage fontSize={"xs"} fontWeight={500}>
|
||||
{errors.ChangePassword?.message}
|
||||
</FormErrorMessage>
|
||||
</FormControl>
|
||||
</Stack>
|
||||
</ModalBody>
|
||||
|
||||
<DrawerFooter mb={5}>
|
||||
{/* <Button
|
||||
// variant="outline"
|
||||
bg={"#e0ebeb"}
|
||||
rounded={"sm"}
|
||||
size={"sm"}
|
||||
mr={3}
|
||||
onClick={handleClose}
|
||||
>
|
||||
Cancel
|
||||
</Button> */}
|
||||
|
||||
<Button
|
||||
w={"100%"}
|
||||
colorScheme={"forestGreen"}
|
||||
rounded={"md"}
|
||||
size={"md"}
|
||||
onClick={() => setAlert(true)}
|
||||
fontWeight={400}
|
||||
>
|
||||
Send Login Link
|
||||
</Button>
|
||||
</DrawerFooter>
|
||||
</ModalContent>
|
||||
</Modal>
|
||||
|
||||
<CustomAlertDialog
|
||||
isOpen={alert}
|
||||
onClose={() => setAlert(false)}
|
||||
alertHandler={handleSave}
|
||||
message={"Are you sure you want to change password?"}
|
||||
isLoading={isLoading}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default ForgetPassword;
|
||||
|
||||
@@ -4,10 +4,7 @@ import {
|
||||
Box,
|
||||
Button,
|
||||
HStack,
|
||||
Input,
|
||||
Table,
|
||||
Tag,
|
||||
Tbody,
|
||||
Input,
|
||||
Text,
|
||||
Th,
|
||||
Tooltip,
|
||||
@@ -22,7 +19,7 @@ import { OPACITY_ON_LOAD } from "../../../../Layout/animations";
|
||||
import NormalTable from "../../../../Components/DataTable/NormalTable";
|
||||
import GlobalStateContext from "../../../../Contexts/GlobalStateContext";
|
||||
import CustomAlertDialog from "../../../../Components/CustomAlertDialog";
|
||||
import * as XLSX from "xlsx";
|
||||
import * as XLSX from "xlsx";
|
||||
import ToastBox from "../../../../Components/ToastBox";
|
||||
import AddCashDetails from "../AddCashDetails";
|
||||
import { debounce } from "../../../Admin/Contact";
|
||||
|
||||
@@ -182,7 +182,7 @@ const Investors = ({ data }) => {
|
||||
{item?.clientReference_id}
|
||||
</Text>
|
||||
),
|
||||
"First name": (
|
||||
"First Name": (
|
||||
<Text
|
||||
justifyContent={slideFromRight ? "right" : "center"}
|
||||
as={"span"}
|
||||
@@ -193,7 +193,7 @@ const Investors = ({ data }) => {
|
||||
{item.firstName}
|
||||
</Text>
|
||||
),
|
||||
"Last name": (
|
||||
"Last Name": (
|
||||
<Text
|
||||
justifyContent={slideFromRight ? "right" : "center"}
|
||||
as={"span"}
|
||||
@@ -204,7 +204,7 @@ const Investors = ({ data }) => {
|
||||
{item.lastName}
|
||||
</Text>
|
||||
),
|
||||
"Investment amount": (
|
||||
"Investment Amount": (
|
||||
<Text
|
||||
justifyContent={slideFromRight ? "right" : "left"}
|
||||
as={"span"}
|
||||
@@ -313,7 +313,7 @@ const Investors = ({ data }) => {
|
||||
})}`}
|
||||
</Text>
|
||||
),
|
||||
"Total return on Investment": (
|
||||
"Total Return on Investment": (
|
||||
<Text
|
||||
justifyContent={slideFromRight ? "right" : "center"}
|
||||
as={"span"}
|
||||
|
||||
@@ -3,7 +3,7 @@ import Input01 from "../Components/Inputs/Input01";
|
||||
import logo from "../assets/logo2.png";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
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 { yupResolver } from "@hookform/resolvers/yup";
|
||||
import { useForm } from "react-hook-form";
|
||||
@@ -12,12 +12,15 @@ import Loader01 from "../Components/Loaders/Loader01";
|
||||
import Asset1 from "../assets/asset1.png";
|
||||
import Asset2 from "../assets/asset2.png";
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
FormControl,
|
||||
FormLabel,
|
||||
Input,
|
||||
InputGroup,
|
||||
InputRightElement,
|
||||
Text,
|
||||
useDisclosure,
|
||||
useToast,
|
||||
} from "@chakra-ui/react";
|
||||
import GlobalStateContext from "../Contexts/GlobalStateContext";
|
||||
@@ -28,6 +31,7 @@ import { useLoginMutation } from "../Services/token.serivce";
|
||||
|
||||
// import { yupResolver } from "@hookform/resolvers/yup";
|
||||
import * as Yup from "yup";
|
||||
import ForgetPassword from "./ForgetPassword";
|
||||
|
||||
|
||||
const validationSchema = Yup.object().shape({
|
||||
@@ -50,6 +54,8 @@ const Login = () => {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const [login] = useLoginMutation()
|
||||
const { isOpen, onOpen, onClose } = useDisclosure();
|
||||
const firstField = useRef();
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@@ -205,7 +211,7 @@ const Login = () => {
|
||||
)}
|
||||
</FormControl>
|
||||
|
||||
<FormControl className="mb-4">
|
||||
<FormControl className="mb-2">
|
||||
<FormLabel className="rubix-text-dark ps-1 web-text-medium fw-bold">
|
||||
Password <span className="text-danger">*</span>
|
||||
</FormLabel>
|
||||
@@ -238,6 +244,9 @@ const Login = () => {
|
||||
</span>
|
||||
)}
|
||||
</FormControl>
|
||||
<Box fontSize={"sm"} display={"flex"} justifyContent={"end"} mt={0}>
|
||||
<Text fontWeight={500} cursor={"pointer"} onClick={onOpen}>Forget Password?</Text>
|
||||
</Box>
|
||||
|
||||
<Button
|
||||
isLoading={isLoading}
|
||||
@@ -317,6 +326,11 @@ const Login = () => {
|
||||
src={Asset2}
|
||||
alt="bg-img"
|
||||
/>
|
||||
<ForgetPassword
|
||||
isOpen={isOpen}
|
||||
onClose={onClose}
|
||||
firstField={firstField}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
375
src/Pages/SubAdmin/SubAdmin.jsx
Normal file
375
src/Pages/SubAdmin/SubAdmin.jsx
Normal file
@@ -0,0 +1,375 @@
|
||||
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 ? 1 : 2,
|
||||
};
|
||||
try {
|
||||
const res = await toggleStatus(id, data).unwrap();
|
||||
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 minW={24} isTruncated={true}>
|
||||
<Badge
|
||||
py={"2px"}
|
||||
px={"5px"}
|
||||
me={2}
|
||||
bg={item?.role[0]?.role === "Maker" ? "#00ffcc" : "#b3ff99"}
|
||||
>
|
||||
{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;
|
||||
354
src/Pages/SubAdmin/SubAdminUpdateCreate.jsx
Normal file
354
src/Pages/SubAdmin/SubAdminUpdateCreate.jsx
Normal file
@@ -0,0 +1,354 @@
|
||||
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";
|
||||
// ======================= [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==="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?2:1,
|
||||
};
|
||||
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?2:1,
|
||||
};
|
||||
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: "",
|
||||
arabic: true,
|
||||
right: true,
|
||||
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: "",
|
||||
arabic: true,
|
||||
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>
|
||||
<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;
|
||||
@@ -233,6 +233,11 @@ export const nav = [
|
||||
path: "/bank-details",
|
||||
icon: RiBankLine,
|
||||
},
|
||||
{
|
||||
title: "Sub Admin",
|
||||
path: "/subadmin",
|
||||
icon: RiFileUserLine,
|
||||
},
|
||||
],
|
||||
type: "accordion",
|
||||
Icon: MdOutlineAdminPanelSettings,
|
||||
|
||||
@@ -46,6 +46,8 @@ import EmailNotification from "../Pages/EmailNotification/EmailNotification";
|
||||
import User from "../Pages/User/User";
|
||||
import AddUser from "../Pages/User/AddUser";
|
||||
import Profile from "../Pages/Profile/Profile";
|
||||
import SubAdmin from "../Pages/SubAdmin/SubAdmin";
|
||||
import SubAdminUpdateCreate from "../Pages/SubAdmin/SubAdminUpdateCreate";
|
||||
|
||||
export const RouteLink = [
|
||||
// =============[ Tanami ]================
|
||||
@@ -123,6 +125,9 @@ export const RouteLink = [
|
||||
// { path: "/bank-details", Component: UnderConstruction },
|
||||
{ path: "/bank-details/edit-bank-details/:id", Component: EditBankDetails },
|
||||
{ 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: "/approver-history", Component: ApproveHistory },
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
];
|
||||
|
||||
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;
|
||||
@@ -17,6 +17,7 @@ import { deleteRequest } from "../Services/delete.request.service";
|
||||
import { banInvestorDetails } from "../Services/ban.investor.service";
|
||||
import { fawateerRequest } from "../Services/fawateer.request.service";
|
||||
import { fawateerMaker } from "../Services/fawateer.maker.service";
|
||||
import { sabAdminMaster } from "../Services/subadmin.service";
|
||||
|
||||
export const store = configureStore({
|
||||
reducer: {
|
||||
@@ -35,6 +36,7 @@ export const store = configureStore({
|
||||
[banInvestorDetails.reducerPath]: banInvestorDetails.reducer,
|
||||
[fawateerRequest.reducerPath]: fawateerRequest.reducer,
|
||||
[fawateerMaker.reducerPath]: fawateerMaker.reducer,
|
||||
[sabAdminMaster.reducerPath]: sabAdminMaster.reducer,
|
||||
|
||||
// Add other reducers as needed
|
||||
},
|
||||
@@ -59,7 +61,7 @@ export const store = configureStore({
|
||||
banInvestorDetails.middleware,
|
||||
fawateerRequest.middleware,
|
||||
fawateerMaker.middleware,
|
||||
|
||||
sabAdminMaster.middleware,
|
||||
),
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user