From 9c0b231e620d366f552a34e3b991f98184701cdc Mon Sep 17 00:00:00 2001
From: YasinShaikh123 <123150391+YasinShaikh123@users.noreply.github.com>
Date: Mon, 9 Dec 2024 20:10:47 +0530
Subject: [PATCH] update changes
---
src/Layout/DefaultLayout.jsx | 64 +++--
src/Pages/ChangePassword.jsx | 193 ++++++-------
src/Pages/ForgetPassword.jsx | 304 +++++++++-----------
src/Pages/Login.jsx | 2 +
src/Pages/SubAdmin/SubAdminUpdateCreate.jsx | 35 +--
src/Routes/Nav.js | 36 ++-
src/Services/change.password.service.js | 3 -
src/Services/forget.password.service.js | 30 ++
src/Services/token.serivce.js | 2 +-
src/Store/Store.js | 3 +
10 files changed, 329 insertions(+), 343 deletions(-)
create mode 100644 src/Services/forget.password.service.js
diff --git a/src/Layout/DefaultLayout.jsx b/src/Layout/DefaultLayout.jsx
index 7afc70a..0ec59c7 100644
--- a/src/Layout/DefaultLayout.jsx
+++ b/src/Layout/DefaultLayout.jsx
@@ -15,7 +15,12 @@ import {
TbTransactionDollar,
} 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 {
Link,
NavLink,
@@ -83,6 +88,7 @@ import ApproveRequest from "../Pages/FawateerChecker/ApproveRequest/ApproveReque
import ApproveHistoryMaker from "../Pages/FawateerChecker/ApproveHistory/ApproveHistoryMaker";
import ApproveHistory from "../Pages/FawateerChecker/ApproveHistory/ApproveHistoryChecker";
import { useProfileQuery } from "../Services/io.service";
+import SubAdmin from "../Pages/SubAdmin/SubAdmin";
const DashboardLayout = ({ isOnline }) => {
const userRole = localStorage.getItem("role");
@@ -165,24 +171,24 @@ const DashboardLayout = ({ isOnline }) => {
Sponsor
);
- case path.startsWith("/email"):
- return (
-
- Email Notifiation
-
- );
+ case path.startsWith("/email"):
+ return (
+
+ Email Notifiation
+
+ );
case path.startsWith("/investment-type"):
return (
Investment Type
);
- case path.startsWith("/profile"):
- return (
-
- Profile
-
- );
+ case path.startsWith("/profile"):
+ return (
+
+ Profile
+
+ );
case path.startsWith("/exchange-rate"):
return (
@@ -241,7 +247,7 @@ const DashboardLayout = ({ isOnline }) => {
Deposite Request
);
-
+
case path.startsWith("/fawateer"):
return (
@@ -249,13 +255,13 @@ const DashboardLayout = ({ isOnline }) => {
Fawateer Deposit
);
- case path.startsWith("/fawateer-history"):
- return (
-
-
- Fawateer Deposit
-
- );
+ case path.startsWith("/fawateer-history"):
+ return (
+
+
+ Fawateer Deposit
+
+ );
case path.startsWith("/withdraw-request"):
return (
@@ -398,6 +404,19 @@ const DashboardLayout = ({ isOnline }) => {
return ;
}
+ 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 (
{
index={openIndex}
onChange={handleAccordionChange}
>
- {nav.map(({ title, type, Icon, submenu, path }, index) => {
+ {filteredNav.map(({ title, type, Icon, submenu, path }, index) => {
if (type === "accordion") {
return (
@@ -788,6 +807,7 @@ const AppContent = ({ data }) => {
)
}
/>
+
} />
);
diff --git a/src/Pages/ChangePassword.jsx b/src/Pages/ChangePassword.jsx
index d33954b..fa6a898 100644
--- a/src/Pages/ChangePassword.jsx
+++ b/src/Pages/ChangePassword.jsx
@@ -17,24 +17,33 @@ import {
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 React, { useState, useContext } from "react";
+import { useForm } 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";
import { useUpdatePasswordMutation } from "../Services/change.password.service";
+import { all } from "axios";
-const ioNav = yup.object().shape({
- transactionDate: yup.string().required("Date is required"),
- transactionAmount: yup.string().required("New NAV is required"),
- comments: yup
+// Validation schema
+const passwordSchema = yup.object().shape({
+ oldPassword: yup.string().required("Current Password is required"),
+ newPassword: yup
.string()
- .notRequired()
- .max(200, "Approve Comment cannot be more than 200 characters"),
+ .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 = ({
@@ -43,175 +52,145 @@ const ChangePassword = ({
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 [showCurrentPassword, setShowCurrentPassword] = useState(false);
const [showNewPassword, setShowNewPassword] = useState(false);
const [showConfirmPassword, setShowConfirmPassword] = useState(false);
- // ======================[ Cotext Api ]
- const { IODetails } = useContext(GlobalStateContext);
- const found = data?.find((item) => item?.id === actionId);
+ const toast = useToast();
- const [updatePassword] = useUpdatePasswordMutation()
- // const {
- // data
- // } = useGetArtifactsQuery(id)
+ const [updatePassword] = useUpdatePasswordMutation();
+ // Form handling
const {
- control,
+ register,
handleSubmit,
- watch,
reset,
formState: { errors },
} = useForm({
- resolver: yupResolver(ioNav),
+ resolver: yupResolver(passwordSchema),
+ mode: "all",
});
- const onSubmit = async (data) => {
- setIsLoading(true);
-
- try {
- const res = await updatePassword({ data});
- if (res?.data?.statusCode === 201) {
- setIsLoading(false);
- toast({
- render: () => ,
- });
- handleClose();
- } else if (res?.error?.status === 400) {
- toast({
- render: () => (
-
- ),
- });
- handleClose();
- }
- } catch (error) {
- console.log(error);
+ // 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: () => ,
+ });
+ handleClose();
+ } else if (res?.error) {
+ toast({
+ render: () => (
+
+ ),
+ });
}
- };
-
- const handleSave = () => {
- handleSubmit(onSubmit)();
+ } catch (error) {
+ console.error(error);
+ } finally {
+ setIsLoading(false);
+ }
};
+ // Handle modal close
const handleClose = () => {
- setIsLoading(false);
setAlert(false);
onClose();
+ reset();
};
return (
<>
-
+
- Change Password
+ Change Password
-
-
+ {/* Current Password */}
+
+
Current Password
setSubject(e.target.value)}
+ {...register("oldPassword")}
+ fontSize="sm"
+ type={showCurrentPassword ? "text" : "password"}
focusBorderColor="forestGreen.300"
- rounded={4}
- type={showCurrentPassword ? "text" : "password"} // Toggles between "text" and "password" based on the `show` state
/>
-
- {errors.ChangePassword?.message}
+
+ {errors.oldPassword?.message}
-
-
+ {/* New Password */}
+
+
New Password
setSubject(e.target.value)}
+ {...register("newPassword")}
+ fontSize="sm"
+ type={showNewPassword ? "text" : "password"}
focusBorderColor="forestGreen.300"
- rounded={4}
- type={showNewPassword ? "text" : "password"} // Toggles between "text" and "password" based on the `show` state
/>
-
+
{errors.newPassword?.message}
-
-
- Re-Type New Password
+ {/* Confirm Password */}
+
+
+ Confirm New Password
setSubject(e.target.value)}
+ {...register("confirmNewPassword")}
+ fontSize="sm"
+ type={showConfirmPassword ? "text" : "password"}
focusBorderColor="forestGreen.300"
- rounded={4}
- type={showConfirmPassword ? "text" : "password"} // Toggles between "text" and "password" based on the `show` state
/>
-
- {errors.conformPassword?.message}
+
+ {errors.confirmNewPassword?.message}
@@ -219,22 +198,20 @@ const ChangePassword = ({
-
@@ -245,8 +222,8 @@ const ChangePassword = ({
setAlert(false)}
- alertHandler={handleSave}
- message={"Are you sure you want to change password?"}
+ alertHandler={handleSubmit(onSubmit)}
+ message={"Are you sure you want to change the password?"}
isLoading={isLoading}
/>
>
diff --git a/src/Pages/ForgetPassword.jsx b/src/Pages/ForgetPassword.jsx
index 8b78aba..23ed47b 100644
--- a/src/Pages/ForgetPassword.jsx
+++ b/src/Pages/ForgetPassword.jsx
@@ -1,178 +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, 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"),
+ 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 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: () => ,
- // });
- // handleClose();
- // } else if (res?.error?.status === 400) {
- // toast({
- // render: () => (
- //
- // ),
- // });
- // handleClose();
- // }
- // } catch (error) {
- // console.log(error);
- // }
- // };
-
- const handleSave = () => {
- handleSubmit(onSubmit)();
- };
-
- const handleClose = () => {
- setIsLoading(false);
- setAlert(false);
- onClose();
- };
+
+ const onSubmit = async (formData) => {
-
- return (
- <>
-
-
-
- Forget Password
-
-
-
-
- Email, Phone, or UserName
- setSubject(e.target.value)}
- focusBorderColor="forestGreen.300"
- rounded={4}
- // type={showPassword ? "text" : "password"}
- type="text"
- />
-
- {errors.ChangePassword?.message}
-
-
-
-
-
-
- {/* */}
-
-
-
-
-
-
- setAlert(false)}
- alertHandler={handleSave}
- message={"Are you sure you want to change password?"}
- isLoading={isLoading}
- />
- >
- );
+ setIsLoading(true);
+ try {
+ const res = await forgetPassword(formData);
+ if (res?.data?.statusCode === 200) {
+ toast({
+ render: () => ,
+ });
+ handleClose();
+ } else if (res?.error?.status === 401) {
+ toast({
+ render: () => (
+
+ ),
+ });
+ handleClose();
+ }
+ } catch (error) {
+ console.error(error);
+ } finally {
+ setIsLoading(false);
+ }
};
-
- export default ForgetPassword;
-
\ No newline at end of file
+
+ const handleClose = () => {
+ setIsLoading(false);
+ onClose();
+ };
+
+ return (
+
+
+
+
+
+
+ );
+};
+
+export default ForgetPassword;
diff --git a/src/Pages/Login.jsx b/src/Pages/Login.jsx
index c871975..2eef3aa 100644
--- a/src/Pages/Login.jsx
+++ b/src/Pages/Login.jsx
@@ -256,6 +256,8 @@ const Login = () => {
color={"whitesmoke"}
colorScheme="green.500"
size="lg"
+ fontWeight={500}
+ fontSize={"md"}
>
Log In
diff --git a/src/Pages/SubAdmin/SubAdminUpdateCreate.jsx b/src/Pages/SubAdmin/SubAdminUpdateCreate.jsx
index 948e78a..c483125 100644
--- a/src/Pages/SubAdmin/SubAdminUpdateCreate.jsx
+++ b/src/Pages/SubAdmin/SubAdminUpdateCreate.jsx
@@ -29,10 +29,8 @@ export const addSubAdmin = yup.object().shape({
.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(),
+ 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
@@ -95,29 +93,30 @@ const SubAdminUpdateCreate = () => {
lastName: subAdminByIdData?.data?.lastName,
emailAddress: subAdminByIdData?.data?.emailAddress,
});
- setIsSwitchOn(subAdminByIdData?.data?.role[0]?.role===encryptString(import.meta.env.VITE_VITE_MAKER));
+ setIsSwitchOn(
+ subAdminByIdData?.data?.role[0]?.role ===
+ encryptString(import.meta.env.VITE_VITE_MAKER)
+ );
console.log(subAdminByIdData?.data?.role);
}
}, [subAdminByIdData, reset]);
-
if (false) {
return ;
}
// ============================ [API]===============================
-
const handleConfirm = async () => {
setIsLoadingBtn(true);
const id = params?.id;
console.log(isSwitchOn);
-
+
if (id) {
try {
const formData = {
...form,
- role_xid: isSwitchOn?2:1,
+ // role_xid: !isSwitchOn ? 1 : 2,
};
await updateSubAdmin({ data: formData, id }).then((response) => {
if (response?.data?.statusCode) {
@@ -151,7 +150,7 @@ const SubAdminUpdateCreate = () => {
try {
const formData = {
...form,
- role_xid: isSwitchOn?2:1,
+ role_xid: isSwitchOn ? 1 : 2,
};
await createSubAdmin(formData).then((response) => {
console.log(response);
@@ -282,11 +281,11 @@ const SubAdminUpdateCreate = () => {
}, {});
// ==================== [On Submit] ========================
-console.log(errors);
+ console.log(errors);
const onSubmit = async (data) => {
console.log("Hit");
-
+
if (Object.keys(errors).length === 0) {
setForm(data);
setAlert(true);
@@ -314,10 +313,14 @@ console.log(errors);
Add Details
-
+ {params?.id ? (
+ ""
+ ) : (
+
+ )}
{/* ====================== [Form Input] ====================== */}
diff --git a/src/Routes/Nav.js b/src/Routes/Nav.js
index 58996f4..76bf644 100644
--- a/src/Routes/Nav.js
+++ b/src/Routes/Nav.js
@@ -104,25 +104,23 @@ export const nav = [
title: "INVESTORS REQUEST",
type: "title",
},
-{
- title: "Fawateer Deposit",
- submenu: [
- {
- title: "Aprover Request",
- path: "/fawateer",
- icon: RiMoneyDollarBoxLine,
- },
- {
- title: "View History",
- path: "/fawateer-history",
- icon: RiExchangeBoxLine,
- },
- ],
- type: "accordion",
- Icon: HiOutlineBanknotes,
-}
-,
-
+ {
+ title: "Fawateer Deposit",
+ submenu: [
+ {
+ title: "Aprover Request",
+ path: "/fawateer",
+ icon: RiMoneyDollarBoxLine,
+ },
+ {
+ title: "View History",
+ path: "/fawateer-history",
+ icon: RiExchangeBoxLine,
+ },
+ ],
+ type: "accordion",
+ Icon: HiOutlineBanknotes,
+ },
{
title: "Bank Deposit",
submenu: [
diff --git a/src/Services/change.password.service.js b/src/Services/change.password.service.js
index 4c8adc3..1d82772 100644
--- a/src/Services/change.password.service.js
+++ b/src/Services/change.password.service.js
@@ -11,10 +11,7 @@ export const changePasswordMake = createApi({
baseQuery: baseQuery,
tagTypes: ["getPassword"],
endpoints: (builder) => ({
-
-
// // ========[ update ]========
-
updatePassword: builder.mutation({
query: (data) => ({
url: `/auth/admin/update-password`,
diff --git a/src/Services/forget.password.service.js b/src/Services/forget.password.service.js
new file mode 100644
index 0000000..9af9f54
--- /dev/null
+++ b/src/Services/forget.password.service.js
@@ -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;
diff --git a/src/Services/token.serivce.js b/src/Services/token.serivce.js
index 1b2b827..9b0cc29 100644
--- a/src/Services/token.serivce.js
+++ b/src/Services/token.serivce.js
@@ -127,6 +127,6 @@ export const apiSlice = createApi({
}),
-});
+});
export const { useLoginMutation, useRefreshTokenMutation, useLogoutMutation } = apiSlice;
diff --git a/src/Store/Store.js b/src/Store/Store.js
index 42f2add..8d1bc65 100644
--- a/src/Store/Store.js
+++ b/src/Store/Store.js
@@ -19,6 +19,7 @@ import { fawateerRequest } from "../Services/fawateer.request.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({
reducer: {
@@ -39,6 +40,7 @@ export const store = configureStore({
[fawateerMaker.reducerPath]: fawateerMaker.reducer,
[sabAdminMaster.reducerPath]: sabAdminMaster.reducer,
[changePasswordMake.reducerPath]: changePasswordMake.reducer,
+ [forgetPasswordMake.reducerPath]: forgetPasswordMake.reducer,
// Add other reducers as needed
},
@@ -65,6 +67,7 @@ export const store = configureStore({
fawateerMaker.middleware,
sabAdminMaster.middleware,
changePasswordMake.middleware,
+ forgetPasswordMake.middleware,
),
});