diff --git a/src/components/master/ManageExpenseStatus.jsx b/src/components/master/ManageExpenseStatus.jsx new file mode 100644 index 00000000..eccc3bf8 --- /dev/null +++ b/src/components/master/ManageExpenseStatus.jsx @@ -0,0 +1,165 @@ +import React, { useEffect } from "react"; +import { + useForm, + FormProvider, +} from "react-hook-form"; +import { z } from "zod"; +import { zodResolver } from "@hookform/resolvers/zod"; +import SelectMultiple from "../common/SelectMultiple"; +import { useFeatures } from "../../hooks/useMasterRole"; +import { EXPENSE_MANAGEMENT } from "../../utils/constants"; +import { useCreateExpenseStatus, useUpdateExpenseStatus } from "../../hooks/masterHook/useMaster"; +import { displayName } from "react-quill"; +import { AppColorconfig } from "../../utils/appUtils"; + +const ExpenseStatusSchema = z.object({ + name: z.string().min(1, { message: "Name is required" }), + displayName: z.string().min(1, { message: "Display Name is required" }), + description: z.string().min(1, { message: "Description is required" }), + permissionIds: z.array(z.string()).min(1, { + message: "At least one permission is required", + }), + color: z + .string() + .regex(/^#([0-9A-F]{3}){1,2}$/i, { message: "Invalid hex color" }), +}); + +const ManageExpenseStatus = ({data, onClose }) => { + const methods = useForm({ + resolver: zodResolver(ExpenseStatusSchema), + defaultValues: { + name: "", + displayName: "", + description: "", + permissionIds: [], + color: AppColorconfig.colors.primary, + }, + }); + + const { + register, + handleSubmit, + reset, + formState: { errors }, + } = methods; + + const { masterFeatures, loading } = useFeatures(); + + const ExpenseFeature = masterFeatures?.find( + (appfeature) => appfeature.id === EXPENSE_MANAGEMENT + ); + const {mutate:CreateExpenseStatus,isPending:isPending} = useCreateExpenseStatus(()=>onClose?.()) + const {mutate:UpdateExpenseStatus,isPending:Updating} = useUpdateExpenseStatus(()=>onClose?.()); + + + + const onSubmit = (payload) => { + if(data){ + UpdateExpenseStatus({id:data.id,payload:{...payload,id:data.id}}) + }else{ + CreateExpenseStatus(payload) + } + }; + + + useEffect(()=>{ + if(data){ + reset({ + name:data.name ?? "", + displayName:data.displayName ?? "", + description:data.description ?? "", + permissionIds:data.permissionIds ?? [], + color:data.color ?? AppColorconfig.colors.primary + }) + } + },[data]) + return ( + + {loading ? ( + Loading... + ) : ( + + + Expense Status Name + + {errors.name && {errors.name.message}} + + + + Status Display Name + + {errors.displayName && ( + {errors.displayName.message} + )} + + + + + {errors.permissionIds && ( + {errors.permissionIds.message} + )} + + + + Select Color + + {errors.color && ( + {errors.color.message} + )} + + + + Description + + {errors.description && ( + {errors.description.message} + )} + + + + + {isPending || Updating ? "Please Wait..." : Updating ? "Update" : "Submit"} + + + Cancel + + + + )} + + ); +}; + +export default ManageExpenseStatus; diff --git a/src/components/master/MasterModal.jsx b/src/components/master/MasterModal.jsx index 63405529..0a472727 100644 --- a/src/components/master/MasterModal.jsx +++ b/src/components/master/MasterModal.jsx @@ -19,6 +19,7 @@ import EditContactTag from "./EditContactTag"; import { useDeleteMasterItem } from "../../hooks/masterHook/useMaster"; import ManageExpenseType from "./ManageExpenseType"; import ManagePaymentMode from "./ManagePaymentMode"; +import ManageExpenseStatus from "./ManageExpenseStatus"; const MasterModal = ({ modaldata, closeModal }) => { @@ -93,7 +94,9 @@ const MasterModal = ({ modaldata, closeModal }) => { "Expense Type":, "Edit-Expense Type":, "Payment Mode":, - "Edit-Payment Mode": + "Edit-Payment Mode":, + "Expense Status":, + "Edit-Expense Status": }; return modalComponents[modalType] || null; diff --git a/src/hooks/masterHook/useMaster.js b/src/hooks/masterHook/useMaster.js index 131178b8..15dc3305 100644 --- a/src/hooks/masterHook/useMaster.js +++ b/src/hooks/masterHook/useMaster.js @@ -626,7 +626,49 @@ export const useUpdatePaymentMode = (onSuccessCallback)=>{ } }) } +// -------------------Expense Status---------------------------------- +export const useCreateExpenseStatus =(onSuccessCallback)=>{ + const queryClient = useQueryClient(); + return useMutation( { + mutationFn: async ( payload ) => + { + const resp = await MasterRespository.createExpenseStatus(payload); + return resp.data; + }, + onSuccess: ( data ) => + { + queryClient.invalidateQueries( {queryKey:[ "masterData", "Expense Status" ]} ) + showToast( "Expense Status added successfully", "success" ); + if(onSuccessCallback) onSuccessCallback(data) + }, + onError: ( error ) => + { + showToast(error.message || "Something went wrong", "error"); + } + }) +} +export const useUpdateExpenseStatus = (onSuccessCallback)=>{ + const queryClient = useQueryClient(); + + return useMutation( { + mutationFn: async ( {id,payload} ) => + { + const resp = await MasterRespository.updateExepnseStatus(id,payload); + return resp.data; + }, + onSuccess: ( data ) => + { + queryClient.invalidateQueries( {queryKey:[ "masterData", "Expense Status" ]} ) + showToast( "Expense Status Updated successfully", "success" ); + if(onSuccessCallback) onSuccessCallback(data) + }, + onError: ( error ) => + { + showToast(error.message || "Something went wrong", "error"); + } + }) +} // -Delete Master -------- export const useDeleteMasterItem = () => { const queryClient = useQueryClient(); diff --git a/src/pages/master/MasterTable.jsx b/src/pages/master/MasterTable.jsx index b47c703f..c064bd11 100644 --- a/src/pages/master/MasterTable.jsx +++ b/src/pages/master/MasterTable.jsx @@ -19,7 +19,8 @@ const MasterTable = ({ data, columns, loading, handleModalData }) => { "isActive", "noOfPersonsRequired", "color", - "displayName" + "displayName", + "permissionIds" ]; const safeData = Array.isArray(data) ? data : []; diff --git a/src/repositories/MastersRepository.jsx b/src/repositories/MastersRepository.jsx index 535a9cd4..6f3fb89b 100644 --- a/src/repositories/MastersRepository.jsx +++ b/src/repositories/MastersRepository.jsx @@ -42,8 +42,10 @@ export const MasterRespository = { "Contact Tag": (id) => api.delete(`/api/master/contact-tag/${id}`), "Expense Type": (id, isActive) => api.delete(`/api/Master/expenses-type/delete/${id}`, (isActive = false)), - "Payment Mode": (id,isActive) => + "Payment Mode": (id, isActive) => api.delete(`/api/Master/payment-mode/delete/${id}`, (isActive = false)), + "Expense Status": (id, isActive) => + api.delete(`/api/Master/expenses-status/delete/${id}`, (isActive = false)), getWorkCategory: () => api.get(`/api/master/work-categories`), createWorkCategory: (data) => api.post(`/api/master/work-category`, data), @@ -74,4 +76,7 @@ export const MasterRespository = { api.put(`/api/Master/payment-mode/edit/${id}`, data), getExpenseStatus: () => api.get("/api/Master/expenses-status"), + createExpenseStatus: (data) => api.post("/api/Master/expenses-status", data), + updateExepnseStatus: (id, data) => + api.put(`/api/Master/expenses-status/edit/${id}`, data), }; diff --git a/src/utils/constants.jsx b/src/utils/constants.jsx index 1ccd4d36..f882fbe3 100644 --- a/src/utils/constants.jsx +++ b/src/utils/constants.jsx @@ -56,5 +56,11 @@ export const PROCESS_EXPENSE = "ea5a1529-4ee8-4828-80ea-0e23c9d4dd11" export const EXPENSE_MANAGE = "ea5a1529-4ee8-4828-80ea-0e23c9d4dd11" + +// -------------------Application Role------------------------------ + +// 1 - Expense Manage +export const EXPENSE_MANAGEMENT = "a4e25142-449b-4334-a6e5-22f70e4732d7" + export const BASE_URL = process.env.VITE_BASE_URL; // export const BASE_URL = "https://api.marcoaiot.com"; \ No newline at end of file
{errors.name.message}
{errors.displayName.message}
{errors.permissionIds.message}
{errors.color.message}
{errors.description.message}