Merge branch 'dev-rohit' of http://git.wdipl.com/Siddhesh.More/SSA-Admin-Panel into testing
This commit is contained in:
@@ -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 (
|
||||
<VStack gap={0} w="100%" h="100vh" bg="#F2F2F2">
|
||||
<ProgressBar isLoading={isBarLoading} />
|
||||
<HStack overflow={'hidden'} position={'relative'} bg="#F2F2F2" backgroundPosition="center" backgroundRepeat="repeat" backgroundSize="cover" gap={0} w="100%" h="calc(100% - 4px)" p={0}>
|
||||
|
||||
<VStack pt={0} zIndex={1} gap={0} rounded={'lg'} h="100%" w="15%" overflow={'auto'} >
|
||||
<HStack w={'100%'} p={3} h={'7%'} justifyContent={'center'}>
|
||||
<Image w={55} src={logo} />
|
||||
</HStack>
|
||||
<VStack w={'100%'} p={2} pt={0}>
|
||||
{nav?.map(({ title, path, Icon, type, children, initPath }, index) => type === 'single' ?
|
||||
<NavLink className="link" key={index} to={path||''} style={{ cursor: 'pointer', borderRadius: '8px', padding: '6px', width: '100%', display: 'flex', alignItems: 'center', gap: 6, border: '1px solid #ffffff', backgroundColor:'#fff', color:'#000', boxShadow:'rgba(99, 99, 99, 0.2) 0px 2px 8px 0px'}} ><Icon style={{ fontSize: '20px' }} /> <Text fontSize={'xs'} w={'100%'}>{title}</Text></NavLink> :
|
||||
<AccordionRoot border={location?.pathname.startsWith(initPath ?? path) ? "1px solid #02A0A0" : '1px' } key={index} bg={'#fff'} rounded={'lg'} collapsible>
|
||||
<AccordionItem rounded={'lg'} bg={'#fff'} boxShadow={'rgba(99, 99, 99, 0.2) 0px 2px 8px 0px'} borderBottom={'none'} p={0} key={index} value={title}>
|
||||
<AccordionItemTrigger className="Oxygen" color={'#fff'} onClick={() => 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', }}> <Text fontSize={'xs'} gap={1} display={'flex'} alignItems={'center'} ><Icon style={{ fontSize: '20px' }} />{title}</Text></AccordionItemTrigger>
|
||||
{children?.map(({ title, path, Icon }, index) => <AccordionItemContent className={`linkChild Oxygen ${location?.pathname === path && 'activeChild'}`} key={index} onClick={()=>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' }} ><Icon style={{ fontSize: '20px' }} /> <Text fontSize={'xs'} w={'100%'}>{title}</Text></AccordionItemContent>)}
|
||||
</AccordionItem>
|
||||
</AccordionRoot>)}
|
||||
</VStack>
|
||||
<VStack w={'100%'} p={3} pt={0}>
|
||||
<HStack onClick={handleLogout} className="link" style={{ cursor: 'pointer', borderRadius: '8px', padding: '6px', width: '100%', display: 'flex', alignItems: 'center', gap: 6, border: '1px solid #ffffff', backgroundColor:'#fff', color:'#000', boxShadow:'rgba(99, 99, 99, 0.2) 0px 2px 8px 0px'}} ><LuLogOut style={{ fontSize: '20px' }} /> <Text fontSize={'xs'} w={'100%'}>Logout</Text></HStack>
|
||||
</VStack>
|
||||
</VStack>
|
||||
<VStack gap={0} h="100%" w="85%" >
|
||||
|
||||
<HStack h={'11%'} w={'100%'} justifyContent={'flex-end'} pe={3} gap={6}>
|
||||
|
||||
<NavLink to={'/manage-notification'}><RiNotificationLine color="#013e3e" cursor={'pointer'} style={{ fontSize: '22px' }} /></NavLink>
|
||||
<HStack cursor={'pointer'} onClick={() => navigate('/profile')} >
|
||||
<Avatar size={'sm'} src="https://i.pinimg.com/736x/d6/cd/0f/d6cd0ffd4634b0763d3958a7325ce26e.jpg" />
|
||||
<VStack color={'#013e3e'} gap={0} alignItems={'flex-start'}>
|
||||
<Text fontSize={'sm'} fontWeight={'bold'}>Ritesh Pandey</Text>
|
||||
<Text fontSize={'xs'} >ritesh.pandey@wdimails.com</Text>
|
||||
</VStack>
|
||||
<ProgressBar isLoading={isBarLoading} />
|
||||
<HStack overflow={'hidden'} position={'relative'} bg="#F2F2F2" backgroundPosition="center" backgroundRepeat="repeat" backgroundSize="cover" gap={0} w="100%" h="calc(100% - 4px)" p={0}>
|
||||
|
||||
<VStack pt={0} zIndex={1} gap={0} rounded={'lg'} h="100%" w="15%" overflow={'auto'} >
|
||||
<HStack w={'100%'} p={3} h={'7%'} justifyContent={'center'}>
|
||||
<Image w={55} src={logo} />
|
||||
</HStack>
|
||||
</HStack>
|
||||
{children}
|
||||
</VStack>
|
||||
</HStack>
|
||||
<VStack w={'100%'} p={2} pt={0}>
|
||||
{nav?.map(({ title, path, Icon, type, children, initPath }, index) => type === 'single' ?
|
||||
<NavLink className="link" key={index} to={path || ''} style={{ cursor: 'pointer', borderRadius: '8px', padding: '6px', width: '100%', display: 'flex', alignItems: 'center', gap: 6, border: '1px solid #ffffff', backgroundColor: '#fff', color: '#000', boxShadow: 'rgba(99, 99, 99, 0.2) 0px 2px 8px 0px' }} ><Icon style={{ fontSize: '20px' }} /> <Text fontSize={'xs'} w={'100%'}>{title}</Text></NavLink> :
|
||||
<AccordionRoot border={location?.pathname.startsWith(initPath ?? path) ? "1px solid #02A0A0" : '1px'} key={index} bg={'#fff'} rounded={'lg'} collapsible>
|
||||
<AccordionItem rounded={'lg'} bg={'#fff'} boxShadow={'rgba(99, 99, 99, 0.2) 0px 2px 8px 0px'} borderBottom={'none'} p={0} key={index} value={title}>
|
||||
<AccordionItemTrigger className="Oxygen" color={'#fff'} onClick={() => 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', }}> <Text fontSize={'xs'} gap={1} display={'flex'} alignItems={'center'} ><Icon style={{ fontSize: '20px' }} />{title}</Text></AccordionItemTrigger>
|
||||
{children?.map(({ title, path, Icon }, index) => <AccordionItemContent className={`linkChild Oxygen ${location?.pathname === path && 'activeChild'}`} key={index} onClick={() => 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' }} ><Icon style={{ fontSize: '20px' }} /> <Text fontSize={'xs'} w={'100%'}>{title}</Text></AccordionItemContent>)}
|
||||
</AccordionItem>
|
||||
</AccordionRoot>)}
|
||||
</VStack>
|
||||
<VStack w={'100%'} p={3} pt={0}>
|
||||
<HStack onClick={handleLogout} className="link" style={{ cursor: 'pointer', borderRadius: '8px', padding: '6px', width: '100%', display: 'flex', alignItems: 'center', gap: 6, border: '1px solid #ffffff', backgroundColor: '#fff', color: '#000', boxShadow: 'rgba(99, 99, 99, 0.2) 0px 2px 8px 0px' }} ><LuLogOut style={{ fontSize: '20px' }} /> <Text fontSize={'xs'} w={'100%'}>Logout</Text></HStack>
|
||||
</VStack>
|
||||
</VStack>
|
||||
<VStack gap={0} h="100%" w="85%" >
|
||||
|
||||
<HStack h={'11%'} w={'100%'} justifyContent={'flex-end'} pe={3} gap={6}>
|
||||
|
||||
<NavLink to={'/manage-notification'}><RiNotificationLine color="#013e3e" cursor={'pointer'} style={{ fontSize: '22px' }} /></NavLink>
|
||||
<HStack cursor={'pointer'} onClick={() => navigate('/profile')} >
|
||||
<Avatar size={'sm'} src="https://i.pinimg.com/736x/d6/cd/0f/d6cd0ffd4634b0763d3958a7325ce26e.jpg" />
|
||||
<VStack color={'#013e3e'} gap={0} alignItems={'flex-start'}>
|
||||
<Text fontSize={'sm'} fontWeight={'bold'}>{`${data?.data?.first_name.charAt(0).toUpperCase()}${data?.data.first_name.slice(1)}`}</Text>
|
||||
<Text fontSize={'xs'} >{data?.data?.phone_number}</Text>
|
||||
</VStack>
|
||||
</HStack>
|
||||
</HStack>
|
||||
{children}
|
||||
</VStack>
|
||||
</HStack>
|
||||
</VStack>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -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<any[]>([]);
|
||||
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}
|
||||
>
|
||||
<Spinner color={'teal'}/>
|
||||
<Spinner color={'teal'} />
|
||||
</HStack>
|
||||
)
|
||||
}
|
||||
@@ -208,13 +213,18 @@ const FAQ = () => {
|
||||
</HStack>
|
||||
{isFetching && <Spinner />}
|
||||
{!isLoading && !data?.data ? (
|
||||
<NoData message={'No data found'} text={'Please add new data'}/>
|
||||
<NoData message={'No data found'} text={'Please add new data'} />
|
||||
) : (<DataTable
|
||||
sortableColumns={["Name"]}
|
||||
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}
|
||||
/>)}
|
||||
</Box>
|
||||
<Toaster />
|
||||
|
||||
@@ -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<any[]>([]);
|
||||
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}
|
||||
/>
|
||||
</Box>
|
||||
</MainFrame>
|
||||
|
||||
@@ -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": (
|
||||
// <HStack justifyContent="center">
|
||||
// <EditCountryModel />
|
||||
// <Box>
|
||||
// <Switch colorPalette={'teal'} size={"xs"} />
|
||||
// </Box>
|
||||
// </HStack>
|
||||
// ),
|
||||
// })),
|
||||
// ];
|
||||
|
||||
const Country = () => {
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
const { data, refetch } = useGetCountryMasterQuery(currentPage)
|
||||
const [countryToggle] = useCountryToggleMutation()
|
||||
const [localData, setLocalData] = useState<any[]>([]);
|
||||
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": (
|
||||
<HStack justifyContent="center">
|
||||
<EditCountryModel />
|
||||
<EditCountryModel rowData={{ id: agency.id, en_name: agency.en_name, country_code: agency.country_code, phonecode: agency.phonecode, capital: agency.capital, currency: agency.currency, currency_name: agency.currency_name, currency_symbol: agency.currency_symbol }} refetch={refetch} />
|
||||
<Box>
|
||||
<Switch colorPalette={'teal'} size={"xs"}/>
|
||||
<Switch
|
||||
colorPalette={'teal'}
|
||||
size={"xs"}
|
||||
checked={agency.is_active === '1'}
|
||||
onChange={() => handleToggle(agency.id, agency.is_active)}
|
||||
/>
|
||||
</Box>
|
||||
</HStack>
|
||||
),
|
||||
})),
|
||||
];
|
||||
}))
|
||||
|
||||
const Country = () => {
|
||||
return (
|
||||
|
||||
<MainFrame>
|
||||
@@ -46,11 +111,11 @@ const Country = () => {
|
||||
px={3}
|
||||
>
|
||||
<Text as={"span"} fontSize={"sm"} fontWeight={500} color={"#000"}>
|
||||
Country
|
||||
Country
|
||||
</Text>
|
||||
|
||||
<HStack >
|
||||
<InputGroup
|
||||
{/* <InputGroup
|
||||
startElement={
|
||||
<LuSearch fontSize={"xs"} style={{ position: 'relative', left: '10px' }} />
|
||||
}
|
||||
@@ -69,7 +134,14 @@ const Country = () => {
|
||||
bgColor={'#EEEEEE'}
|
||||
ps={8}
|
||||
/>
|
||||
</InputGroup>
|
||||
</InputGroup> */}
|
||||
<SearchComponent
|
||||
value={searchTerm}
|
||||
onChange={(value) => {
|
||||
setSearchTerm(value);
|
||||
setCurrentPage(1);
|
||||
}}
|
||||
/>
|
||||
{/* <Button bgColor={'#EEEEEE'} pl={3} pr={3}><IoMdAdd /> <Text>Add</Text></Button> */}
|
||||
<CountryAddModel />
|
||||
</HStack>
|
||||
@@ -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}
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
</MainFrame>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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<PostCountry>({
|
||||
en_name: '',
|
||||
country_code: '',
|
||||
phonecode: '',
|
||||
capital: '',
|
||||
currency: '',
|
||||
currency_name: '',
|
||||
currency_symbol: '',
|
||||
});
|
||||
|
||||
<DialogRoot placement="center">
|
||||
<DialogTrigger asChild>
|
||||
{/* <Button bg={"transparent"} size="sm">
|
||||
const handleOpenModal = () => {
|
||||
setIsOpen(true); // Open modal when clicking "Add"
|
||||
};
|
||||
|
||||
const handleSubmit = async () => {
|
||||
if (countryName.en_name === "") {
|
||||
toaster.create({
|
||||
title: "Error",
|
||||
description: "Input fields cannot be empty",
|
||||
type: "error",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const payload: PostCountry = {
|
||||
en_name: countryName.en_name,
|
||||
country_code: countryName.country_code,
|
||||
phonecode: countryName.phonecode,
|
||||
capital: countryName.capital,
|
||||
currency: countryName.currency,
|
||||
currency_name: countryName.currency_name,
|
||||
currency_symbol: countryName.currency_symbol,
|
||||
};
|
||||
|
||||
try {
|
||||
const response = await createCountryPost(payload).unwrap();
|
||||
if (response) {
|
||||
toaster.create({
|
||||
title: "Success",
|
||||
description: "Country added successfully",
|
||||
type: "success",
|
||||
});
|
||||
setIsOpen(false);
|
||||
} else {
|
||||
toaster.create({
|
||||
title: "Error",
|
||||
description: "Failed to add Country",
|
||||
type: "error",
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error updating template:", error);
|
||||
// alert("Failed to update template");
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<DialogRoot placement="center" open={isOpen} onOpenChange={({ open }) => setIsOpen(open)}>
|
||||
<DialogTrigger asChild>
|
||||
{/* <Button bg={"transparent"} size="sm">
|
||||
<MdOutlineRemoveRedEye style={{ cursor: "pointer", fontSize: "16px" }} />
|
||||
</Button> */}
|
||||
<Button px={5} size={"xs"} bg={"#02A0A0"}>
|
||||
<IoMdAdd /> <Text>Add</Text>
|
||||
</Button>
|
||||
|
||||
</DialogTrigger>
|
||||
|
||||
<DialogContent
|
||||
bg={"#fff"}
|
||||
// w={{ lg: "60%", md: "230px" }}
|
||||
w={{ base: '90%', md: '400px' }}
|
||||
height={'auto'}
|
||||
|
||||
overflowX="hidden"
|
||||
p={3} // Reduced padding
|
||||
bgSize={'md'}
|
||||
>
|
||||
<DialogHeader bg="white" >
|
||||
<DialogTitle alignSelf="center" color="black" fontSize="14px">Add</DialogTitle>
|
||||
</DialogHeader>
|
||||
|
||||
<DialogBody bg="white">
|
||||
<Stack py={3}>
|
||||
|
||||
<Field.Root>
|
||||
<Field.Label color="black" pt={1} fontSize="12px">Country</Field.Label>
|
||||
<Input placeholder="" bgColor="#EEEEEE" color="black" border="none" pl={1} fontSize="12px" height="30px" />
|
||||
</Field.Root>
|
||||
</Stack>
|
||||
|
||||
</DialogBody>
|
||||
<DialogFooter display="flex" justifyContent="center" pt={"2"}>
|
||||
<Button w="100%" bg="#02A0A0" color={"#fff"}>
|
||||
Save
|
||||
<Button px={5} size={"xs"} bg={"#02A0A0"} onClick={handleOpenModal}>
|
||||
<IoMdAdd /> <Text>Add</Text>
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
|
||||
<DialogCloseTrigger color="black" />
|
||||
</DialogContent>
|
||||
</DialogRoot >
|
||||
</DialogTrigger>
|
||||
|
||||
<DialogContent
|
||||
bg={"#fff"}
|
||||
// w={{ lg: "60%", md: "230px" }}
|
||||
w={{ base: '90%', md: '400px' }}
|
||||
height={'auto'}
|
||||
|
||||
overflowX="hidden"
|
||||
p={3} // Reduced padding
|
||||
bgSize={'md'}
|
||||
>
|
||||
<DialogHeader bg="white" >
|
||||
<DialogTitle alignSelf="center" color="black" fontSize="14px">Add</DialogTitle>
|
||||
</DialogHeader>
|
||||
|
||||
<DialogBody bg="white">
|
||||
<Stack py={3}>
|
||||
|
||||
<Field.Root>
|
||||
<Field.Label color="black" pt={1} fontSize="12px">Country</Field.Label>
|
||||
<Input
|
||||
placeholder=""
|
||||
bgColor="#EEEEEE"
|
||||
color="black"
|
||||
border="none"
|
||||
pl={1}
|
||||
fontSize="12px"
|
||||
height="30px"
|
||||
value={countryName.en_name}
|
||||
onChange={(e) => setCountryName({ ...countryName, en_name: e.target.value })}
|
||||
/>
|
||||
|
||||
<Field.Label color="black" pt={1} fontSize="12px">Country Code</Field.Label>
|
||||
<Input
|
||||
placeholder=""
|
||||
bgColor="#EEEEEE"
|
||||
color="black"
|
||||
border="none"
|
||||
pl={1}
|
||||
fontSize="12px"
|
||||
height="30px"
|
||||
value={countryName.country_code}
|
||||
onChange={(e) => setCountryName({ ...countryName, country_code: e.target.value })}
|
||||
/>
|
||||
|
||||
<Field.Label color="black" pt={1} fontSize="12px">Phone Code</Field.Label>
|
||||
<Input
|
||||
placeholder=""
|
||||
bgColor="#EEEEEE"
|
||||
color="black"
|
||||
border="none"
|
||||
pl={1}
|
||||
fontSize="12px"
|
||||
height="30px"
|
||||
value={countryName.phonecode}
|
||||
onChange={(e) => setCountryName({ ...countryName, phonecode: e.target.value })}
|
||||
/>
|
||||
<Field.Label color="black" pt={1} fontSize="12px">Capital</Field.Label>
|
||||
<Input
|
||||
placeholder=""
|
||||
bgColor="#EEEEEE"
|
||||
color="black"
|
||||
border="none"
|
||||
pl={1}
|
||||
fontSize="12px"
|
||||
height="30px"
|
||||
value={countryName.capital}
|
||||
onChange={(e) => setCountryName({ ...countryName, capital: e.target.value })}
|
||||
/>
|
||||
<Field.Label color="black" pt={1} fontSize="12px">Currency</Field.Label>
|
||||
<Input
|
||||
placeholder=""
|
||||
bgColor="#EEEEEE"
|
||||
color="black"
|
||||
border="none"
|
||||
pl={1}
|
||||
fontSize="12px"
|
||||
height="30px"
|
||||
value={countryName.currency}
|
||||
onChange={(e) => setCountryName({ ...countryName, currency: e.target.value })}
|
||||
/>
|
||||
<Field.Label color="black" pt={1} fontSize="12px">Currency name</Field.Label>
|
||||
<Input
|
||||
placeholder=""
|
||||
bgColor="#EEEEEE"
|
||||
color="black"
|
||||
border="none"
|
||||
pl={1}
|
||||
fontSize="12px"
|
||||
height="30px"
|
||||
value={countryName.currency_name}
|
||||
onChange={(e) => setCountryName({ ...countryName, currency_name: e.target.value })}
|
||||
/>
|
||||
<Field.Label color="black" pt={1} fontSize="12px">Currency Symbol</Field.Label>
|
||||
<Input
|
||||
placeholder=""
|
||||
bgColor="#EEEEEE"
|
||||
color="black"
|
||||
border="none"
|
||||
pl={1}
|
||||
fontSize="12px"
|
||||
height="30px"
|
||||
value={countryName.currency_symbol}
|
||||
onChange={(e) => setCountryName({ ...countryName, currency_symbol: e.target.value })}
|
||||
/>
|
||||
</Field.Root>
|
||||
</Stack>
|
||||
|
||||
</DialogBody>
|
||||
<DialogFooter display="flex" justifyContent="center" pt={"2"}>
|
||||
<Button w="100%" bg="#02A0A0" color={"#fff"} onClick={handleSubmit}>
|
||||
Save
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
|
||||
<DialogCloseTrigger color="black" />
|
||||
</DialogContent>
|
||||
</DialogRoot >
|
||||
<Toaster />
|
||||
</>
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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 (
|
||||
<DialogRoot placement="center">
|
||||
<DialogTrigger asChild>
|
||||
<Span><Edit /></Span>
|
||||
</DialogTrigger>
|
||||
<>
|
||||
<DialogRoot placement="center" key={editData.id} open={isOpen} onOpenChange={({ open }) => setIsOpen(open)}>
|
||||
<DialogTrigger asChild>
|
||||
<Button bg="transparent" color={"black"} h={"18px"} onClick={handleOpenModal}><Edit /></Button>
|
||||
</DialogTrigger>
|
||||
|
||||
<DialogContent
|
||||
bg={"#fff"}
|
||||
// w={{ lg: "60%", md: "230px" }}
|
||||
w={{ base: "90%", md: "400px" }}
|
||||
height={"auto"}
|
||||
overflowX="hidden"
|
||||
p={3} // Reduced padding
|
||||
bgSize={"md"}
|
||||
>
|
||||
<DialogHeader bg="white">
|
||||
<DialogTitle alignSelf="center" color="black" fontSize="14px">
|
||||
Edit
|
||||
</DialogTitle>
|
||||
</DialogHeader>
|
||||
<DialogContent
|
||||
bg={"#fff"}
|
||||
// w={{ lg: "60%", md: "230px" }}
|
||||
w={{ base: "90%", md: "400px" }}
|
||||
height={"auto"}
|
||||
overflowX="hidden"
|
||||
p={3} // Reduced padding
|
||||
bgSize={"md"}
|
||||
>
|
||||
<DialogHeader bg="white">
|
||||
<DialogTitle alignSelf="center" color="black" fontSize="14px">
|
||||
Edit
|
||||
</DialogTitle>
|
||||
</DialogHeader>
|
||||
<DialogBody bg="white">
|
||||
<Stack py={3}>
|
||||
<Field.Root>
|
||||
<Field.Label color="black" pt={1} fontSize="12px">
|
||||
Country
|
||||
</Field.Label>
|
||||
<Input
|
||||
value={editData.en_name}
|
||||
onChange={(e) => setEditData({ ...editData, en_name: e.target.value })}
|
||||
bgColor="#EEEEEE"
|
||||
color="black"
|
||||
border="none"
|
||||
pl={1}
|
||||
fontSize="12px"
|
||||
height="30px"
|
||||
/>
|
||||
</Field.Root>
|
||||
</Stack>
|
||||
</DialogBody>
|
||||
<DialogFooter display="flex" justifyContent="center" pt={"2"}>
|
||||
<Button w="100%" bg="#02A0A0" color={"#fff"} onClick={handleSubmit}>
|
||||
Save
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
|
||||
<DialogBody bg="white">
|
||||
<Stack py={3}>
|
||||
<Field.Root>
|
||||
<Field.Label color="black" pt={1} fontSize="12px">
|
||||
Country
|
||||
</Field.Label>
|
||||
<Input
|
||||
value="Lorem Ipsum"
|
||||
bgColor="#EEEEEE"
|
||||
color="black"
|
||||
border="none"
|
||||
pl={1}
|
||||
fontSize="12px"
|
||||
height="30px"
|
||||
/>
|
||||
</Field.Root>
|
||||
</Stack>
|
||||
</DialogBody>
|
||||
<DialogFooter display="flex" justifyContent="center" pt={"2"}>
|
||||
<Button w="100%" bg="#02A0A0" color={"#fff"}>
|
||||
Save
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
|
||||
<DialogCloseTrigger color="black" />
|
||||
</DialogContent>
|
||||
</DialogRoot>
|
||||
<DialogCloseTrigger color="black" />
|
||||
</DialogContent>
|
||||
</DialogRoot>
|
||||
<Toaster />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -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<any[]>([]);
|
||||
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 = () => {
|
||||
</Text>
|
||||
|
||||
<HStack >
|
||||
<InputGroup
|
||||
startElement={
|
||||
<LuSearch fontSize={"xs"} style={{ position: 'relative', left: '10px' }} />
|
||||
}
|
||||
color={"#000"}
|
||||
>
|
||||
<Input
|
||||
p={3}
|
||||
w={300}
|
||||
bg={"#fff"}
|
||||
colorPalette={"blue"}
|
||||
_focus={{ border: "1px solid #02A0A0" }}
|
||||
rounded={"md"}
|
||||
size={"xs"}
|
||||
fontSize={"sm"}
|
||||
placeholder="Search..."
|
||||
bgColor={'#EEEEEE'}
|
||||
ps={8}
|
||||
/>
|
||||
</InputGroup>
|
||||
<SearchComponent
|
||||
value={searchTerm}
|
||||
onChange={(value) => {
|
||||
setSearchTerm(value);
|
||||
setCurrentPage(1);
|
||||
}}
|
||||
/>
|
||||
{/* <Button bgColor={'#EEEEEE'} pl={3} pr={3}><IoMdAdd /> <Text>Add</Text></Button> */}
|
||||
{/* <ViewAgencyAddModel /> */}
|
||||
<AddIndustryMaster refetch={refetch}/>
|
||||
<AddIndustryMaster refetch={refetch} />
|
||||
</HStack>
|
||||
</HStack>
|
||||
<DataTable
|
||||
sortableColumns={["Name"]}
|
||||
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}
|
||||
/>
|
||||
</Box>
|
||||
</MainFrame>
|
||||
|
||||
@@ -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<any[]>([]);
|
||||
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 = () => {
|
||||
</Text>
|
||||
|
||||
<HStack >
|
||||
<InputGroup
|
||||
startElement={
|
||||
<LuSearch fontSize={"xs"} style={{ position: 'relative', left: '10px' }} />
|
||||
}
|
||||
color={"#000"}
|
||||
>
|
||||
<Input
|
||||
p={3}
|
||||
w={300}
|
||||
bg={"#fff"}
|
||||
colorPalette={"blue"}
|
||||
_focus={{ border: "1px solid #02A0A0" }}
|
||||
rounded={"md"}
|
||||
size={"xs"}
|
||||
fontSize={"sm"}
|
||||
placeholder="Search..."
|
||||
bgColor={'#EEEEEE'}
|
||||
ps={8}
|
||||
/>
|
||||
</InputGroup>
|
||||
<SearchComponent
|
||||
value={searchTerm}
|
||||
onChange={(value) => {
|
||||
setSearchTerm(value);
|
||||
setCurrentPage(1);
|
||||
}}
|
||||
/>
|
||||
{/* <Button bgColor={'#EEEEEE'} pl={3} pr={3}><IoMdAdd /> <Text>Add</Text></Button> */}
|
||||
<JobAddModel refetch={refetch} />
|
||||
</HStack>
|
||||
@@ -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}
|
||||
/>
|
||||
</Box>
|
||||
</MainFrame>
|
||||
|
||||
@@ -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<any[]>([]);
|
||||
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}
|
||||
/>
|
||||
</Box>
|
||||
</MainFrame>
|
||||
|
||||
@@ -70,8 +70,8 @@ export const agencyMasterModule = createApi({
|
||||
}),
|
||||
}),
|
||||
|
||||
getAgencyMaster: builder.query<AgencyResponse, void>({
|
||||
query: () => "/agency-master"
|
||||
getAgencyMaster: builder.query<AgencyResponse, number>({
|
||||
query: (page = 1) => `/agency-master?page=${page}`
|
||||
}),
|
||||
|
||||
agencyMasterToggle: builder.mutation({
|
||||
|
||||
110
src/Redux/Service/country.master.ts
Normal file
110
src/Redux/Service/country.master.ts
Normal file
@@ -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<PostCountry, Partial<PostCountry>>({
|
||||
query: (data) => ({
|
||||
url: "/country-add",
|
||||
method: "POST",
|
||||
body: data,
|
||||
}),
|
||||
}),
|
||||
// 🔹 GET: Fetch all posts
|
||||
getCountryMaster: builder.query<ApiResponse, number>({
|
||||
query: (page = 1) => `/country-list?page=${page}`,
|
||||
}),
|
||||
|
||||
getCountryMasterEdit: builder.query<CountryEdit, number>({
|
||||
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;
|
||||
@@ -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<ApiResponse, void>({
|
||||
query: () => "/faq-list",
|
||||
getFaq: builder.query<ApiResponse, number>({
|
||||
query: (page = 1) => `/faq-list?page=${page}`,
|
||||
}),
|
||||
|
||||
updateFaq: builder.mutation({
|
||||
|
||||
@@ -61,8 +61,8 @@ export const industryMaster = createApi({
|
||||
}),
|
||||
}),
|
||||
// 🔹 GET: Fetch all posts
|
||||
getIndustryMaster: builder.query<IndustryMasterResponse, void>({
|
||||
query: () => "/industry-master-list",
|
||||
getIndustryMaster: builder.query<IndustryMasterResponse, number>({
|
||||
query: (page = 1) => `/industry-master-list?page=${page}`,
|
||||
}),
|
||||
|
||||
updateIndustryMaster: builder.mutation({
|
||||
|
||||
@@ -59,8 +59,8 @@ export const jobType = createApi({
|
||||
}),
|
||||
}),
|
||||
// 🔹 GET: Fetch all posts
|
||||
getJobType: builder.query<JobTypeResponse, void>({
|
||||
query: () => "/job-type",
|
||||
getJobType: builder.query<JobTypeResponse, number>({
|
||||
query: (page = 1) => `/job-type?page=${page}`,
|
||||
}),
|
||||
|
||||
updateJobType: builder.mutation({
|
||||
|
||||
@@ -73,8 +73,8 @@ export const templateMaster = createApi({
|
||||
}),
|
||||
}),
|
||||
// 🔹 GET: Fetch all posts
|
||||
getTemplateMaster: builder.query<TemplateResponse, void>({
|
||||
query: () => "/template-master",
|
||||
getTemplateMaster: builder.query<TemplateResponse, number>({
|
||||
query: (page = 1) => `/template-master?page=${page}`,
|
||||
}),
|
||||
|
||||
updateTemplateMaster: builder.mutation<Post, FormData>({
|
||||
|
||||
@@ -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,
|
||||
),
|
||||
});
|
||||
|
||||
|
||||
@@ -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<string, any>[];
|
||||
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<TableProps> = ({
|
||||
@@ -21,30 +26,18 @@ const DataTable: React.FC<TableProps> = ({
|
||||
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<TableProps> = ({
|
||||
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<TableProps> = ({
|
||||
</Table.Row>
|
||||
</Table.Header>
|
||||
<Table.Body>
|
||||
{sortedData.map((item: any, index) => (
|
||||
{data.map((item: any, index) => (
|
||||
<Table.Row
|
||||
key={index}
|
||||
bg={index % 2 === 0 ? "#fff" : "#007F3310"}
|
||||
@@ -139,22 +127,24 @@ const DataTable: React.FC<TableProps> = ({
|
||||
</Table.Body>
|
||||
</Table.Root>
|
||||
</Table.ScrollArea>
|
||||
{lastPage > 1 && <PaginationRoot
|
||||
count={totalCount}
|
||||
pageSize={pageSize}
|
||||
defaultPage={currentPage}
|
||||
{last_page > 1 && (<PaginationRoot
|
||||
count={paginationData?.total ?? 0}
|
||||
pageSize={paginationData?.per_page ?? 0}
|
||||
page={current_page}
|
||||
onPageChange={handlePageChange}
|
||||
size={"xs"}
|
||||
siblingCount={1}
|
||||
// count={20}
|
||||
// pageSize={2}
|
||||
// defaultPage={1}
|
||||
mb={4}
|
||||
>
|
||||
<HStack justifyContent="flex-end">
|
||||
<PaginationPrevTrigger onClick={() => handlePageChange(page - 1)} disabled={page === 1} />
|
||||
<PaginationPrevTrigger onClick={() => handlePageChange({ page: current_page - 1 })} disabled={current_page === 1} />
|
||||
<PaginationItems />
|
||||
<PaginationNextTrigger onClick={() => handlePageChange(page + 1)} disabled={page === lastPage} />
|
||||
<PaginationNextTrigger onClick={() => handlePageChange({ page: current_page + 1 })} disabled={current_page === last_page} />
|
||||
</HStack>
|
||||
</PaginationRoot>}
|
||||
</PaginationRoot>)}
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -198,16 +198,40 @@ export const PaginationNextTrigger = React.forwardRef<
|
||||
export const PaginationItems = (props: React.HTMLAttributes<HTMLElement>) => {
|
||||
return (
|
||||
<ChakraPagination.Context>
|
||||
{({ pages }) =>
|
||||
pages.map((page, index) => (
|
||||
<PaginationItem
|
||||
key={index}
|
||||
type="page"
|
||||
value={page.type === "page" ? page.value : 0}
|
||||
{...props}
|
||||
/>
|
||||
))
|
||||
}
|
||||
{({ pages }) =>(
|
||||
<>
|
||||
{pages.map((page, index) => {
|
||||
if(page.type === "ellipsis") {
|
||||
return (
|
||||
(
|
||||
<Text
|
||||
key={`ellipsis-${index}`}
|
||||
mx={1}
|
||||
display="inline-flex"
|
||||
alignItems="center"
|
||||
height="100%"
|
||||
>
|
||||
...
|
||||
</Text>
|
||||
)
|
||||
)
|
||||
}
|
||||
if (page.type === 'page') {
|
||||
return (
|
||||
<PaginationItem
|
||||
key={index}
|
||||
type="page"
|
||||
value={page.value}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// Skip rendering for other types
|
||||
return null;
|
||||
})}
|
||||
</>
|
||||
)}
|
||||
</ChakraPagination.Context>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user