From 963b85b15fb7d5a926070ba7af536ab5e847af05 Mon Sep 17 00:00:00 2001 From: rockyeverlast Date: Mon, 14 Apr 2025 19:34:59 +0530 Subject: [PATCH] Api integration for Department master completed --- .../DepartmentMaster/AddDepartmentMaster.tsx | 155 +++++++++++++++++ .../DepartmentMaster/DepartmentMasterList.tsx | 141 ++++++++++++++++ .../DepartmentMaster/EditDepartmentMaster.tsx | 159 ++++++++++++++++++ src/Redux/Service/department.master.ts | 109 ++++++++++++ src/Redux/Service/job.status.ts | 110 ++++++++++++ src/Redux/Store.tsx | 3 + src/Routes/Nav.ts | 5 + src/Routes/Routes.ts | 2 + 8 files changed, 684 insertions(+) create mode 100644 src/Pages/MasterModule/DepartmentMaster/AddDepartmentMaster.tsx create mode 100644 src/Pages/MasterModule/DepartmentMaster/DepartmentMasterList.tsx create mode 100644 src/Pages/MasterModule/DepartmentMaster/EditDepartmentMaster.tsx create mode 100644 src/Redux/Service/department.master.ts create mode 100644 src/Redux/Service/job.status.ts diff --git a/src/Pages/MasterModule/DepartmentMaster/AddDepartmentMaster.tsx b/src/Pages/MasterModule/DepartmentMaster/AddDepartmentMaster.tsx new file mode 100644 index 0000000..741a261 --- /dev/null +++ b/src/Pages/MasterModule/DepartmentMaster/AddDepartmentMaster.tsx @@ -0,0 +1,155 @@ +import { DialogBody, DialogCloseTrigger, DialogContent, DialogFooter, DialogHeader, DialogRoot, DialogTitle, DialogTrigger } from "../../../components/ui/dialog" +import { Field, Input, Stack, Text } from "@chakra-ui/react" +import { IoMdAdd } from "react-icons/io" +import { Button } from "../../../components/ui/button" +import { useState } from "react"; +import { toaster } from "../../../components/ui/toaster"; +import { useCreateDepartmentPostMutation, useGetDepartmentMasterDropDownQuery } from "../../../Redux/Service/department.master"; + +function AddDepartmentMaster({ refetch }: { refetch: VoidFunction }) { + const [jobType, setJobType] = useState(""); + const [isOpen, setIsOpen] = useState(false); + const [createDepartmentPost] = useCreateDepartmentPostMutation() + const { data } = useGetDepartmentMasterDropDownQuery() + const [selectdDep, setSelectdDep] = useState({ + id: '', + en_name: '', + }); + + + const handleOpenModal = () => { + setIsOpen(true); // Open modal when clicking "Add" + }; + + const handleSubmit = async () => { + if (!jobType.trim() || !selectdDep.id) { + toaster.create({ + title: "Error", + description: "Title and Subtitle cannot be empty.", + type: "error", + }); + return; + } + + const payload = { + en_name: jobType, + industry_masters_xid: selectdDep.id, + }; + + try { + await createDepartmentPost(payload); + refetch() + setIsOpen(false); + setJobType(""); + setSelectdDep({ + id: '', + en_name: '', + }) + } catch (error) { + console.error("Error updating template:", error); + alert("Failed to update template"); + } + }; + + console.log("Selected Department", selectdDep); + + + return ( + + + + {/* */} + + + + + + + Add + + + + + + + + Select Industry + + + + + + Department + setJobType(e.target.value)} + /> + + + + + + + + + setIsOpen(false)} /> + + + + ) +} + +export default AddDepartmentMaster \ No newline at end of file diff --git a/src/Pages/MasterModule/DepartmentMaster/DepartmentMasterList.tsx b/src/Pages/MasterModule/DepartmentMaster/DepartmentMasterList.tsx new file mode 100644 index 0000000..351cea5 --- /dev/null +++ b/src/Pages/MasterModule/DepartmentMaster/DepartmentMasterList.tsx @@ -0,0 +1,141 @@ +import { Box, HStack, Text } from "@chakra-ui/react"; +import MainFrame from "../../../components/MainFrame" +// import { InputGroup } from "../../../components/ui/input-group"; +// import { LuSearch } from "react-icons/lu"; +import DataTable from "../../../components/DataTable"; +import { Switch } from "../../../components/ui/switch"; +import { useEffect, useState } from "react"; +import SearchComponent from "../../../components/SearchComponent"; +import { useDepartmentToggleMutation, useGetDepartmentMasterQuery } from "../../../Redux/Service/department.master"; +import AddDepartmentMaster from "./AddDepartmentMaster"; +import EditDepartmentMaster from "./EditDepartmentMaster"; + + +// table data + +const tableHeadRow = [ + "Sr. No", + "Title", + "Action" + +]; + + + +const DepartmentMasterList = () => { + const [currentPage, setCurrentPage] = useState(1); + const { data, refetch } = useGetDepartmentMasterQuery(currentPage) + const [departmentToggle] = useDepartmentToggleMutation() + const [localData, setLocalData] = useState([]); + const [searchTerm, setSearchTerm] = useState(""); + + console.log("Department Data", data?.data.data) + + useEffect(() => { + if (data?.data?.data) { + setLocalData(data?.data.data); + } + }, [data]); + + const handlePageChange = (page: number) => { + setCurrentPage(page); + }; + + const handleToggle = async (agencyId: string, currentStatus: number) => { + const newStatus = currentStatus ? 0 : 1; + setLocalData((prevData) => + prevData.map((agency) => + agency.id === agencyId ? { ...agency, is_active: newStatus } : agency + ) + ); + try { + await departmentToggle({ id: agencyId, is_active: newStatus }).unwrap(); + refetch() + } catch (error) { + console.error("Error updating privacy policy:", error); + setLocalData((prevData) => + prevData.map((agency) => + agency.id === agencyId ? { ...agency, is_active: currentStatus } : agency + ) + ); + } + }; + + const filteredData = localData?.filter((agency) => { + const searchLower = searchTerm.toLowerCase(); + const title = agency.en_name?.toLowerCase().includes(searchLower); + return title; + }); + + const managepost = filteredData?.map((agency: any, index: number) => ({ + 'id': agency.id, + "Sr. No": (currentPage - 1) * (data?.data.per_page ?? 0) + index + 1, + "Title": agency.en_name, + "is_active": agency.is_active, + "Action": ( + + {/* */} + + + handleToggle(agency.id, Number(agency.is_active))} + checked={Boolean(Number(agency.is_active))} + /> + + + ), + })); + + // useEffect(() => { + // console.log("Fetched data:", data); + // console.log("Local data:", localData); + // console.log("Managepost data:", managepost); + // }, [data, localData, managepost]); + + return ( + + + + + + Department Master + + + + { + setSearchTerm(value); + setCurrentPage(1); + }} + /> + {/* */} + {/* */} + + + + + + + ) +} +export default DepartmentMasterList \ No newline at end of file diff --git a/src/Pages/MasterModule/DepartmentMaster/EditDepartmentMaster.tsx b/src/Pages/MasterModule/DepartmentMaster/EditDepartmentMaster.tsx new file mode 100644 index 0000000..13d262a --- /dev/null +++ b/src/Pages/MasterModule/DepartmentMaster/EditDepartmentMaster.tsx @@ -0,0 +1,159 @@ +import { + DialogBody, + DialogCloseTrigger, + DialogContent, + DialogFooter, + DialogHeader, + DialogRoot, + DialogTitle, + DialogTrigger, +} from "../../../components/ui/dialog"; +import { Box, Field, Input, Stack } from "@chakra-ui/react"; +import { Button } from "../../../components/ui/button"; +import Edit from "../../../components/ActionIcons/Edit"; +import { useState } from "react"; +import { toaster } from "../../../components/ui/toaster"; +import { useGetDepartmentMasterDropDownQuery, useUpdateDepartmentMutation } from "../../../Redux/Service/department.master"; + +function EditDepartmentMaster({ localData, refetch }: { localData: any, refetch: VoidFunction }) { + const [jobtype, setJobType] = useState(""); + const [updateDepartment] = useUpdateDepartmentMutation() + const { data } = useGetDepartmentMasterDropDownQuery() + const [isOpen, setIsOpen] = useState(false); + const [selectdDep, setSelectdDep] = useState({ + id: localData.industry_master.id, + en_name: localData.industry_master.en_name, + }); + + const handleOpenModal = () => { + // const template = localData?.find((item: any) => item.id === id); + if (localData) { + setJobType(localData.en_name); + setSelectdDep({ + id: localData.industry_master.id, + en_name: localData.industry_master.en_name, + }) + setIsOpen(true); + } + }; + + + const handleSubmit = async () => { + if (!jobtype.trim()) { + toaster.create({ + title: "Error", + description: "Title and Subtitle cannot be empty.", + type: "error", + }); + return; + } + + const payload = { + id: localData.id, + industry_masters_xid: selectdDep.id != null ? selectdDep.id : localData.industry_master.id, + en_name: jobtype + }; + + try { + await updateDepartment(payload).unwrap(); + refetch() + setIsOpen(false); + } catch (error) { + console.error("Error updating template:", error); + alert("Failed to update template"); + } + }; + + console.log("Dropdown Data", selectdDep); + console.log("Dep Data", localData) + + + return ( + setIsOpen(open)}> + + + + + + + + + + Edit Title + + + + + + + + Select Industry + + + + + + + Department + + setJobType(e.target.value)} + /> + + + + + + + + setIsOpen(false)} /> + + + ); +} + +export default EditDepartmentMaster; diff --git a/src/Redux/Service/department.master.ts b/src/Redux/Service/department.master.ts new file mode 100644 index 0000000..28e617d --- /dev/null +++ b/src/Redux/Service/department.master.ts @@ -0,0 +1,109 @@ +import { createApi } from "@reduxjs/toolkit/query/react"; +import { baseQueryWithReauth } from "./apiSlice"; + +export interface DepartmentData { + id: number; + industry_masters_xid: number; + en_name: string; + hi_name: string; + mr_name: string; + te_name: string; + ta_name: string; + bn_name: string; + or_name: string; + is_active: string; +} + +interface ApiResponse { + status: string; + status_code: number; + message: string; + data: { + current_page: number, + last_page: number, + total: number, + from: number, + per_page: number, + to: number, + data: DepartmentData[]; + }; +} + +export interface CountryEdit { + status: string; + status_code: number; + message: string; + data: DepartmentData[]; +} + +export interface DropDown{ + status: string; + status_code: number; + message: string; + data: { + id: number; + en_name: string; + }[] +} + +export type PostDepartment = { + en_name: string; + industry_masters_xid: number; +}; + + +export const departmentMaster = createApi({ + reducerPath: "departmentMaster", + baseQuery: baseQueryWithReauth, // Use enhanced baseQuery with error handling + endpoints: (builder) => ({ + createDepartmentPost: builder.mutation>({ + query: (data) => ({ + url: "/department-master-store", + method: "POST", + body: data, + }), + }), + // 🔹 GET: Fetch all posts + getDepartmentMaster: builder.query({ + query: (page = 1) => `/department-master-list?page=${page}`, + }), + + getDepartmentMasterDropDown: builder.query({ + query: () => `/industry-master-get-category`, + }), + + updateDepartment: builder.mutation({ + query: (updatedData) => ({ + url: "/department-master-update", + method: "POST", + body: updatedData, + }), + }), + + departmentToggle: builder.mutation({ + query: ({ id, is_active }) => ({ + url: `/department-master-status`, + method: "POST", + body: { id, is_active }, + }), + }), + + // deleteFaqPost: builder.mutation<{ status: string; message: string }, { id: number }>({ + // query: ({ id }) => ({ + // url: `/faq-delete`, + // method: "POST", + // body: { id }, + // }), + // }), + + }), +}); + +export const { + useGetDepartmentMasterQuery, + useGetDepartmentMasterDropDownQuery, + useCreateDepartmentPostMutation, + useUpdateDepartmentMutation, + useDepartmentToggleMutation, + // useDeleteFaqPostMutation +} = departmentMaster; \ No newline at end of file diff --git a/src/Redux/Service/job.status.ts b/src/Redux/Service/job.status.ts new file mode 100644 index 0000000..f70f360 --- /dev/null +++ b/src/Redux/Service/job.status.ts @@ -0,0 +1,110 @@ +import { createApi } from "@reduxjs/toolkit/query/react"; +import { baseQueryWithReauth } from "./apiSlice"; + +export interface CountryData { + id: number; + en_name: string; + hi_name: string; + mr_name: string; + te_name: string; + ta_name: string; + bn_name: string; + or_name: string; + country_code: string; + phonecode: string; + capital: string; + currency: string; + currency_name: string; + currency_symbol: string; + is_active: string; +} + +interface ApiResponse { + status: string; + status_code: number; + message: string; + data: { + current_page: number, + last_page: number, + total: number, + from: number, + per_page: number, + to: number, + data: CountryData[]; + }; +} + +export interface CountryEdit { + status: string; + status_code: number; + message: string; + data: CountryData[]; +} + + +export type PostCountry = { + en_name: string; + country_code: string; + phonecode: string; + capital: string; + currency: string; + currency_name: string; + currency_symbol: string; +}; + + +export const countryMaster = createApi({ + reducerPath: "countryMaster", + baseQuery: baseQueryWithReauth, // Use enhanced baseQuery with error handling + endpoints: (builder) => ({ + createCountryPost: builder.mutation>({ + query: (data) => ({ + url: "/country-add", + method: "POST", + body: data, + }), + }), + // 🔹 GET: Fetch all posts + getCountryMaster: builder.query({ + query: (page = 1) => `/country-list?page=${page}`, + }), + + getCountryMasterEdit: builder.query({ + query: (id) => `/country-edit/${id}`, + }), + + updateCountry: builder.mutation({ + query: (updatedData) => ({ + url: "/country-update", + method: "POST", + body: updatedData, + }), + }), + + countryToggle: builder.mutation({ + query: ({ id, is_active }) => ({ + url: `/country-status`, + method: "POST", + body: { id, is_active }, + }), + }), + + // deleteFaqPost: builder.mutation<{ status: string; message: string }, { id: number }>({ + // query: ({ id }) => ({ + // url: `/faq-delete`, + // method: "POST", + // body: { id }, + // }), + // }), + + }), +}); + +export const { + useGetCountryMasterQuery, + useGetCountryMasterEditQuery, + useCreateCountryPostMutation, + useUpdateCountryMutation, + useCountryToggleMutation, + // useDeleteFaqPostMutation +} = countryMaster; \ No newline at end of file diff --git a/src/Redux/Store.tsx b/src/Redux/Store.tsx index 3dd366c..7d17505 100644 --- a/src/Redux/Store.tsx +++ b/src/Redux/Store.tsx @@ -20,6 +20,7 @@ import { jobType } from "./Service/job.type.service"; import { industryMaster } from "./Service/industry.master.service"; import { profile } from "./Service/profile.password"; import { countryMaster } from "./Service/country.master"; +import { departmentMaster } from "./Service/department.master"; export const store = configureStore({ reducer: { @@ -43,6 +44,7 @@ export const store = configureStore({ [industryMaster.reducerPath]: industryMaster.reducer, [profile.reducerPath]: profile.reducer, [countryMaster.reducerPath]: countryMaster.reducer, + [departmentMaster.reducerPath]: departmentMaster.reducer, auth: authReducer, }, middleware: (getDefaultMiddleware) => @@ -66,6 +68,7 @@ export const store = configureStore({ industryMaster.middleware, profile.middleware, countryMaster.middleware, + departmentMaster.middleware, ), }); diff --git a/src/Routes/Nav.ts b/src/Routes/Nav.ts index cd1dfbe..ed01aa7 100644 --- a/src/Routes/Nav.ts +++ b/src/Routes/Nav.ts @@ -143,6 +143,11 @@ export const nav = [ path: "/master-module/industry-master", Icon: GoDotFill, }, + { + title: "Department Master", + path: "/master-module/department-master", + Icon: GoDotFill, + }, ], }, ]; \ No newline at end of file diff --git a/src/Routes/Routes.ts b/src/Routes/Routes.ts index 2aaef49..996191f 100644 --- a/src/Routes/Routes.ts +++ b/src/Routes/Routes.ts @@ -24,6 +24,7 @@ import RegisterUsers from "../Pages/ManageUsers/RegisterUsers/RegisterUsers"; import DeactivatedAccounts from "../Pages/ManageUsers/DeactivatedAccounts/DeactivatedAccounts"; import { Spinner } from "../components/Sipnner/Spinner"; import IndustryMasterList from "../Pages/MasterModule/IndustryMaster/IndustryMasterList"; +import DepartmentMasterList from "../Pages/MasterModule/DepartmentMaster/DepartmentMasterList"; export const RouteLink = [ { path: "/", Component: Dashboard }, @@ -63,6 +64,7 @@ export const RouteLink = [ { path: "/master-module/country", Component: Country}, { path: "/master-module/job-status", Component: JobStatus}, { path: "/master-module/industry-master", Component: IndustryMasterList}, + { path: "/master-module/department-master", Component: DepartmentMasterList}, // { path: "/job-status", Component: Spinner}, ] \ No newline at end of file