From 354903567280da46004b95b79d78af5e812216ce Mon Sep 17 00:00:00 2001 From: rockyeverlast Date: Wed, 19 Mar 2025 17:39:29 +0530 Subject: [PATCH 01/12] Initial commit to testing --- .env | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/.env b/.env index 25f5e16..514dab8 100644 --- a/.env +++ b/.env @@ -1,5 +1,11 @@ -VITE_API_URL='https://ssa.betadelivery.com/apia/v1' -# VITE_API_URL='http://192.16.50.44/seo-backend/apia/v1' +# VITE_API_URL='https://ssa.betadelivery.com/apia/v1' +# # VITE_API_URL='http://192.16.50.44/seo-backend/apia/v1' +# VITE_USER_NAME="Admin" +# VITE_PASSWORD="71%@L%es^bUX94`J9XT*@bh,._WWM{$%^^&&" +# VITE_APP_NAME=MyViteApp +# VITE_IMG_TEMPLATES='https://ssa.betadelivery.com/storage/app/public/uploads/post_templates/' +VITE_API_URL='https://ssa.betadelivery.com/testing/apia/' +VITE_API_URL='http://192.16.50.44/seo-backend/apia/v1' VITE_USER_NAME="Admin" VITE_PASSWORD="71%@L%es^bUX94`J9XT*@bh,._WWM{$%^^&&" VITE_APP_NAME=MyViteApp From 628ab225ff20a2f579a2677426966b8dd2da1047 Mon Sep 17 00:00:00 2001 From: rockyeverlast Date: Wed, 19 Mar 2025 17:46:16 +0530 Subject: [PATCH 02/12] updated env for Testing --- .env | 1 - 1 file changed, 1 deletion(-) diff --git a/.env b/.env index 514dab8..ed13177 100644 --- a/.env +++ b/.env @@ -5,7 +5,6 @@ # VITE_APP_NAME=MyViteApp # VITE_IMG_TEMPLATES='https://ssa.betadelivery.com/storage/app/public/uploads/post_templates/' VITE_API_URL='https://ssa.betadelivery.com/testing/apia/' -VITE_API_URL='http://192.16.50.44/seo-backend/apia/v1' VITE_USER_NAME="Admin" VITE_PASSWORD="71%@L%es^bUX94`J9XT*@bh,._WWM{$%^^&&" VITE_APP_NAME=MyViteApp From 0192d4be37c0f0341bead455922044e52948b32b Mon Sep 17 00:00:00 2001 From: rockyeverlast Date: Wed, 19 Mar 2025 17:50:35 +0530 Subject: [PATCH 03/12] update API url in env --- .env | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.env b/.env index ed13177..5754764 100644 --- a/.env +++ b/.env @@ -4,7 +4,7 @@ # VITE_PASSWORD="71%@L%es^bUX94`J9XT*@bh,._WWM{$%^^&&" # VITE_APP_NAME=MyViteApp # VITE_IMG_TEMPLATES='https://ssa.betadelivery.com/storage/app/public/uploads/post_templates/' -VITE_API_URL='https://ssa.betadelivery.com/testing/apia/' +VITE_API_URL='https://ssa.betadelivery.com/testing/apia/v1' VITE_USER_NAME="Admin" VITE_PASSWORD="71%@L%es^bUX94`J9XT*@bh,._WWM{$%^^&&" VITE_APP_NAME=MyViteApp From ab029438fbf31baa39e257921fc446805ab5cbde Mon Sep 17 00:00:00 2001 From: rockyeverlast Date: Thu, 3 Apr 2025 14:45:48 +0530 Subject: [PATCH 04/12] updated testing .env file --- .env | 6 ++++-- src/Pages/Login.tsx | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.env b/.env index 5754764..e73dab8 100644 --- a/.env +++ b/.env @@ -4,8 +4,10 @@ # VITE_PASSWORD="71%@L%es^bUX94`J9XT*@bh,._WWM{$%^^&&" # VITE_APP_NAME=MyViteApp # VITE_IMG_TEMPLATES='https://ssa.betadelivery.com/storage/app/public/uploads/post_templates/' -VITE_API_URL='https://ssa.betadelivery.com/testing/apia/v1' +# VITE_API_URL='https://ssa.betadelivery.com/testing/apia/v1' +VITE_API_URL='https://ssa.betadelivery.com/apia/v1' VITE_USER_NAME="Admin" -VITE_PASSWORD="71%@L%es^bUX94`J9XT*@bh,._WWM{$%^^&&" +# VITE_PASSWORD="71%@L%es^bUX94`J9XT*@bh,._WWM{$%^^&&" +VITE_PASSWORD="71%@L%es^bUX94`J9XT*%4&^%tUU^%Q^ffgt" VITE_APP_NAME=MyViteApp VITE_IMG_TEMPLATES='https://ssa.betadelivery.com/storage/app/public/uploads/post_templates/' \ No newline at end of file diff --git a/src/Pages/Login.tsx b/src/Pages/Login.tsx index 8a749ef..a023088 100644 --- a/src/Pages/Login.tsx +++ b/src/Pages/Login.tsx @@ -46,7 +46,7 @@ const Login = () => { // Encode Basic Auth Credentials const username = import.meta.env.VITE_USER_NAME || ""; // Replace with actual username const password = import.meta.env.VITE_PASSWORD || ""; // Replace with actual password - const basicAuth = `${username} : ${password}`; // Encode to Base64 + const basicAuth = `${username}:${password}`; // Encode to Base64 try { const res = await axios.post( From f08fdc682b52d040ff94f1e7d907ed911b58ebbd Mon Sep 17 00:00:00 2001 From: rockyeverlast Date: Thu, 3 Apr 2025 14:58:15 +0530 Subject: [PATCH 05/12] basic auth encoded in base64 --- src/Pages/Login.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Pages/Login.tsx b/src/Pages/Login.tsx index a023088..7b9077f 100644 --- a/src/Pages/Login.tsx +++ b/src/Pages/Login.tsx @@ -46,7 +46,8 @@ const Login = () => { // Encode Basic Auth Credentials const username = import.meta.env.VITE_USER_NAME || ""; // Replace with actual username const password = import.meta.env.VITE_PASSWORD || ""; // Replace with actual password - const basicAuth = `${username}:${password}`; // Encode to Base64 + const credentials = `${username}:${password}`; // Encode to Base64 + const basicAuth = btoa(credentials); // Use btoa for Base64 encoding try { const res = await axios.post( From 6856b4b61095c698779a0564a4ccbe871e810c82 Mon Sep 17 00:00:00 2001 From: rockyeverlast Date: Wed, 9 Apr 2025 16:47:24 +0530 Subject: [PATCH 06/12] Fixed env for testing --- .env | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.env b/.env index 016f2eb..d495681 100644 --- a/.env +++ b/.env @@ -4,10 +4,10 @@ # VITE_PASSWORD="71%@L%es^bUX94`J9XT*@bh,._WWM{$%^^&&" # VITE_APP_NAME=MyViteApp # VITE_IMG_TEMPLATES='https://ssa.betadelivery.com/storage/app/public/uploads/post_templates/' -# VITE_API_URL='https://ssa.betadelivery.com/testing/apia/v1' -VITE_API_URL='https://ssa.betadelivery.com/apia/v1' +VITE_API_URL='https://ssa.betadelivery.com/testing/apia/v1' +# VITE_API_URL='https://ssa.betadelivery.com/apia/v1' VITE_USER_NAME="Admin" VITE_PASSWORD="71%@L%es^bUX94`J9XT*@bh,._WWM{$%^^&&" # VITE_PASSWORD="71%@L%es^bUX94`J9XT*%4&^%tUU^%Q^ffgt" VITE_APP_NAME=MyViteApp -VITE_IMG_TEMPLATES='https://ssa.betadelivery.com/storage/app/public/uploads/post_templates/' \ No newline at end of file +VITE_IMG_TEMPLATES='https://ssa.betadelivery.com/testing/storage/app/public/uploads/post_templates/' \ No newline at end of file From a1781ade46491bca4d819cf6824bd3c7c2e70cef Mon Sep 17 00:00:00 2001 From: rockyeverlast Date: Thu, 10 Apr 2025 20:13:14 +0530 Subject: [PATCH 07/12] Fixed pagination and Master module country updated --- src/Layouts/DefaultLayout.tsx | 85 +++---- src/Pages/ManageCMS/FAQ/FAQ.tsx | 22 +- .../AgencyMaster/AgencyMaster.tsx | 18 +- src/Pages/MasterModule/Country/Country.tsx | 113 +++++++-- .../MasterModule/Country/CountryAddModel.tsx | 230 ++++++++++++++---- .../MasterModule/Country/EditCountryModel.tsx | 188 ++++++++++---- .../IndustryMaster/IndustryMasterList.tsx | 73 +++--- src/Pages/MasterModule/JobType/JobType.tsx | 61 ++--- .../TemplateMaster/TemplateMaster.tsx | 18 +- .../Service/agency.master.module.service.ts | 4 +- src/Redux/Service/country.master.ts | 110 +++++++++ src/Redux/Service/faqs.service.ts | 6 +- src/Redux/Service/industry.master.service.ts | 4 +- src/Redux/Service/job.type.service.ts | 4 +- src/Redux/Service/template.master.service.ts | 4 +- src/Redux/Store.tsx | 3 + src/components/DataTable.tsx | 66 +++-- src/components/ui/pagination.tsx | 44 +++- 18 files changed, 771 insertions(+), 282 deletions(-) create mode 100644 src/Redux/Service/country.master.ts diff --git a/src/Layouts/DefaultLayout.tsx b/src/Layouts/DefaultLayout.tsx index 5558658..92581ab 100644 --- a/src/Layouts/DefaultLayout.tsx +++ b/src/Layouts/DefaultLayout.tsx @@ -12,9 +12,10 @@ import { useDispatch } from "react-redux"; import GlobalStateContext from "../Contexts/GlobalStateContext"; import { useLogOutMutation } from "../Redux/Service/apiSlice"; import ProgressBar from "../components/ProgressBar/ProgressBar"; +import { useGetProfileQuery } from "../Redux/Service/profile.password"; const DefaultLayout: FC<{ children: React.ReactNode }> = ({ children }) => { - + const { data } = useGetProfileQuery() const dispatch = useDispatch() const navigate = useNavigate() const location = useLocation() @@ -25,20 +26,20 @@ const DefaultLayout: FC<{ children: React.ReactNode }> = ({ children }) => { throw new Error('App must be used within a GlobalStateProvider'); } const { setIsAuthenticate, isBarLoading } = context; - const [ logOutAdmin ] = useLogOutMutation() + const [logOutAdmin] = useLogOutMutation() // Logout function const handleLogout = async () => { try { // ✅ Call mutation and wait for the response - const res = await logOutAdmin().unwrap(); + const res = await logOutAdmin().unwrap(); console.log("Logout Success:", res); - + // ✅ Clear local storage & update authentication state dispatch(logout()); - localStorage.removeItem("token"); - setIsAuthenticate(false); + localStorage.removeItem("token"); + setIsAuthenticate(false); // ✅ Redirect to login page navigate("/login"); } catch (error) { @@ -48,43 +49,43 @@ const DefaultLayout: FC<{ children: React.ReactNode }> = ({ children }) => { return ( - - - - - - - - - {nav?.map(({ title, path, Icon, type, children, initPath }, index) => type === 'single' ? - {title} : - - - navigate(path||'')} gap={0} style={{ cursor: 'pointer', borderRadius: '8px', padding: '5px', width: '100%', display: 'flex', alignItems: 'center', border: '1px solid #ffffff', backgroundColor:'#fff',color:'#000', fontSize: '14px', }}> {title} - {children?.map(({ title, path, Icon }, index) => navigate(path)} style={{ marginTop: 6, cursor: 'pointer', borderRadius: '8px', padding: '6px', width: '100%', display: 'flex', alignItems: 'center', gap: 6, border: '1px solid #ffffff', backgroundColor:'#fff',color:'#919198' }} > {title})} - - )} - - - Logout - - - - - - - - navigate('/profile')} > - - - Ritesh Pandey - ritesh.pandey@wdimails.com - + + + + + + - - {children} - - + + {nav?.map(({ title, path, Icon, type, children, initPath }, index) => type === 'single' ? + {title} : + + + navigate(path || '')} gap={0} style={{ cursor: 'pointer', borderRadius: '8px', padding: '5px', width: '100%', display: 'flex', alignItems: 'center', border: '1px solid #ffffff', backgroundColor: '#fff', color: '#000', fontSize: '14px', }}> {title} + {children?.map(({ title, path, Icon }, index) => navigate(path)} style={{ marginTop: 6, cursor: 'pointer', borderRadius: '8px', padding: '6px', width: '100%', display: 'flex', alignItems: 'center', gap: 6, border: '1px solid #ffffff', backgroundColor: '#fff', color: '#919198' }} > {title})} + + )} + + + Logout + + + + + + + + navigate('/profile')} > + + + {`${data?.data?.first_name.charAt(0).toUpperCase()}${data?.data.first_name.slice(1)}`} + {data?.data?.phone_number} + + + + {children} + + ); }; diff --git a/src/Pages/ManageCMS/FAQ/FAQ.tsx b/src/Pages/ManageCMS/FAQ/FAQ.tsx index 504b263..94f54f8 100644 --- a/src/Pages/ManageCMS/FAQ/FAQ.tsx +++ b/src/Pages/ManageCMS/FAQ/FAQ.tsx @@ -53,7 +53,8 @@ const tableHeadRow = [ // ]; const FAQ = () => { - const { data, refetch, isLoading, isFetching } = useGetFaqQuery() + const [currentPage, setCurrentPage] = useState(1); + const { data, refetch, isLoading, isFetching } = useGetFaqQuery(currentPage) const [localData, setLocalData] = useState([]); const [faqToggle] = useFaqToggleMutation() const [deleteFaqPost] = useDeleteFaqPostMutation() @@ -69,6 +70,10 @@ const FAQ = () => { } }, [data]); + const handlePageChange = (page: number) => { + setCurrentPage(page); + }; + const handleToggle = async (agencyId: number, currentStatus: string) => { const newStatus = currentStatus === '1' ? '0' : '1'; @@ -129,7 +134,7 @@ const FAQ = () => { const managepost = filteredData?.flatMap((agency: FaqData, index: number) => agency.translations.map((translation: any) => ({ 'id': translation.id, - "Sr. No": index + 1, + "Sr. No": (currentPage - 1) * (data?.data.per_page ?? 0) + index + 1, "Question": translation.question, "Answer": translation.answer, 'Category': agency.principal_type_xid === 2 ? "Job Seeker" : "Recruiter", @@ -178,7 +183,7 @@ const FAQ = () => { py={0} px={3} > - + ) } @@ -208,13 +213,18 @@ const FAQ = () => { {isFetching && } {!isLoading && !data?.data ? ( - + ) : ()} diff --git a/src/Pages/MasterModule/AgencyMaster/AgencyMaster.tsx b/src/Pages/MasterModule/AgencyMaster/AgencyMaster.tsx index 451660b..b2e8025 100644 --- a/src/Pages/MasterModule/AgencyMaster/AgencyMaster.tsx +++ b/src/Pages/MasterModule/AgencyMaster/AgencyMaster.tsx @@ -47,7 +47,8 @@ const tableHeadRow = [ // ]; const AgencyMaster = () => { - const { data, refetch } = useGetAgencyMasterQuery() + const [currentPage, setCurrentPage] = useState(1); + const { data, refetch } = useGetAgencyMasterQuery(currentPage) const [agencyMasterToggle] = useAgencyMasterToggleMutation() const [localData, setLocalData] = useState([]); const [searchTerm, setSearchTerm] = useState(""); @@ -72,13 +73,17 @@ const AgencyMaster = () => { } }; + const handlePageChange = (page: number) => { + setCurrentPage(page); + }; + const filteredData = localData?.filter((agency) => agency?.name.toLowerCase().includes(searchTerm.toLowerCase()) ); const managepost = filteredData?.map((agency: any, index: number) => ({ 'id': agency.id, - "Sr. No": index + 1, + "Sr. No": (currentPage - 1) * (data?.data.per_page ?? 0) + index + 1, "Agency Name": agency.name, "RC no.": agency.rc_number, "State": agency.state, @@ -162,8 +167,13 @@ const AgencyMaster = () => { sortableColumns={["Name", "Registration Date "]} tableHeadRow={tableHeadRow} data={managepost || []} - paginationData={data?.data.data} - refetch={refetch} + paginationData={{ + current_page: data?.data.current_page || 1, + last_page: data?.data.last_page || 1, + per_page: data?.data.per_page || 10, + total: data?.data.total || 0 + }} + onPageChange={handlePageChange} /> diff --git a/src/Pages/MasterModule/Country/Country.tsx b/src/Pages/MasterModule/Country/Country.tsx index 96afe6e..9b0c5a1 100644 --- a/src/Pages/MasterModule/Country/Country.tsx +++ b/src/Pages/MasterModule/Country/Country.tsx @@ -1,11 +1,12 @@ -import { Box, HStack, Input, Text } from "@chakra-ui/react"; +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 CountryAddModel from "./CountryAddModel"; import EditCountryModel from "./EditCountryModel"; +import { CountryData, useCountryToggleMutation, useGetCountryMasterQuery } from "../../../Redux/Service/country.master"; +import { useEffect, useState } from "react"; +import SearchComponent from "../../../components/SearchComponent"; @@ -15,25 +16,89 @@ const tableHeadRow = [ "Sr. No", "Title", "Action" - + ]; -const managepost: any[] = [ - ...Array.from({ length: 12 }, (_, i) => ({ - "Sr. No": i + 1, - "Title": "Lorem Ipsum", +// const managepost: any[] = [ +// ...Array.from({ length: 12 }, (_, i) => ({ +// "Sr. No": i + 1, +// "Title": "Lorem Ipsum", +// "Action": ( +// +// +// +// +// +// +// ), +// })), +// ]; + +const Country = () => { + const [currentPage, setCurrentPage] = useState(1); + const { data, refetch } = useGetCountryMasterQuery(currentPage) + const [countryToggle] = useCountryToggleMutation() + const [localData, setLocalData] = useState([]); + const [searchTerm, setSearchTerm] = useState(""); + console.log("Country Data", data?.data.data) + + useEffect(() => { + if (data) { + setLocalData(data?.data.data); + } + }, [data]); + + const handlePageChange = (page: number) => { + setCurrentPage(page); + }; + + const filteredData = localData?.filter((agency) => { + const searchLower = searchTerm.toLowerCase(); + const countryName = agency.en_name?.toLowerCase().includes(searchLower); + const capitalName = agency.capital?.toLowerCase().includes(searchLower); + return countryName || capitalName; + }); + + const handleToggle = async (agencyId: number, currentStatus: string) => { + const newStatus = currentStatus === '1' ? '0' : '1'; + + setLocalData((prevData) => + prevData.map((agency) => + agency.id === agencyId ? { ...agency, is_active: newStatus } : agency + ) + ); + + try { + await countryToggle({ 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 managepost = filteredData?.flatMap((agency: CountryData, index: number) => ({ + "Sr. No": (currentPage - 1) * (data?.data.per_page ?? 0) + index + 1, + "Title": agency.en_name, "Action": ( - + - + handleToggle(agency.id, agency.is_active)} + /> ), - })), -]; + })) -const Country = () => { return ( @@ -46,11 +111,11 @@ const Country = () => { px={3} > - Country + Country - } @@ -69,7 +134,14 @@ const Country = () => { bgColor={'#EEEEEE'} ps={8} /> - + */} + { + setSearchTerm(value); + setCurrentPage(1); + }} + /> {/* */} @@ -78,8 +150,15 @@ const Country = () => { sortableColumns={["Name", "Registration Date "]} tableHeadRow={tableHeadRow} data={managepost} + paginationData={{ + current_page: data?.data.current_page || 1, + last_page: data?.data.last_page || 1, + per_page: data?.data.per_page || 10, + total: data?.data.total || 0 + }} + onPageChange={handlePageChange} /> - + ) } diff --git a/src/Pages/MasterModule/Country/CountryAddModel.tsx b/src/Pages/MasterModule/Country/CountryAddModel.tsx index 0ba1064..b2a7834 100644 --- a/src/Pages/MasterModule/Country/CountryAddModel.tsx +++ b/src/Pages/MasterModule/Country/CountryAddModel.tsx @@ -2,55 +2,201 @@ import { DialogBody, DialogCloseTrigger, DialogContent, DialogFooter, DialogHead 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 { PostCountry, useCreateCountryPostMutation } from "../../../Redux/Service/country.master"; +import { Toaster, toaster } from "../../../components/ui/toaster"; function CountryAddModel() { - - return ( + const [createCountryPost] = useCreateCountryPostMutation() + const [isOpen, setIsOpen] = useState(false); + const [countryName, setCountryName] = useState({ + en_name: '', + country_code: '', + phonecode: '', + capital: '', + currency: '', + currency_name: '', + currency_symbol: '', + }); - - - {/* */} - - - - - - - Add - - - - - - - Country - - - - - - - - - - - + + + + + Add + + + + + + + Country + setCountryName({ ...countryName, en_name: e.target.value })} + /> + + Country Code + setCountryName({ ...countryName, country_code: e.target.value })} + /> + + Phone Code + setCountryName({ ...countryName, phonecode: e.target.value })} + /> + Capital + setCountryName({ ...countryName, capital: e.target.value })} + /> + Currency + setCountryName({ ...countryName, currency: e.target.value })} + /> + Currency name + setCountryName({ ...countryName, currency_name: e.target.value })} + /> + Currency Symbol + setCountryName({ ...countryName, currency_symbol: e.target.value })} + /> + + + + + + + + + + + + + ) } diff --git a/src/Pages/MasterModule/Country/EditCountryModel.tsx b/src/Pages/MasterModule/Country/EditCountryModel.tsx index 422c9e8..2b4f47e 100644 --- a/src/Pages/MasterModule/Country/EditCountryModel.tsx +++ b/src/Pages/MasterModule/Country/EditCountryModel.tsx @@ -8,59 +8,153 @@ import { DialogTitle, DialogTrigger, } from "../../../components/ui/dialog"; -import { Field, Input, Span, Stack } from "@chakra-ui/react"; +import { Field, Input, Stack } from "@chakra-ui/react"; import { Button } from "../../../components/ui/button"; import Edit from "../../../components/ActionIcons/Edit"; +import { useUpdateCountryMutation } from "../../../Redux/Service/country.master"; +import { Toaster, toaster } from "../../../components/ui/toaster"; +import { useEffect, useState } from "react"; + +export interface EditCountryModelProps { + 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; +} + + + + +function EditCountryModel({ rowData, refetch }: { rowData: EditCountryModelProps, refetch: VoidFunction }) { + const [updateCountry] = useUpdateCountryMutation() + const [editData, setEditData] = useState(rowData) + const [isOpen, setIsOpen] = useState(false); + + useEffect(() => { + if(rowData){ + setEditData(rowData) + } + }, [rowData]) + + + const handleOpenModal = () => { + setIsOpen(true); + }; + + const handleSubmit = async () => { + if (editData?.en_name === '') { + toaster.create({ + title: "Error", + description: "Input fields cannot be empty", + type: "error", + }); + return; + } + + // Only en_name is editable, so we only need to send that in the payload. + const payload = { + id: rowData?.id, + en_name: editData?.en_name, + country_code: rowData?.country_code, + phonecode: rowData?.phonecode, + capital: rowData?.capital, + currency: rowData?.currency, + currency_name: rowData?.currency_name, + currency_symbol: rowData?.currency_symbol, + }; + + // console.log('payload', payload) + + try { + const response = await updateCountry(payload).unwrap(); + if (response?.status === "success") { + toaster.create({ + title: "Success", + description: "Country updated successfully", + type: "success", + }); + setIsOpen(false); + refetch() + } else { + toaster.create({ + title: "Error", + description: "Failed to update Country", + type: "error", + }); + } + } catch (error) { + console.error("Error updating template:", error); + // alert("Failed to update template"); + toaster.create({ + title: "Error", + description: "Something went wrong", + type: "error", + }); + } + }; + -function EditCountryModel() { return ( - - - - + <> + setIsOpen(open)}> + + + - - - - Edit - - + + + + Edit + + + + + + + Country + + setEditData({ ...editData, en_name: e.target.value })} + bgColor="#EEEEEE" + color="black" + border="none" + pl={1} + fontSize="12px" + height="30px" + /> + + + + + + - - - - - Country - - - - - - - - - - - - + + + + + ); } diff --git a/src/Pages/MasterModule/IndustryMaster/IndustryMasterList.tsx b/src/Pages/MasterModule/IndustryMaster/IndustryMasterList.tsx index ccd9501..76f2231 100644 --- a/src/Pages/MasterModule/IndustryMaster/IndustryMasterList.tsx +++ b/src/Pages/MasterModule/IndustryMaster/IndustryMasterList.tsx @@ -1,13 +1,14 @@ -import { Box, HStack, Input, Text } from "@chakra-ui/react"; +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 { 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 { useGetIndustryMasterQuery, useIndustryMasterToggleMutation } from "../../../Redux/Service/industry.master.service"; import EditIndustryMaster from "./EditIndustryMaster"; import AddIndustryMaster from "./AddIndustryMaster"; +import SearchComponent from "../../../components/SearchComponent"; // table data @@ -42,9 +43,11 @@ const tableHeadRow = [ // ]; const IndustryMasterList = () => { - const { data, refetch } = useGetIndustryMasterQuery() + const [currentPage, setCurrentPage] = useState(1); + const { data, refetch } = useGetIndustryMasterQuery(currentPage) const [industryMasterToggle] = useIndustryMasterToggleMutation() const [localData, setLocalData] = useState([]); + const [searchTerm, setSearchTerm] = useState(""); useEffect(() => { if (data?.data?.data) { @@ -52,6 +55,10 @@ const IndustryMasterList = () => { } }, [data]); + const handlePageChange = (page: number) => { + setCurrentPage(page); + }; + const handleToggle = async (agencyId: string, currentStatus: number) => { const newStatus = currentStatus ? 0 : 1; setLocalData((prevData) => @@ -72,9 +79,15 @@ const IndustryMasterList = () => { } }; - const managepost = localData?.map((agency: any, index: number) => ({ + 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": index + 1, + "Sr. No": (currentPage - 1) * (data?.data.per_page ?? 0) + index + 1, "Title": agency.en_name, "is_active": agency.is_active, "Action": ( @@ -93,11 +106,11 @@ const IndustryMasterList = () => { ), })); - useEffect(() => { - console.log("Fetched data:", data); - console.log("Local data:", localData); - console.log("Managepost data:", managepost); - }, [data, localData, managepost]); + // useEffect(() => { + // console.log("Fetched data:", data); + // console.log("Local data:", localData); + // console.log("Managepost data:", managepost); + // }, [data, localData, managepost]); return ( @@ -115,37 +128,29 @@ const IndustryMasterList = () => { - - } - color={"#000"} - > - - + { + setSearchTerm(value); + setCurrentPage(1); + }} + /> {/* */} {/* */} - + diff --git a/src/Pages/MasterModule/JobType/JobType.tsx b/src/Pages/MasterModule/JobType/JobType.tsx index 81ffb2f..d4757e8 100644 --- a/src/Pages/MasterModule/JobType/JobType.tsx +++ b/src/Pages/MasterModule/JobType/JobType.tsx @@ -1,13 +1,14 @@ -import { Box, HStack, Input, Text } from "@chakra-ui/react"; +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 { InputGroup } from "../../../components/ui/input-group"; +// import { LuSearch } from "react-icons/lu"; import DataTable from "../../../components/DataTable"; import { Switch } from "../../../components/ui/switch"; import JobAddModel from "./JobAddModel"; import EditJobeModel from "./EditJobModel"; import { JobTypeData, useGetJobTypeQuery } from "../../../Redux/Service/job.type.service"; import { useEffect, useState } from "react"; +import SearchComponent from "../../../components/SearchComponent"; @@ -36,8 +37,10 @@ const tableHeadRow = [ // ]; const JobType = () => { - const { data, refetch } = useGetJobTypeQuery() + const [currentPage, setCurrentPage] = useState(1); + const { data, refetch } = useGetJobTypeQuery(currentPage) const [localData, setLocalData] = useState([]); + const [searchTerm, setSearchTerm] = useState(""); // const [templateMasterToggle] = useTemplateMasterToggleMutation() console.log('DATA', data?.data.data); @@ -48,6 +51,16 @@ const JobType = () => { } }, [data]); + const handlePageChange = (page: number) => { + setCurrentPage(page); + }; + + const filteredData = localData?.filter((agency) => { + const searchLower = searchTerm.toLowerCase(); + const title = agency.en_name?.toLowerCase().includes(searchLower); + return title; + }); + // const handleToggle = async (agencyId: string, currentStatus: number) => { // const newStatus = currentStatus ? 0 : 1; // setLocalData((prevData) => @@ -69,8 +82,8 @@ const JobType = () => { // }; - const managepost = localData?.map((agency: JobTypeData, index: number) => ({ - 'id': agency.id, + const managepost = filteredData?.map((agency: JobTypeData, index: number) => ({ + 'id': (currentPage - 1) * (data?.data.per_page ?? 0) + index + 1, "Sr. No": index + 1, "Title": agency.en_name, @@ -106,26 +119,13 @@ const JobType = () => { - - } - color={"#000"} - > - - + { + setSearchTerm(value); + setCurrentPage(1); + }} + /> {/* */} @@ -134,8 +134,13 @@ const JobType = () => { sortableColumns={["Name", "Registration Date "]} tableHeadRow={tableHeadRow} data={managepost} - paginationData={data?.data} - refetch={refetch} + paginationData={{ + current_page: data?.data.current_page || 1, + last_page: data?.data.last_page || 1, + per_page: data?.data.per_page || 10, + total: data?.data.total || 0 + }} + onPageChange={handlePageChange} /> diff --git a/src/Pages/MasterModule/TemplateMaster/TemplateMaster.tsx b/src/Pages/MasterModule/TemplateMaster/TemplateMaster.tsx index 38fe32b..031a0a6 100644 --- a/src/Pages/MasterModule/TemplateMaster/TemplateMaster.tsx +++ b/src/Pages/MasterModule/TemplateMaster/TemplateMaster.tsx @@ -45,7 +45,8 @@ const tableHeadRow = [ // ]; const TemplateMaster = () => { - const { data, refetch } = useGetTemplateMasterQuery() + const [currentPage, setCurrentPage] = useState(1); + const { data, refetch } = useGetTemplateMasterQuery(currentPage) const [localData, setLocalData] = useState([]); const [templateMasterToggle] = useTemplateMasterToggleMutation(); const [searchTerm, setSearchTerm] = useState(""); @@ -57,6 +58,10 @@ const TemplateMaster = () => { } }, [data]); + const handlePageChange = (page: number) => { + setCurrentPage(page); + }; + const handleToggle = async (agencyId: string, currentStatus: number) => { const newStatus = currentStatus ? 0 : 1; setLocalData((prevData) => @@ -83,7 +88,7 @@ const TemplateMaster = () => { const managepost = filteredData?.map((agency: Template, index: number) => ({ 'id': agency.id, - "Sr. No": index + 1, + "Sr. No": (currentPage - 1) * (data?.data.per_page ?? 0) + index + 1, "Title": agency.post_template_translate.length > 0 ? agency.post_template_translate[0].title : "N/A", @@ -160,8 +165,13 @@ const TemplateMaster = () => { sortableColumns={["Name", "Registration Date "]} tableHeadRow={tableHeadRow} data={managepost} - paginationData={data?.data.data} - refetch={refetch} + paginationData={{ + current_page: data?.data.current_page || 1, + last_page: data?.data.last_page || 1, + per_page: data?.data.per_page || 10, + total: data?.data.total || 0 + }} + onPageChange={handlePageChange} /> diff --git a/src/Redux/Service/agency.master.module.service.ts b/src/Redux/Service/agency.master.module.service.ts index 8b29368..f96d017 100644 --- a/src/Redux/Service/agency.master.module.service.ts +++ b/src/Redux/Service/agency.master.module.service.ts @@ -70,8 +70,8 @@ export const agencyMasterModule = createApi({ }), }), - getAgencyMaster: builder.query({ - query: () => "/agency-master" + getAgencyMaster: builder.query({ + query: (page = 1) => `/agency-master?page=${page}` }), agencyMasterToggle: builder.mutation({ diff --git a/src/Redux/Service/country.master.ts b/src/Redux/Service/country.master.ts new file mode 100644 index 0000000..f70f360 --- /dev/null +++ b/src/Redux/Service/country.master.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/Service/faqs.service.ts b/src/Redux/Service/faqs.service.ts index 2577898..332b87c 100644 --- a/src/Redux/Service/faqs.service.ts +++ b/src/Redux/Service/faqs.service.ts @@ -23,6 +23,8 @@ interface ApiResponse { last_page: number, total: number, from: number, + per_page: number, + to: number, data: FaqData[]; }; } @@ -48,8 +50,8 @@ export const faqs = createApi({ }), }), // 🔹 GET: Fetch all posts - getFaq: builder.query({ - query: () => "/faq-list", + getFaq: builder.query({ + query: (page = 1) => `/faq-list?page=${page}`, }), updateFaq: builder.mutation({ diff --git a/src/Redux/Service/industry.master.service.ts b/src/Redux/Service/industry.master.service.ts index 76a5e76..d227bf8 100644 --- a/src/Redux/Service/industry.master.service.ts +++ b/src/Redux/Service/industry.master.service.ts @@ -61,8 +61,8 @@ export const industryMaster = createApi({ }), }), // 🔹 GET: Fetch all posts - getIndustryMaster: builder.query({ - query: () => "/industry-master-list", + getIndustryMaster: builder.query({ + query: (page = 1) => `/industry-master-list?page=${page}`, }), updateIndustryMaster: builder.mutation({ diff --git a/src/Redux/Service/job.type.service.ts b/src/Redux/Service/job.type.service.ts index 3d8c5a9..6aa7dd0 100644 --- a/src/Redux/Service/job.type.service.ts +++ b/src/Redux/Service/job.type.service.ts @@ -59,8 +59,8 @@ export const jobType = createApi({ }), }), // 🔹 GET: Fetch all posts - getJobType: builder.query({ - query: () => "/job-type", + getJobType: builder.query({ + query: (page = 1) => `/job-type?page=${page}`, }), updateJobType: builder.mutation({ diff --git a/src/Redux/Service/template.master.service.ts b/src/Redux/Service/template.master.service.ts index e6a3ef6..f770228 100644 --- a/src/Redux/Service/template.master.service.ts +++ b/src/Redux/Service/template.master.service.ts @@ -73,8 +73,8 @@ export const templateMaster = createApi({ }), }), // 🔹 GET: Fetch all posts - getTemplateMaster: builder.query({ - query: () => "/template-master", + getTemplateMaster: builder.query({ + query: (page = 1) => `/template-master?page=${page}`, }), updateTemplateMaster: builder.mutation({ diff --git a/src/Redux/Store.tsx b/src/Redux/Store.tsx index a97cdac..3dd366c 100644 --- a/src/Redux/Store.tsx +++ b/src/Redux/Store.tsx @@ -19,6 +19,7 @@ import { templateMaster } from "./Service/template.master.service"; 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"; export const store = configureStore({ reducer: { @@ -41,6 +42,7 @@ export const store = configureStore({ [jobType.reducerPath]: jobType.reducer, [industryMaster.reducerPath]: industryMaster.reducer, [profile.reducerPath]: profile.reducer, + [countryMaster.reducerPath]: countryMaster.reducer, auth: authReducer, }, middleware: (getDefaultMiddleware) => @@ -63,6 +65,7 @@ export const store = configureStore({ jobType.middleware, industryMaster.middleware, profile.middleware, + countryMaster.middleware, ), }); diff --git a/src/components/DataTable.tsx b/src/components/DataTable.tsx index a43ee43..f7e33b1 100644 --- a/src/components/DataTable.tsx +++ b/src/components/DataTable.tsx @@ -1,4 +1,4 @@ -import { useEffect, useState } from "react"; +import { useState } from "react"; import { HStack, Stack, Table } from "@chakra-ui/react"; import { PaginationItems, PaginationNextTrigger, PaginationPrevTrigger, PaginationRoot } from "./ui/pagination"; // import { @@ -12,8 +12,13 @@ interface TableProps { tableHeadRow: string[]; data: Record[]; sortableColumns?: string[]; // Specify which columns are sortable - paginationData?: any, - refetch?: (params?: any) => void; + paginationData?: { + current_page: number; + last_page: number; + per_page: number; + total: number; + }, + onPageChange?: (page: number) => void; } const DataTable: React.FC = ({ @@ -21,30 +26,18 @@ const DataTable: React.FC = ({ data, sortableColumns = [], paginationData, - refetch -}) => { - const totalCount = paginationData?.total || 0; - const pageSize = paginationData?.per_page || 10; - const currentPage = paginationData?.current_page || 1; - const lastPage = paginationData?.last_page || 1; - const [page, setPage] = useState(currentPage); - - const [sortedData, setSortedData] = useState(data); + onPageChange +}: TableProps) => { + const { current_page = 1, last_page = 1 } = paginationData || {}; const [sortConfig, setSortConfig] = useState<{ key: string; direction: "asc" | "desc"; } | null>(null); - useEffect(() => { - setSortedData(data); - }, [data]); - - const handlePageChange = (newPage: any) => { - if (newPage >= 1 && newPage <= lastPage) { - setPage(newPage); - if (refetch) { - refetch({ page: newPage }); - } + const handlePageChange = (details: { page: number }) => { + const newPage = details.page; + if (newPage >= 1 && newPage <= last_page) { + onPageChange?.(newPage); } }; @@ -60,14 +53,9 @@ const DataTable: React.FC = ({ direction = "desc"; } - const sortedArray = [...sortedData].sort((a, b) => { - if (a[column] < b[column]) return direction === "asc" ? -1 : 1; - if (a[column] > b[column]) return direction === "asc" ? 1 : -1; - return 0; - }); - - setSortedData(sortedArray); - setSortConfig({ key: column, direction }); + const newSortConfig = { key: column, direction }; + setSortConfig(newSortConfig); + onPageChange?.(1); }; return ( @@ -110,7 +98,7 @@ const DataTable: React.FC = ({ - {sortedData.map((item: any, index) => ( + {data.map((item: any, index) => ( = ({ - {lastPage > 1 && 1 && ( - handlePageChange(page - 1)} disabled={page === 1} /> + handlePageChange({ page: current_page - 1 })} disabled={current_page === 1} /> - handlePageChange(page + 1)} disabled={page === lastPage} /> + handlePageChange({ page: current_page + 1 })} disabled={current_page === last_page} /> - } + )} ); }; diff --git a/src/components/ui/pagination.tsx b/src/components/ui/pagination.tsx index 92e7175..ff2fe62 100644 --- a/src/components/ui/pagination.tsx +++ b/src/components/ui/pagination.tsx @@ -198,16 +198,40 @@ export const PaginationNextTrigger = React.forwardRef< export const PaginationItems = (props: React.HTMLAttributes) => { return ( - {({ pages }) => - pages.map((page, index) => ( - - )) - } + {({ pages }) =>( + <> + {pages.map((page, index) => { + if(page.type === "ellipsis") { + return ( + ( + + ... + + ) + ) + } + if (page.type === 'page') { + return ( + + ); + } + + // Skip rendering for other types + return null; + })} + + )} ); }; From 963b85b15fb7d5a926070ba7af536ab5e847af05 Mon Sep 17 00:00:00 2001 From: rockyeverlast Date: Mon, 14 Apr 2025 19:34:59 +0530 Subject: [PATCH 08/12] 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 From 29f30f9f9849a8db200568e454306269f3677688 Mon Sep 17 00:00:00 2001 From: rockyeverlast Date: Tue, 15 Apr 2025 20:43:48 +0530 Subject: [PATCH 09/12] Api integrated for WorkSpace and JobStatus --- .../DepartmentMaster/EditDepartmentMaster.tsx | 3 +- .../JobStatus/EditJobStatusModel.tsx | 62 +++++++- .../MasterModule/JobStatus/JobStatus.tsx | 133 ++++++++++++----- .../JobStatus/JobStatusAddModel.tsx | 73 +++++++-- .../WorkspaceMode/EditWorkModel.tsx | 57 ++++++- .../WorkspaceMode/WorkAddModel.tsx | 76 ++++++++-- .../WorkspaceMode/WorkspaceMode.tsx | 139 +++++++++++++----- src/Redux/Service/job.status.ts | 69 ++++----- src/Redux/Service/workspace.mode.ts | 96 ++++++++++++ src/Redux/Store.tsx | 6 + 10 files changed, 558 insertions(+), 156 deletions(-) create mode 100644 src/Redux/Service/workspace.mode.ts diff --git a/src/Pages/MasterModule/DepartmentMaster/EditDepartmentMaster.tsx b/src/Pages/MasterModule/DepartmentMaster/EditDepartmentMaster.tsx index 13d262a..0364cec 100644 --- a/src/Pages/MasterModule/DepartmentMaster/EditDepartmentMaster.tsx +++ b/src/Pages/MasterModule/DepartmentMaster/EditDepartmentMaster.tsx @@ -12,7 +12,7 @@ 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 { Toaster, toaster } from "../../../components/ui/toaster"; import { useGetDepartmentMasterDropDownQuery, useUpdateDepartmentMutation } from "../../../Redux/Service/department.master"; function EditDepartmentMaster({ localData, refetch }: { localData: any, refetch: VoidFunction }) { @@ -152,6 +152,7 @@ function EditDepartmentMaster({ localData, refetch }: { localData: any, refetch: setIsOpen(false)} /> + ); } diff --git a/src/Pages/MasterModule/JobStatus/EditJobStatusModel.tsx b/src/Pages/MasterModule/JobStatus/EditJobStatusModel.tsx index 239b33b..f6d0f0a 100644 --- a/src/Pages/MasterModule/JobStatus/EditJobStatusModel.tsx +++ b/src/Pages/MasterModule/JobStatus/EditJobStatusModel.tsx @@ -1,19 +1,58 @@ import { DialogBody, DialogCloseTrigger, DialogContent, DialogFooter, DialogHeader, DialogRoot, DialogTitle, DialogTrigger } from "../../../components/ui/dialog" -import { Field, Input, Span, Stack } from "@chakra-ui/react" +import { Box, Field, Input, Stack } from "@chakra-ui/react" import { Button } from "../../../components/ui/button" // import { FaRegEdit } from "react-icons/fa"; import Edit from "../../../components/ActionIcons/Edit"; +import { useState } from "react"; +import { useUpdateJobStatusMutation } from "../../../Redux/Service/job.status"; +import { Toaster, toaster } from "../../../components/ui/toaster"; -function EditJobStatusModel() { +function EditJobStatusModel({ localData, refetch }: { localData: any, refetch: VoidFunction }) { + const [updateJobStatus] = useUpdateJobStatusMutation() + const [title, setTitle] = useState(localData.translation.title); + const [isOpen, setIsOpen] = useState(false); + console.log(localData); + + const handleOpenModal = () => { + if (localData) { + setIsOpen(true); + } + }; + const handleSubmit = async () => { + if (!title.trim()) { + toaster.create({ + title: "Error", + description: "Title field cannot be empty.", + type: "error", + }); + return; + } + + const payload = { + id: localData?.id, + title: title + }; + + try { + await updateJobStatus(payload).unwrap(); + refetch() + setIsOpen(false); + } catch (error) { + console.error("Error updating template:", error); + alert("Failed to update template"); + } + }; return ( - + setIsOpen(open)}> - + + + Job Status - + setTitle(e.target.value)} + /> - + - ) } diff --git a/src/Pages/MasterModule/JobStatus/JobStatus.tsx b/src/Pages/MasterModule/JobStatus/JobStatus.tsx index b99f0d3..6d465b5 100644 --- a/src/Pages/MasterModule/JobStatus/JobStatus.tsx +++ b/src/Pages/MasterModule/JobStatus/JobStatus.tsx @@ -1,11 +1,13 @@ -import { Box, HStack, Input, Text } from "@chakra-ui/react"; +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 JobStatusAddModel from "./JobStatusAddModel"; import EditJobStatusModel from "./EditJobStatusModel"; +import { useGetJobStatusQuery, useJobStatusToggleMutation } from "../../../Redux/Service/job.status"; +import { useEffect, useState } from "react"; +import SearchComponent from "../../../components/SearchComponent"; +import { toaster } from "../../../components/ui/toaster"; @@ -18,22 +20,93 @@ const tableHeadRow = [ ]; -const managepost: any[] = [ - ...Array.from({ length: 12 }, (_, i) => ({ - "Sr. No": i + 1, - "Title": "Lorem Ipsum", +// const managepost: any[] = [ +// ...Array.from({ length: 12 }, (_, i) => ({ +// "Sr. No": i + 1, +// "Title": "Lorem Ipsum", +// "Action": ( +// +// +// +// +// +// +// ), +// })), +// ]; + +const JobStatus = () => { + const [currentPage, setCurrentPage] = useState(1); + const { data, refetch } = useGetJobStatusQuery(currentPage) + const [localData, setLocalData] = useState([]); + const [searchTerm, setSearchTerm] = useState(""); + const [jobStatusToggle] = useJobStatusToggleMutation() + console.log(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 jobStatusToggle({ id: agencyId, is_active: newStatus }).unwrap(); + refetch() + } catch (error) { + console.error("Error updating:", error); + toaster.create({ + title: "Error", + description: "Someting went wrong.", + type: "error", + }); + setLocalData((prevData) => + prevData.map((agency) => + agency.id === agencyId ? { ...agency, is_active: currentStatus } : agency + ) + ); + } + }; + + const filteredData = localData?.filter((agency) => { + return (agency.job_status_translation.map((item: any) => { + const searchLower = searchTerm.toLowerCase(); + const title = item.title?.toLowerCase().includes(searchLower); + return title; + })) + }); + + const managepost = filteredData?.flatMap((agency: any, index: number) => (agency.job_status_translation.map((translation: any) => ({ + 'id': agency.id, + "Sr. No": (currentPage - 1) * (data?.data.per_page ?? 0) + index + 1, + "Title": translation.title, + "is_active": agency.is_active, "Action": ( - + {/* */} + - + handleToggle(agency.id, Number(agency.is_active))} + checked={Boolean(Number(agency.is_active))} + /> ), - })), -]; + })))); -const JobStatus = () => { return ( @@ -50,34 +123,28 @@ const JobStatus = () => { - - } - color={"#000"} - > - - + { + setSearchTerm(value); + setCurrentPage(1); + }} + /> {/* */} - + diff --git a/src/Pages/MasterModule/JobStatus/JobStatusAddModel.tsx b/src/Pages/MasterModule/JobStatus/JobStatusAddModel.tsx index f01b40d..095b303 100644 --- a/src/Pages/MasterModule/JobStatus/JobStatusAddModel.tsx +++ b/src/Pages/MasterModule/JobStatus/JobStatusAddModel.tsx @@ -2,31 +2,66 @@ import { DialogBody, DialogCloseTrigger, DialogContent, DialogFooter, DialogHead import { Field, Input, Stack, Text } from "@chakra-ui/react" import { IoMdAdd } from "react-icons/io" import { Button } from "../../../components/ui/button" +import { useCreateJobStatusPostMutation } from "../../../Redux/Service/job.status" +import { toaster } from "../../../components/ui/toaster" +import { useState } from "react" + +function JobStatusAddModel({ refetch }: { refetch: VoidFunction }) { + const [title, setTitle] = useState('') + const [isOpen, setIsOpen] = useState(false); + const [createJobStatusPost] = useCreateJobStatusPostMutation() + + const handleOpenModal = () => { + setIsOpen(true); + }; + + const handleSubmit = async () => { + if (!title.trim()) { + toaster.create({ + title: "Error", + description: "Title field cannot be empty.", + type: "error", + }); + return; + } + + const payload = { + title: title, + }; + + try { + await createJobStatusPost(payload).unwrap(); + refetch() + setIsOpen(false); + setTitle('') + } catch (error) { + console.error("Error updating template:", error); + alert("Failed to update template"); + } + }; -function JobStatusAddModel() { - return ( - + {/* */} - Add @@ -37,18 +72,28 @@ function JobStatusAddModel() { Job Status - + setTitle(e.target.value)} + /> - - + setIsOpen(false)} /> diff --git a/src/Pages/MasterModule/WorkspaceMode/EditWorkModel.tsx b/src/Pages/MasterModule/WorkspaceMode/EditWorkModel.tsx index d9bcb62..a85b43f 100644 --- a/src/Pages/MasterModule/WorkspaceMode/EditWorkModel.tsx +++ b/src/Pages/MasterModule/WorkspaceMode/EditWorkModel.tsx @@ -9,20 +9,64 @@ import { DialogTrigger, } from "../../../components/ui/dialog"; import { + Box, Field, Input, - Span, Stack, } from "@chakra-ui/react"; import { Button } from "../../../components/ui/button"; // import { FaRegEdit } from "react-icons/fa"; import Edit from "../../../components/ActionIcons/Edit"; +import { useState } from "react"; +import { toaster } from "../../../components/ui/toaster"; +import { useUpdateWorkSpaceMutation } from "../../../Redux/Service/workspace.mode"; + +function EditWorkModel({ localData, refetch }: {localData: any, refetch: VoidFunction}) { + const [title, setTitle] = useState(localData?.en_name); + const [isOpen, setIsOpen] = useState(false); + const [updateWorkSpace] = useUpdateWorkSpaceMutation() + console.log("localData", localData) + + const handleOpenModal = () => { + // const template = localData?.find((item: any) => item.id === id); + if (localData) { + setIsOpen(true); + // setTitle(localData?.localData.en_name); + } + }; + + + const handleSubmit = async () => { + if (!title.trim()) { + toaster.create({ + title: "Error", + description: "Title field cannot be empty.", + type: "error", + }); + return; + } + + const payload = { + id: localData?.id, + en_name: title + }; + + try { + await updateWorkSpace(payload).unwrap(); + refetch() + setIsOpen(false); + } catch (error) { + console.error("Error updating template:", error); + alert("Failed to update template"); + } + }; -function EditWorkModel() { return ( - + setIsOpen(open)}> - + + + setTitle(e.target.value)} /> - diff --git a/src/Pages/MasterModule/WorkspaceMode/WorkAddModel.tsx b/src/Pages/MasterModule/WorkspaceMode/WorkAddModel.tsx index 84f189e..becbddd 100644 --- a/src/Pages/MasterModule/WorkspaceMode/WorkAddModel.tsx +++ b/src/Pages/MasterModule/WorkspaceMode/WorkAddModel.tsx @@ -1,32 +1,67 @@ import { DialogBody, DialogCloseTrigger, DialogContent, DialogFooter, DialogHeader, DialogRoot, DialogTitle, DialogTrigger } from "../../../components/ui/dialog" -import {Field, Input, Stack, Text } from "@chakra-ui/react" +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 { useCreateWorkspacePostMutation } from "../../../Redux/Service/workspace.mode"; +import { Toaster, toaster } from "../../../components/ui/toaster"; + +function WorkAddModel({ refetch }: { refetch: VoidFunction }) { + const [title, setTitle] = useState('') + const [isOpen, setIsOpen] = useState(false); + const [createWorkspacePost] = useCreateWorkspacePostMutation() + + const handleOpenModal = () => { + setIsOpen(true); + }; + + const handleSubmit = async () => { + if (!title.trim()) { + toaster.create({ + title: "Error", + description: "Title field cannot be empty.", + type: "error", + }); + return; + } + + const payload = { + en_name: title, + }; + + try { + await createWorkspacePost(payload); + refetch() + setIsOpen(false); + setTitle('') + } catch (error) { + console.error("Error updating template:", error); + alert("Failed to update template"); + } + }; -function WorkAddModel() { - return ( - + {/* */} - Add @@ -37,19 +72,30 @@ function WorkAddModel() { Workspace Mode - + setTitle(e.target.value)} + /> - - + setIsOpen(false)} /> + ) diff --git a/src/Pages/MasterModule/WorkspaceMode/WorkspaceMode.tsx b/src/Pages/MasterModule/WorkspaceMode/WorkspaceMode.tsx index 99f7007..875fa2f 100644 --- a/src/Pages/MasterModule/WorkspaceMode/WorkspaceMode.tsx +++ b/src/Pages/MasterModule/WorkspaceMode/WorkspaceMode.tsx @@ -1,11 +1,13 @@ -import { Box, HStack, Input, Text } from "@chakra-ui/react"; +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 WorkAddModel from "./WorkAddModel"; import EditWorkModel from "./EditWorkModel"; +import { useEffect, useState } from "react"; +import { useGetWorkSpaceModeQuery, useWorkspaceToggleMutation } from "../../../Redux/Service/workspace.mode"; +import SearchComponent from "../../../components/SearchComponent"; +import { Toaster, toaster } from "../../../components/ui/toaster"; @@ -15,25 +17,95 @@ const tableHeadRow = [ "Sr. No", "Title", "Action" - + ]; -const managepost: any[] = [ - ...Array.from({ length: 12 }, (_, i) => ({ - "Sr. No": i + 1, - "Title": "Lorem Ipsum", +// const managepost: any[] = [ +// ...Array.from({ length: 12 }, (_, i) => ({ +// "Sr. No": i + 1, +// "Title": "Lorem Ipsum", +// "Action": ( +// +// +// +// +// +// +// ), +// })), +// ]; + +const WorkspaceMode = () => { + const [currentPage, setCurrentPage] = useState(1); + const { data, refetch } = useGetWorkSpaceModeQuery(currentPage) + const [localData, setLocalData] = useState([]); + const [searchTerm, setSearchTerm] = useState(""); + const [workspaceToggle] = useWorkspaceToggleMutation() + + console.log("Workspace 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 workspaceToggle({ id: agencyId, is_active: newStatus }).unwrap(); + refetch() + } catch (error) { + console.error("Error updating privacy policy:", error); + toaster.create({ + title: "Error", + description: "Someting went wrong.", + type: "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))} + /> ), - })), -]; + })); -const WorkspaceMode = () => { return ( @@ -46,40 +118,35 @@ const WorkspaceMode = () => { px={3} > - Workspace Mode + Workspace Mode - - } - color={"#000"} - > - - + { + setSearchTerm(value); + setCurrentPage(1); + }} + /> {/* */} - + - + + ) } diff --git a/src/Redux/Service/job.status.ts b/src/Redux/Service/job.status.ts index f70f360..2135cc3 100644 --- a/src/Redux/Service/job.status.ts +++ b/src/Redux/Service/job.status.ts @@ -1,22 +1,14 @@ import { createApi } from "@reduxjs/toolkit/query/react"; import { baseQueryWithReauth } from "./apiSlice"; -export interface CountryData { +export interface JobStatusData { 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; + job_status_translation:{ + job_status_xid: number, + title:string, + language_xid:number + }[], } interface ApiResponse { @@ -30,7 +22,7 @@ interface ApiResponse { from: number, per_page: number, to: number, - data: CountryData[]; + data: JobStatusData[]; }; } @@ -38,52 +30,42 @@ export interface CountryEdit { status: string; status_code: number; message: string; - data: CountryData[]; + data: JobStatusData[]; } -export type PostCountry = { - en_name: string; - country_code: string; - phonecode: string; - capital: string; - currency: string; - currency_name: string; - currency_symbol: string; +export type PostJobStatus = { + title: string }; -export const countryMaster = createApi({ - reducerPath: "countryMaster", +export const jobStatus = createApi({ + reducerPath: "jobStatus", baseQuery: baseQueryWithReauth, // Use enhanced baseQuery with error handling endpoints: (builder) => ({ - createCountryPost: builder.mutation>({ + createJobStatusPost: builder.mutation>({ query: (data) => ({ - url: "/country-add", + url: "/job-status-store", method: "POST", body: data, }), }), // 🔹 GET: Fetch all posts - getCountryMaster: builder.query({ - query: (page = 1) => `/country-list?page=${page}`, + getJobStatus: builder.query({ + query: (page = 1) => `/job-status-list?page=${page}`, }), - getCountryMasterEdit: builder.query({ - query: (id) => `/country-edit/${id}`, - }), - - updateCountry: builder.mutation({ + updateJobStatus: builder.mutation({ query: (updatedData) => ({ - url: "/country-update", + url: "/job-status-update", method: "POST", body: updatedData, }), }), - countryToggle: builder.mutation({ + jobStatusToggle: builder.mutation({ query: ({ id, is_active }) => ({ - url: `/country-status`, + url: `/job-status-status`, method: "POST", body: { id, is_active }, }), @@ -101,10 +83,9 @@ export const countryMaster = createApi({ }); export const { - useGetCountryMasterQuery, - useGetCountryMasterEditQuery, - useCreateCountryPostMutation, - useUpdateCountryMutation, - useCountryToggleMutation, + useGetJobStatusQuery, + useCreateJobStatusPostMutation, + useUpdateJobStatusMutation, + useJobStatusToggleMutation, // useDeleteFaqPostMutation -} = countryMaster; \ No newline at end of file +} = jobStatus; \ No newline at end of file diff --git a/src/Redux/Service/workspace.mode.ts b/src/Redux/Service/workspace.mode.ts new file mode 100644 index 0000000..8d88c49 --- /dev/null +++ b/src/Redux/Service/workspace.mode.ts @@ -0,0 +1,96 @@ +import { createApi } from "@reduxjs/toolkit/query/react"; +import { baseQueryWithReauth } from "./apiSlice"; + +export interface WorkspaceData { + id: number; + en_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: WorkspaceData[]; + }; +} + +export interface CountryEdit { + status: string; + status_code: number; + message: string; + data: WorkspaceData[]; +} + +export interface DropDown { + status: string; + status_code: number; + message: string; + data: { + id: number; + en_name: string; + }[] +} + +export type PostDepartment = { + en_name: string; +}; + + +export const workspaceMode = createApi({ + reducerPath: "workspaceMode", + baseQuery: baseQueryWithReauth, // Use enhanced baseQuery with error handling + endpoints: (builder) => ({ + createWorkspacePost: builder.mutation>({ + query: (data) => ({ + url: "/department-master-store", + method: "POST", + body: data, + }), + }), + // 🔹 GET: Fetch all posts + getWorkSpaceMode: builder.query({ + query: (page = 1) => `/workspace-mode?page=${page}`, + }), + + updateWorkSpace: builder.mutation({ + query: (updatedData) => ({ + url: "/workspace-update", + method: "POST", + body: updatedData, + }), + }), + + workspaceToggle: builder.mutation({ + query: ({ id, is_active }) => ({ + url: `/workspace-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 { + useGetWorkSpaceModeQuery, + useCreateWorkspacePostMutation, + useUpdateWorkSpaceMutation, + useWorkspaceToggleMutation, + // useDeleteFaqPostMutation +} = workspaceMode; \ No newline at end of file diff --git a/src/Redux/Store.tsx b/src/Redux/Store.tsx index 7d17505..167c063 100644 --- a/src/Redux/Store.tsx +++ b/src/Redux/Store.tsx @@ -21,6 +21,8 @@ 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"; +import { workspaceMode } from "./Service/workspace.mode"; +import { jobStatus } from "./Service/job.status"; export const store = configureStore({ reducer: { @@ -45,6 +47,8 @@ export const store = configureStore({ [profile.reducerPath]: profile.reducer, [countryMaster.reducerPath]: countryMaster.reducer, [departmentMaster.reducerPath]: departmentMaster.reducer, + [workspaceMode.reducerPath]: workspaceMode.reducer, + [jobStatus.reducerPath]: jobStatus.reducer, auth: authReducer, }, middleware: (getDefaultMiddleware) => @@ -69,6 +73,8 @@ export const store = configureStore({ profile.middleware, countryMaster.middleware, departmentMaster.middleware, + workspaceMode.middleware, + jobStatus.middleware, ), }); From e6e8f59afa5498448ac10da1a92daa1099c77f0b Mon Sep 17 00:00:00 2001 From: rockyeverlast Date: Mon, 5 May 2025 18:04:31 +0530 Subject: [PATCH 10/12] APi call from Manage post completed --- .env | 4 +- dev-dist/sw.js | 2 +- src/Pages/ManageJobs/ManageJobs.tsx | 12 +- src/Pages/ManagePost/ManagePost.tsx | 242 ++++++++++++++---- src/Pages/ManagePost/ViewDailog.tsx | 63 ++++- src/Pages/MasterModule/Country/Country.tsx | 3 +- .../DepartmentMaster/DepartmentMasterList.tsx | 3 +- .../IndustryMaster/IndustryMasterList.tsx | 3 +- .../MasterModule/JobStatus/JobStatus.tsx | 3 +- src/Pages/MasterModule/JobType/JobType.tsx | 3 +- .../WorkspaceMode/WorkspaceMode.tsx | 3 +- src/Redux/Service/manage.jobs.service.ts | 104 ++++++-- src/Redux/Service/manage.post.service.ts | 82 ++++++ src/Redux/Service/manage.posts.service.ts | 26 -- src/Redux/Store.tsx | 10 +- 15 files changed, 429 insertions(+), 134 deletions(-) create mode 100644 src/Redux/Service/manage.post.service.ts delete mode 100644 src/Redux/Service/manage.posts.service.ts diff --git a/.env b/.env index ec188ed..8f55d85 100644 --- a/.env +++ b/.env @@ -1,7 +1,9 @@ VITE_API_URL='https://ssa.betadelivery.com/apia/v1' +VITE_MAIN_URL='https://ssa.betadelivery.com' # VITE_API_URL='http://192.16.50.44/seo-backend/apia/v1' VITE_USER_NAME="Admin" VITE_PASSWORD="71%@L%es^bUX94`J9XT*@bh,._WWM{$%^^&&" # VITE_PASSWORD="71%@L%es^bUX94`J9XT*%4&^%tUU^%Q^ffgt" VITE_APP_NAME=MyViteApp -VITE_IMG_TEMPLATES='https://ssa.betadelivery.com/storage/app/public/uploads/post_templates/' \ No newline at end of file +VITE_IMG_TEMPLATES='https://ssa.betadelivery.com/storage/app/public/uploads/post_templates/' +VITE_POST_IMG=`${VITE_MAIN_URL}/storage/app/public/uploads/post/` \ No newline at end of file diff --git a/dev-dist/sw.js b/dev-dist/sw.js index 69b4925..266fb26 100644 --- a/dev-dist/sw.js +++ b/dev-dist/sw.js @@ -82,7 +82,7 @@ define(['./workbox-54d0af47'], (function (workbox) { 'use strict'; "revision": "3ca0b8505b4bec776b69afdba2768812" }, { "url": "index.html", - "revision": "0.4sre1e6vpfo" + "revision": "0.bma87cujt8g" }], {}); workbox.cleanupOutdatedCaches(); workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("index.html"), { diff --git a/src/Pages/ManageJobs/ManageJobs.tsx b/src/Pages/ManageJobs/ManageJobs.tsx index 2daf901..744fd6e 100644 --- a/src/Pages/ManageJobs/ManageJobs.tsx +++ b/src/Pages/ManageJobs/ManageJobs.tsx @@ -1,6 +1,8 @@ -import { Box, HStack, +import { + Box, HStack, // Image, - Input, Text } from "@chakra-ui/react"; + Input, Text +} from "@chakra-ui/react"; import { LuSearch } from "react-icons/lu"; // import { RiDeleteBin5Line } from "react-icons/ri"; // import AlertDailog from "../../components/AlertDailog"; @@ -9,6 +11,8 @@ import MainFrame from "../../components/MainFrame"; import { InputGroup } from "../../components/ui/input-group"; import ManageJobsAdd from "./ManageJobsAdd"; import ViewManageJob from "./ViewManageJob"; +// import { useState } from "react"; +// import { useGetManageJobsQuery } from "../../Redux/Service/manage.jobs.service"; // import Delete from "../../components/ActionIcons/Delete"; // table data @@ -50,6 +54,10 @@ const managepost: any[] = [ ]; const ManageJobs = () => { + // const [currentPage, setCurrentPage] = useState(1); + // const { data, refetch } = useGetManageJobsQuery(currentPage) + // console.log(data?.data.data); + return ( diff --git a/src/Pages/ManagePost/ManagePost.tsx b/src/Pages/ManagePost/ManagePost.tsx index c9e5dd2..e55c559 100644 --- a/src/Pages/ManagePost/ManagePost.tsx +++ b/src/Pages/ManagePost/ManagePost.tsx @@ -1,67 +1,205 @@ -import { Box, HStack, Image, Input, +import { + Box, HStack, Icon, Image, // Span, - Text } from "@chakra-ui/react"; + Text +} from "@chakra-ui/react"; import MainFrame from "../../components/MainFrame"; -import { InputGroup } from "../../components/ui/input-group"; -import { LuSearch } from "react-icons/lu"; +// import { InputGroup } from "../../components/ui/input-group"; +// import { LuSearch } from "react-icons/lu"; import DataTable from "../../components/DataTable"; // import AlertDailog from "../../components/AlertDailog"; import { Switch } from "../../components/ui/switch"; -import img from "../../assets/waterfall.jpg"; +// import img from "../../assets/waterfall.jpg"; // import { RiDeleteBin5Line } from "react-icons/ri"; import ViewDailog from "./ViewDailog"; +import { useGetManagePostsQuery, usePostStatusToggleMutation } from "../../Redux/Service/manage.post.service"; +import { useEffect, useState } from "react"; +import { toaster } from "../../components/ui/toaster"; +import { FaVideo } from "react-icons/fa"; +import SearchComponent from "../../components/SearchComponent"; // import Delete from "../../components/ActionIcons/Delete"; // import ViewDailog from './ViewDailog' -// table data +const APIURL = import.meta.env.VITE_POST_IMG const tableHeadRow = [ "Sr. No", "Images", "Description", "Publish Data", - "Activate/Deactivate", + // "Activate/Deactivate", "Action", ]; -const managepost: any[] = [ - ...Array.from({ length: 12 }, (_, i) => ({ - "Sr. No": i + 1, +// const managepost: any[] = [ +// ...Array.from({ length: 12 }, (_, i) => ({ +// "Sr. No": i + 1, +// Images: ( +// // +// +// ), +// Description: ( +// +// {`Lorem ipsum dolor, sit amet consectetur adipisicing elit.}`.slice( +// 0, +// 30 +// ) + "..."} +// +// ), +// "Publish Data": "12/01/2025", +// "Activate/Deactivate": ( +// +// +// +// ), +// Action: ( +// +// +// {/* } +// alertText="Delete Users" +// alertIcon={} +// alertCaption="are you sure you want to delete ?" +// onConfirm={() => { +// console.log("User deleted:", i + 1); +// }} +// /> */} +// +// ), +// })), +// ]; + +const ManagePost = () => { + const [currentPage, setCurrentPage] = useState(1); + const { data, refetch } = useGetManagePostsQuery(currentPage) + const [localData, setLocalData] = useState([]); + const [searchTerm, setSearchTerm] = useState(""); + const [postStatusToggle] = usePostStatusToggleMutation() + console.log('POSTS', 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 postStatusToggle({ id: agencyId, is_active: newStatus }).unwrap(); + refetch() + } catch (error) { + console.error("Error updating:", error); + toaster.create({ + title: "Error", + description: "Someting went wrong.", + type: "error", + }); + setLocalData((prevData) => + prevData.map((agency) => + agency.id === agencyId ? { ...agency, is_active: currentStatus } : agency + ) + ); + } + }; + + + function formatAPIDate(apiDateString: any) { + const date = new Date(apiDateString); + + // Get month, day, and year + const month = date.getMonth() + 1; // Months are 0-indexed + const day = date.getDate(); + const year = date.getFullYear(); + + // Pad with leading zeros if needed + const formattedMonth = month.toString().padStart(2, '0'); + const formattedDay = day.toString().padStart(2, '0'); + + return `${formattedMonth}/${formattedDay}/${year}`; + } + + const filteredData = localData?.filter((agency) => { + return (agency.post_content_translation.some((item: any) => { + const searchLower = searchTerm.toLowerCase(); + const title = item.content?.toLowerCase().includes(searchLower); + return title; + })) + }); + + const managepost = filteredData?.flatMap((agency: any, index: number) => (agency.post_content_translation.map((translation: any) => ({ + 'id': agency.id, + "Sr. No": (currentPage - 1) * (data?.data.per_page ?? 0) + index + 1, Images: ( - // - + agency.images.length > 0 ? + agency.images[0].type === "image" ? ( + + + + {`${Number(agency.images.length) > 1 ? '+' + (Number(agency.images.length) - 1) : ''}`} + + + ) : ( + + + + + + {`${Number(agency.images.length) > 1 ? '+' + (Number(agency.images.length) - 1) : ''}`} + + + ) : '' + // ), Description: ( - {`Lorem ipsum dolor, sit amet consectetur adipisicing elit.}`.slice( + {`${translation?.content}`.slice( 0, 30 ) + "..."} ), - "Publish Data": "12/01/2025", - "Activate/Deactivate": ( - - - - ), - Action: ( + "Publish Data": formatAPIDate(agency.created_at), + "is_active": agency.is_active, + "Action": ( - - {/* } - alertText="Delete Users" - alertIcon={} - alertCaption="are you sure you want to delete ?" - onConfirm={() => { - console.log("User deleted:", i + 1); - }} - /> */} + {/* */} + + + handleToggle(agency.id, Number(agency.is_active))} + checked={Boolean(Number(agency.is_active))} + /> + ), - })), -]; -const ManagePost = () => { + })))); + + return ( @@ -77,35 +215,27 @@ const ManagePost = () => { - - } - color={"#000"} - > - - + { + setSearchTerm(value); + // setCurrentPage(1); + refetch() + }} + /> diff --git a/src/Pages/ManagePost/ViewDailog.tsx b/src/Pages/ManagePost/ViewDailog.tsx index f2fc6d4..9688341 100644 --- a/src/Pages/ManagePost/ViewDailog.tsx +++ b/src/Pages/ManagePost/ViewDailog.tsx @@ -1,15 +1,18 @@ -import { Field, Image, Input, Span, Stack } from "@chakra-ui/react" +import { Field, HStack, Image, Input, Stack } from "@chakra-ui/react" // import { TbEdit } from "react-icons/tb" -import img from "../../assets/waterfall.jpg" +// import img from "../../assets/waterfall.jpg" import { DialogBody, DialogCloseTrigger, DialogContent, DialogHeader, DialogRoot, DialogTitle, DialogTrigger } from "../../components/ui/dialog" -import Edit from "../../components/ActionIcons/Edit" +// import Edit from "../../components/ActionIcons/Edit" +import { LuEye } from "react-icons/lu" -function ViewDailog() { +const APIURL = import.meta.env.VITE_POST_IMG + +function ViewDailog({ localData }: { localData: any, refetch: VoidFunction }) { return ( - - + {/* */} + - Title - - - Subtitle - - Description - + + {/* Subtitle + */} + + {/* Description + */} Image - + + {localData.images.map((img: any) => ( + img.type === 'image' ? ( + + ) : ( + + ) + ))} + + + {/* */} diff --git a/src/Pages/MasterModule/Country/Country.tsx b/src/Pages/MasterModule/Country/Country.tsx index 9b0c5a1..c2be07a 100644 --- a/src/Pages/MasterModule/Country/Country.tsx +++ b/src/Pages/MasterModule/Country/Country.tsx @@ -139,7 +139,8 @@ const Country = () => { value={searchTerm} onChange={(value) => { setSearchTerm(value); - setCurrentPage(1); + // setCurrentPage(1); + refetch() }} /> {/* */} diff --git a/src/Pages/MasterModule/DepartmentMaster/DepartmentMasterList.tsx b/src/Pages/MasterModule/DepartmentMaster/DepartmentMasterList.tsx index 351cea5..fc4e7ae 100644 --- a/src/Pages/MasterModule/DepartmentMaster/DepartmentMasterList.tsx +++ b/src/Pages/MasterModule/DepartmentMaster/DepartmentMasterList.tsx @@ -114,7 +114,8 @@ const DepartmentMasterList = () => { value={searchTerm} onChange={(value) => { setSearchTerm(value); - setCurrentPage(1); + // setCurrentPage(1); + refetch() }} /> {/* */} diff --git a/src/Pages/MasterModule/IndustryMaster/IndustryMasterList.tsx b/src/Pages/MasterModule/IndustryMaster/IndustryMasterList.tsx index 76f2231..55b8213 100644 --- a/src/Pages/MasterModule/IndustryMaster/IndustryMasterList.tsx +++ b/src/Pages/MasterModule/IndustryMaster/IndustryMasterList.tsx @@ -132,7 +132,8 @@ const IndustryMasterList = () => { value={searchTerm} onChange={(value) => { setSearchTerm(value); - setCurrentPage(1); + // setCurrentPage(1); + refetch() }} /> {/* */} diff --git a/src/Pages/MasterModule/JobStatus/JobStatus.tsx b/src/Pages/MasterModule/JobStatus/JobStatus.tsx index 6d465b5..17852a3 100644 --- a/src/Pages/MasterModule/JobStatus/JobStatus.tsx +++ b/src/Pages/MasterModule/JobStatus/JobStatus.tsx @@ -127,7 +127,8 @@ const JobStatus = () => { value={searchTerm} onChange={(value) => { setSearchTerm(value); - setCurrentPage(1); + // setCurrentPage(1); + refetch() }} /> {/* */} diff --git a/src/Pages/MasterModule/JobType/JobType.tsx b/src/Pages/MasterModule/JobType/JobType.tsx index d4757e8..df048c1 100644 --- a/src/Pages/MasterModule/JobType/JobType.tsx +++ b/src/Pages/MasterModule/JobType/JobType.tsx @@ -123,7 +123,8 @@ const JobType = () => { value={searchTerm} onChange={(value) => { setSearchTerm(value); - setCurrentPage(1); + // setCurrentPage(1); + refetch() }} /> {/* */} diff --git a/src/Pages/MasterModule/WorkspaceMode/WorkspaceMode.tsx b/src/Pages/MasterModule/WorkspaceMode/WorkspaceMode.tsx index 875fa2f..a094097 100644 --- a/src/Pages/MasterModule/WorkspaceMode/WorkspaceMode.tsx +++ b/src/Pages/MasterModule/WorkspaceMode/WorkspaceMode.tsx @@ -126,7 +126,8 @@ const WorkspaceMode = () => { value={searchTerm} onChange={(value) => { setSearchTerm(value); - setCurrentPage(1); + // setCurrentPage(1); + refetch() }} /> {/* */} diff --git a/src/Redux/Service/manage.jobs.service.ts b/src/Redux/Service/manage.jobs.service.ts index c5face7..0ce6b24 100644 --- a/src/Redux/Service/manage.jobs.service.ts +++ b/src/Redux/Service/manage.jobs.service.ts @@ -1,26 +1,84 @@ -import { createApi } from "@reduxjs/toolkit/query"; +import { createApi } from "@reduxjs/toolkit/query/react"; import { baseQueryWithReauth } from "./apiSlice"; -export const manageJobs = createApi({ - reducerPath: "manageJobs", - baseQuery: baseQueryWithReauth, // Use enhanced baseQuery with error handling - endpoints: (builder) => ({ - - - - getPosts: builder.query({ query: () => "/posts" }), - - - - - - }), - }); - - export const { } = manageJobs; - - export type Post = { +export interface JobStatusData { + id: number; + job_title: string; + workspace_mode_xid: number; + industry_xid: number; + department_xid: number; + company_name: string; + ctc_currency_symbol: string; + ctc_amount: string; + experience: string; + job_location: string; + country_xid: number; + job_type_xid: number; + skill_description: string; + job_description: string; + job_image: string | null; + industry: { id: number; - title: string; - body: string; - }; \ No newline at end of file + en_name: string; + }; + department: { + id: number; + en_name: string; + }; + workspace: { + id: number; + en_name: string; + }; + country: { + id: number; + en_name: string; + }; + job_type: { + id: number; + en_name: 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: JobStatusData[]; + }; +} + +export interface CountryEdit { + status: string; + status_code: number; + message: string; + data: JobStatusData[]; +} + + +export type PostJobStatus = { + title: string +}; + +export const manageJobs = createApi({ + reducerPath: "manageJobs", + baseQuery: baseQueryWithReauth, // Use enhanced baseQuery with error handling + endpoints: (builder) => ({ + getManageJobs: builder.query({ + query: (page = 1) => `/manage-jobs-list?page=${page}`, + }), + + + + + + }), +}); + +export const { useGetManageJobsQuery } = manageJobs; diff --git a/src/Redux/Service/manage.post.service.ts b/src/Redux/Service/manage.post.service.ts new file mode 100644 index 0000000..8c32391 --- /dev/null +++ b/src/Redux/Service/manage.post.service.ts @@ -0,0 +1,82 @@ +import { createApi } from "@reduxjs/toolkit/query/react"; +import { baseQueryWithReauth } from "./apiSlice"; + +export interface JobStatusData { + id: number; + is_active: string; + created_at:string, + job_status_translation:{ + job_status_xid: number, + title:string, + language_xid:number + }[], +} + +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: JobStatusData[]; + }; +} + +export interface CountryEdit { + status: string; + status_code: number; + message: string; + data: JobStatusData[]; +} + + +export type PostJobStatus = { + title: string +}; + + +export const managePosts = createApi({ + reducerPath: "managePosts", + baseQuery: baseQueryWithReauth, // Use enhanced baseQuery with error handling + endpoints: (builder) => ({ + // createJobStatusPost: builder.mutation>({ + // query: (data) => ({ + // url: "/job-status-store", + // method: "POST", + // body: data, + // }), + // }), + // 🔹 GET: Fetch all posts + getManagePosts: builder.query({ + query: (page = 1) => `/manage-post-list?page=${page}`, + }), + + postStatusToggle: builder.mutation({ + query: ({ id, is_active }) => ({ + url: `/manage-post-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 { + useGetManagePostsQuery, + usePostStatusToggleMutation, + // useDeleteFaqPostMutation +} = managePosts; \ No newline at end of file diff --git a/src/Redux/Service/manage.posts.service.ts b/src/Redux/Service/manage.posts.service.ts deleted file mode 100644 index d51e7ab..0000000 --- a/src/Redux/Service/manage.posts.service.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { createApi } from "@reduxjs/toolkit/query"; -import { baseQueryWithReauth } from "./apiSlice"; - -export const managePosts = createApi({ - reducerPath: "managePosts", - baseQuery: baseQueryWithReauth, // Use enhanced baseQuery with error handling - endpoints: (builder) => ({ - - - - getPosts: builder.query({ query: () => "/posts" }), - - - - - - }), - }); - - export const { } = managePosts; - - export type Post = { - id: number; - title: string; - body: string; - }; \ No newline at end of file diff --git a/src/Redux/Store.tsx b/src/Redux/Store.tsx index 167c063..6619090 100644 --- a/src/Redux/Store.tsx +++ b/src/Redux/Store.tsx @@ -4,7 +4,6 @@ import authReducer from "./Service/authSlice"; import { registerUser } from "./Service/register.user.service"; import { deactivatedAccounts } from "./Service/deactivated.account.service"; import { faqs } from "./Service/faqs.service"; -import { managePosts } from "./Service/manage.posts.service"; import { manageSubAdmin } from "./Service/manage.subadmin.service"; import { manageJobs } from "./Service/manage.jobs.service"; import { manageGroups } from "./Service/manage.groups.service"; @@ -23,6 +22,7 @@ import { countryMaster } from "./Service/country.master"; import { departmentMaster } from "./Service/department.master"; import { workspaceMode } from "./Service/workspace.mode"; import { jobStatus } from "./Service/job.status"; +import { managePosts } from "./Service/manage.post.service"; export const store = configureStore({ reducer: { @@ -30,7 +30,6 @@ export const store = configureStore({ [registerUser.reducerPath]: registerUser.reducer, [deactivatedAccounts.reducerPath]: deactivatedAccounts.reducer, [faqs.reducerPath]: faqs.reducer, - [managePosts.reducerPath]: managePosts.reducer, [manageSubAdmin.reducerPath]: manageSubAdmin.reducer, [manageJobs.reducerPath]: manageJobs.reducer, [manageGroups.reducerPath]: manageGroups.reducer, @@ -49,13 +48,13 @@ export const store = configureStore({ [departmentMaster.reducerPath]: departmentMaster.reducer, [workspaceMode.reducerPath]: workspaceMode.reducer, [jobStatus.reducerPath]: jobStatus.reducer, + [managePosts.reducerPath]: managePosts.reducer, auth: authReducer, }, middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat( - dashboard.middleware, + dashboard.middleware, deactivatedAccounts.middleware, - managePosts.middleware, faqs.middleware, manageSubAdmin.middleware, manageJobs.middleware, @@ -75,7 +74,8 @@ export const store = configureStore({ departmentMaster.middleware, workspaceMode.middleware, jobStatus.middleware, - ), + managePosts.middleware, + ), }); export type RootState = ReturnType; From f1772a7e077b697fcf0e605e7e72444368d1d91e Mon Sep 17 00:00:00 2001 From: rockyeverlast Date: Mon, 5 May 2025 18:13:33 +0530 Subject: [PATCH 11/12] Uploads img url updated --- .env | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.env b/.env index d495681..7328291 100644 --- a/.env +++ b/.env @@ -10,4 +10,6 @@ VITE_USER_NAME="Admin" VITE_PASSWORD="71%@L%es^bUX94`J9XT*@bh,._WWM{$%^^&&" # VITE_PASSWORD="71%@L%es^bUX94`J9XT*%4&^%tUU^%Q^ffgt" VITE_APP_NAME=MyViteApp -VITE_IMG_TEMPLATES='https://ssa.betadelivery.com/testing/storage/app/public/uploads/post_templates/' \ No newline at end of file +VITE_IMG_TEMPLATES='https://ssa.betadelivery.com/testing/storage/app/public/uploads/post_templates/' +VITE_MAIN_URL='https://ssa.betadelivery.com/testing' +VITE_POST_IMG=`${VITE_MAIN_URL}/storage/app/public/uploads/post/` \ No newline at end of file From 4a1a9584751648bc9bc947170ce04583b1ccaab5 Mon Sep 17 00:00:00 2001 From: rockyeverlast Date: Sat, 31 May 2025 23:53:54 +0530 Subject: [PATCH 12/12] API integration for register user list --- src/Pages/Login.tsx | 8 +- src/Pages/ManageCMS/FAQ/FAQ.tsx | 2 +- .../RegisterUsers/RegisterUsers.tsx | 187 ++++++++++++------ src/Redux/Service/manage.user.ts | 108 ++++++++++ src/Redux/Service/register.user.service.ts | 26 --- src/Redux/Store.tsx | 5 +- 6 files changed, 245 insertions(+), 91 deletions(-) create mode 100644 src/Redux/Service/manage.user.ts delete mode 100644 src/Redux/Service/register.user.service.ts diff --git a/src/Pages/Login.tsx b/src/Pages/Login.tsx index a023088..fa551c8 100644 --- a/src/Pages/Login.tsx +++ b/src/Pages/Login.tsx @@ -77,13 +77,13 @@ const Login = () => { console.log(res); console.log("===================================="); } - } catch (error) { - console.log('error', error); + } catch (error: any) { + console.log('error', error.response.data.message); if (error) { toaster.create({ - // title: error?.response?.data?.message, - title: "Something Went Wrong", + title: error?.response?.data?.message, + // title: "Something Went Wrong", type: "info", }) // console.log("Login failed", error?.response?.data?.message); diff --git a/src/Pages/ManageCMS/FAQ/FAQ.tsx b/src/Pages/ManageCMS/FAQ/FAQ.tsx index 94f54f8..c1def1d 100644 --- a/src/Pages/ManageCMS/FAQ/FAQ.tsx +++ b/src/Pages/ManageCMS/FAQ/FAQ.tsx @@ -137,7 +137,7 @@ const FAQ = () => { "Sr. No": (currentPage - 1) * (data?.data.per_page ?? 0) + index + 1, "Question": translation.question, "Answer": translation.answer, - 'Category': agency.principal_type_xid === 2 ? "Job Seeker" : "Recruiter", + 'Category': agency.principal_type_xid === 2 ? "Recruiter" : "Job Seeker", "Action": ( diff --git a/src/Pages/ManageUsers/RegisterUsers/RegisterUsers.tsx b/src/Pages/ManageUsers/RegisterUsers/RegisterUsers.tsx index ce674f1..484953f 100644 --- a/src/Pages/ManageUsers/RegisterUsers/RegisterUsers.tsx +++ b/src/Pages/ManageUsers/RegisterUsers/RegisterUsers.tsx @@ -1,16 +1,19 @@ -import { Box, HStack, +import { + Box, HStack, // Image, - Input, Text } from "@chakra-ui/react"; + Text +} from "@chakra-ui/react"; import MainFrame from "../../../components/MainFrame"; // import AlertDailog from "../../../components/AlertDailog"; // import { RiDeleteBin5Line } from "react-icons/ri"; import DataTable from "../../../components/DataTable"; import { Switch } from "../../../components/ui/switch"; -import { InputGroup } from "../../../components/ui/input-group"; -import { LuSearch } from "react-icons/lu"; import ViewRegisterUsers from "./ViewRegisterUsers"; import EditRegisterUsers from "./EditRegisterUsers"; import AddRegisterUsers from "./AddRegisterUsers"; +import { useEffect, useState } from "react"; +import { useGetManageUserQuery, UserData, useUserToggleMutation } from "../../../Redux/Service/manage.user"; +import SearchComponent from "../../../components/SearchComponent"; // import Delete from "../../../components/ActionIcons/Delete"; const tableHeadRow = [ @@ -25,40 +28,113 @@ const tableHeadRow = [ "Action", ]; -const registerUser: any[] = [ - ...Array.from({ length: 12 }, (_, i) => ({ - "Sr. No": i + 1, - "First Name": "Ritesh", - "Mobile Number": "akanksha@gmail.com", - "Gender": "9876543210", - "DOB": "Female", - "Type Of User": "15-01-1990", - "Language": "Mumbai", - "Activate/Deactivate": ( - - - - ), - "Action": ( - - - - {/* */} - {/* } // Pass as function - alertText="Delete Users" - alertIcon={} - alertCaption="Are You Sure You Want To Delete This User ?" - onConfirm={() => { - console.log("User deleted:", i + 1); - }} - /> */} - - ), - })), -]; +// const registerUser: any[] = [ +// ...Array.from({ length: 12 }, (_, i) => ({ +// "Sr. No": i + 1, +// "First Name": "Ritesh", +// "Mobile Number": "akanksha@gmail.com", +// "Gender": "9876543210", +// "DOB": "Female", +// "Type Of User": "15-01-1990", +// "Language": "Mumbai", +// "Activate/Deactivate": ( +// +// +// +// ), +// "Action": ( +// +// +// +// {/* */} +// {/* } // Pass as function +// alertText="Delete Users" +// alertIcon={} +// alertCaption="Are You Sure You Want To Delete This User ?" +// onConfirm={() => { +// console.log("User deleted:", i + 1); +// }} +// /> */} +// +// ), +// })), +// ]; const RegisterUsers = () => { + const [currentPage, setCurrentPage] = useState(1); + const { data, refetch } = useGetManageUserQuery(currentPage) + const [localData, setLocalData] = useState([]); + const [searchTerm, setSearchTerm] = useState(""); + const [userToggle] = useUserToggleMutation() + console.log("Register Users Data", data?.data.data); + + useEffect(() => { + if (data) { + setLocalData(data?.data.data); + } + }, [data]); + + const handlePageChange = (page: number) => { + setCurrentPage(page); + } + + const filteredData = localData?.filter((agency) => { + const searchLower = searchTerm.toLowerCase(); + const firstName = agency.first_name?.toLowerCase().includes(searchLower); + // const email = agency.capital?.toLowerCase().includes(searchLower); + return firstName; + }); + + const handleToggle = async (agencyId: number, currentStatus: string) => { + const newStatus = currentStatus === '1' ? '0' : '1'; + + setLocalData((prevData) => + prevData.map((agency) => + agency.id === agencyId ? { ...agency, is_active: newStatus } : agency + ) + ); + + try { + await userToggle({ 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 managepost = filteredData?.flatMap((agency: UserData, index: number) => ({ + "Sr. No": (currentPage - 1) * (data?.data.per_page ?? 0) + index + 1, + "First Name": agency.first_name, + "Mobile Number": agency.phone_number, + "Gender": agency.gender, + "DOB": agency.date_of_birth ? new Date(agency.date_of_birth).toLocaleDateString('en-GB').replace(/\//g, '-') : 'N/A', + "Type Of User": agency.principal_type?.principal_type_title || 'N/A', + // "Language": agency.principle_language_links.map(lang => lang.language_name).join(', ') || 'N/A', + "Action": ( + + + + + handleToggle(agency.id, agency.is_active ? '1' : '0')} + /> + + + ), + })) + return ( @@ -73,34 +149,29 @@ const RegisterUsers = () => { Register Users - - - } - color={"#000"} - > - - + + { + setSearchTerm(value); + // setCurrentPage(1); + refetch() + }} + /> diff --git a/src/Redux/Service/manage.user.ts b/src/Redux/Service/manage.user.ts new file mode 100644 index 0000000..f2be3f0 --- /dev/null +++ b/src/Redux/Service/manage.user.ts @@ -0,0 +1,108 @@ +import { createApi } from "@reduxjs/toolkit/query/react"; +import { baseQueryWithReauth } from "./apiSlice"; + +export interface UserData { + id: number; + principal_type_xid: number + first_name: string; + last_name: string; + phone_number: string; + gender: string; + date_of_birth: string; + is_active: boolean; + principal_type:{ + id: number; + principal_type_title: string; + }, + principle_language_links:[] +} + +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: UserData[]; + }; +} + +export interface CountryEdit { + status: string; + status_code: number; + message: string; + data: UserData[]; +} + + +export type PostCountry = { + en_name: string; + country_code: string; + phonecode: string; + capital: string; + currency: string; + currency_name: string; + currency_symbol: string; +}; + + +export const registerUser = createApi({ + reducerPath: "registerUser", + 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 + getManageUser: builder.query({ + query: (page = 1) => `/manage-user-list?page=${page}`, + }), + + getCountryMasterEdit: builder.query({ + query: (id) => `/country-edit/${id}`, + }), + + updateCountry: builder.mutation({ + query: (updatedData) => ({ + url: "/country-update", + method: "POST", + body: updatedData, + }), + }), + + userToggle: builder.mutation({ + query: ({ id, is_active }) => ({ + url: `/manage-user-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 { + useGetManageUserQuery, + useGetCountryMasterEditQuery, + useCreateCountryPostMutation, + useUpdateCountryMutation, + useUserToggleMutation, + // useDeleteFaqPostMutation +} = registerUser; \ No newline at end of file diff --git a/src/Redux/Service/register.user.service.ts b/src/Redux/Service/register.user.service.ts deleted file mode 100644 index 801912d..0000000 --- a/src/Redux/Service/register.user.service.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { createApi } from "@reduxjs/toolkit/query"; -import { baseQueryWithReauth } from "./apiSlice"; - -export const registerUser = createApi({ - reducerPath: "registerUser", - baseQuery: baseQueryWithReauth, // Use enhanced baseQuery with error handling - endpoints: (builder) => ({ - - - - getPosts: builder.query({ query: () => "/posts" }), - - - - - - }), - }); - - export const { } = registerUser; - - export type Post = { - id: number; - title: string; - body: string; - }; \ No newline at end of file diff --git a/src/Redux/Store.tsx b/src/Redux/Store.tsx index 6619090..340ad1b 100644 --- a/src/Redux/Store.tsx +++ b/src/Redux/Store.tsx @@ -1,7 +1,6 @@ import { configureStore } from "@reduxjs/toolkit"; import { dashboard } from "./Service/apiSlice"; import authReducer from "./Service/authSlice"; -import { registerUser } from "./Service/register.user.service"; import { deactivatedAccounts } from "./Service/deactivated.account.service"; import { faqs } from "./Service/faqs.service"; import { manageSubAdmin } from "./Service/manage.subadmin.service"; @@ -23,11 +22,11 @@ import { departmentMaster } from "./Service/department.master"; import { workspaceMode } from "./Service/workspace.mode"; import { jobStatus } from "./Service/job.status"; import { managePosts } from "./Service/manage.post.service"; +import { registerUser } from "./Service/manage.user"; export const store = configureStore({ reducer: { [dashboard.reducerPath]: dashboard.reducer, - [registerUser.reducerPath]: registerUser.reducer, [deactivatedAccounts.reducerPath]: deactivatedAccounts.reducer, [faqs.reducerPath]: faqs.reducer, [manageSubAdmin.reducerPath]: manageSubAdmin.reducer, @@ -49,6 +48,7 @@ export const store = configureStore({ [workspaceMode.reducerPath]: workspaceMode.reducer, [jobStatus.reducerPath]: jobStatus.reducer, [managePosts.reducerPath]: managePosts.reducer, + [registerUser.reducerPath]: registerUser.reducer, auth: authReducer, }, middleware: (getDefaultMiddleware) => @@ -75,6 +75,7 @@ export const store = configureStore({ workspaceMode.middleware, jobStatus.middleware, managePosts.middleware, + registerUser.middleware, ), });