This commit is contained in:
rockyeverlast
2025-09-11 20:21:13 +05:30
12 changed files with 301 additions and 179 deletions

View File

@@ -1,6 +1,6 @@
import { HStack, Image, Text, VStack } from "@chakra-ui/react";
import React, { FC, useContext } from "react";
import { RiNotificationLine } from "react-icons/ri";
// import { RiNotificationLine } from "react-icons/ri";
import { NavLink, useLocation, useNavigate } from "react-router-dom";
import { nav } from "../Routes/Nav";
import logo from '../assets/logo.svg';
@@ -74,7 +74,7 @@ const DefaultLayout: FC<{ children: React.ReactNode }> = ({ children }) => {
<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>
{/* <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'}>

View File

@@ -16,6 +16,7 @@ import "react-quill/dist/quill.snow.css"; // Import the styles
import { useState } from "react";
import { useUpdateAboutUsMutation } from "../../../Redux/Service/manage.aboutus.service";
import { useForm, Controller } from "react-hook-form"; // Import React Hook Form
import { toaster, Toaster } from "../../../components/ui/toaster";
function AboutUsAddModel({ aboutUsData }: { aboutUsData: any }) {
const [isOpen, setIsOpen] = useState(false);
@@ -55,87 +56,95 @@ function AboutUsAddModel({ aboutUsData }: { aboutUsData: any }) {
}).unwrap();
setIsOpen(false); // Close dialog on success
reset(); // Reset the form
} catch (error) {
} catch (error: any) {
console.error("Update failed:", error);
toaster.create({
title: "Error",
description: `${error.data.message || "Failed to update"}`,
type: "error",
});
}
};
return (
<DialogRoot placement="center" open={isOpen}>
<DialogTrigger asChild>
<Button
bgColor="#EEEEEE"
pl={3}
pr={3}
size="xs"
color="#000"
onClick={() => handleEditClick(aboutUsData)} // Set content before opening modal
>
<FaRegEdit color="#000" style={{ height: "14px", width: "14px" }} />
<Text color="#000" mt={1}>Edit</Text>
</Button>
</DialogTrigger>
<DialogContent bg="#fff" w={{ base: "90%", md: "1200px" }} height="auto" p={3}>
<DialogHeader bg="white">
<DialogTitle alignSelf="center" color="black" fontSize="14px">
Edit About Us
</DialogTitle>
</DialogHeader>
<DialogBody bg="white">
<Stack py={3} mb={8}>
<Field.Root>
<Field.Label color="black" pt={1} fontSize="12px">
About Us Content
</Field.Label>
{/* Use Controller to integrate ReactQuill with React Hook Form */}
<Controller
name="content"
control={control}
render={({ field }) => (
<ReactQuill
value={field.value}
onChange={field.onChange}
placeholder="Enter About Us content"
modules={{
toolbar: [
[{ 'header': [1, 2, false] }],
['bold', 'italic', 'underline', 'strike'],
['link', 'image'],
[{ 'list': 'ordered' }, { 'list': 'bullet' }],
['clean']
],
}}
formats={[
'header',
'bold', 'italic', 'underline', 'strike',
'list', 'bullet',
'link', 'image'
]}
style={{ color: "black", border: "none", fontSize: "12px", height: "170px", width: "100%" }}
/>
)}
/>
</Field.Root>
</Stack>
</DialogBody>
<DialogFooter display="flex" justifyContent="center" pt="2">
<>
<DialogRoot placement="center" open={isOpen}>
<DialogTrigger asChild>
<Button
w="100%"
bg="#02A0A0"
color="#fff"
// isLoading={isLoading}
onClick={handleSubmit(onSubmit)} // Use handleSubmit to trigger form submission
bgColor="#EEEEEE"
pl={3}
pr={3}
size="xs"
color="#000"
onClick={() => handleEditClick(aboutUsData)} // Set content before opening modal
>
Save
<FaRegEdit color="#000" style={{ height: "14px", width: "14px" }} />
<Text color="#000" mt={1}>Edit</Text>
</Button>
</DialogFooter>
</DialogTrigger>
<DialogCloseTrigger color="black" onClick={() => setIsOpen(false)} />
</DialogContent>
</DialogRoot>
<DialogContent bg="#fff" w={{ base: "90%", md: "1200px" }} height="auto" p={3}>
<DialogHeader bg="white">
<DialogTitle alignSelf="center" color="black" fontSize="14px">
Edit About Us
</DialogTitle>
</DialogHeader>
<DialogBody bg="white">
<Stack py={3} mb={8}>
<Field.Root>
<Field.Label color="black" pt={1} fontSize="12px">
About Us Content
</Field.Label>
{/* Use Controller to integrate ReactQuill with React Hook Form */}
<Controller
name="content"
control={control}
render={({ field }) => (
<ReactQuill
value={field.value}
onChange={field.onChange}
placeholder="Enter About Us content"
modules={{
toolbar: [
[{ 'header': [1, 2, false] }],
['bold', 'italic', 'underline', 'strike'],
['link', 'image'],
[{ 'list': 'ordered' }, { 'list': 'bullet' }],
['clean']
],
}}
formats={[
'header',
'bold', 'italic', 'underline', 'strike',
'list', 'bullet',
'link', 'image'
]}
style={{ color: "black", border: "none", fontSize: "12px", height: "170px", width: "100%" }}
/>
)}
/>
</Field.Root>
</Stack>
</DialogBody>
<DialogFooter display="flex" justifyContent="center" pt="2">
<Button
w="100%"
bg="#02A0A0"
color="#fff"
// isLoading={isLoading}
onClick={handleSubmit(onSubmit)} // Use handleSubmit to trigger form submission
>
Save
</Button>
</DialogFooter>
<DialogCloseTrigger color="black" onClick={() => setIsOpen(false)} />
</DialogContent>
</DialogRoot>
<Toaster />
</>
);
}

