Faq / JobType / IndustryMaster/TemplateMaster/Pagination data enabled

This commit is contained in:
rockyeverlast
2025-03-07 20:13:25 +05:30
parent c0b0a5f431
commit 44a6f60868
21 changed files with 1177 additions and 156 deletions

View File

@@ -93,20 +93,82 @@ import {
} from "../../../components/ui/dialog";
import { Field, Input, Stack, Textarea } from "@chakra-ui/react";
import Edit from "../../../components/ActionIcons/Edit";
import { useUpdateFaqMutation } from "../../../Redux/Service/faqs.service";
import { useEffect, useState } from "react";
import { toaster } from "../../../components/ui/toaster";
interface RowData {
id: string;
id: number;
question: string;
answer: string;
}
function EditDetails(rowData: RowData) {
function EditDetails({ rowData, refetch }: {rowData: RowData, refetch: VoidFunction}) {
const [faqQuestion, setFaqQuestion] = useState(rowData?.question);
const [faqAnswer, setFaqAnswer] = useState(rowData?.answer);
const [isOpen, setIsOpen] = useState(false);
const [updateFaq] = useUpdateFaqMutation()
// console.log('ROWDATA', rowData);
useEffect(() => {
if (rowData) {
setFaqQuestion(rowData.question);
setFaqAnswer(rowData.answer);
}
}, [rowData]);
const handleOpenModal = () => {
setIsOpen(true);
};
const handleSubmit = async () => {
if (!faqQuestion.trim() || !faqAnswer.trim()) {
toaster.create({
title: "Error",
description: "Input fields cannot be empty",
type: "error",
});
return;
}
const payload = {
id: rowData?.id,
question: faqQuestion,
answer: faqAnswer
};
try {
const response = await updateFaq(payload).unwrap();
if (response?.status === "success") {
toaster.create({
title: "Success",
description: "FAQ updated successfully",
type: "success",
});
refetch()
setIsOpen(false);
} else {
toaster.create({
title: "Error",
description: "Failed to update FAQ",
type: "error",
});
}
} catch (error) {
console.error("Error updating template:", error);
// alert("Failed to update template");
}
};
return (
<DialogRoot placement="center">
<DialogRoot placement="center" open={isOpen} onOpenChange={({ open }) => setIsOpen(open)}>
<DialogTrigger asChild>
<Button bg="transparent" color={"black"} h={"18px"}> <Edit /></Button>
<Button bg="transparent" color={"black"} h={"18px"} onClick={handleOpenModal}><Edit /></Button>
</DialogTrigger>
<DialogContent
@@ -135,7 +197,8 @@ function EditDetails(rowData: RowData) {
pl={1}
fontSize="12px"
height="30px"
defaultValue={rowData?.question} // Pre-fill question
value={faqQuestion}
onChange={(e) => setFaqQuestion(e.target.value)}
/>
<Field.Label color="black" pt={1} fontSize="12px">
@@ -148,21 +211,22 @@ function EditDetails(rowData: RowData) {
border="none"
p={2}
fontSize="12px"
height="30px"
height="auto"
pt={1.5}
defaultValue={rowData?.answer} // Pre-fill answer
value={faqAnswer}
onChange={(e) => setFaqAnswer(e.target.value)}
/>
</Field.Root>
</Stack>
</DialogBody>
<DialogFooter display="flex" justifyContent="center" pt={"2"}>
<Button w="100%" bg="#02A0A0" color={"#fff"}>
<Button w="100%" bg="#02A0A0" color={"#fff"} onClick={handleSubmit}>
Save
</Button>
</DialogFooter>
<DialogCloseTrigger color="black" />
<DialogCloseTrigger color="black" onClick={() => setIsOpen(false)} />
</DialogContent>
</DialogRoot>
);

View File

@@ -8,6 +8,8 @@ import AlertDailog from "../../../components/AlertDailog";
import { Switch } from "../../../components/ui/switch";
import FaqAddModel from "./FaqAddModel";
import Delete from "../../../components/ActionIcons/Delete";
import { useEffect, useState } from "react";
import { FaqData, useDeleteFaqPostMutation, useFaqToggleMutation, useGetFaqQuery } from "../../../Redux/Service/faqs.service";
// table data
@@ -19,18 +21,88 @@ const tableHeadRow = [
"Action",
];
const managepost: any[] = [
...Array.from({ length: 12 }, (_, i) => ({
"Sr. No": i + 1,
"Question": "Lorem Ipsum",
"Answer": "Lorem Ipsum",
// const managepost: any[] = [
// ...Array.from({ length: 12 }, (_, i) => ({
// "Sr. No": i + 1,
// "Question": "Lorem Ipsum",
// "Answer": "Lorem Ipsum",
// "Action": (
// <HStack justifyContent="center">
// <Box>
// <Switch colorPalette={'teal'} size={"xs"} />
// </Box>
// {/* <EditDetails /> */}
// <EditDetails id={(i + 1).toString()} question="Lorem Ipsum" answer="Lorem Ipsum" />
// <AlertDailog
// AltertTiggerIcon={() => <Delete />}
// alertText="Delete Users"
// alertIcon={<Image src={"DeleteIcon"} h={"39px"} />}
// alertCaption="are you sure you want to delete ?"
// onConfirm={() => {
// console.log("User deleted:", i + 1);
// }}
// />
// </HStack>
// ),
// })),
// ];
const FAQ = () => {
const { data, refetch } = useGetFaqQuery()
const [localData, setLocalData] = useState<any[]>([]);
const [faqToggle] = useFaqToggleMutation()
const [deleteFaqPost] = useDeleteFaqPostMutation()
console.log('DATA', data?.data);
useEffect(() => {
if (data?.data) {
setLocalData(data?.data);
}
}, [data]);
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 faqToggle({ 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 handleDeleteFaq = async (faqId: number) => {
try {
const response = await deleteFaqPost(faqId).unwrap();
refetch()
console.log("FAQ deleted successfully:", response);
// Optionally, refetch data or update state after deletion
} catch (error) {
console.error("Error deleting FAQ:", error);
}
};
const managepost = localData?.map((agency: FaqData, index: number) => ({
'id': agency.id,
"Sr. No": index + 1,
"Question": agency.question,
"Answer": agency.answer,
"Action": (
<HStack justifyContent="center">
<Box>
<Switch colorPalette={'teal'} size={"xs"} />
</Box>
{/* <EditDetails /> */}
<EditDetails id={(i + 1).toString()} question="Lorem Ipsum" answer="Lorem Ipsum" />
<EditDetails rowData={{ id: agency.id, question: agency.question, answer: agency.answer }} refetch={refetch} />
<AlertDailog
AltertTiggerIcon={() => <Delete />}
@@ -38,15 +110,22 @@ const managepost: any[] = [
alertIcon={<Image src={"DeleteIcon"} h={"39px"} />}
alertCaption="are you sure you want to delete ?"
onConfirm={() => {
console.log("User deleted:", i + 1);
// console.log("User deleted:", index + 1);
handleDeleteFaq(agency.id)
}}
/>
<Box>
<Switch
colorPalette={'teal'}
size={"xs"}
onChange={() => handleToggle(agency.id.toString(), Number(agency.is_active))}
checked={Boolean(Number(agency.is_active))}
/>
</Box>
</HStack>
),
})),
];
}));
const FAQ = () => {
return (
<MainFrame>
@@ -84,13 +163,15 @@ const FAQ = () => {
/>
</InputGroup>
{/* <Button bgColor={'#EEEEEE'} pl={3} pr={3}><IoMdAdd /> <Text>Add</Text></Button> */}
<FaqAddModel />
<FaqAddModel refetch={refetch} />
</HStack>
</HStack>
<DataTable
sortableColumns={["Name", "Registration Date "]}
sortableColumns={["Name"]}
tableHeadRow={tableHeadRow}
data={managepost}
paginationData={data?.data}
refetch={refetch}
/>
</Box>
</MainFrame>

View File

@@ -8,15 +8,77 @@ import {
DialogTitle,
DialogTrigger,
} from "../../../components/ui/dialog";
import { Field, Input, Stack, Text, Textarea } from "@chakra-ui/react";
import { Box, Field, Input, Stack, Text, Textarea } 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 { useCreateFaqPostMutation } from "../../../Redux/Service/faqs.service";
function FaqAddModel({ refetch }: { refetch: VoidFunction }) {
const [faqQuestion, setFaqQuestion] = useState('');
const [faqAnswer, setFaqAnswer] = useState('');
const [userType, setUserType] = useState("");
const [isOpen, setIsOpen] = useState(false);
const [createFaqPost] = useCreateFaqPostMutation()
const handleOpenModal = () => {
setIsOpen(true); // Open modal when clicking "Add"
};
const handleSubmit = async () => {
if (userType === "" || isNaN(Number(userType))) {
toaster.create({
title: "Error",
description: "Please select a valid user type.",
type: "error",
});
return;
}
if (!faqQuestion.trim() || !faqAnswer.trim()) {
toaster.create({
title: "Error",
description: "Please fill in all required fields",
type: "error",
});
return;
}
const payload = {
principal_type_xid: Number(userType),
language_code: 'en',
question: faqQuestion,
answer: faqAnswer
};
try {
const response = await createFaqPost(payload).unwrap();
if (response) {
toaster.create({
title: "Success",
description: "FAQ updated successfully",
type: "success",
});
refetch()
setIsOpen(false);
} else {
toaster.create({
title: "Error",
description: "Failed to update FAQ",
type: "error",
});
}
} catch (error) {
console.error("Error updating template:", error);
// alert("Failed to update template");
}
};
function FaqAddModel() {
return (
<DialogRoot placement="center">
<DialogRoot placement="center" open={isOpen} onOpenChange={({ open }) => setIsOpen(open)}>
<DialogTrigger asChild>
<Button px={5} size={"xs"} bg={"#02A0A0"}>
<Button px={5} size={"xs"} bg={"#02A0A0"} onClick={handleOpenModal}>
<IoMdAdd /> <Text>Add</Text>
</Button>
</DialogTrigger>
@@ -37,6 +99,29 @@ function FaqAddModel() {
<DialogBody bg="white">
<Stack py={3}>
<Field.Root>
<Field.Label color="black" pt={1} fontSize="12px">Select User Type</Field.Label>
<Box bgColor="#EEEEEE" borderRadius="md" p={1}>
<select
style={{
width: "100%",
background: "transparent",
color: "black",
border: "none",
fontSize: "12px",
height: "30px",
outline: "none",
}}
value={userType}
onChange={(e) => setUserType(e.target.value)}
>
<option value="" disabled>Select User Type</option>
<option value="2">Recruiter</option>
<option value="3">Jobseeker</option>
</select>
</Box>
</Field.Root>
<Field.Root>
<Field.Label color="black" pt={1} fontSize="12px">
Questions
@@ -48,8 +133,10 @@ function FaqAddModel() {
border="none"
pl={1}
fontSize="12px"
_focusVisible={{outline:'none'}}
_focusVisible={{ outline: 'none' }}
size={'sm'}
value={faqQuestion}
onChange={(e) => setFaqQuestion(e.target.value)}
/>
<Field.Label color="black" pt={1} fontSize="12px">
@@ -64,18 +151,20 @@ function FaqAddModel() {
fontSize="12px"
height="120px"
resize={'none'}
_focusVisible={{outline:'none'}}
_focusVisible={{ outline: 'none' }}
value={faqAnswer}
onChange={(e) => setFaqAnswer(e.target.value)}
/>
</Field.Root>
</Stack>
</DialogBody>
<DialogFooter display="flex" justifyContent="center" pt={"2"}>
<Button w="100%" bg="#02A0A0" color={"#fff"}>
<Button w="100%" bg="#02A0A0" color={"#fff"} onClick={handleSubmit}>
Save
</Button>
</DialogFooter>
<DialogCloseTrigger color="black" />
<DialogCloseTrigger color="black" onClick={() => setIsOpen(false)} />
</DialogContent>
</DialogRoot>
);

View File

@@ -156,6 +156,8 @@ const AgencyMaster = () => {
sortableColumns={["Name", "Registration Date "]}
tableHeadRow={tableHeadRow}
data={managepost || []}
paginationData={data?.data}
refetch={refetch}
/>
</Box>
</MainFrame>

View File

@@ -0,0 +1,103 @@
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 { useCreateIndustryMasterPostMutation } from "../../../Redux/Service/industry.master.service";
function AddIndustryMaster({ refetch }: { refetch: VoidFunction }) {
const [jobType, setJobType] = useState("");
const [isOpen, setIsOpen] = useState(false);
const [createIndustryMasterPost] = useCreateIndustryMasterPostMutation()
const handleOpenModal = () => {
setIsOpen(true); // Open modal when clicking "Add"
};
const handleSubmit = async () => {
if (!jobType.trim()) {
toaster.create({
title: "Error",
description: "Title and Subtitle cannot be empty.",
type: "error",
});
return;
}
const payload = {
en_name: jobType,
categories_masters_xid:4
};
try {
await createIndustryMasterPost(payload);
refetch()
setIsOpen(false);
} catch (error) {
console.error("Error updating template:", error);
alert("Failed to update template");
}
};
return (
<DialogRoot placement="center" open={isOpen}>
<DialogTrigger asChild>
{/* <Button bg={"transparent"} size="sm">
<MdOutlineRemoveRedEye style={{ cursor: "pointer", fontSize: "16px" }} />
</Button> */}
<Button px={5} size={"xs"} bg={"#02A0A0"} onClick={handleOpenModal}>
<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">Job Type</Field.Label>
<Input
placeholder=""
bgColor="#EEEEEE"
color="black"
border="none"
pl={1}
fontSize="12px"
height="30px"
value={jobType}
onChange={(e) => setJobType(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" onClick={() => setIsOpen(false)} />
</DialogContent>
</DialogRoot >
)
}
export default AddIndustryMaster

View File

@@ -0,0 +1,112 @@
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 { useUpdateIndustryMasterMutation } from "../../../Redux/Service/industry.master.service";
function EditIndustryMaster({ id, localData, refetch, categories }: { id: number, localData: any, refetch: VoidFunction, categories: any }) {
const [jobtype, setJobType] = useState("");
const [updateIndustryMaster] = useUpdateIndustryMasterMutation()
const [isOpen, setIsOpen] = useState(false);
const handleOpenModal = () => {
const template = localData?.find((item: any) => item.id === id);
if (template) {
setJobType(template.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: id,
en_name: jobtype,
categories_masters_xid: categories
};
try {
await updateIndustryMaster(payload);
refetch()
setIsOpen(false);
} 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>
<Box bg={"transparent"} onClick={handleOpenModal}>
<Edit />
</Box>
</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>
<DialogBody bg="white">
<Stack py={3}>
<Field.Root>
<Field.Label color="black" pt={1} fontSize="12px">
Job Type
</Field.Label>
<Input
value={jobtype}
bgColor="#EEEEEE"
color="black"
border="none"
pl={1}
fontSize="12px"
height="30px"
onChange={(e) => setJobType(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" onClick={() => setIsOpen(false)} />
</DialogContent>
</DialogRoot>
);
}
export default EditIndustryMaster;

View File

@@ -0,0 +1,154 @@
import { Box, HStack, Input, 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 { useGetIndustryMasterQuery, useIndustryMasterToggleMutation } from "../../../Redux/Service/industry.master.service";
import EditIndustryMaster from "./EditIndustryMaster";
import AddIndustryMaster from "./AddIndustryMaster";
// table data
const tableHeadRow = [
"Sr. No",
"Title",
"Action"
];
// const managepost: any[] = [
// ...Array.from({ length: 12 }, (_, i) => ({
// "Sr. No": i + 1,
// "Agency Name": "Lorem Ipsum",
// "RC no.": "Lorem Ipsum",
// "State": "Lorem Ipsum",
// "RC Status": "Active",
// "Registered Office Address": "Lorem Ipsum",
// "Website/Domain": "Lorem Ipsum",
// "GST no.": "Lorem Ipsum",
// "Action": (
// <HStack justifyContent="center">
// <ViewAgencyMaster/>
// <EditAgencyMaster />
// <Box>
// <Switch colorPalette={'teal'} size={"xs"}/>
// </Box>
// </HStack>
// ),
// })),
// ];
const IndustryMasterList = () => {
const { data, refetch } = useGetIndustryMasterQuery()
const [industryMasterToggle] = useIndustryMasterToggleMutation()
const [localData, setLocalData] = useState<any[]>([]);
useEffect(() => {
if (data?.data?.data) {
setLocalData(data?.data.data);
}
}, [data]);
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 industryMasterToggle({ 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 = localData?.map((agency: any, index: number) => ({
'id': agency.id,
"Sr. No": index + 1,
"Title": agency.en_name,
"is_active": agency.is_active,
"Action": (
<HStack justifyContent="center">
{/* <ViewAgencyMaster agency={localData} id={agency.id} /> */}
<EditIndustryMaster id={agency.id} localData={localData} refetch={refetch} categories={agency.categories_masters_xid} />
<Box>
<Switch
colorPalette={"teal"}
size={"xs"}
onChange={() => handleToggle(agency.id, Number(agency.is_active))}
checked={Boolean(Number(agency.is_active))}
/>
</Box>
</HStack>
),
}));
useEffect(() => {
console.log("Fetched data:", data);
console.log("Local data:", localData);
console.log("Managepost data:", managepost);
}, [data, localData, managepost]);
return (
<MainFrame>
<Box>
<HStack
w={"100%"}
justifyContent={"space-between"}
mb={4}
py={0}
px={3}
>
<Text as={"span"} fontSize={"sm"} fontWeight={500} color={"#000"}>
Industry Master
</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>
{/* <Button bgColor={'#EEEEEE'} pl={3} pr={3}><IoMdAdd /> <Text>Add</Text></Button> */}
{/* <ViewAgencyAddModel /> */}
<AddIndustryMaster refetch={refetch}/>
</HStack>
</HStack>
<DataTable
sortableColumns={["Name"]}
tableHeadRow={tableHeadRow}
data={managepost || []}
paginationData={data?.data}
refetch={refetch}
/>
</Box>
</MainFrame>
)
}
export default IndustryMasterList

View File

@@ -8,15 +8,58 @@ import {
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 Edit from "../../../components/ActionIcons/Edit";
import { useState } from "react";
import { useUpdateJobTypeMutation } from "../../../Redux/Service/job.type.service";
import { toaster } from "../../../components/ui/toaster";
function EditJobeModel({ id, localData, refetch }: { id: number, localData: any, refetch: VoidFunction }) {
const [jobtype, setJobType] = useState("");
const [updateJobType] = useUpdateJobTypeMutation()
const [isOpen, setIsOpen] = useState(false);
const handleOpenModal = () => {
const template = localData?.find((item: any) => item.id === id);
if (template) {
setJobType(template.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: id,
en_name: jobtype,
};
try {
await updateJobType(payload);
refetch()
setIsOpen(false);
} catch (error) {
console.error("Error updating template:", error);
alert("Failed to update template");
}
};
function EditJobeModel() {
return (
<DialogRoot placement="center">
<DialogRoot placement="center" open={isOpen} onOpenChange={({ open }) => setIsOpen(open)}>
<DialogTrigger asChild>
<Span><Edit /></Span>
<Box bg={"transparent"} onClick={handleOpenModal}>
<Edit />
</Box>
</DialogTrigger>
<DialogContent
@@ -41,24 +84,25 @@ function EditJobeModel() {
Job Type
</Field.Label>
<Input
value="Lorem Ipsum"
value={jobtype}
bgColor="#EEEEEE"
color="black"
border="none"
pl={1}
fontSize="12px"
height="30px"
onChange={(e) => setJobType(e.target.value)}
/>
</Field.Root>
</Stack>
</DialogBody>
<DialogFooter display="flex" justifyContent="center" pt={"2"}>
<Button w="100%" bg="#02A0A0" color={"#fff"}>
<Button w="100%" bg="#02A0A0" color={"#fff"} onClick={handleSubmit}>
Save
</Button>
</DialogFooter>
<DialogCloseTrigger color="black" />
<DialogCloseTrigger color="black" onClick={() => setIsOpen(false)} />
</DialogContent>
</DialogRoot>
);

View File

@@ -2,31 +2,65 @@ 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 { useCreateJobTypePostMutation } from "../../../Redux/Service/job.type.service";
import { toaster } from "../../../components/ui/toaster";
function JobAddModel({ refetch }: { refetch: VoidFunction }) {
const [jobType, setJobType] = useState("");
const [isOpen, setIsOpen] = useState(false);
const [createJobTypePost] = useCreateJobTypePostMutation()
const handleOpenModal = () => {
setIsOpen(true); // Open modal when clicking "Add"
};
const handleSubmit = async () => {
if (!jobType.trim()) {
toaster.create({
title: "Error",
description: "Title and Subtitle cannot be empty.",
type: "error",
});
return;
}
const payload = {
en_name: jobType,
};
try {
await createJobTypePost(payload);
refetch()
setIsOpen(false);
} catch (error) {
console.error("Error updating template:", error);
alert("Failed to update template");
}
};
function JobAddModel() {
return (
<DialogRoot placement="center">
<DialogRoot placement="center" open={isOpen}>
<DialogTrigger asChild>
{/* <Button bg={"transparent"} size="sm">
<MdOutlineRemoveRedEye style={{ cursor: "pointer", fontSize: "16px" }} />
</Button> */}
<Button px={5} size={"xs"} bg={"#02A0A0"}>
<Button px={5} size={"xs"} bg={"#02A0A0"} onClick={handleOpenModal}>
<IoMdAdd /> <Text>Add</Text>
</Button>
</DialogTrigger>
<DialogContent
bg={"#fff"}
// w={{ lg: "60%", md: "230px" }}
w={{ base: '90%', md: '400px' }}
bg={"#fff"}
// w={{ lg: "60%", md: "230px" }}
w={{ base: '90%', md: '400px' }}
height={'auto'}
overflowX="hidden"
p={3} // Reduced padding
bgSize={'md'}
overflowX="hidden"
p={3} // Reduced padding
bgSize={'md'}
>
<DialogHeader bg="white" >
<DialogTitle alignSelf="center" color="black" fontSize="14px">Add</DialogTitle>
@@ -37,18 +71,28 @@ function JobAddModel() {
<Field.Root>
<Field.Label color="black" pt={1} fontSize="12px">Job Type</Field.Label>
<Input placeholder="" bgColor="#EEEEEE" color="black" border="none" pl={1} fontSize="12px" height="30px" />
<Input
placeholder=""
bgColor="#EEEEEE"
color="black"
border="none"
pl={1}
fontSize="12px"
height="30px"
value={jobType}
onChange={(e) => setJobType(e.target.value)}
/>
</Field.Root>
</Stack>
</DialogBody>
<DialogFooter display="flex" justifyContent="center" pt={"2"}>
<Button w="100%" bg="#02A0A0" color={"#fff"}>
<Button w="100%" bg="#02A0A0" color={"#fff"} onClick={handleSubmit}>
Save
</Button>
</DialogFooter>
<DialogCloseTrigger color="black" />
<DialogCloseTrigger color="black" onClick={() => setIsOpen(false)} />
</DialogContent>
</DialogRoot >

View File

@@ -6,6 +6,8 @@ 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";
@@ -15,25 +17,79 @@ 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">
// <EditJobeModel />
// <Box>
// <Switch colorPalette={'teal'} size={"xs"} />
// </Box>
// </HStack>
// ),
// })),
// ];
const JobType = () => {
const { data, refetch } = useGetJobTypeQuery()
const [localData, setLocalData] = useState<any[]>([]);
// const [templateMasterToggle] = useTemplateMasterToggleMutation()
console.log('DATA', data?.data.data);
useEffect(() => {
if (data?.data?.data) {
setLocalData(data?.data.data);
}
}, [data]);
// 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 templateMasterToggle({ 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 = localData?.map((agency: JobTypeData, index: number) => ({
'id': agency.id,
"Sr. No": index + 1,
"Title": agency.en_name,
"Action": (
<HStack justifyContent="center">
<EditJobeModel />
<EditJobeModel id={agency.id} localData={localData} refetch={refetch} />
<Box>
<Switch colorPalette={'teal'} size={"xs"}/>
<Switch
colorPalette={'teal'}
size={"xs"}
// onChange={() => handleToggle(agency.id, Number(agency.is_active))}
checked={Boolean(Number(agency.is_active))}
/>
</Box>
</HStack>
),
})),
];
}));
const JobType = () => {
return (
<MainFrame>
@@ -46,11 +102,11 @@ const JobType = () => {
px={3}
>
<Text as={"span"} fontSize={"sm"} fontWeight={500} color={"#000"}>
Job Type
Job Type
</Text>
<HStack >
<InputGroup
<InputGroup
startElement={
<LuSearch fontSize={"xs"} style={{ position: 'relative', left: '10px' }} />
}
@@ -71,15 +127,17 @@ const JobType = () => {
/>
</InputGroup>
{/* <Button bgColor={'#EEEEEE'} pl={3} pr={3}><IoMdAdd /> <Text>Add</Text></Button> */}
<JobAddModel />
<JobAddModel refetch={refetch} />
</HStack>
</HStack>
<DataTable
sortableColumns={["Name", "Registration Date "]}
tableHeadRow={tableHeadRow}
data={managepost}
paginationData={data?.data}
refetch={refetch}
/>
</Box>
</Box>
</MainFrame>
)
}

View File

@@ -19,31 +19,38 @@ import { useState } from "react";
// import { FaRegEdit } from "react-icons/fa";
import Edit from "../../../components/ActionIcons/Edit";
import { Toaster, toaster } from "../../../components/ui/toaster";
import { Template, useUpdateTemplateMasterMutation } from "../../../Redux/Service/template.master.service";
import { Template } from "../../../Redux/Service/template.master.service";
import axios from "axios";
const APIURL = import.meta.env.VITE_IMG_TEMPLATES
// const IMGURL = import.meta.env.VITE_IMG_TEMPLATES
const APIURL = import.meta.env.VITE_API_URL
function EditTemplateModel({ id, localData }: { id: any, localData: any }) {
function EditTemplateModel({ id, localData, refetch }: { id: number, localData: any, refetch:VoidFunction }) {
const [title, setTitle] = useState("");
const [subTitle, setSubTitle] = useState("");
const [userType, setUserType] = useState<number | "">("");
const [images, setImages] = useState<(File | string)[]>([]);
const [updateTemplateMaster] = useUpdateTemplateMasterMutation()
// const [objectURLs, setObjectURLs] = useState<string[]>([]); // Store object URLs separately
// const [updateTemplateMaster] = useUpdateTemplateMasterMutation()
const [isOpen, setIsOpen] = useState(false);
const [selectedTemplate, setSelectedTemplate] = useState<Template | null>(null);
const token = localStorage.getItem("token");
console.log(selectedTemplate);
const handleImageChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const handleImageChange = async (event: React.ChangeEvent<HTMLInputElement>) => {
if (event.target.files) {
const selectedFiles = Array.from(event.target.files);
const file = event.target.files[0];
if (!["image/jpeg", "image/jpg", "image/png"].includes(file.type)) {
toaster.create({
title: "Error",
description: "Only JPEG, JPG, and PNG files are allowed.",
type: "error",
});
return;
}
const newImages = selectedFiles.map((file) => {
return URL.createObjectURL(file); // Convert to preview URL
});
setImages((prevImages) => [...prevImages, ...newImages]); // Append new images
setImages((prevImages) => [...prevImages, file]);
}
};
@@ -56,8 +63,8 @@ function EditTemplateModel({ id, localData }: { id: any, localData: any }) {
setUserType(template.principle_type_xid?.toString() || "");
// Convert image URLs to File objects if needed
const templateImages = template.post_template_image.map((img: any) => `${APIURL}${img.image_name}`);
setImages(templateImages);
// const templateImages = template.post_template_image.map((img: any) => `${IMGURL}${img.image_name}`);
// setImages(templateImages);
setIsOpen(true);
}
@@ -92,26 +99,90 @@ function EditTemplateModel({ id, localData }: { id: any, localData: any }) {
return;
}
const existingImageUrls = images.filter((img) => typeof img === "string") as string[];
const newBase64Images = images.filter((img) => typeof img === "string" && img.startsWith("data:image")) as string[];
const formData = new FormData();
formData.append("id", `${id}`);
formData.append("principle_type_xid", `${userType}`);
formData.append("title", title);
formData.append("sub_title", subTitle);
const payload = {
id: id,
principle_type_xid: userType,
title,
sub_title: subTitle,
image_name: [...existingImageUrls, ...newBase64Images], // Send only Base64 strings
};
images.forEach((image, index) => {
if (typeof image === "string") {
// Append existing image URLs
formData.append(`existing_images[${index}]`, image);
} else {
// Append new image files
formData.append(`new_images[${index}]`, image, image.name);
}
});
try {
await updateTemplateMaster(payload)
setIsOpen(false)
// await updateTemplateMaster(formData);
if (token) {
await axios.post(`${APIURL}/template-update`, formData, {
headers: {
'Content-Type': 'multipart/form-data',
'access-token': `${token}`,
},
// withCredentials: true,
});
}
setIsOpen(false);
refetch()
} catch (error) {
console.error("Error creating template:", error);
alert("Failed to create template");
console.error("Error updating template:", error);
alert("Failed to update template");
}
};
// const handleSubmit = async () => {
// if (!title.trim() || !subTitle.trim()) {
// toaster.create({
// title: "Error",
// description: "Title and Subtitle cannot be empty.",
// type: "error",
// });
// return;
// }
// if (userType === "" || isNaN(Number(userType))) {
// toaster.create({
// title: "Error",
// description: "Please select a valid user type.",
// type: "error",
// });
// return;
// }
// if (images.length === 0) {
// toaster.create({
// title: "Error",
// description: "Please upload at least one image.",
// type: "error",
// });
// return;
// }
// const existingImageUrls = images.filter((img) => typeof img === "string") as string[];
// const newBase64Images = images.filter((img) => typeof img === "string" && img.startsWith("data:image")) as string[];
// const payload = {
// id: id,
// principle_type_xid: userType,
// title,
// sub_title: subTitle,
// image_name: [...existingImageUrls, ...newBase64Images], // Send only Base64 strings
// };
// try {
// await updateTemplateMaster(payload)
// setIsOpen(false)
// } catch (error) {
// console.error("Error creating template:", error);
// alert("Failed to create template");
// }
// };
return (
<DialogRoot placement="center" open={isOpen} onOpenChange={({ open }) => setIsOpen(open)}>
{/* <Button bg={"transparent"} size="sm">
@@ -133,7 +204,7 @@ function EditTemplateModel({ id, localData }: { id: any, localData: any }) {
bgSize={'md'}
>
<DialogHeader bg="white" >
<DialogTitle alignSelf="center" color="black" fontSize="14px">Add</DialogTitle>
<DialogTitle alignSelf="center" color="black" fontSize="14px">Edit</DialogTitle>
</DialogHeader>
<DialogBody bg="white">

View File

@@ -8,8 +8,9 @@ import { useState } from "react";
import { Toaster, toaster } from "../../../components/ui/toaster"
import axios from "axios";
const APIURL = import.meta.env.VITE_API_URL
function TemplateAddModel({refetch}:{refetch: VoidFunction}) {
function TemplateAddModel({ refetch }: { refetch: VoidFunction }) {
const [title, setTitle] = useState("");
const [subTitle, setSubTitle] = useState("");
const [userType, setUserType] = useState<number | "">("");
@@ -45,7 +46,7 @@ function TemplateAddModel({refetch}:{refetch: VoidFunction}) {
const handleSubmit = async () => {
if (!title || !subTitle || !userType || images.length === 0) {
if (!title || !subTitle || images.length === 0) {
toaster.create({
title: "Error",
description: "Please fill in all required fields and upload at least one image.",
@@ -54,6 +55,15 @@ function TemplateAddModel({refetch}:{refetch: VoidFunction}) {
return;
}
if (userType === "" || isNaN(Number(userType))) {
toaster.create({
title: "Error",
description: "Please select a valid user type.",
type: "error",
});
return;
}
// const payload = {
// id: id,
// principle_type_xid: userType,
@@ -82,7 +92,7 @@ function TemplateAddModel({refetch}:{refetch: VoidFunction}) {
try {
// await createTemplatePost(formData)
if (token) {
await axios.post(`https://ssa.betadelivery.com/apia/v1/template-store`, formData, {
await axios.post(`${APIURL}/template-store`, formData, {
headers: {
'Content-Type': 'multipart/form-data',
'access-token': `${token}`,
@@ -102,7 +112,7 @@ function TemplateAddModel({refetch}:{refetch: VoidFunction}) {
}
};
console.log("Token stored:", window.localStorage.getItem("token"));
// console.log("Token stored:", window.localStorage.getItem("token"));
return (

View File

@@ -96,7 +96,7 @@ const TemplateMaster = () => {
"Action": (
<HStack justifyContent="center">
<EditTemplateModel id={agency.id} localData={localData} />
<EditTemplateModel id={agency.id} localData={localData} refetch={refetch} />
<Box>
<Switch
colorPalette={'teal'}
@@ -153,6 +153,8 @@ const TemplateMaster = () => {
sortableColumns={["Name", "Registration Date "]}
tableHeadRow={tableHeadRow}
data={managepost}
paginationData={data?.data}
refetch={refetch}
/>
</Box>
</MainFrame>

View File

@@ -1,26 +1,84 @@
import { createApi } from "@reduxjs/toolkit/query";
import { createApi } from "@reduxjs/toolkit/query/react";
import { baseQueryWithReauth } from "./apiSlice";
interface Faq {
id: number;
principal_type_xid: number;
is_active: string;
}
export interface FaqData {
id: number;
faqs_xid: number;
language_master_xid: number;
question: string;
answer: string;
is_active: string;
faq: Faq;
}
interface ApiResponse {
status: string;
status_code: number;
message: string;
data: FaqData[];
}
export type Post = {
principal_type_xid: number;
language_code: string;
question: string;
answer: string;
};
export const faqs = createApi({
reducerPath: "faqs",
baseQuery: baseQueryWithReauth, // Use enhanced baseQuery with error handling
endpoints: (builder) => ({
getPosts: builder.query<Post[], void>({ query: () => "/posts" }),
reducerPath: "faqs",
baseQuery: baseQueryWithReauth, // Use enhanced baseQuery with error handling
endpoints: (builder) => ({
createFaqPost: builder.mutation<Post, Partial<Post>>({
query: (data) => ({
url: "/faq-store",
method: "POST",
body: data,
}),
}),
});
export const { } = faqs;
export type Post = {
id: number;
title: string;
body: string;
};
// 🔹 GET: Fetch all posts
getFaq: builder.query<ApiResponse, void>({
query: () => "/faq-list",
}),
updateFaq: builder.mutation({
query: (updatedData) => ({
url: "/faq-update",
method: "POST",
body: updatedData,
}),
}),
faqToggle: builder.mutation({
query: ({ id, is_active }) => ({
url: `/faq-status`,
method: "POST",
body: { id, is_active },
}),
}),
deleteFaqPost: builder.mutation<{ success: boolean }, number>({
query: (id) => ({
url: `/faq-delete/${id}`,
method: "DELETE",
}),
}),
}),
});
export const {
useGetFaqQuery,
useCreateFaqPostMutation,
useUpdateFaqMutation,
useFaqToggleMutation,
useDeleteFaqPostMutation
} = faqs;

View File

@@ -0,0 +1,92 @@
import { createApi } from "@reduxjs/toolkit/query/react";
import { baseQueryWithReauth } from "./apiSlice";
interface IndustryMasterResponse {
status: string;
status_code: number;
message: string;
data: PaginationData;
}
interface PaginationData {
current_page: number;
data: IndustryMaster[];
first_page_url: string;
from: number;
last_page: number;
last_page_url: string;
links: PaginationLink[];
next_page_url: string | null;
path: string;
per_page: number;
prev_page_url: string | null;
to: number;
total: number;
}
export interface IndustryMaster {
id: number;
categories_masters_xid: number,
is_active: boolean;
en_name: string;
hi_name: string;
mr_name: string,
te_name: string,
ta_name: string,
bn_name: string,
or_name: string,
}
interface PaginationLink {
url: string | null;
label: string;
active: boolean;
}
export interface Post {
en_name: string,
categories_masters_xid: number
}
export const industryMaster = createApi({
reducerPath: "industryMaster",
baseQuery: baseQueryWithReauth, // Use enhanced baseQuery with error handling
endpoints: (builder) => ({
createIndustryMasterPost: builder.mutation<Post, Partial<Post>>({
query: (data) => ({
url: "/industry-master-store",
method: "POST",
body: data,
}),
}),
// 🔹 GET: Fetch all posts
getIndustryMaster: builder.query<IndustryMasterResponse, void>({
query: () => "/industry-master-list",
}),
updateIndustryMaster: builder.mutation({
query: (updatedData) => ({
url: "industry-master-update",
method: "POST",
body: updatedData,
}),
}),
industryMasterToggle: builder.mutation({
query: ({ id, is_active }) => ({
url: `/industry-master-status`,
method: "POST",
body: { id, is_active },
}),
}),
}),
});
export const {
useGetIndustryMasterQuery,
useCreateIndustryMasterPostMutation,
useUpdateIndustryMasterMutation,
useIndustryMasterToggleMutation,
} = industryMaster;

View File

@@ -44,25 +44,18 @@ interface PaginationLink {
}
export interface Post {
id: number,
principle_type_xid: number,
title: string,
sub_title: string,
image_name: string[]
en_name: string
}
export const jobType = createApi({
reducerPath: "jobType",
baseQuery: baseQueryWithReauth, // Use enhanced baseQuery with error handling
endpoints: (builder) => ({
createTemplatePost: builder.mutation<Post, FormData>({
createJobTypePost: builder.mutation<Post, Partial<Post>>({
query: (data) => ({
url: "/template-store",
url: "/job-type-add",
method: "POST",
body: data,
headers: {
token_access: `Bearer ${localStorage.getItem("token")}`,
},
}),
}),
// 🔹 GET: Fetch all posts
@@ -70,9 +63,9 @@ export const jobType = createApi({
query: () => "/job-type",
}),
updateTemplateMaster: builder.mutation({
updateJobType: builder.mutation({
query: (updatedData) => ({
url: "/template-update",
url: "job-type-update",
method: "POST",
body: updatedData,
}),
@@ -91,7 +84,7 @@ export const jobType = createApi({
export const {
useGetJobTypeQuery,
useCreateTemplatePostMutation,
useUpdateTemplateMasterMutation,
useCreateJobTypePostMutation,
useUpdateJobTypeMutation,
useTemplateMasterToggleMutation,
} = jobType;

View File

@@ -77,12 +77,18 @@ export const templateMaster = createApi({
query: () => "/template-master",
}),
updateTemplateMaster: builder.mutation({
query: (updatedData) => ({
url: "/template-update",
method: "POST",
body: updatedData,
}),
updateTemplateMaster: builder.mutation<Post, FormData>({
query: (updatedData) => {
const token = localStorage.getItem("token");
return {
url: "/template-update",
method: "POST",
body: updatedData,
headers: {
'access-token': `${token}`,
},
};
},
}),
templateMasterToggle: builder.mutation({

View File

@@ -17,6 +17,7 @@ import { agencyMasterModule } from "./Service/agency.master.module.service";
import { termsAndCondition } from "./Service/terms.and.condition.service";
import { templateMaster } from "./Service/template.master.service";
import { jobType } from "./Service/job.type.service";
import { industryMaster } from "./Service/industry.master.service";
export const store = configureStore({
reducer: {
@@ -37,6 +38,7 @@ export const store = configureStore({
[termsAndCondition.reducerPath]: termsAndCondition.reducer,
[templateMaster.reducerPath]: templateMaster.reducer,
[jobType.reducerPath]: jobType.reducer,
[industryMaster.reducerPath]: industryMaster.reducer,
auth: authReducer,
},
middleware: (getDefaultMiddleware) =>
@@ -57,6 +59,7 @@ export const store = configureStore({
termsAndCondition.middleware,
templateMaster.middleware,
jobType.middleware,
industryMaster.middleware,
),
});

View File

@@ -89,11 +89,11 @@ export const nav = [
path: "/manage-cms/terms-conditions",
Icon: GoDotFill,
},
{
title: "Privacy",
path: "/manage-cms/privacy",
Icon: GoDotFill,
},
// {
// title: "Privacy",
// path: "/manage-cms/privacy",
// Icon: GoDotFill,
// },
],
},
{
@@ -138,6 +138,11 @@ export const nav = [
path: "/master-module/job-status",
Icon: GoDotFill,
},
{
title: "Industry Master",
path: "/master-module/industry-master",
Icon: GoDotFill,
},
],
},
];

View File

@@ -23,6 +23,7 @@ import JobStatus from "../Pages/MasterModule/JobStatus/JobStatus";
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";
export const RouteLink = [
{ path: "/", Component: Dashboard },
@@ -61,6 +62,7 @@ export const RouteLink = [
{ path: "/master-module/workspace-mode", Component: WorkspaceMode},
{ path: "/master-module/country", Component: Country},
{ path: "/master-module/job-status", Component: JobStatus},
{ path: "/master-module/industry-master", Component: IndustryMasterList},
// { path: "/job-status", Component: Spinner},
]

View File

@@ -12,13 +12,23 @@ interface TableProps {
tableHeadRow: string[];
data: Record<string, any>[];
sortableColumns?: string[]; // Specify which columns are sortable
paginationData?: any,
refetch?: (params?: any) => void;
}
const DataTable: React.FC<TableProps> = ({
tableHeadRow,
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);
const [sortConfig, setSortConfig] = useState<{
key: string;
@@ -29,6 +39,15 @@ const DataTable: React.FC<TableProps> = ({
setSortedData(data);
}, [data]);
const handlePageChange = (newPage: any) => {
if (newPage >= 1 && newPage <= lastPage) {
setPage(newPage);
if (refetch) {
refetch({ page: newPage });
}
}
};
const handleSort = (column: string) => {
if (!sortableColumns.includes(column)) return;
@@ -106,7 +125,13 @@ const DataTable: React.FC<TableProps> = ({
fontWeight={500}
border={"none"}
>
{item[heading]}
{/* {item[heading]} */}
{(() => {
const words = item[heading]?.toString().split(" ") || [];
return words.length > 5
? `${words.slice(0, 5).join(" ")}...`
: item[heading];
})()}
</Table.Cell>
))}
</Table.Row>
@@ -114,19 +139,22 @@ const DataTable: React.FC<TableProps> = ({
</Table.Body>
</Table.Root>
</Table.ScrollArea>
<PaginationRoot
{lastPage > 1 && <PaginationRoot
count={totalCount}
pageSize={pageSize}
defaultPage={currentPage}
size={"xs"}
count={20}
pageSize={2}
defaultPage={1}
// count={20}
// pageSize={2}
// defaultPage={1}
mb={4}
>
<HStack justifyContent="flex-end">
<PaginationPrevTrigger />
<PaginationPrevTrigger onClick={() => handlePageChange(page - 1)} disabled={page === 1} />
<PaginationItems />
<PaginationNextTrigger />
<PaginationNextTrigger onClick={() => handlePageChange(page + 1)} disabled={page === lastPage} />
</HStack>
</PaginationRoot>
</PaginationRoot>}
</Stack>
);
};