diff --git a/src/components/master/InventoryManagement/ProductCategory.jsx b/src/components/master/InventoryManagement/ProductCategory.jsx new file mode 100644 index 00000000..0642fec5 --- /dev/null +++ b/src/components/master/InventoryManagement/ProductCategory.jsx @@ -0,0 +1,97 @@ +import React, { useEffect } from "react"; +import { useForm } from "react-hook-form"; +import { z } from "zod"; +import { zodResolver } from "@hookform/resolvers/zod"; +import Label from "../../common/Label"; +import { useCreateProductCategory, useUpdateProductCategory } from "../../../hooks/masterHook/useMaster"; + +const ProductCategorySchema = z.object({ + name: z.string().min(1, { message: "Name is required" }), + description: z.string().min(1, { message: "Description is required" }), +}); + +const ProductCategory = ({ data = null, onClose }) => { + const { + register, + handleSubmit, + reset, + formState: { errors }, + } = useForm({ + resolver: zodResolver(ProductCategorySchema), + defaultValues: { name: "", description: "" }, + }); + + const { mutate: CreateProductCategory, isPending } = useCreateProductCategory(() => + onClose?.() + ); + const { mutate: UpdateProductCategory, isPending: Updating } = useUpdateProductCategory(() => onClose?.()) + + const onSubmit = (payload) => { + if (data) { + UpdateProductCategory({ id: data.id, payload: { ...payload, id: data.id } }) + } else ( + CreateProductCategory(payload) + ) + + }; + + useEffect(() => { + if (data) { + reset({ + name: data.name ?? "", + description: data.description ?? "" + }) + } + }, [data]) + + + return ( +
+
+ + + {errors.name &&

{errors.name.message}

} +
+
+ + + + {errors.description && ( +

{errors.description.message}

+ )} +
+ +
+ + + +
+
+ ); +}; + +export default ProductCategory; diff --git a/src/components/master/MasterModal.jsx b/src/components/master/MasterModal.jsx index b3b02fbc..a760bae5 100644 --- a/src/components/master/MasterModal.jsx +++ b/src/components/master/MasterModal.jsx @@ -19,6 +19,7 @@ import ServiceGroups from "./Services/ServicesGroups"; import ManagePaymentHead from "./paymentAdjustmentHead/ManagePaymentHead"; import RequisitionStatus from "./InventoryManagement/RequisitionStatus"; import PurchaseOrderStatus from "./InventoryManagement/PurchaseOrderStatus"; +import ProductCategory from "./InventoryManagement/ProductCategory"; const MasterModal = ({ modaldata, closeModal }) => { if (!modaldata?.modalType || modaldata.modalType === "delete") { @@ -74,6 +75,10 @@ const MasterModal = ({ modaldata, closeModal }) => { "Edit-Purchase Order Status": ( ), + "Product Category": , + "Edit-Product Category": ( + + ), }; return ( diff --git a/src/hooks/masterHook/useMaster.js b/src/hooks/masterHook/useMaster.js index 76f0db91..c91ce451 100644 --- a/src/hooks/masterHook/useMaster.js +++ b/src/hooks/masterHook/useMaster.js @@ -309,6 +309,8 @@ const fetchMasterData = async (masterType,isActiveMaster) => { return (await MasterRespository.getRequisitionStatus(isActiveMaster)).data; case "Purchase Order Status": return (await MasterRespository.getPurchaseOrderStatus(isActiveMaster)).data; + case "Product Category": + return (await MasterRespository.getProductCategory(isActiveMaster)).data; case "Status": return [ { @@ -1090,6 +1092,49 @@ export const useUpdateRequisitionStatus = (onSuccessCallback) => { }); }; +// ============================== Product Category ============================= + +export const useCreateProductCategory = (onSuccessCallback) => { + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: async (payload) => { + const resp = await MasterRespository.createProductCategory(payload); + return resp.data; + }, + onSuccess: (data) => { + queryClient.invalidateQueries({ + queryKey: ["masterData", "Product Category"], + }); + showToast("Product Category successfully", "success"); + if (onSuccessCallback) onSuccessCallback(data); + }, + onError: (error) => { + showToast(error.message || "Something went wrong", "error"); + }, + }); +}; +export const useUpdateProductCategory = (onSuccessCallback) => { + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: async ({ id, payload }) => { + const resp = await MasterRespository.updateProductCategory(id, payload); + return resp.data; + }, + onSuccess: (data) => { + queryClient.invalidateQueries({ + queryKey: ["masterData", "Product Category"], + }); + showToast("Product Category Updated successfully", "success"); + if (onSuccessCallback) onSuccessCallback(data); + }, + onError: (error) => { + showToast(error.message || "Something went wrong", "error"); + }, + }); +}; + // ============================== Purchase Order Status ============================= export const useCreatePurhaseOrderStatus = (onSuccessCallback) => { diff --git a/src/pages/master/MasterPage.jsx b/src/pages/master/MasterPage.jsx index 978e8153..87b685b0 100644 --- a/src/pages/master/MasterPage.jsx +++ b/src/pages/master/MasterPage.jsx @@ -199,7 +199,7 @@ const MasterPage = () => { {(selectedMaster === "Purchase Order Status" || - selectedMaster === "Requisition Status") && ( + selectedMaster === "Requisition Status" || selectedMaster === "Product Category") && (
api.delete(`/api/master/purchase-order-status/delete/${id}?isActive=${isActive}`), + "Product Category": (id, isActive = false) => + api.delete(`/api/master/product-category/delete/${id}?isActive=${isActive}`), getWorkCategory: () => api.get(`/api/master/work-categories`), @@ -152,6 +154,10 @@ export const MasterRespository = { createPurchaseOrderStatus: (data) => api.post(`/api/master/purchase-order-status/create`, data), updatePurchaseOrderStatus: (id, data) => api.put(`/api/master/purchase-order-status/edit/${id}`, data), + getProductCategory: (isActive = true) => + api.get(`/api/master/product-category/list?isActive=${isActive}`), + createProductCategory: (data) => api.post(`/api/master/product-category/create`, data), + updateProductCategory: (id, data) => api.put(`/api/master/product-category/edit/${id}`, data),