View File

@@ -1,4 +1,4 @@
import { Field, Input, Stack } from "@chakra-ui/react";
import { Box, Field, Input, Stack } from "@chakra-ui/react";
import {
DialogActionTrigger,
DialogBody,
@@ -12,20 +12,31 @@ import {
} from "../../../components/ui/dialog";
import { Button } from "../../../components/ui/button";
import { IoMdAdd } from "react-icons/io";
import { useState } from "react";
// import { useCreateUserMutation } from "../../../Redux/Service/manage.user";
// import { useState } from "react";
function AddRegisterUsers() {
// const [createUser] = useCreateUserMutation();
const [userType, setUserType] = useState<number | "">("");
// const [user, setUser] = useState({
// first_name: '',
// last_name: '',
// date_of_birth: '',
// gender: '',
// date_of_birth: '',
// principle_language_linkss: [],
// });
const [user, setUser] = useState<{
principal_type_xid: number;
principal_source_xid: number | "";
first_name: string;
last_name: string;
gender: string;
date_of_birth: string;
language_name: string[];
}>({
principal_type_xid: 1,
principal_source_xid: userType,
first_name: '',
last_name: '',
gender: '',
date_of_birth: '',
language_name: [],
});
return (
<DialogRoot placement="center">
@@ -36,13 +47,13 @@ function AddRegisterUsers() {
</DialogTrigger>
<DialogContent
bg={"#fff"}
w={{ base: '90%', md: '400px' }}
height={'80vh'}
overflow={'scroll'}
overflowX="hidden"
p={3} // Reduced padding
bgSize={'md'}
bg={"#fff"}
w={{ base: '90%', md: '400px' }}
height={'80vh'}
overflow={'scroll'}
overflowX="hidden"
p={3} // Reduced padding
bgSize={'md'}
>
<DialogHeader bg="white" >
<DialogTitle alignSelf="center" color="black" fontSize="14px">
@@ -57,42 +68,110 @@ function AddRegisterUsers() {
First Name
</Field.Label>
<Input
bgColor="#EEEEEE" color="black" border="none" pl={1} fontSize="12px" height="30px"
bgColor="#EEEEEE"
color="black"
border="none"
pl={1}
fontSize="12px"
height="30px"
value={user.first_name}
onChange={(e) => setUser({ ...user, first_name: e.target.value })}
/>
<Field.Label color="black" pt={1} fontSize="12px">
Last Name
</Field.Label>
<Input
bgColor="#EEEEEE" color="black" border="none" pl={1} fontSize="12px" height="30px"
bgColor="#EEEEEE"
color="black"
border="none"
pl={1}
fontSize="12px"
height="30px"
value={user.last_name}
onChange={(e) => setUser({ ...user, last_name: e.target.value })}
/>
<Field.Label color="black" pt={1} fontSize="12px">
Gender
</Field.Label>
<Input
bgColor="#EEEEEE" color="black" border="none" pl={1} fontSize="12px" height="30px"
bgColor="#EEEEEE"
color="black"
border="none"
pl={1}
fontSize="12px"
height="30px"
value={user.gender}
onChange={(e) => setUser({ ...user, gender: e.target.value })}
/>
<Field.Label color="black" pt={1} fontSize="12px">
DOB
</Field.Label>
<Input
bgColor="#EEEEEE" color="black" border="none" pl={1} fontSize="12px" height="30px" type="date"
bgColor="#EEEEEE"
color="black"
border="none"
pl={1}
fontSize="12px"
height="30px"
type="date"
value={user.date_of_birth}
onChange={(e) => setUser({ ...user, date_of_birth: e.target.value })}
/>
<Field.Label color="black" pt={1} fontSize="12px">
<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(Number(e.target.value))}
>
<option value="">Select User Type</option>
<option value="2">Recruiter</option>
<option value="3">Jobseeker</option>
</select>
</Box>
</Field.Root>
{/* <Field.Label color="black" pt={1} fontSize="12px">
OTP Verified
</Field.Label>
<Input
bgColor="#EEEEEE" color="black" border="none" pl={1} fontSize="12px" height="30px"
/>
/> */}
<Field.Label color="black" pt={1} fontSize="12px">
Language
</Field.Label>
<Input
bgColor="#EEEEEE" color="black" border="none" pl={1} fontSize="12px" height="30px"
bgColor="#EEEEEE"
color="black"
border="none"
pl={1}
fontSize="12px"
height="30px"
value={user.language_name.join(", ")} // display as comma-separated string
onChange={(e) =>
setUser({
...user,
language_name: e.target.value
.split(",")
.map(lang => lang.trim())
.filter(Boolean), // remove empty strings
})
}
/>
</Field.Root>
</Stack>

View File

@@ -1,5 +1,6 @@
import {
Box, HStack,
Image,
// Image,
Text,
} from "@chakra-ui/react";
@@ -10,10 +11,13 @@ import DataTable from "../../../components/DataTable";
import { Switch } from "../../../components/ui/switch";
import ViewRegisterUsers from "./ViewRegisterUsers";
import EditRegisterUsers from "./EditRegisterUsers";
import AddRegisterUsers from "./AddRegisterUsers";
// import AddRegisterUsers from "./AddRegisterUsers";
import { useEffect, useState } from "react";
import { useGetManageUserQuery, UserData, useUserToggleMutation } from "../../../Redux/Service/manage.user";
import { useDeleteUserMutation, useGetManageUserQuery, UserData, useUserToggleMutation } from "../../../Redux/Service/manage.user";
import SearchComponent from "../../../components/SearchComponent";
import AlertDailog from "../../../components/AlertDailog";
import { toaster } from "../../../components/ui/toaster";
import Delete from "../../../components/ActionIcons/Delete";
// import Delete from "../../../components/ActionIcons/Delete";
const tableHeadRow = [
@@ -67,6 +71,10 @@ const RegisterUsers = () => {
const [localData, setLocalData] = useState<any[]>([]);
const [searchTerm, setSearchTerm] = useState("");
const [userToggle] = useUserToggleMutation()
const [deleteFaqPost] = useDeleteUserMutation()
const [deleteModal, setDeleteModal] = useState(false)
const [selectedFaqId, setSelectedFaqId] = useState<number | null>(null);
console.log("Register Users Data", data?.data.data);
useEffect(() => {
@@ -108,6 +116,29 @@ const RegisterUsers = () => {
}
}
const handleDeleteFaq = async (faqId: number) => {
try {
const response = await deleteFaqPost({ id: faqId }).unwrap();
if (response?.status === "success") {
toaster.create({
title: "Success",
description: "User deleted successfully",
type: "success",
});
refetch()
console.log("User deleted successfully:", response);
}
// Optionally, refetch data or update state after deletion
} catch (error) {
console.error("Error deleting User:", error);
toaster.create({
title: "Error",
description: "Something went wrong",
type: "error",
});
}
};
const managepost = filteredData?.flatMap((agency: UserData, index: number) => ({
"Sr. No": (currentPage - 1) * (data?.data.per_page ?? 0) + index + 1,
"First Name": agency.first_name,
@@ -134,6 +165,24 @@ const RegisterUsers = () => {
onChange={() => handleToggle(agency.id, agency.is_active ? '1' : '0')}
/>
</Box>
<AlertDailog
isOpen={deleteModal}
AltertTiggerIcon={() => <Delete onClick={() => {
setSelectedFaqId(agency.id);
setDeleteModal(true)
}} />}
alertText="Do you want to delete user?"
alertIcon={<Image src={"DeleteIcon"} h={"39px"} />}
alertCaption="are you sure you want to delete ?"
onClose={() => setDeleteModal(false)}
onConfirm={() => {
// console.log("Deleting FAQ with ID:", selectedFaqId); // Correct ID
if (selectedFaqId) {
setDeleteModal(false);
handleDeleteFaq(selectedFaqId);
}
}}
/>
</HStack>
),
}))
@@ -161,7 +210,7 @@ const RegisterUsers = () => {
refetch()
}}
/>
<AddRegisterUsers />
{/* <AddRegisterUsers /> */}
</HStack>
</HStack>
<DataTable

View File

@@ -70,7 +70,7 @@ function ViewAgencyAddModel({ refetch }: { refetch: VoidFunction }) {
console.error("Error updating template:", error);
toaster.create({
title: "Error",
description: "Something went wrong",
description: "Please try again later",
type: "error",
});

View File

@@ -50,7 +50,10 @@ function EditTemplateModel({ id, localData, refetch }: { id: number, localData:
return;
}
setImages((prevImages) => [...prevImages, file]);
// setImages((prevImages) => [...prevImages, file]);
if (file) {
setImages([file])
}
}
};
@@ -126,11 +129,11 @@ function EditTemplateModel({ id, localData, refetch }: { id: number, localData:
}
setIsOpen(false);
refetch()
} catch (error) {
} catch (error: any) {
console.error("Error updating template:", error);
toaster.create({
title: "Error",
description: "Failed to update template. Please try again.",
description: `${error.response?.data?.message || "Please try again later."}`,
type: "error",
});
}

View File

@@ -50,7 +50,10 @@ function TemplateAddModel({ refetch }: { refetch: VoidFunction }) {
return;
}
setImages((prevImages) => [...prevImages, file]);
// setImages((prevImages) => [...prevImages, file]);
if(file){
setImages([file])
}
}
};
@@ -116,9 +119,14 @@ function TemplateAddModel({ refetch }: { refetch: VoidFunction }) {
setUserType("");
setImages([]);
setIsOpen(false)
} catch (error) {
} catch (error: any) {
console.error("Error creating template:", error);
// alert("Failed to create template");
toaster.create({
title: "Error",
description: `${error.response?.data?.message || "Please try again later."}`,
type: "error",
});
}
};

View File

@@ -16,7 +16,7 @@ import { PermissionResponse, useCreateSubAdminPostMutation } from "../../Redux/S
import { toaster, Toaster } from "../../components/ui/toaster";
import { useEffect, useState } from "react";
function AddModel({ refetch, allPermissions }: { refetch: VoidFunction, allPermissions: PermissionResponse }) {
function AddModel({ refetch, allPermissions }: { refetch: VoidFunction, allPermissions?: PermissionResponse }) {
const [createSubAdminPost] = useCreateSubAdminPostMutation();
// State fields
@@ -281,15 +281,20 @@ useEffect(() => {
</Field.Root>
<Grid templateColumns="repeat(2, 1fr)" gap={4}>
{allPermissions?.data.permission.map((permission: any) => (
<Checkbox size="sm"
color="black"
key={permission.id}
checked={permissions.includes(permission.id)}
onChange={() => handleCheckboxToggle(permission.id)}>
<Text fontSize={12}>{permission.app_resource_title}</Text>
</Checkbox>
))}
{Array.isArray(allPermissions?.data?.permission)
? allPermissions.data.permission.map((permission: any) => (
<Checkbox
size="sm"
color="black"
key={permission.id}
checked={permissions.includes(permission.id)}
onChange={() => handleCheckboxToggle(permission.id)}
>
<Text fontSize={12}>{permission.app_resource_title}</Text>
</Checkbox>
))
: <Text fontSize={12} color="gray.500">Loading permissions...</Text>
}
</Grid>
</Stack>
</DialogBody>

View File

@@ -19,17 +19,15 @@ import { Toaster, toaster } from "../../components/ui/toaster";
const resourceIdToLabel: { [key: number]: string } = {
1: 'Dashboard',
2: 'Manage contact us',
3: 'Manage User',
4: 'Manage CMS',
5: 'Manage Post',
6: 'Manage Reports',
7: 'Manage Sub-Admin',
8: 'My profile',
9: 'Manage Jobs',
10: 'Manage feedbacks',
11: 'Manage community',
12: 'Notification',
2: 'Manage User',
3: 'Manage Post',
4: 'Manage Subadmin',
5: 'Manage Jobs',
6: 'Manage Groups',
7: 'Manage Contact Us',
8: 'Manage CMS',
9: 'My Profile',
10: 'Master Module',
};
@@ -43,7 +41,7 @@ interface ResourceActionLink {
}
}
function EditSubAdmin({ id, refetch, allPermissions }: { id: number, refetch: VoidFunction, allPermissions: PermissionResponse }) {
function EditSubAdmin({ id, refetch, allPermissions }: { id: number, refetch: VoidFunction, allPermissions?: PermissionResponse }) {
const [trigger, { data }] = useLazyViewSubAdminQuery();
const [updateSubAdmin] = useUpdateSubAdminMutation()
const [isOpen, setIsOpen] = useState(false);
@@ -269,44 +267,6 @@ function EditSubAdmin({ id, refetch, allPermissions }: { id: number, refetch: Vo
Permissions
</Heading>
</Field.Root>
{/* <Grid templateColumns="repeat(2, 1fr)" gap={4}>
<Checkbox size={"sm"} color={"black"}>
<Text fontSize={12}>Dashboard</Text>
</Checkbox>
<Checkbox size={"sm"} color={"black"}>
<Text fontSize={12}>Manage contact us</Text>
</Checkbox>
<Checkbox size={"sm"} color={"black"}>
<Text fontSize={12}>manage User</Text>
</Checkbox>
<Checkbox size={"sm"} color={"black"}>
<Text fontSize={12}>Manage CMS</Text>
</Checkbox>
<Checkbox size={"sm"} color={"black"}>
<Text fontSize={12}>Manage Post</Text>
</Checkbox>
<Checkbox size={"sm"} color={"black"}>
<Text fontSize={12}>Manage Reports</Text>
</Checkbox>
<Checkbox size={"sm"} color={"black"}>
<Text fontSize={12}>manage Sub-Admin</Text>
</Checkbox>
<Checkbox size={"sm"} color={"black"}>
<Text fontSize={12}>My profile</Text>
</Checkbox>
<Checkbox size={"sm"} color={"black"}>
<Text fontSize={12}>Manage Jobs</Text>{" "}
</Checkbox>
<Checkbox size={"sm"} color={"black"}>
<Text fontSize={12}> manage feedbacks</Text>
</Checkbox>
<Checkbox size={"sm"} color={"black"}>
<Text fontSize={12}>Manage community</Text>{" "}
</Checkbox>
<Checkbox size={"sm"} color={"black"}>
<Text fontSize={12}> Notification</Text>
</Checkbox>
</Grid> */}
<Grid templateColumns="repeat(2, 1fr)" gap={4}>
{editData.permission.map((permission) => {
const label = resourceIdToLabel[permission.app_resource_xid];

View File

@@ -11,7 +11,7 @@ import ViewSubAdmin from "./ViewSubAdmin"
import Delete from "../../components/ActionIcons/Delete"
import { PermissionResponse, useDeleteSubAdminPostMutation, useGetPermissionQuery, useGetSubAdminQuery } from "../../Redux/Service/manage.subadmin.service"
import { useEffect, useState } from "react"
import { toaster } from "../../components/ui/toaster"
import { Toaster, toaster } from "../../components/ui/toaster"
import { useDebounce } from "../../components/Hooks/useDebounce"
import SearchComponent from "../../components/SearchComponent"
@@ -140,7 +140,7 @@ const SubAdmin = () => {
<HStack justifyContent="center">
{/* <EditDetails rowData={{ id: agency.id, question: agency.question, answer: agency.answer }} refetch={refetch} /> */}
<ViewSubAdmin id={agency.id} />
{allPermissions && <EditSubAdmin id={agency.id} refetch={refetch} allPermissions={allPermissions} />}
<EditSubAdmin id={agency.id} refetch={refetch} allPermissions={permissions} />
<AlertDailog
isOpen={deleteModal}
@@ -180,7 +180,7 @@ const SubAdmin = () => {
onChange={handleSearchChange}
/>
{/* <Button bgColor={'#EEEEEE'} pl={3} pr={3}><IoMdAdd /> <Text>Add</Text></Button> */}
{allPermissions && <AddModel refetch={refetch} allPermissions={allPermissions} />}
<AddModel refetch={refetch} allPermissions={permissions} />
</HStack>
</HStack>
<DataTable
@@ -198,6 +198,7 @@ const SubAdmin = () => {
isError={isError}
/>
</Box>
<Toaster />
</MainFrame>
)
}

View File

@@ -10,11 +10,11 @@ export interface UserData {
gender: string;
date_of_birth: string;
is_active: boolean;
principal_type:{
principal_type: {
id: number;
principal_type_title: string;
},
principle_language_linkss:{
principle_language_linkss: {
id: number;
language_xid: number;
iam_principal_xid: number;
@@ -103,13 +103,13 @@ export const registerUser = createApi({
}),
}),
// deleteFaqPost: builder.mutation<{ status: string; message: string }, { id: number }>({
// query: ({ id }) => ({
// url: `/faq-delete`,
// method: "POST",
// body: { id },
// }),
// }),
deleteUser: builder.mutation({
query: ({ id }) => ({
url: `/manage-user-delete`,
method: "POST",
body: { id },
}),
}),
}),
});
@@ -121,5 +121,5 @@ export const {
useUserToggleMutation,
useGetDeactivateUserQuery,
useUserDeactivateToggleMutation,
// useDeleteFaqPostMutation
useDeleteUserMutation
} = registerUser;

View File

@@ -122,6 +122,14 @@ const DataTable: React.FC<TableProps> = ({
</Box>
) : (
<Table.Body h="100%">
{data.length === 0 && (
<Box textAlign={"center"} py={20} position="absolute" w="84%">
<Image src={EmptyFile} alt="No data" maxW="65px" mx="auto" />
<Text fontSize={"18px"} fontWeight={500} mt={2}>
No records found theyll appear here if available.
</Text>
</Box>
)}
{data.map((item: any, index) => (
<Table.Row
key={index}