Compare commits
44 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e2c17a3d4a | ||
|
|
0ecc030f20 | ||
|
|
5b37c9da1e | ||
|
|
9bfbf5ddb8 | ||
|
|
2e8f8d5a77 | ||
|
|
248980d24b | ||
|
|
8966295260 | ||
|
|
df62dcda64 | ||
|
|
44f34490a0 | ||
|
|
8efb309fa9 | ||
|
|
171a92a3dc | ||
|
|
ec021ee33c | ||
|
|
3aa9ebf619 | ||
|
|
8f19a41c57 | ||
|
|
638a68ff03 | ||
|
|
e5361a5d77 | ||
|
|
71c23a2125 | ||
|
|
abaae9603e | ||
|
|
7a3e76aa35 | ||
|
|
eaf8e77b79 | ||
|
|
2488ab98c0 | ||
|
|
6648cd3bf3 | ||
| d1cc504397 | |||
|
|
1e7b7347e4 | ||
|
|
32ccea4917 | ||
|
|
1fafdfe54d | ||
|
|
20a92a60ab | ||
|
|
284b5f3099 | ||
|
|
901dfb93a6 | ||
|
|
2805528ba3 | ||
|
|
a8a0e2ffef | ||
|
|
897572c1f1 | ||
|
|
03ab1dcd6f | ||
|
|
9d8278900d | ||
|
|
f65b5f9b2d | ||
|
|
ffda4cf04b | ||
|
|
f2d101ef16 | ||
|
|
b91c97c6c2 | ||
|
|
2a0517d8dc | ||
|
|
0c6238c843 | ||
|
|
49e8e5531f | ||
|
|
15c9cc1d94 | ||
|
|
cb7bdcdeb3 | ||
|
|
8106d505a0 |
14
.env
14
.env
@@ -4,12 +4,20 @@
|
|||||||
# VITE_PASSWORD="71%@L%es^bUX94`J9XT*@bh,._WWM{$%^^&&"
|
# VITE_PASSWORD="71%@L%es^bUX94`J9XT*@bh,._WWM{$%^^&&"
|
||||||
# VITE_APP_NAME=MyViteApp
|
# VITE_APP_NAME=MyViteApp
|
||||||
# VITE_IMG_TEMPLATES='https://ssa.betadelivery.com/storage/app/public/uploads/post_templates/'
|
# VITE_IMG_TEMPLATES='https://ssa.betadelivery.com/storage/app/public/uploads/post_templates/'
|
||||||
VITE_API_URL='https://ssa.betadelivery.com/testing/apia/v1'
|
# VITE_API_URL='https://ssa.betadelivery.com/testing/apia/v1'
|
||||||
# VITE_API_URL='https://ssa.betadelivery.com/apia/v1'
|
# VITE_API_URL='https://ssa.betadelivery.com/apia/v1'
|
||||||
|
# VITE_USER_NAME="Admin"
|
||||||
|
# VITE_PASSWORD="71%@L%es^bUX94`J9XT*@bh,._WWM{$%^^&&"
|
||||||
|
# # VITE_PASSWORD="71%@L%es^bUX94`J9XT*%4&^%tUU^%Q^ffgt"
|
||||||
|
# VITE_APP_NAME=MyViteApp
|
||||||
|
# VITE_IMG_TEMPLATES='https://ssa.betadelivery.com/testing/storage/app/public/uploads/post_templates/'
|
||||||
|
# VITE_MAIN_URL='https://ssa.betadelivery.com/testing'
|
||||||
|
# VITE_POST_IMG=`${VITE_MAIN_URL}/storage/app/public/uploads/post/`
|
||||||
|
VITE_API_URL='https://ssa.betadelivery.com/testing/apia/v1'
|
||||||
VITE_USER_NAME="Admin"
|
VITE_USER_NAME="Admin"
|
||||||
VITE_PASSWORD="71%@L%es^bUX94`J9XT*@bh,._WWM{$%^^&&"
|
VITE_PASSWORD="71%@L%es^bUX94`J9XT*@bh,._WWM{$%^^&&"
|
||||||
# VITE_PASSWORD="71%@L%es^bUX94`J9XT*%4&^%tUU^%Q^ffgt"
|
|
||||||
VITE_APP_NAME=MyViteApp
|
VITE_APP_NAME=MyViteApp
|
||||||
VITE_IMG_TEMPLATES='https://ssa.betadelivery.com/testing/storage/app/public/uploads/post_templates/'
|
|
||||||
VITE_MAIN_URL='https://ssa.betadelivery.com/testing'
|
VITE_MAIN_URL='https://ssa.betadelivery.com/testing'
|
||||||
|
VITE_IMG_TEMPLATES=`${VITE_MAIN_URL}/storage/app/public/uploads/post_templates/`
|
||||||
|
VITE_IMG_PROFILE=`${VITE_MAIN_URL}/storage/app/public/uploads/profile/`
|
||||||
VITE_POST_IMG=`${VITE_MAIN_URL}/storage/app/public/uploads/post/`
|
VITE_POST_IMG=`${VITE_MAIN_URL}/storage/app/public/uploads/post/`
|
||||||
12
.env.testing
12
.env.testing
@@ -1,5 +1,7 @@
|
|||||||
# VITE_API_URL='https://ssa.betadelivery.com/testing/apia/'
|
VITE_API_URL='https://ssa.betadelivery.com/testing/apia/v1'
|
||||||
# VITE_USER_NAME="Admin"
|
VITE_USER_NAME="Admin"
|
||||||
# VITE_PASSWORD="71%@L%es^bUX94`J9XT*@bh,._WWM{$%^^&&"
|
VITE_PASSWORD="71%@L%es^bUX94`J9XT*@bh,._WWM{$%^^&&"
|
||||||
# VITE_APP_NAME=MyViteApp
|
VITE_APP_NAME=MyViteApp
|
||||||
# VITE_IMG_TEMPLATES='https://ssa.betadelivery.com/storage/app/public/uploads/post_templates/'
|
VITE_IMG_TEMPLATES='https://ssa.betadelivery.com/storage/app/public/uploads/post_templates/'
|
||||||
|
VITE_MAIN_URL='https://ssa.betadelivery.com/testing'
|
||||||
|
VITE_POST_IMG=`${VITE_MAIN_URL}/storage/app/public/uploads/post/`
|
||||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -22,4 +22,4 @@ dist-ssr
|
|||||||
*.njsproj
|
*.njsproj
|
||||||
*.sln
|
*.sln
|
||||||
*.sw?
|
*.sw?
|
||||||
.env
|
*.env
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ define(['./workbox-54d0af47'], (function (workbox) { 'use strict';
|
|||||||
"revision": "3ca0b8505b4bec776b69afdba2768812"
|
"revision": "3ca0b8505b4bec776b69afdba2768812"
|
||||||
}, {
|
}, {
|
||||||
"url": "index.html",
|
"url": "index.html",
|
||||||
"revision": "0.p75md0vraj"
|
"revision": "0.73grfmd27h8"
|
||||||
}], {});
|
}], {});
|
||||||
workbox.cleanupOutdatedCaches();
|
workbox.cleanupOutdatedCaches();
|
||||||
workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("index.html"), {
|
workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("index.html"), {
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ export interface GlobalStateContextType {
|
|||||||
setIsAuthenticate: Dispatch<SetStateAction<boolean>>;
|
setIsAuthenticate: Dispatch<SetStateAction<boolean>>;
|
||||||
isBarLoading: boolean;
|
isBarLoading: boolean;
|
||||||
setIsBarLoading: Dispatch<SetStateAction<boolean>>;
|
setIsBarLoading: Dispatch<SetStateAction<boolean>>;
|
||||||
|
userAccess: string[];
|
||||||
|
setUserAccess: Dispatch<SetStateAction<string[]>>;
|
||||||
}
|
}
|
||||||
// Create the context with a default value of `undefined`
|
// Create the context with a default value of `undefined`
|
||||||
const GlobalStateContext = createContext<GlobalStateContextType | undefined>(undefined);
|
const GlobalStateContext = createContext<GlobalStateContextType | undefined>(undefined);
|
||||||
|
|||||||
@@ -6,6 +6,10 @@ import GlobalStateContext from "./GlobalStateContext";
|
|||||||
const GlobalStateProvider = ({ children }: { children: ReactNode }) => {
|
const GlobalStateProvider = ({ children }: { children: ReactNode }) => {
|
||||||
const [isAuthenticate, setIsAuthenticate] = useState<boolean>(true);
|
const [isAuthenticate, setIsAuthenticate] = useState<boolean>(true);
|
||||||
const [isBarLoading, setIsBarLoading] = useState<boolean>(false); // ✅ Fixed typo
|
const [isBarLoading, setIsBarLoading] = useState<boolean>(false); // ✅ Fixed typo
|
||||||
|
const [userAccess, setUserAccess] = useState<string[]>(() => {
|
||||||
|
const stored = sessionStorage.getItem('userAccess');
|
||||||
|
return stored ? JSON.parse(stored) : [];
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -15,6 +19,8 @@ const GlobalStateProvider = ({ children }: { children: ReactNode }) => {
|
|||||||
setIsAuthenticate,
|
setIsAuthenticate,
|
||||||
isBarLoading,
|
isBarLoading,
|
||||||
setIsBarLoading, // ✅ Fixed typo
|
setIsBarLoading, // ✅ Fixed typo
|
||||||
|
userAccess,
|
||||||
|
setUserAccess
|
||||||
}}>
|
}}>
|
||||||
{children}
|
{children}
|
||||||
</GlobalStateContext.Provider>
|
</GlobalStateContext.Provider>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { HStack, Image, Text, VStack } from "@chakra-ui/react";
|
import { HStack, Image, Text, VStack } from "@chakra-ui/react";
|
||||||
import React, { FC, useContext } from "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 { NavLink, useLocation, useNavigate } from "react-router-dom";
|
||||||
import { nav } from "../Routes/Nav";
|
import { nav } from "../Routes/Nav";
|
||||||
import logo from '../assets/logo.svg';
|
import logo from '../assets/logo.svg';
|
||||||
@@ -14,6 +14,8 @@ import { useLogOutMutation } from "../Redux/Service/apiSlice";
|
|||||||
import ProgressBar from "../components/ProgressBar/ProgressBar";
|
import ProgressBar from "../components/ProgressBar/ProgressBar";
|
||||||
import { useGetProfileQuery } from "../Redux/Service/profile.password";
|
import { useGetProfileQuery } from "../Redux/Service/profile.password";
|
||||||
|
|
||||||
|
const PROFILEIMGURL = import.meta.env.VITE_IMG_PROFILE
|
||||||
|
|
||||||
const DefaultLayout: FC<{ children: React.ReactNode }> = ({ children }) => {
|
const DefaultLayout: FC<{ children: React.ReactNode }> = ({ children }) => {
|
||||||
const { data } = useGetProfileQuery()
|
const { data } = useGetProfileQuery()
|
||||||
const dispatch = useDispatch()
|
const dispatch = useDispatch()
|
||||||
@@ -25,9 +27,13 @@ const DefaultLayout: FC<{ children: React.ReactNode }> = ({ children }) => {
|
|||||||
if (!context) {
|
if (!context) {
|
||||||
throw new Error('App must be used within a GlobalStateProvider');
|
throw new Error('App must be used within a GlobalStateProvider');
|
||||||
}
|
}
|
||||||
const { setIsAuthenticate, isBarLoading } = context;
|
const { setIsAuthenticate, isBarLoading, userAccess } = context;
|
||||||
const [logOutAdmin] = useLogOutMutation()
|
const [logOutAdmin] = useLogOutMutation()
|
||||||
|
|
||||||
|
const filteredNav = nav.filter(item =>
|
||||||
|
userAccess.includes('*') || !item.resourceTitle || userAccess.includes(item.resourceTitle)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
// Logout function
|
// Logout function
|
||||||
const handleLogout = async () => {
|
const handleLogout = async () => {
|
||||||
@@ -57,7 +63,7 @@ const DefaultLayout: FC<{ children: React.ReactNode }> = ({ children }) => {
|
|||||||
<Image w={55} src={logo} />
|
<Image w={55} src={logo} />
|
||||||
</HStack>
|
</HStack>
|
||||||
<VStack w={'100%'} p={2} pt={0}>
|
<VStack w={'100%'} p={2} pt={0}>
|
||||||
{nav?.map(({ title, path, Icon, type, children, initPath }, index) => type === 'single' ?
|
{filteredNav?.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> :
|
<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>
|
<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}>
|
<AccordionItem rounded={'lg'} bg={'#fff'} boxShadow={'rgba(99, 99, 99, 0.2) 0px 2px 8px 0px'} borderBottom={'none'} p={0} key={index} value={title}>
|
||||||
@@ -74,12 +80,12 @@ const DefaultLayout: FC<{ children: React.ReactNode }> = ({ children }) => {
|
|||||||
|
|
||||||
<HStack h={'11%'} w={'100%'} justifyContent={'flex-end'} pe={3} gap={6}>
|
<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')} >
|
<HStack cursor={'pointer'} onClick={() => navigate('/profile')} >
|
||||||
<Avatar size={'sm'} src="https://i.pinimg.com/736x/d6/cd/0f/d6cd0ffd4634b0763d3958a7325ce26e.jpg" />
|
<Avatar size={'sm'} src={`${PROFILEIMGURL}${data?.data.profile_photo}`} />
|
||||||
<VStack color={'#013e3e'} gap={0} alignItems={'flex-start'}>
|
<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={'sm'} fontWeight={'bold'}>{data?.data?.first_name ? `${data?.data?.first_name.charAt(0).toUpperCase()}${data?.data.first_name.slice(1)}` : ''}</Text>
|
||||||
<Text fontSize={'xs'} >{data?.data?.phone_number}</Text>
|
<Text fontSize={'xs'} >{data?.data?.phone_number ? data?.data?.phone_number : ''}</Text>
|
||||||
</VStack>
|
</VStack>
|
||||||
</HStack>
|
</HStack>
|
||||||
</HStack>
|
</HStack>
|
||||||
|
|||||||
@@ -1,61 +1,68 @@
|
|||||||
import { Box, HStack, Image, Input, Stack, Text } from "@chakra-ui/react";
|
import {
|
||||||
import React, { useState, useEffect } from "react";
|
Box,
|
||||||
|
HStack,
|
||||||
|
// Image, Input, Stack,
|
||||||
|
Text
|
||||||
|
} from "@chakra-ui/react";
|
||||||
|
// import React, { useState, useEffect } from "react";
|
||||||
import { Button } from "../../components/ui/button";
|
import { Button } from "../../components/ui/button";
|
||||||
import { IoAddSharp } from "react-icons/io5";
|
// import { IoAddSharp } from "react-icons/io5";
|
||||||
import delateIcon from "../../assets/deleteIcon.png";
|
// import delateIcon from "../../assets/deleteIcon.png";
|
||||||
import { FaClockRotateLeft } from "react-icons/fa6";
|
// import { FaClockRotateLeft } from "react-icons/fa6";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
import { AgencyList } from "../../Redux/Service/dashBoard";
|
||||||
|
|
||||||
interface Todo {
|
// interface Todo {
|
||||||
id: number;
|
// id: number;
|
||||||
text: string;
|
// text: string;
|
||||||
completed: boolean;
|
// completed: boolean;
|
||||||
timestamp: string;
|
// timestamp: string;
|
||||||
}
|
// }
|
||||||
|
|
||||||
const AgencyName: React.FC = () => {
|
const AgencyName = ({ agencyList }: { agencyList: AgencyList }) => {
|
||||||
const [todos, setTodos] = useState<Todo[]>([]);
|
// const [todos, setTodos] = useState<Todo[]>([]);
|
||||||
const [input, setInput] = useState<string>("");
|
// const [input, setInput] = useState<string>("");
|
||||||
|
|
||||||
|
|
||||||
const getCurrentTime = () => {
|
|
||||||
const now = new Date();
|
|
||||||
return now.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
const addTodo = () => {
|
// const getCurrentTime = () => {
|
||||||
if (input.trim() === "") return;
|
// const now = new Date();
|
||||||
setTodos([...todos, { id: Date.now(), text: input, completed: false, timestamp: getCurrentTime() }]);
|
// return now.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
|
||||||
setInput("");
|
// };
|
||||||
};
|
|
||||||
|
|
||||||
|
// const addTodo = () => {
|
||||||
|
// if (input.trim() === "") return;
|
||||||
|
// setTodos([...todos, { id: Date.now(), text: input, completed: false, timestamp: getCurrentTime() }]);
|
||||||
|
// setInput("");
|
||||||
|
// };
|
||||||
|
|
||||||
// Delete a task
|
// Delete a task
|
||||||
const deleteTodo = (id: number) => {
|
// const deleteTodo = (id: number) => {
|
||||||
setTodos(todos.filter((todo) => todo.id !== id));
|
// setTodos(todos.filter((todo) => todo.id !== id));
|
||||||
};
|
// };
|
||||||
|
|
||||||
useEffect(() => {
|
// useEffect(() => {
|
||||||
const savedTodos = localStorage.getItem("todos");
|
// const savedTodos = localStorage.getItem("todos");
|
||||||
if (savedTodos) {
|
// if (savedTodos) {
|
||||||
setTodos(JSON.parse(savedTodos));
|
// setTodos(JSON.parse(savedTodos));
|
||||||
}
|
// }
|
||||||
}, []); // Runs only on mount
|
// }, []); // Runs only on mount
|
||||||
|
|
||||||
// 🔹 Save todos to localStorage whenever they change
|
// // 🔹 Save todos to localStorage whenever they change
|
||||||
useEffect(() => {
|
// useEffect(() => {
|
||||||
if (todos.length > 0) {
|
// if (todos.length > 0) {
|
||||||
localStorage.setItem("todos", JSON.stringify(todos));
|
// localStorage.setItem("todos", JSON.stringify(todos));
|
||||||
}
|
// }
|
||||||
}, [todos]); // Runs when `todos` changes
|
// }, [todos]); // Runs when `todos` changes
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box p={"10px"}>
|
<Box p={"10px"}>
|
||||||
<HStack justifyContent={"space-between"} mb={5}>
|
<HStack justifyContent={"space-between"} mb={5}>
|
||||||
<Text fontSize={"xs"} fontWeight={500}>
|
<Text fontSize={"xs"} fontWeight={500}>
|
||||||
Add Agency Name
|
Agency List
|
||||||
</Text>
|
</Text>
|
||||||
<Button
|
{/* <Button
|
||||||
bg={"#fff"}
|
bg={"#fff"}
|
||||||
color={"#222222CC"}
|
color={"#222222CC"}
|
||||||
px={3}
|
px={3}
|
||||||
@@ -64,9 +71,18 @@ const AgencyName: React.FC = () => {
|
|||||||
onClick={addTodo}
|
onClick={addTodo}
|
||||||
>
|
>
|
||||||
<IoAddSharp /> Add
|
<IoAddSharp /> Add
|
||||||
|
</Button> */}
|
||||||
|
<Button
|
||||||
|
bg={"#fff"}
|
||||||
|
color={"#222222CC"}
|
||||||
|
px={3}
|
||||||
|
fontSize={"12px"}
|
||||||
|
h={"28px"}
|
||||||
|
>
|
||||||
|
<Link to="/master-module/agency-master">View ALL</Link>
|
||||||
</Button>
|
</Button>
|
||||||
</HStack>
|
</HStack>
|
||||||
<Input
|
{/* <Input
|
||||||
type="text"
|
type="text"
|
||||||
value={input}
|
value={input}
|
||||||
onChange={(e) => setInput(e.target.value)}
|
onChange={(e) => setInput(e.target.value)}
|
||||||
@@ -76,14 +92,14 @@ const AgencyName: React.FC = () => {
|
|||||||
w={"100%"}
|
w={"100%"}
|
||||||
p={2}
|
p={2}
|
||||||
mb={4}
|
mb={4}
|
||||||
/>
|
/> */}
|
||||||
{todos.map((todo) => (
|
{agencyList?.data.map((todo) => (
|
||||||
<HStack key={todo.id} backgroundColor={"#fff"} rounded={5} mb={3} p={4} justifyContent={'space-between'} alignItems={'inherit'}>
|
<HStack key={todo.id} backgroundColor={"#fff"} rounded={5} mb={3} p={4} justifyContent={'space-between'} alignItems={'inherit'}>
|
||||||
<Text fontSize={'sm'} color={'#222222bd'} fontWeight={400}>{todo.text}</Text>
|
<Text fontSize={'sm'} color={'#222222bd'} fontWeight={400}>{todo.name}</Text>
|
||||||
<Stack display={'flex'} alignItems={'end'} w={'130px'}>
|
{/* <Stack display={'flex'} alignItems={'end'} w={'130px'}>
|
||||||
<Box display={'flex'} alignItems={'center'} gap={2}>
|
<Box display={'flex'} alignItems={'center'} gap={2}>
|
||||||
<FaClockRotateLeft fontSize={'10px'} style={{fontSize:'13px',color:'#222222bd'}} />
|
<FaClockRotateLeft fontSize={'10px'} style={{ fontSize: '13px', color: '#222222bd' }} />
|
||||||
<Text fontSize={"xs"} color={"#222222bd"}>{todo.timestamp}</Text>
|
<Text fontSize={"xs"} color={"#222222bd"}>{todo.timestamp}</Text>
|
||||||
</Box>
|
</Box>
|
||||||
<Box
|
<Box
|
||||||
onClick={() => deleteTodo(todo.id)}
|
onClick={() => deleteTodo(todo.id)}
|
||||||
@@ -93,7 +109,7 @@ const AgencyName: React.FC = () => {
|
|||||||
>
|
>
|
||||||
<Image w={"16px"} src={delateIcon} />
|
<Image w={"16px"} src={delateIcon} />
|
||||||
</Box>
|
</Box>
|
||||||
</Stack>
|
</Stack> */}
|
||||||
</HStack>
|
</HStack>
|
||||||
))}
|
))}
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@@ -26,8 +26,31 @@ import {
|
|||||||
SelectValueText
|
SelectValueText
|
||||||
} from "../../components/ui/select";
|
} from "../../components/ui/select";
|
||||||
import AgencyName from "./AgencyName";
|
import AgencyName from "./AgencyName";
|
||||||
|
import { useGetAgencyListQuery, useGetFaqListQuery, useGetNewUserQuery, useGetPastUserQuery, useGetTotalUserQuery } from "../../Redux/Service/dashBoard";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
|
||||||
const Dashboard = () => {
|
const Dashboard = () => {
|
||||||
|
const { data: totalUsers } = useGetTotalUserQuery()
|
||||||
|
const { data: pastUsers } = useGetPastUserQuery()
|
||||||
|
const { data: newUsers } = useGetNewUserQuery()
|
||||||
|
const {data: agencyList} = useGetAgencyListQuery()
|
||||||
|
const { data: faqList } = useGetFaqListQuery()
|
||||||
|
const [activeTab, setActiveTab] = useState("tab-1");
|
||||||
|
const [totalUser, setTotalUser] = useState<any>(null);
|
||||||
|
|
||||||
|
console.log("data", totalUser)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (activeTab === "tab-1") {
|
||||||
|
setTotalUser( pastUsers?.data)
|
||||||
|
} else if (activeTab === "tab-2") {
|
||||||
|
setTotalUser(totalUsers?.data)
|
||||||
|
} else if (activeTab === "tab-3") {
|
||||||
|
setTotalUser(newUsers?.data)
|
||||||
|
}
|
||||||
|
}, [totalUsers?.data, pastUsers?.data, newUsers?.data, activeTab]);
|
||||||
|
|
||||||
const frameworks = createListCollection({
|
const frameworks = createListCollection({
|
||||||
items: [
|
items: [
|
||||||
{ label: "Today", value: "Today" },
|
{ label: "Today", value: "Today" },
|
||||||
@@ -37,35 +60,35 @@ const Dashboard = () => {
|
|||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
const accItems = [
|
// const accItems = [
|
||||||
{
|
// {
|
||||||
value: "1",
|
// value: "1",
|
||||||
title: "How to create new account?",
|
// title: "How to create new account?",
|
||||||
text: "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since. Lorem Ipsum has been the industry's standard dummy text ever since.",
|
// text: "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since. Lorem Ipsum has been the industry's standard dummy text ever since.",
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
value: "2",
|
// value: "2",
|
||||||
title: "How to create new account?",
|
// title: "How to create new account?",
|
||||||
text: "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since. Lorem Ipsum has been the industry's standard dummy text ever since.",
|
// text: "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since. Lorem Ipsum has been the industry's standard dummy text ever since.",
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
value: "3",
|
// value: "3",
|
||||||
title: "How to create new account?",
|
// title: "How to create new account?",
|
||||||
text: "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since. Lorem Ipsum has been the industry's standard dummy text ever since.",
|
// text: "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since. Lorem Ipsum has been the industry's standard dummy text ever since.",
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
value: "4",
|
// value: "4",
|
||||||
title: "How to create new account?",
|
// title: "How to create new account?",
|
||||||
text: "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since. Lorem Ipsum has been the industry's standard dummy text ever since.",
|
// text: "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since. Lorem Ipsum has been the industry's standard dummy text ever since.",
|
||||||
},
|
// },
|
||||||
];
|
// ];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MainFrame>
|
<MainFrame>
|
||||||
<Box display={"flex"} p={"20px"} pe={'20px'} gap={5}>
|
<Box display={"flex"} p={"20px"} pe={'20px'} gap={5}>
|
||||||
<Box rounded={'lg'} w={"30%"} boxShadow={"rgba(99, 99, 99, 0.2) 0px 2px 8px 0px"}>
|
<Box rounded={'lg'} w={"30%"} boxShadow={"rgba(99, 99, 99, 0.2) 0px 2px 8px 0px"}>
|
||||||
<Heading fontSize={"sm"} p={2}>
|
<Heading fontSize={"sm"} p={2}>
|
||||||
Total Users
|
Total Users : {totalUsers?.data?.totalUserCount ?? 0}
|
||||||
</Heading>
|
</Heading>
|
||||||
<Tabs.Root
|
<Tabs.Root
|
||||||
size={"sm"}
|
size={"sm"}
|
||||||
@@ -74,6 +97,8 @@ const Dashboard = () => {
|
|||||||
variant="enclosed"
|
variant="enclosed"
|
||||||
fitted
|
fitted
|
||||||
defaultValue={"tab-1"}
|
defaultValue={"tab-1"}
|
||||||
|
value={activeTab}
|
||||||
|
onValueChange={(details) => setActiveTab(details.value)}
|
||||||
mb={6}
|
mb={6}
|
||||||
>
|
>
|
||||||
<Tabs.List>
|
<Tabs.List>
|
||||||
@@ -89,7 +114,7 @@ const Dashboard = () => {
|
|||||||
</Tabs.List>
|
</Tabs.List>
|
||||||
</Tabs.Root>
|
</Tabs.Root>
|
||||||
<Box>
|
<Box>
|
||||||
<SemiDoughnutChart />
|
{totalUser && <SemiDoughnutChart totalUser={totalUser} />}
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<Box
|
<Box
|
||||||
@@ -101,11 +126,11 @@ const Dashboard = () => {
|
|||||||
>
|
>
|
||||||
<Status.Root colorPalette="blue">
|
<Status.Root colorPalette="blue">
|
||||||
<Status.Indicator />
|
<Status.Indicator />
|
||||||
Recruiter <Text fontWeight={500}>2554</Text>
|
Recruiter <Text fontWeight={500}>{totalUser?.past24hourRecruiterCount ?? totalUser?.totalRecruiterCount ?? totalUser?.newRecuiterCount }</Text>
|
||||||
</Status.Root>
|
</Status.Root>
|
||||||
<Status.Root colorPalette="blue">
|
<Status.Root colorPalette="blue">
|
||||||
<Status.Indicator />
|
<Status.Indicator />
|
||||||
Customer <Text fontWeight={500}>1224</Text>
|
Customer <Text fontWeight={500}>{totalUser?.past24hourCustomercount ?? totalUser?.totalCustomerCount ?? totalUser?.newCustomerCount}</Text>
|
||||||
</Status.Root>
|
</Status.Root>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
@@ -142,8 +167,8 @@ const Dashboard = () => {
|
|||||||
<CircularApp />
|
<CircularApp />
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
<Box p={"20px"} pt={0} display={"flex"} gap={5}>
|
<Box p={"20px"} pt={0} display={"flex"} gap={5}>
|
||||||
<Box w={"50%"} rounded={'lg'} bg={"#f2f2f2"} h={'100%'} p={"10px"} overflow={'auto'}>
|
<Box w={"50%"} rounded={'lg'} bg={"#f2f2f2"} h={'100%'} p={"10px"} overflowY={'scroll'} height={'292px'}>
|
||||||
<HStack justifyContent={"space-between"} mb={5}>
|
<HStack justifyContent={"space-between"} mb={5}>
|
||||||
<Text fontSize={"xs"} fontWeight={500}>Faqs</Text>
|
<Text fontSize={"xs"} fontWeight={500}>Faqs</Text>
|
||||||
<Button
|
<Button
|
||||||
@@ -153,15 +178,15 @@ const Dashboard = () => {
|
|||||||
fontSize={"12px"}
|
fontSize={"12px"}
|
||||||
h={"28px"}
|
h={"28px"}
|
||||||
>
|
>
|
||||||
View ALL
|
<Link to="/manage-cms/faq">View ALL</Link>
|
||||||
</Button>
|
</Button>
|
||||||
</HStack>
|
</HStack>
|
||||||
<AccordionRoot collapsible defaultValue={["b"]}>
|
<AccordionRoot collapsible defaultValue={["b"]}>
|
||||||
{accItems.map((item, index) => (
|
{faqList?.data.map((item) => (
|
||||||
<AccordionItem
|
<AccordionItem
|
||||||
boxShadow={'rgba(99, 99, 99, 0.2) 0px 2px 8px 0px'}
|
boxShadow={'rgba(99, 99, 99, 0.2) 0px 2px 8px 0px'}
|
||||||
key={index}
|
key={item.id}
|
||||||
value={item.value}
|
value={item.faqs_xid.toString()}
|
||||||
bg={"#fff"}
|
bg={"#fff"}
|
||||||
mb={2}
|
mb={2}
|
||||||
p={"12px"}
|
p={"12px"}
|
||||||
@@ -169,17 +194,17 @@ const Dashboard = () => {
|
|||||||
borderBottom={0}
|
borderBottom={0}
|
||||||
>
|
>
|
||||||
<AccordionItemTrigger fontSize={"sm"} >
|
<AccordionItemTrigger fontSize={"sm"} >
|
||||||
{item.title}
|
{item.question}
|
||||||
</AccordionItemTrigger>
|
</AccordionItemTrigger>
|
||||||
<AccordionItemContent fontSize={"xs"} color={'#222222CC'} pt={2}>
|
<AccordionItemContent fontSize={"xs"} color={'#222222CC'} pt={2}>
|
||||||
{item.text}
|
{item.answer}
|
||||||
</AccordionItemContent>
|
</AccordionItemContent>
|
||||||
</AccordionItem>
|
</AccordionItem>
|
||||||
))}
|
))}
|
||||||
</AccordionRoot>
|
</AccordionRoot>
|
||||||
</Box>
|
</Box>
|
||||||
<Box w={"50%"} rounded={'lg'} bg={"#f2f2f2"} h={'100%'} overflow={'auto'}>
|
<Box w={"50%"} rounded={'lg'} bg={"#f2f2f2"} alignItems={'flex-start'} overflowY={'scroll'} height={'292px'}>
|
||||||
<AgencyName />
|
{agencyList && <AgencyName agencyList={agencyList}/>}
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
</MainFrame>
|
</MainFrame>
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ const Login = () => {
|
|||||||
if (!context) {
|
if (!context) {
|
||||||
throw new Error("App must be used within a GlobalStateProvider");
|
throw new Error("App must be used within a GlobalStateProvider");
|
||||||
}
|
}
|
||||||
const { setIsAuthenticate } = context;
|
const { setIsAuthenticate, setUserAccess } = context;
|
||||||
const {
|
const {
|
||||||
register,
|
register,
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
@@ -43,10 +43,10 @@ const Login = () => {
|
|||||||
|
|
||||||
const onSubmit = handleSubmit(async (data) => {
|
const onSubmit = handleSubmit(async (data) => {
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
// Encode Basic Auth Credentials
|
|
||||||
const username = import.meta.env.VITE_USER_NAME || ""; // Replace with actual username
|
const username = import.meta.env.VITE_USER_NAME || "";
|
||||||
const password = import.meta.env.VITE_PASSWORD || ""; // Replace with actual password
|
const password = import.meta.env.VITE_PASSWORD || "";
|
||||||
const basicAuth = `${username}:${password}`; // Encode to Base64
|
const basicAuth = `${username}:${password}`;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await axios.post(
|
const res = await axios.post(
|
||||||
@@ -62,35 +62,36 @@ const Login = () => {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
console.log("============", res);
|
|
||||||
|
|
||||||
|
const loginData = res.data?.data;
|
||||||
|
const { principal_type_xid, role_permission } = loginData;
|
||||||
|
|
||||||
|
const isAdmin = principal_type_xid === 1;
|
||||||
|
|
||||||
|
const allowedTitles = isAdmin
|
||||||
|
? ['*']
|
||||||
|
: role_permission?.get_resource_action_link
|
||||||
|
?.filter((link: unknown) => (link as any).is_active)
|
||||||
|
.map((link: unknown) => (link as any).app_resource.app_resource_title) ?? [];
|
||||||
|
|
||||||
|
setIsAuthenticate(true);
|
||||||
|
setUserAccess(allowedTitles);
|
||||||
|
dispatch(setToken(String(loginData["access-token"])));
|
||||||
|
sessionStorage.setItem('userAccess', JSON.stringify(allowedTitles));
|
||||||
|
navigate("/dashboard");
|
||||||
|
setIsLoading(false);
|
||||||
|
|
||||||
if (res.data) {
|
|
||||||
setIsAuthenticate(true);
|
|
||||||
console.log("====================================");
|
|
||||||
console.log(res.data?.data);
|
|
||||||
console.log("====================================");
|
|
||||||
navigate("/dashboard");
|
|
||||||
dispatch(setToken(String(res.data?.data["access-token"])));
|
|
||||||
} else {
|
|
||||||
console.log("====================================");
|
|
||||||
console.log(res);
|
|
||||||
console.log("====================================");
|
|
||||||
}
|
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.log('error', error.response.data.message);
|
console.log('error', error?.response?.data?.message);
|
||||||
|
toaster.create({
|
||||||
if (error) {
|
title: "Error",
|
||||||
toaster.create({
|
description: error?.response?.data?.message || "Login failed",
|
||||||
title: error?.response?.data?.message,
|
type: "error",
|
||||||
// title: "Something Went Wrong",
|
});
|
||||||
type: "info",
|
setIsLoading(false);
|
||||||
})
|
|
||||||
// console.log("Login failed", error?.response?.data?.message);
|
|
||||||
setIsLoading(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
// console.log("User Access in Context:", userAccess);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
||||||
|
|||||||
@@ -16,12 +16,13 @@ import "react-quill/dist/quill.snow.css"; // Import the styles
|
|||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { useUpdateAboutUsMutation } from "../../../Redux/Service/manage.aboutus.service";
|
import { useUpdateAboutUsMutation } from "../../../Redux/Service/manage.aboutus.service";
|
||||||
import { useForm, Controller } from "react-hook-form"; // Import React Hook Form
|
import { useForm, Controller } from "react-hook-form"; // Import React Hook Form
|
||||||
|
import { toaster, Toaster } from "../../../components/ui/toaster";
|
||||||
|
|
||||||
function AboutUsAddModel({ aboutUsData }: { aboutUsData: any }) {
|
function AboutUsAddModel({ aboutUsData }: { aboutUsData: any }) {
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
|
|
||||||
// RTK Query Mutation Hook
|
// RTK Query Mutation Hook
|
||||||
const [updateAboutUs] = useUpdateAboutUsMutation();
|
const [updateAboutUs, { isLoading }] = useUpdateAboutUsMutation();
|
||||||
|
|
||||||
// React Hook Form
|
// React Hook Form
|
||||||
const {
|
const {
|
||||||
@@ -55,87 +56,96 @@ function AboutUsAddModel({ aboutUsData }: { aboutUsData: any }) {
|
|||||||
}).unwrap();
|
}).unwrap();
|
||||||
setIsOpen(false); // Close dialog on success
|
setIsOpen(false); // Close dialog on success
|
||||||
reset(); // Reset the form
|
reset(); // Reset the form
|
||||||
} catch (error) {
|
} catch (error: any) {
|
||||||
console.error("Update failed:", error);
|
console.error("Update failed:", error);
|
||||||
|
toaster.create({
|
||||||
|
title: "Error",
|
||||||
|
description: `${error.data.message || "Failed to update"}`,
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DialogRoot placement="center" open={isOpen}>
|
<>
|
||||||
<DialogTrigger asChild>
|
<DialogRoot placement="center" open={isOpen}>
|
||||||
<Button
|
<DialogTrigger asChild>
|
||||||
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">
|
|
||||||
<Button
|
<Button
|
||||||
w="100%"
|
bgColor="#EEEEEE"
|
||||||
bg="#02A0A0"
|
pl={3}
|
||||||
color="#fff"
|
pr={3}
|
||||||
// isLoading={isLoading}
|
size="xs"
|
||||||
onClick={handleSubmit(onSubmit)} // Use handleSubmit to trigger form submission
|
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>
|
</Button>
|
||||||
</DialogFooter>
|
</DialogTrigger>
|
||||||
|
|
||||||
<DialogCloseTrigger color="black" onClick={() => setIsOpen(false)} />
|
<DialogContent bg="#fff" w={{ base: "90%", md: "1200px" }} height="auto" p={3}>
|
||||||
</DialogContent>
|
<DialogHeader bg="white">
|
||||||
</DialogRoot>
|
<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}
|
||||||
|
disabled={isLoading}
|
||||||
|
onClick={handleSubmit(onSubmit)} // Use handleSubmit to trigger form submission
|
||||||
|
>
|
||||||
|
Save
|
||||||
|
</Button>
|
||||||
|
</DialogFooter>
|
||||||
|
|
||||||
|
<DialogCloseTrigger color="black" onClick={() => setIsOpen(false)} />
|
||||||
|
</DialogContent>
|
||||||
|
</DialogRoot>
|
||||||
|
<Toaster />
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ function EditDetails({ rowData, refetch }: {rowData: RowData, refetch: VoidFunct
|
|||||||
const [faqQuestion, setFaqQuestion] = useState(rowData?.question);
|
const [faqQuestion, setFaqQuestion] = useState(rowData?.question);
|
||||||
const [faqAnswer, setFaqAnswer] = useState(rowData?.answer);
|
const [faqAnswer, setFaqAnswer] = useState(rowData?.answer);
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
const [updateFaq] = useUpdateFaqMutation()
|
const [updateFaq, { isLoading }] = useUpdateFaqMutation()
|
||||||
|
|
||||||
// console.log('ROWDATA', rowData);
|
// console.log('ROWDATA', rowData);
|
||||||
|
|
||||||
@@ -146,7 +146,7 @@ function EditDetails({ rowData, refetch }: {rowData: RowData, refetch: VoidFunct
|
|||||||
</DialogBody>
|
</DialogBody>
|
||||||
|
|
||||||
<DialogFooter display="flex" justifyContent="center" pt={"2"}>
|
<DialogFooter display="flex" justifyContent="center" pt={"2"}>
|
||||||
<Button w="100%" bg="#02A0A0" color={"#fff"} onClick={handleSubmit}>
|
<Button w="100%" bg="#02A0A0" color={"#fff"} onClick={handleSubmit} disabled={isLoading}>
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
</DialogFooter>
|
</DialogFooter>
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ const tableHeadRow = [
|
|||||||
|
|
||||||
const FAQ = () => {
|
const FAQ = () => {
|
||||||
const [currentPage, setCurrentPage] = useState(1);
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
const { data, refetch, isLoading, isFetching } = useGetFaqQuery(currentPage)
|
const { data, refetch, isLoading, isFetching, isError } = useGetFaqQuery(currentPage)
|
||||||
const [localData, setLocalData] = useState<any[]>([]);
|
const [localData, setLocalData] = useState<any[]>([]);
|
||||||
const [faqToggle] = useFaqToggleMutation()
|
const [faqToggle] = useFaqToggleMutation()
|
||||||
const [deleteFaqPost] = useDeleteFaqPostMutation()
|
const [deleteFaqPost] = useDeleteFaqPostMutation()
|
||||||
@@ -85,9 +85,21 @@ const FAQ = () => {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
await faqToggle({ id: agencyId, is_active: newStatus }).unwrap();
|
await faqToggle({ id: agencyId, is_active: newStatus }).unwrap();
|
||||||
refetch()
|
toaster.create({
|
||||||
|
title: "Success",
|
||||||
|
description: "Status updated successfully",
|
||||||
|
type: "success",
|
||||||
|
});
|
||||||
|
setTimeout(() => {
|
||||||
|
refetch();
|
||||||
|
}, 500);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error updating privacy policy:", error);
|
console.error("Error updating privacy policy:", error);
|
||||||
|
toaster.create({
|
||||||
|
title: "Error",
|
||||||
|
description: "Someting went wrong.",
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
setLocalData((prevData) =>
|
setLocalData((prevData) =>
|
||||||
prevData.map((agency) =>
|
prevData.map((agency) =>
|
||||||
agency.id === agencyId ? { ...agency, is_active: currentStatus } : agency
|
agency.id === agencyId ? { ...agency, is_active: currentStatus } : agency
|
||||||
@@ -160,7 +172,7 @@ const FAQ = () => {
|
|||||||
handleDeleteFaq(selectedFaqId);
|
handleDeleteFaq(selectedFaqId);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Box>
|
<Box>
|
||||||
<Switch
|
<Switch
|
||||||
colorPalette={'teal'}
|
colorPalette={'teal'}
|
||||||
@@ -225,6 +237,8 @@ const FAQ = () => {
|
|||||||
total: data?.data.total || 0
|
total: data?.data.total || 0
|
||||||
}}
|
}}
|
||||||
onPageChange={handlePageChange}
|
onPageChange={handlePageChange}
|
||||||
|
isLoading={isFetching}
|
||||||
|
isError={isError}
|
||||||
/>)}
|
/>)}
|
||||||
</Box>
|
</Box>
|
||||||
<Toaster />
|
<Toaster />
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ function FaqAddModel({ refetch }: { refetch: VoidFunction }) {
|
|||||||
const [faqAnswer, setFaqAnswer] = useState('');
|
const [faqAnswer, setFaqAnswer] = useState('');
|
||||||
const [userType, setUserType] = useState("");
|
const [userType, setUserType] = useState("");
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
const [createFaqPost] = useCreateFaqPostMutation()
|
const [createFaqPost, { isLoading }] = useCreateFaqPostMutation()
|
||||||
|
|
||||||
const handleOpenModal = () => {
|
const handleOpenModal = () => {
|
||||||
setIsOpen(true); // Open modal when clicking "Add"
|
setIsOpen(true); // Open modal when clicking "Add"
|
||||||
@@ -159,7 +159,7 @@ function FaqAddModel({ refetch }: { refetch: VoidFunction }) {
|
|||||||
</Stack>
|
</Stack>
|
||||||
</DialogBody>
|
</DialogBody>
|
||||||
<DialogFooter display="flex" justifyContent="center" pt={"2"}>
|
<DialogFooter display="flex" justifyContent="center" pt={"2"}>
|
||||||
<Button w="100%" bg="#02A0A0" color={"#fff"} onClick={handleSubmit}>
|
<Button w="100%" bg="#02A0A0" color={"#fff"} onClick={handleSubmit} disabled={isLoading}>
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
</DialogFooter>
|
</DialogFooter>
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import ReactQuill from "react-quill";
|
|||||||
|
|
||||||
function PrivacyPolicyAddModel({ policyData, refetch }: { policyData: any, refetch: VoidFunction }) {
|
function PrivacyPolicyAddModel({ policyData, refetch }: { policyData: any, refetch: VoidFunction }) {
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
const [updatePrivacyPolicy] = useUpdatePrivacyPolicyMutation()
|
const [updatePrivacyPolicy, { isLoading }] = useUpdatePrivacyPolicyMutation()
|
||||||
const {
|
const {
|
||||||
control,
|
control,
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
@@ -139,7 +139,7 @@ function PrivacyPolicyAddModel({ policyData, refetch }: { policyData: any, refet
|
|||||||
</Stack>
|
</Stack>
|
||||||
</DialogBody>
|
</DialogBody>
|
||||||
<DialogFooter display="flex" justifyContent="center" pt={"2"}>
|
<DialogFooter display="flex" justifyContent="center" pt={"2"}>
|
||||||
<Button w="100%" bg="#02A0A0" color={"#fff"} mt={'4'} onClick={handleSubmit(onSubmit)}>
|
<Button w="100%" bg="#02A0A0" color={"#fff"} mt={'4'} onClick={handleSubmit(onSubmit)} disabled={isLoading}>
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
</DialogFooter>
|
</DialogFooter>
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import { useUpdateTermsMutation } from "../../../Redux/Service/terms.and.conditi
|
|||||||
|
|
||||||
function TermsAndConditionsAddModel({ termsData, refetch }: { termsData: any, refetch: VoidFunction }) {
|
function TermsAndConditionsAddModel({ termsData, refetch }: { termsData: any, refetch: VoidFunction }) {
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
const [updateTerms] = useUpdateTermsMutation()
|
const [updateTerms, { isLoading }] = useUpdateTermsMutation()
|
||||||
const {
|
const {
|
||||||
control,
|
control,
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
@@ -136,7 +136,7 @@ function TermsAndConditionsAddModel({ termsData, refetch }: { termsData: any, re
|
|||||||
</Stack>
|
</Stack>
|
||||||
</DialogBody>
|
</DialogBody>
|
||||||
<DialogFooter display="flex" justifyContent="center" pt={"2"}>
|
<DialogFooter display="flex" justifyContent="center" pt={"2"}>
|
||||||
<Button w="100%" bg="#02A0A0" color={"#fff"} mt={'4'} onClick={handleSubmit(onSubmit)}>
|
<Button w="100%" bg="#02A0A0" color={"#fff"} mt={'4'} onClick={handleSubmit(onSubmit)} disabled={isLoading}>
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
</DialogFooter>
|
</DialogFooter>
|
||||||
|
|||||||
@@ -1,19 +1,26 @@
|
|||||||
import { Box, HStack, Input, Text } from "@chakra-ui/react";
|
import { Box, HStack, Text } from "@chakra-ui/react";
|
||||||
import MainFrame from "../../components/MainFrame";
|
import MainFrame from "../../components/MainFrame";
|
||||||
import PendingRequests from "../../Pages/ManageContact/PendingRequests";
|
import PendingRequests from "../../Pages/ManageContact/PendingRequests";
|
||||||
import { InputGroup } from "../../components/ui/input-group";
|
// import { InputGroup } from "../../components/ui/input-group";
|
||||||
import { LuSearch } from "react-icons/lu";
|
// import { LuSearch } from "react-icons/lu";
|
||||||
import DataTable from "../../components/DataTable";
|
import DataTable from "../../components/DataTable";
|
||||||
import { useGetContactQuery } from "../../Redux/Service/manage.contactus.service";
|
import { useGetContactQuery } from "../../Redux/Service/manage.contactus.service";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { Spinner } from "../../components/Sipnner/Spinner";
|
import { Spinner } from "../../components/Sipnner/Spinner";
|
||||||
|
import { useDebounce } from "../../components/Hooks/useDebounce";
|
||||||
|
import SearchComponent from "../../components/SearchComponent";
|
||||||
|
|
||||||
// table data
|
// table data
|
||||||
const tableHeadRow = ["Sr. No", "Email id", "Name", "Date", "Action"];
|
const tableHeadRow = ["Sr. No", "Email id", "Name", "Date", "Action"];
|
||||||
|
|
||||||
const ManageContact = () => {
|
const ManageContact = () => {
|
||||||
const { data, isLoading, isError } = useGetContactQuery();
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
const [localData, setLocalData] = useState([]);
|
const [localData, setLocalData] = useState<any[]>([]);
|
||||||
|
const [searchTerm, setSearchTerm] = useState("");
|
||||||
|
const debouncedSearchTerm = useDebounce(searchTerm, 500);
|
||||||
|
const queryArgs = debouncedSearchTerm ? { page: currentPage, search: debouncedSearchTerm } : { page: currentPage };
|
||||||
|
const { data, isLoading, isError, refetch, isFetching } = useGetContactQuery(queryArgs);
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (data) {
|
if (data) {
|
||||||
@@ -21,6 +28,20 @@ const ManageContact = () => {
|
|||||||
}
|
}
|
||||||
}, [data]);
|
}, [data]);
|
||||||
|
|
||||||
|
const handlePageChange = (page: number) => {
|
||||||
|
setCurrentPage(page);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSearchChange = (value: string) => {
|
||||||
|
setSearchTerm(value);
|
||||||
|
setCurrentPage(1);
|
||||||
|
};
|
||||||
|
|
||||||
|
const filteredData = localData?.filter((agency) =>
|
||||||
|
agency?.first_name.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
||||||
|
agency?.email.toLowerCase().includes(searchTerm.toLowerCase())
|
||||||
|
);
|
||||||
|
|
||||||
const formatDateOfBirth = (dob: string): string => {
|
const formatDateOfBirth = (dob: string): string => {
|
||||||
return new Date(dob).toLocaleDateString("en-GB", {
|
return new Date(dob).toLocaleDateString("en-GB", {
|
||||||
day: "2-digit",
|
day: "2-digit",
|
||||||
@@ -29,14 +50,15 @@ const ManageContact = () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const managepost = localData?.map((agency: any, index: number) => ({
|
const managepost = filteredData?.map((agency: any, index: number) => ({
|
||||||
"Sr. No": index + 1, // Typically Sr. No starts from 1, not using id which might not be sequential
|
"Sr. No": index + 1, // Typically Sr. No starts from 1, not using id which might not be sequential
|
||||||
"Email id": agency?.email || "-",
|
"Email id": agency?.email || "-",
|
||||||
Name: agency?.first_name || "-",
|
Name: agency?.first_name || "-",
|
||||||
Date: formatDateOfBirth(agency?.created_at) || "-",
|
Date: formatDateOfBirth(agency?.created_at) || "-",
|
||||||
Action: (
|
Action: (
|
||||||
<HStack justifyContent="center">
|
<HStack justifyContent="center" cursor={agency.response_status === 0 ? 'pointer' : 'default'}>
|
||||||
<PendingRequests />
|
{agency.response_status === 0 ? <PendingRequests data={agency} refetch={refetch} /> : 'Resolved'}
|
||||||
|
{/* <PendingRequests data={agency} refetch={refetch} /> */}
|
||||||
</HStack>
|
</HStack>
|
||||||
),
|
),
|
||||||
}));
|
}));
|
||||||
@@ -86,35 +108,25 @@ const ManageContact = () => {
|
|||||||
</Text>
|
</Text>
|
||||||
|
|
||||||
<HStack>
|
<HStack>
|
||||||
<InputGroup
|
<SearchComponent
|
||||||
startElement={
|
value={searchTerm}
|
||||||
<LuSearch
|
onChange={handleSearchChange}
|
||||||
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>
|
|
||||||
</HStack>
|
</HStack>
|
||||||
</HStack>
|
</HStack>
|
||||||
<DataTable
|
<DataTable
|
||||||
sortableColumns={["Name", "Registration Date "]}
|
sortableColumns={["Name", "Registration Date "]}
|
||||||
tableHeadRow={tableHeadRow}
|
tableHeadRow={tableHeadRow}
|
||||||
data={managepost || []} // Ensure an empty array is passed if managepost is undefined
|
data={managepost || []} // Ensure an empty array is passed if managepost is undefined
|
||||||
|
paginationData={{
|
||||||
|
current_page: (data?.data as any)?.current_page || 1,
|
||||||
|
last_page: (data?.data as any)?.last_page || 1,
|
||||||
|
per_page: (data?.data as any)?.per_page || 10,
|
||||||
|
total: (data?.data as any)?.total || 0
|
||||||
|
}}
|
||||||
|
onPageChange={handlePageChange}
|
||||||
|
isLoading={isFetching}
|
||||||
|
isError={isError}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
</MainFrame>
|
</MainFrame>
|
||||||
|
|||||||
@@ -10,95 +10,160 @@ import {
|
|||||||
DialogTrigger,
|
DialogTrigger,
|
||||||
} from "../../components/ui/dialog";
|
} from "../../components/ui/dialog";
|
||||||
import { Badge, Field, HStack, Input, Stack, Textarea } from "@chakra-ui/react";
|
import { Badge, Field, HStack, Input, Stack, Textarea } from "@chakra-ui/react";
|
||||||
function PendingRequests() {
|
import { usePendingRequestMutation } from "../../Redux/Service/manage.contactus.service";
|
||||||
|
import { useState } from "react";
|
||||||
|
import { Toaster, toaster } from "../../components/ui/toaster";
|
||||||
|
|
||||||
|
function PendingRequests({ data, refetch }: { data: any, refetch: VoidFunction }) {
|
||||||
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
|
const [res, setRes] = useState({
|
||||||
|
contact_us_xid: data.id,
|
||||||
|
message: data.message,
|
||||||
|
solution: '',
|
||||||
|
})
|
||||||
|
const [pendingRequest, { isLoading }] = usePendingRequestMutation()
|
||||||
|
|
||||||
|
const handleOpenModal = () => {
|
||||||
|
setIsOpen(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const handleSubmit = async (status: string) => {
|
||||||
|
const payload = { ...res, response_status: status };
|
||||||
|
|
||||||
|
if(res.solution === ''){
|
||||||
|
toaster.create({
|
||||||
|
title: "Error",
|
||||||
|
description: "All fields are required",
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const response = await pendingRequest(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: any) {
|
||||||
|
toaster.create({
|
||||||
|
title: "Error",
|
||||||
|
description: error?.data?.message || "Something went wrong",
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DialogRoot placement="center">
|
<>
|
||||||
<DialogTrigger asChild>
|
<DialogRoot placement="center" key={data.id} open={isOpen} onOpenChange={({ open }) => setIsOpen(open)}>
|
||||||
<Badge fontSize={"xs"} px={2} bg={'#02a0a01f'}>
|
<DialogTrigger asChild>
|
||||||
Answer request
|
<Badge fontSize={"xs"} px={2} bg={'#02a0a01f'} onClick={handleOpenModal}>
|
||||||
</Badge>
|
Answer request
|
||||||
</DialogTrigger>
|
</Badge>
|
||||||
|
</DialogTrigger>
|
||||||
|
|
||||||
<DialogContent
|
<DialogContent
|
||||||
bg={"#fff"}
|
bg={"#fff"}
|
||||||
w={{ base: "90%", md: "400px" }}
|
w={{ base: "90%", md: "400px" }}
|
||||||
height={"auto"}
|
height={"auto"}
|
||||||
p={3} // Reduced padding
|
p={3} // Reduced padding
|
||||||
bgSize={"md"}
|
bgSize={"md"}
|
||||||
>
|
|
||||||
<DialogHeader bg="white">
|
|
||||||
<DialogTitle alignSelf="center" color="black" fontSize="14px">
|
|
||||||
Pending Requests
|
|
||||||
</DialogTitle>
|
|
||||||
</DialogHeader>
|
|
||||||
|
|
||||||
<DialogBody bg="white">
|
|
||||||
<Stack py={3}>
|
|
||||||
<Field.Root>
|
|
||||||
<Field.Label color="black" pt={1} fontSize="12px">
|
|
||||||
Request Type
|
|
||||||
</Field.Label>
|
|
||||||
<Input
|
|
||||||
placeholder="Message"
|
|
||||||
bgColor="#EEEEEE"
|
|
||||||
color="black"
|
|
||||||
border="none"
|
|
||||||
pl={1}
|
|
||||||
fontSize="12px"
|
|
||||||
height="30px"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Field.Label color="black" pt={1} fontSize="12px">
|
|
||||||
Solution
|
|
||||||
</Field.Label>
|
|
||||||
<Textarea
|
|
||||||
placeholder=""
|
|
||||||
bgColor="#EEEEEE"
|
|
||||||
color="black"
|
|
||||||
border="none"
|
|
||||||
pl={1}
|
|
||||||
fontSize="12px"
|
|
||||||
height="80px"
|
|
||||||
pt={1.5}
|
|
||||||
/>
|
|
||||||
</Field.Root>
|
|
||||||
</Stack>
|
|
||||||
</DialogBody>
|
|
||||||
<DialogFooter
|
|
||||||
display={{ base: "block", md: "flex" }}
|
|
||||||
justifyContent="center"
|
|
||||||
gap={1}
|
|
||||||
pt={2}
|
|
||||||
>
|
>
|
||||||
<HStack mt={2} mb={3} width={"100%"} justifyContent={"space-between"}>
|
<DialogHeader bg="white">
|
||||||
<Button
|
<DialogTitle alignSelf="center" color="black" fontSize="14px">
|
||||||
width={"48%"}
|
Pending Requests
|
||||||
color="black"
|
</DialogTitle>
|
||||||
_hover={{ bgColor: "white" }}
|
</DialogHeader>
|
||||||
variant="outline"
|
|
||||||
borderRadius="sm"
|
|
||||||
border="1px solid #02A0A0"
|
|
||||||
size={"xs"}
|
|
||||||
>
|
|
||||||
Unresolved
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
width={"48%"}
|
|
||||||
borderRadius="sm"
|
|
||||||
// bgColor="#007F33"
|
|
||||||
bgColor={"#02A0A0"}
|
|
||||||
color="white"
|
|
||||||
// colorPalette="#007F33"
|
|
||||||
size={"xs"}
|
|
||||||
>
|
|
||||||
Resolved
|
|
||||||
</Button>
|
|
||||||
</HStack>
|
|
||||||
</DialogFooter>
|
|
||||||
|
|
||||||
<DialogCloseTrigger color="black" />
|
<DialogBody bg="white">
|
||||||
</DialogContent>
|
<Stack py={3}>
|
||||||
</DialogRoot>
|
<Field.Root>
|
||||||
|
<Field.Label color="black" pt={1} fontSize="12px">
|
||||||
|
Request Type
|
||||||
|
</Field.Label>
|
||||||
|
<Input
|
||||||
|
placeholder="Message"
|
||||||
|
bgColor="#EEEEEE"
|
||||||
|
color="black"
|
||||||
|
border="none"
|
||||||
|
pl={1}
|
||||||
|
fontSize="12px"
|
||||||
|
height="30px"
|
||||||
|
value={res.message}
|
||||||
|
disabled
|
||||||
|
// onChange={(e) => setRes({ ...res, message: e.target.value })}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Field.Label color="black" pt={1} fontSize="12px">
|
||||||
|
Solution
|
||||||
|
</Field.Label>
|
||||||
|
<Textarea
|
||||||
|
placeholder=""
|
||||||
|
bgColor="#EEEEEE"
|
||||||
|
color="black"
|
||||||
|
border="none"
|
||||||
|
pl={1}
|
||||||
|
fontSize="12px"
|
||||||
|
height="80px"
|
||||||
|
pt={1.5}
|
||||||
|
onChange={(e) => setRes({ ...res, solution: e.target.value })}
|
||||||
|
/>
|
||||||
|
</Field.Root>
|
||||||
|
</Stack>
|
||||||
|
</DialogBody>
|
||||||
|
<DialogFooter
|
||||||
|
display={{ base: "block", md: "flex" }}
|
||||||
|
justifyContent="center"
|
||||||
|
gap={1}
|
||||||
|
pt={2}
|
||||||
|
>
|
||||||
|
<HStack mt={2} mb={3} width={"100%"} justifyContent={"space-between"}>
|
||||||
|
<Button
|
||||||
|
width={"48%"}
|
||||||
|
color="black"
|
||||||
|
_hover={{ bgColor: "white" }}
|
||||||
|
variant="outline"
|
||||||
|
borderRadius="sm"
|
||||||
|
border="1px solid #02A0A0"
|
||||||
|
size={"xs"}
|
||||||
|
onClick={() => handleSubmit('1')}
|
||||||
|
disabled={isLoading}
|
||||||
|
>
|
||||||
|
Unresolved
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
width={"48%"}
|
||||||
|
borderRadius="sm"
|
||||||
|
// bgColor="#007F33"
|
||||||
|
bgColor={"#02A0A0"}
|
||||||
|
color="white"
|
||||||
|
// colorPalette="#007F33"
|
||||||
|
size={"xs"}
|
||||||
|
onClick={() => handleSubmit('0')}
|
||||||
|
disabled={isLoading}
|
||||||
|
>
|
||||||
|
Resolved
|
||||||
|
</Button>
|
||||||
|
</HStack>
|
||||||
|
</DialogFooter>
|
||||||
|
|
||||||
|
<DialogCloseTrigger color="black" />
|
||||||
|
</DialogContent>
|
||||||
|
</DialogRoot>
|
||||||
|
<Toaster />
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,15 +3,14 @@ import {
|
|||||||
HStack,
|
HStack,
|
||||||
Image,
|
Image,
|
||||||
// Image,
|
// Image,
|
||||||
Input,
|
|
||||||
Text,
|
Text,
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import { LuSearch } from "react-icons/lu";
|
// import { LuSearch } from "react-icons/lu";
|
||||||
// import { RiDeleteBin5Line } from "react-icons/ri";
|
// import { RiDeleteBin5Line } from "react-icons/ri";
|
||||||
// import AlertDailog from "../../components/AlertDailog";
|
// import AlertDailog from "../../components/AlertDailog";
|
||||||
import DataTable from "../../components/DataTable";
|
import DataTable from "../../components/DataTable";
|
||||||
import MainFrame from "../../components/MainFrame";
|
import MainFrame from "../../components/MainFrame";
|
||||||
import { InputGroup } from "../../components/ui/input-group";
|
// import { InputGroup } from "../../components/ui/input-group";
|
||||||
import ManageJobsAdd from "./ManageJobsAdd";
|
import ManageJobsAdd from "./ManageJobsAdd";
|
||||||
import ViewManageJob from "./ViewManageJob";
|
import ViewManageJob from "./ViewManageJob";
|
||||||
import {
|
import {
|
||||||
@@ -21,8 +20,10 @@ import {
|
|||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { Spinner } from "../../components/Sipnner/Spinner";
|
import { Spinner } from "../../components/Sipnner/Spinner";
|
||||||
import Delete from "../../components/ActionIcons/Delete";
|
import Delete from "../../components/ActionIcons/Delete";
|
||||||
import { toaster } from "../../components/ui/toaster";
|
import { Toaster, toaster } from "../../components/ui/toaster";
|
||||||
import AlertDailog from "../../components/AlertDailog";
|
import AlertDailog from "../../components/AlertDailog";
|
||||||
|
import { useDebounce } from "../../components/Hooks/useDebounce";
|
||||||
|
import SearchComponent from "../../components/SearchComponent";
|
||||||
// import { useState } from "react";
|
// import { useState } from "react";
|
||||||
// import { useGetManageJobsQuery } from "../../Redux/Service/manage.jobs.service";
|
// import { useGetManageJobsQuery } from "../../Redux/Service/manage.jobs.service";
|
||||||
// import Delete from "../../components/ActionIcons/Delete";
|
// import Delete from "../../components/ActionIcons/Delete";
|
||||||
@@ -40,9 +41,12 @@ const tableHeadRow = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
const ManageJobs = () => {
|
const ManageJobs = () => {
|
||||||
const [currentPage] = useState(1);
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
const [localData, setLocalData] = useState([]);
|
const [localData, setLocalData] = useState([]);
|
||||||
const { data, refetch, isLoading } = useGetManageJobsQuery(currentPage);
|
const [searchTerm, setSearchTerm] = useState("");
|
||||||
|
const debouncedSearchTerm = useDebounce(searchTerm, 500);
|
||||||
|
const queryArgs = debouncedSearchTerm ? { page: currentPage, search: debouncedSearchTerm } : { page: currentPage };
|
||||||
|
const { data, refetch, isLoading, isError, isFetching } = useGetManageJobsQuery(queryArgs);
|
||||||
const [deleteJobsPost] = useDeleteJobsPostMutation();
|
const [deleteJobsPost] = useDeleteJobsPostMutation();
|
||||||
const [deleteModal, setDeleteModal] = useState(false);
|
const [deleteModal, setDeleteModal] = useState(false);
|
||||||
const [selectedJobsId, setSelectedJobsId] = useState<number | null>(null);
|
const [selectedJobsId, setSelectedJobsId] = useState<number | null>(null);
|
||||||
@@ -52,7 +56,16 @@ const ManageJobs = () => {
|
|||||||
setLocalData((data as any)?.data?.data || []);
|
setLocalData((data as any)?.data?.data || []);
|
||||||
}
|
}
|
||||||
}, [data]);
|
}, [data]);
|
||||||
console.log(data?.data.data);
|
// console.log(data?.data.data);
|
||||||
|
|
||||||
|
const handleSearchChange = (value: string) => {
|
||||||
|
setSearchTerm(value);
|
||||||
|
setCurrentPage(1);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handlePageChange = (page: number) => {
|
||||||
|
setCurrentPage(page);
|
||||||
|
};
|
||||||
|
|
||||||
const handleDeleteJobs = async (jobsId: number) => {
|
const handleDeleteJobs = async (jobsId: number) => {
|
||||||
try {
|
try {
|
||||||
@@ -84,8 +97,8 @@ const ManageJobs = () => {
|
|||||||
Salary: agency?.ctc_amount,
|
Salary: agency?.ctc_amount,
|
||||||
Action: (
|
Action: (
|
||||||
<HStack justifyContent="center">
|
<HStack justifyContent="center">
|
||||||
<ViewManageJob />
|
<ViewManageJob data={agency} />
|
||||||
<ManageJobsAdd />
|
<ManageJobsAdd data={agency} refetch={refetch}/>
|
||||||
<AlertDailog
|
<AlertDailog
|
||||||
isOpen={deleteModal}
|
isOpen={deleteModal}
|
||||||
AltertTiggerIcon={() => (
|
AltertTiggerIcon={() => (
|
||||||
@@ -142,29 +155,10 @@ const ManageJobs = () => {
|
|||||||
</Text>
|
</Text>
|
||||||
|
|
||||||
<HStack>
|
<HStack>
|
||||||
<InputGroup
|
<SearchComponent
|
||||||
startElement={
|
value={searchTerm}
|
||||||
<LuSearch
|
onChange={handleSearchChange}
|
||||||
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> */}
|
{/* <Button bgColor={'#EEEEEE'} pl={3} pr={3}><IoMdAdd /> <Text>Add</Text></Button> */}
|
||||||
</HStack>
|
</HStack>
|
||||||
</HStack>
|
</HStack>
|
||||||
@@ -172,8 +166,18 @@ const ManageJobs = () => {
|
|||||||
sortableColumns={["Name", "Registration Date "]}
|
sortableColumns={["Name", "Registration Date "]}
|
||||||
tableHeadRow={tableHeadRow}
|
tableHeadRow={tableHeadRow}
|
||||||
data={managepost}
|
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}
|
||||||
|
isLoading={isFetching}
|
||||||
|
isError={isError}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
<Toaster />
|
||||||
</MainFrame>
|
</MainFrame>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
import {
|
import {
|
||||||
Field,
|
Field,
|
||||||
Input,
|
Input,
|
||||||
SelectValueText,
|
|
||||||
Span,
|
Span,
|
||||||
Stack,
|
Stack,
|
||||||
createListCollection,
|
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import { Button } from "../../components/ui/button";
|
import { Button } from "../../components/ui/button";
|
||||||
import {
|
import {
|
||||||
@@ -19,24 +17,151 @@ import {
|
|||||||
} from "../../components/ui/dialog";
|
} from "../../components/ui/dialog";
|
||||||
|
|
||||||
// import { TbEdit } from "react-icons/tb";
|
// import { TbEdit } from "react-icons/tb";
|
||||||
import {
|
|
||||||
SelectContent,
|
|
||||||
SelectItem,
|
|
||||||
SelectLabel,
|
|
||||||
SelectRoot,
|
|
||||||
SelectTrigger,
|
|
||||||
} from "../../components/ui/select";
|
|
||||||
import Edit from "../../components/ActionIcons/Edit";
|
import Edit from "../../components/ActionIcons/Edit";
|
||||||
|
import { JobStatusData, useGetCountryQuery, useGetDepartmentQuery, useGetIndustryQuery, useGetManageJobTypeQuery, useGetWorkspaceModesQuery, useUpdateJobsMutation, WorkSpace } from "../../Redux/Service/manage.jobs.service";
|
||||||
|
import { useReducer, useRef } from "react";
|
||||||
|
import { Toaster, toaster } from "../../components/ui/toaster";
|
||||||
|
|
||||||
|
const reducerFunction = (state: any, action: any) => {
|
||||||
|
switch (action.type) {
|
||||||
|
case "SET_JOB_TITLE":
|
||||||
|
return { ...state, jobTitle: action.payload };
|
||||||
|
case "SET_WORKSPACE_MODE":
|
||||||
|
return { ...state, workspaceMode: action.payload };
|
||||||
|
case "SET_CATEGORY":
|
||||||
|
return { ...state, category: action.payload };
|
||||||
|
case "SET_SUB_CATEGORY":
|
||||||
|
return { ...state, subCategory: action.payload };
|
||||||
|
case "SET_SALARY":
|
||||||
|
return { ...state, salary: action.payload };
|
||||||
|
case "SET_EXPERIENCE":
|
||||||
|
return { ...state, experience: action.payload };
|
||||||
|
case "SET_JOB_LOCATION":
|
||||||
|
return { ...state, jobLocation: action.payload };
|
||||||
|
case "SET_COUNTRY_SELECTION":
|
||||||
|
return { ...state, countrySelection: action.payload };
|
||||||
|
case "SET_JOB_TYPE":
|
||||||
|
return { ...state, jobType: action.payload };
|
||||||
|
case "SET_SKILLS_REQUIRED":
|
||||||
|
return { ...state, skillsRequired: action.payload };
|
||||||
|
case "SET_JOB_DESCRIPTION":
|
||||||
|
return { ...state, jobDescription: action.payload };
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function ManageJobsAdd({ data, refetch }: { data: JobStatusData, refetch: () => void }) {
|
||||||
|
const { data: workspaceModes } = useGetWorkspaceModesQuery({});
|
||||||
|
const { data: industryData } = useGetIndustryQuery({});
|
||||||
|
const { data: departmentData } = useGetDepartmentQuery({});
|
||||||
|
const { data: countryData } = useGetCountryQuery({});
|
||||||
|
const { data: jobTypeData } = useGetManageJobTypeQuery({});
|
||||||
|
const [updateJobs, { isLoading}] = useUpdateJobsMutation();
|
||||||
|
// console.log('Modes:', jobTypeData?.data.data);
|
||||||
|
|
||||||
|
const initialState = {
|
||||||
|
jobTitle: data?.job_title || "",
|
||||||
|
workspaceMode: data?.workspace_mode_xid || "",
|
||||||
|
category: data?.industry_xid || "",
|
||||||
|
subCategory: data?.department_xid || "",
|
||||||
|
salary: data?.ctc_amount || "",
|
||||||
|
experience: data?.experience || "",
|
||||||
|
jobLocation: data?.job_location || "",
|
||||||
|
countrySelection: data?.country_xid || "",
|
||||||
|
jobType: data?.job_type_xid || "",
|
||||||
|
skillsDescription: data?.skill_description || "",
|
||||||
|
jobDescription: data?.job_description || "",
|
||||||
|
};
|
||||||
|
|
||||||
|
const [state, dispatch] = useReducer(reducerFunction, initialState);
|
||||||
|
const closeRef = useRef<HTMLButtonElement>(null);
|
||||||
|
|
||||||
|
const getDisplayName = (name: string, maxLength = 30) =>
|
||||||
|
name.length > maxLength ? name.slice(0, maxLength) + "..." : name;
|
||||||
|
|
||||||
|
const handleSubmit = async () => {
|
||||||
|
const {
|
||||||
|
jobTitle,
|
||||||
|
workspaceMode,
|
||||||
|
category,
|
||||||
|
subCategory,
|
||||||
|
salary,
|
||||||
|
experience,
|
||||||
|
jobLocation,
|
||||||
|
countrySelection,
|
||||||
|
jobType,
|
||||||
|
skillsDescription,
|
||||||
|
jobDescription,
|
||||||
|
} = state;
|
||||||
|
|
||||||
|
if (
|
||||||
|
!jobTitle ||
|
||||||
|
!workspaceMode ||
|
||||||
|
!category ||
|
||||||
|
!subCategory ||
|
||||||
|
!salary ||
|
||||||
|
!experience ||
|
||||||
|
!jobLocation ||
|
||||||
|
!countrySelection ||
|
||||||
|
!jobType ||
|
||||||
|
!skillsDescription ||
|
||||||
|
!jobDescription
|
||||||
|
) {
|
||||||
|
toaster.create({
|
||||||
|
title: "Missing Fields",
|
||||||
|
description: "Please fill in all required fields before submitting.",
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only en_name is editable, so we only need to send that in the payload.
|
||||||
|
const payload = {
|
||||||
|
id: data?.id,
|
||||||
|
job_title: state.jobTitle,
|
||||||
|
workspace_mode_xid: state.workspaceMode,
|
||||||
|
industry_xid: state.category,
|
||||||
|
department_xid: state.subCategory,
|
||||||
|
ctc_amount: state.salary,
|
||||||
|
experience: state.experience,
|
||||||
|
job_location: state.jobLocation,
|
||||||
|
country_xid: state.countrySelection,
|
||||||
|
job_type_xid: state.jobType,
|
||||||
|
skill_description: state.skillsDescription,
|
||||||
|
job_description: state.jobDescription,
|
||||||
|
};
|
||||||
|
|
||||||
|
// console.log('payload', payload)
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await updateJobs(payload).unwrap();
|
||||||
|
if (response?.status === "success") {
|
||||||
|
toaster.create({
|
||||||
|
title: "Success",
|
||||||
|
description: "Country updated successfully",
|
||||||
|
type: "success",
|
||||||
|
});
|
||||||
|
closeRef.current?.click();
|
||||||
|
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",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const frameworks = createListCollection({
|
|
||||||
items: [
|
|
||||||
{ label: "React.js", value: "react" },
|
|
||||||
{ label: "Vue.js", value: "vue" },
|
|
||||||
{ label: "Angular", value: "angular" },
|
|
||||||
{ label: "Svelte", value: "svelte" },
|
|
||||||
],
|
|
||||||
});
|
|
||||||
function ManageJobsAdd() {
|
|
||||||
return (
|
return (
|
||||||
<DialogRoot placement="center">
|
<DialogRoot placement="center">
|
||||||
<DialogTrigger asChild>
|
<DialogTrigger asChild>
|
||||||
@@ -73,50 +198,182 @@ function ManageJobsAdd() {
|
|||||||
pl={1}
|
pl={1}
|
||||||
fontSize="12px"
|
fontSize="12px"
|
||||||
height="30px"
|
height="30px"
|
||||||
|
value={state.jobTitle}
|
||||||
|
onChange={(e) =>
|
||||||
|
dispatch({
|
||||||
|
type: "SET_JOB_TITLE",
|
||||||
|
payload: e.target.value,
|
||||||
|
})
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</Field.Root>
|
</Field.Root>
|
||||||
<Field.Root>
|
<Field.Root>
|
||||||
<Field.Label color="black" pt={1} fontSize="12px">
|
<Field.Label color="black" pt={1} fontSize="12px">
|
||||||
Workspace mode
|
Workspace mode
|
||||||
</Field.Label>
|
</Field.Label>
|
||||||
<Input
|
<select
|
||||||
placeholder="Enter the Workspace Mode"
|
style={{
|
||||||
bgColor="#EEEEEE"
|
backgroundColor: "#EEEEEE",
|
||||||
color="black"
|
color: "black",
|
||||||
border="none"
|
border: "none",
|
||||||
pl={1}
|
height: "30px",
|
||||||
fontSize="12px"
|
fontSize: "12px",
|
||||||
height="30px"
|
padding: "4px",
|
||||||
/>
|
borderRadius: "4px",
|
||||||
|
width: "100%",
|
||||||
|
}}
|
||||||
|
value={state.workspace_mode_xid}
|
||||||
|
onChange={(e) =>
|
||||||
|
dispatch({
|
||||||
|
type: "SET_WORKSPACE_MODE",
|
||||||
|
payload: Number(e.target.value),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<option value="" disabled>
|
||||||
|
Select country
|
||||||
|
</option>
|
||||||
|
{workspaceModes && workspaceModes?.data.map((mode: WorkSpace) => (
|
||||||
|
<option key={mode.id} value={mode.id}>
|
||||||
|
{getDisplayName(mode.en_name)}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
</Field.Root>
|
</Field.Root>
|
||||||
<Field.Root>
|
<Field.Root>
|
||||||
<Field.Label pt={1} color="black" fontSize="12px">
|
<Field.Label pt={1} color="black" fontSize="12px">
|
||||||
Category
|
Category
|
||||||
</Field.Label>
|
</Field.Label>
|
||||||
<Input
|
<select
|
||||||
placeholder="Enter the Category"
|
style={{
|
||||||
bgColor="#EEEEEE"
|
backgroundColor: "#EEEEEE",
|
||||||
color="black"
|
color: "black",
|
||||||
border="none"
|
border: "none",
|
||||||
pl={1}
|
height: "30px",
|
||||||
fontSize="12px"
|
fontSize: "12px",
|
||||||
height="30px"
|
padding: "4px",
|
||||||
/>
|
borderRadius: "4px",
|
||||||
|
width: "100%",
|
||||||
|
}}
|
||||||
|
value={state.industry_xid}
|
||||||
|
onChange={(e) =>
|
||||||
|
dispatch({
|
||||||
|
type: "SET_INDUSTRY",
|
||||||
|
payload: Number(e.target.value),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<option value="" disabled>
|
||||||
|
Select department
|
||||||
|
</option>
|
||||||
|
{industryData && industryData?.data.map((mode: WorkSpace) => (
|
||||||
|
<option key={mode.id} value={mode.id}>
|
||||||
|
{getDisplayName(mode.en_name)}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
</Field.Root>
|
</Field.Root>
|
||||||
<Field.Root>
|
<Field.Root>
|
||||||
<Field.Label pt={1} color="black" fontSize="12px">
|
<Field.Label pt={1} color="black" fontSize="12px">
|
||||||
Sub-Category
|
Sub-Category
|
||||||
</Field.Label>
|
</Field.Label>
|
||||||
<Input
|
<select
|
||||||
placeholder="Enter the Sub-Category"
|
style={{
|
||||||
bgColor="#EEEEEE"
|
backgroundColor: "#EEEEEE",
|
||||||
color="black"
|
color: "black",
|
||||||
border="none"
|
border: "none",
|
||||||
pl={1}
|
height: "30px",
|
||||||
fontSize="12px"
|
fontSize: "12px",
|
||||||
height="30px"
|
padding: "4px",
|
||||||
/>
|
borderRadius: "4px",
|
||||||
|
width: "100%",
|
||||||
|
}}
|
||||||
|
value={state.department_xid}
|
||||||
|
onChange={(e) =>
|
||||||
|
dispatch({
|
||||||
|
type: "SET_DEPARTMENT",
|
||||||
|
payload: Number(e.target.value),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<option value="" disabled>
|
||||||
|
Select department
|
||||||
|
</option>
|
||||||
|
{departmentData && departmentData?.data.map((mode: WorkSpace) => (
|
||||||
|
<option key={mode.id} value={mode.id}>
|
||||||
|
{getDisplayName(mode.en_name)}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
</Field.Root>
|
</Field.Root>
|
||||||
|
|
||||||
|
<Field.Root>
|
||||||
|
<Field.Label pt={1} color="black" fontSize="12px">
|
||||||
|
Country
|
||||||
|
</Field.Label>
|
||||||
|
<select
|
||||||
|
style={{
|
||||||
|
backgroundColor: "#EEEEEE",
|
||||||
|
color: "black",
|
||||||
|
border: "none",
|
||||||
|
height: "30px",
|
||||||
|
fontSize: "12px",
|
||||||
|
padding: "4px",
|
||||||
|
borderRadius: "4px",
|
||||||
|
width: "100%",
|
||||||
|
}}
|
||||||
|
value={state.country_xid}
|
||||||
|
onChange={(e) =>
|
||||||
|
dispatch({
|
||||||
|
type: "SET_COUNTRY",
|
||||||
|
payload: Number(e.target.value),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<option value="" disabled>
|
||||||
|
Select country
|
||||||
|
</option>
|
||||||
|
{countryData && countryData?.data.map((mode: WorkSpace) => (
|
||||||
|
<option key={mode.id} value={mode.id}>
|
||||||
|
{getDisplayName(mode.en_name)}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</Field.Root>
|
||||||
|
<Field.Root>
|
||||||
|
<Field.Label pt={1} color="black" fontSize="12px">
|
||||||
|
Job type
|
||||||
|
</Field.Label>
|
||||||
|
<select
|
||||||
|
style={{
|
||||||
|
backgroundColor: "#EEEEEE",
|
||||||
|
color: "black",
|
||||||
|
border: "none",
|
||||||
|
height: "30px",
|
||||||
|
fontSize: "12px",
|
||||||
|
padding: "4px",
|
||||||
|
borderRadius: "4px",
|
||||||
|
width: "100%",
|
||||||
|
}}
|
||||||
|
value={state.job_type_xid}
|
||||||
|
onChange={(e) =>
|
||||||
|
dispatch({
|
||||||
|
type: "SET_JOB_TYPE",
|
||||||
|
payload: Number(e.target.value),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<option value="" disabled>
|
||||||
|
Select Job Type
|
||||||
|
</option>
|
||||||
|
{jobTypeData && jobTypeData?.data.data.map((mode: WorkSpace) => (
|
||||||
|
<option key={mode.id} value={mode.id}>
|
||||||
|
{getDisplayName(mode.en_name)}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</Field.Root>
|
||||||
|
|
||||||
<Field.Root>
|
<Field.Root>
|
||||||
<Field.Label pt={1} color="black" fontSize="12px">
|
<Field.Label pt={1} color="black" fontSize="12px">
|
||||||
Salary
|
Salary
|
||||||
@@ -129,6 +386,13 @@ function ManageJobsAdd() {
|
|||||||
pl={1}
|
pl={1}
|
||||||
fontSize="12px"
|
fontSize="12px"
|
||||||
height="30px"
|
height="30px"
|
||||||
|
value={state.salary}
|
||||||
|
onChange={(e) =>
|
||||||
|
dispatch({
|
||||||
|
type: "SET_SALARY",
|
||||||
|
payload: e.target.value,
|
||||||
|
})
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</Field.Root>
|
</Field.Root>
|
||||||
<Field.Root>
|
<Field.Root>
|
||||||
@@ -136,13 +400,20 @@ function ManageJobsAdd() {
|
|||||||
Experience
|
Experience
|
||||||
</Field.Label>
|
</Field.Label>
|
||||||
<Input
|
<Input
|
||||||
placeholder="Enter the Experience"
|
placeholder="Enter the Experience in years"
|
||||||
bgColor="#EEEEEE"
|
bgColor="#EEEEEE"
|
||||||
color="black"
|
color="black"
|
||||||
border="none"
|
border="none"
|
||||||
pl={1}
|
pl={1}
|
||||||
fontSize="12px"
|
fontSize="12px"
|
||||||
height="30px"
|
height="30px"
|
||||||
|
value={state.experience}
|
||||||
|
onChange={(e) =>
|
||||||
|
dispatch({
|
||||||
|
type: "SET_EXPERIENCE",
|
||||||
|
payload: e.target.value,
|
||||||
|
})
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</Field.Root>
|
</Field.Root>
|
||||||
<Field.Root>
|
<Field.Root>
|
||||||
@@ -157,71 +428,34 @@ function ManageJobsAdd() {
|
|||||||
pl={1}
|
pl={1}
|
||||||
fontSize="12px"
|
fontSize="12px"
|
||||||
height="30px"
|
height="30px"
|
||||||
/>
|
value={state.jobLocation}
|
||||||
</Field.Root>
|
onChange={(e) =>
|
||||||
{/* <Field.Label pt={1} color="black" fontSize="12px">Country Selection</Field.Label>
|
dispatch({
|
||||||
<Input placeholder="Enter the Country Selection" /> */}
|
type: "SET_JOB_LOCATION",
|
||||||
<SelectRoot collection={frameworks} size="sm" w={"100%"}>
|
payload: e.target.value,
|
||||||
<SelectLabel pt={1} color="black" fontSize="12px">
|
})
|
||||||
Country Selection
|
}
|
||||||
</SelectLabel>
|
|
||||||
<SelectTrigger
|
|
||||||
bgColor="#EEEEEE"
|
|
||||||
color="black"
|
|
||||||
border="none"
|
|
||||||
pl={1}
|
|
||||||
fontSize="12px"
|
|
||||||
height="30px"
|
|
||||||
borderRadius={"5px"}
|
|
||||||
>
|
|
||||||
<SelectValueText
|
|
||||||
placeholder="Enter the Country Selection"
|
|
||||||
pb={"6px"}
|
|
||||||
fontSize={"12px"}
|
|
||||||
/>
|
|
||||||
</SelectTrigger>
|
|
||||||
<SelectContent position={"relative"} zIndex={"9999"} bg={"#fff"}>
|
|
||||||
{frameworks.items.map((movie) => (
|
|
||||||
<SelectItem
|
|
||||||
item={movie}
|
|
||||||
key={movie.value}
|
|
||||||
color={"black"}
|
|
||||||
pl={2}
|
|
||||||
p={1}
|
|
||||||
_hover={{ bg: "#F0F0F0" }} // Light grey background on hover
|
|
||||||
fontSize="12px"
|
|
||||||
>
|
|
||||||
{movie.label}
|
|
||||||
</SelectItem>
|
|
||||||
))}
|
|
||||||
</SelectContent>
|
|
||||||
</SelectRoot>
|
|
||||||
<Field.Root>
|
|
||||||
<Field.Label pt={1} color="black" fontSize="12px">
|
|
||||||
Job type
|
|
||||||
</Field.Label>
|
|
||||||
<Input
|
|
||||||
placeholder="Enter the Job Type"
|
|
||||||
bgColor="#EEEEEE"
|
|
||||||
color="black"
|
|
||||||
border="none"
|
|
||||||
pl={1}
|
|
||||||
fontSize="12px"
|
|
||||||
height="30px"
|
|
||||||
/>
|
/>
|
||||||
</Field.Root>
|
</Field.Root>
|
||||||
<Field.Root>
|
<Field.Root>
|
||||||
<Field.Label pt={1} color="black" fontSize="12px">
|
<Field.Label pt={1} color="black" fontSize="12px">
|
||||||
Skills required
|
Skills description
|
||||||
</Field.Label>
|
</Field.Label>
|
||||||
<Input
|
<Input
|
||||||
placeholder="Enter the Skills Required"
|
placeholder="Enter the Skills description"
|
||||||
bgColor="#EEEEEE"
|
bgColor="#EEEEEE"
|
||||||
color="black"
|
color="black"
|
||||||
border="none"
|
border="none"
|
||||||
pl={1}
|
pl={1}
|
||||||
fontSize="12px"
|
fontSize="12px"
|
||||||
height="30px"
|
height="30px"
|
||||||
|
value={state.skillsDescription}
|
||||||
|
onChange={(e) =>
|
||||||
|
dispatch({
|
||||||
|
type: "SET_SKILLS_DESCRIPTION",
|
||||||
|
payload: e.target.value,
|
||||||
|
})
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</Field.Root>
|
</Field.Root>
|
||||||
<Field.Root>
|
<Field.Root>
|
||||||
@@ -236,6 +470,13 @@ function ManageJobsAdd() {
|
|||||||
pl={1}
|
pl={1}
|
||||||
fontSize="12px"
|
fontSize="12px"
|
||||||
height="30px"
|
height="30px"
|
||||||
|
value={state.jobDescription}
|
||||||
|
onChange={(e) =>
|
||||||
|
dispatch({
|
||||||
|
type: "SET_JOB_DESCRIPTION",
|
||||||
|
payload: e.target.value,
|
||||||
|
})
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</Field.Root>
|
</Field.Root>
|
||||||
</Stack>
|
</Stack>
|
||||||
@@ -247,13 +488,16 @@ function ManageJobsAdd() {
|
|||||||
color={"#fff"}
|
color={"#fff"}
|
||||||
fontSize="12px"
|
fontSize="12px"
|
||||||
height="30px"
|
height="30px"
|
||||||
|
onClick={handleSubmit}
|
||||||
|
disabled={isLoading}
|
||||||
>
|
>
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
</DialogFooter>
|
</DialogFooter>
|
||||||
|
|
||||||
<DialogCloseTrigger color="black" />
|
<DialogCloseTrigger color="black" ref={closeRef} />
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
|
<Toaster />
|
||||||
</DialogRoot>
|
</DialogRoot>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,13 @@
|
|||||||
import {
|
import {
|
||||||
Field,
|
Field,
|
||||||
Input,
|
Input,
|
||||||
SelectValueText,
|
|
||||||
Span,
|
|
||||||
Stack,
|
Stack,
|
||||||
createListCollection,
|
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import { Button } from "../../components/ui/button";
|
import { Button } from "../../components/ui/button";
|
||||||
import {
|
import {
|
||||||
DialogBody,
|
DialogBody,
|
||||||
DialogCloseTrigger,
|
DialogCloseTrigger,
|
||||||
DialogContent,
|
DialogContent,
|
||||||
DialogFooter,
|
|
||||||
DialogHeader,
|
DialogHeader,
|
||||||
DialogRoot,
|
DialogRoot,
|
||||||
DialogTitle,
|
DialogTitle,
|
||||||
@@ -19,276 +15,290 @@ import {
|
|||||||
} from "../../components/ui/dialog";
|
} from "../../components/ui/dialog";
|
||||||
|
|
||||||
// import { MdOutlineRemoveRedEye } from "react-icons/md";
|
// import { MdOutlineRemoveRedEye } from "react-icons/md";
|
||||||
import {
|
|
||||||
SelectContent,
|
|
||||||
SelectItem,
|
|
||||||
SelectLabel,
|
|
||||||
SelectRoot,
|
|
||||||
SelectTrigger,
|
|
||||||
} from "../../components/ui/select";
|
|
||||||
import View from "../../components/ActionIcons/View";
|
import View from "../../components/ActionIcons/View";
|
||||||
import { useLazyViewJobsQuery } from "../../Redux/Service/manage.jobs.service";
|
import { JobStatusData, useLazyViewJobsQuery } from "../../Redux/Service/manage.jobs.service";
|
||||||
|
|
||||||
const frameworks = createListCollection({
|
function ViewManageJob({ data }: { data: JobStatusData }) {
|
||||||
items: [
|
const [trigger] = useLazyViewJobsQuery();
|
||||||
{ label: "React.js", value: "react" },
|
|
||||||
{ label: "Vue.js", value: "vue" },
|
|
||||||
{ label: "Angular", value: "angular" },
|
|
||||||
{ label: "Svelte", value: "svelte" },
|
|
||||||
],
|
|
||||||
});
|
|
||||||
function ViewManageJob() {
|
|
||||||
const [trigger, { data }] = useLazyViewJobsQuery();
|
|
||||||
|
|
||||||
console.log(data);
|
console.log(data);
|
||||||
|
|
||||||
// const handleView = () => {
|
const handleView = () => {
|
||||||
// trigger(id);
|
trigger(data.id);
|
||||||
// };
|
};
|
||||||
|
|
||||||
const viewJobs = data;
|
// const viewJobs = data;
|
||||||
|
|
||||||
console.log();
|
console.log();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DialogRoot placement="center">
|
<DialogRoot placement="center">
|
||||||
<DialogTrigger asChild>
|
<DialogTrigger asChild>
|
||||||
<Span>
|
<Button
|
||||||
|
onClick={handleView}
|
||||||
|
bg={'transparent'}
|
||||||
|
color={"black"}
|
||||||
|
>
|
||||||
<View />
|
<View />
|
||||||
</Span>
|
</Button>
|
||||||
</DialogTrigger>
|
</DialogTrigger>
|
||||||
|
|
||||||
{/* {viewJobs?.map((data: any) => ( */}
|
{/* {viewJobs?.map((data: any) => ( */}
|
||||||
<DialogContent
|
<DialogContent
|
||||||
bg={"#fff"}
|
bg={"#fff"}
|
||||||
// w={{ lg: "60%", md: "230px" }}
|
// w={{ lg: "60%", md: "230px" }}
|
||||||
w={{ base: "90%", md: "400px" }}
|
w={{ base: "90%", md: "400px" }}
|
||||||
height={"80vh"}
|
height={"80vh"}
|
||||||
overflow={"scroll"}
|
overflow={"scroll"}
|
||||||
overflowX="hidden"
|
overflowX="hidden"
|
||||||
p={3} // Reduced padding
|
p={3} // Reduced padding
|
||||||
bgSize={"md"}
|
bgSize={"md"}
|
||||||
>
|
>
|
||||||
<DialogHeader bg="white">
|
<DialogHeader bg="white">
|
||||||
<DialogTitle alignSelf="center" color="black" fontSize="14px">
|
<DialogTitle alignSelf="center" color="black" fontSize="14px">
|
||||||
Add Details
|
Add Details
|
||||||
</DialogTitle>
|
</DialogTitle>
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
|
|
||||||
<DialogBody bg="white">
|
<DialogBody bg="white">
|
||||||
<Stack py={3}>
|
<Stack py={3}>
|
||||||
<Field.Root>
|
<Field.Root>
|
||||||
<Field.Label color="black" pt={1} fontSize="12px">
|
<Field.Label color="black" pt={1} fontSize="12px">
|
||||||
Job title
|
Job title
|
||||||
</Field.Label>
|
</Field.Label>
|
||||||
<Input
|
<Input
|
||||||
placeholder="Enter the Job Title"
|
placeholder="Enter the Job Title"
|
||||||
bgColor="#EEEEEE"
|
bgColor="#EEEEEE"
|
||||||
color="black"
|
color="black"
|
||||||
border="none"
|
border="none"
|
||||||
pl={1}
|
pl={1}
|
||||||
fontSize="12px"
|
fontSize="12px"
|
||||||
height="30px"
|
height="30px"
|
||||||
/>
|
value={data?.job_title}
|
||||||
</Field.Root>
|
/>
|
||||||
<Field.Root>
|
</Field.Root>
|
||||||
<Field.Label color="black" pt={1} fontSize="12px">
|
<Field.Root>
|
||||||
Workspace mode
|
<Field.Label color="black" pt={1} fontSize="12px">
|
||||||
</Field.Label>
|
Workspace mode
|
||||||
<Input
|
</Field.Label>
|
||||||
placeholder="Enter the Workspace Mode"
|
<Input
|
||||||
bgColor="#EEEEEE"
|
placeholder="Enter the Workspace Mode"
|
||||||
color="black"
|
bgColor="#EEEEEE"
|
||||||
border="none"
|
color="black"
|
||||||
pl={1}
|
border="none"
|
||||||
fontSize="12px"
|
pl={1}
|
||||||
height="30px"
|
fontSize="12px"
|
||||||
/>
|
height="30px"
|
||||||
</Field.Root>
|
value={data?.workspace?.en_name}
|
||||||
<Field.Root>
|
/>
|
||||||
<Field.Label pt={1} color="black" fontSize="12px">
|
</Field.Root>
|
||||||
Category
|
<Field.Root>
|
||||||
</Field.Label>
|
<Field.Label pt={1} color="black" fontSize="12px">
|
||||||
<Input
|
Category
|
||||||
placeholder="Enter the Category"
|
</Field.Label>
|
||||||
bgColor="#EEEEEE"
|
<Input
|
||||||
color="black"
|
placeholder="Enter the Category"
|
||||||
border="none"
|
bgColor="#EEEEEE"
|
||||||
pl={1}
|
color="black"
|
||||||
fontSize="12px"
|
border="none"
|
||||||
height="30px"
|
pl={1}
|
||||||
/>
|
fontSize="12px"
|
||||||
</Field.Root>
|
height="30px"
|
||||||
<Field.Root>
|
value={data?.industry?.en_name}
|
||||||
<Field.Label pt={1} color="black" fontSize="12px">
|
/>
|
||||||
Sub-Category
|
</Field.Root>
|
||||||
</Field.Label>
|
<Field.Root>
|
||||||
<Input
|
<Field.Label pt={1} color="black" fontSize="12px">
|
||||||
placeholder="Enter the Sub-Category"
|
Sub-Category
|
||||||
bgColor="#EEEEEE"
|
</Field.Label>
|
||||||
color="black"
|
<Input
|
||||||
border="none"
|
placeholder="Enter the Sub-Category"
|
||||||
pl={1}
|
bgColor="#EEEEEE"
|
||||||
fontSize="12px"
|
color="black"
|
||||||
height="30px"
|
border="none"
|
||||||
/>
|
pl={1}
|
||||||
</Field.Root>
|
fontSize="12px"
|
||||||
<Field.Root>
|
height="30px"
|
||||||
<Field.Label pt={1} color="black" fontSize="12px">
|
value={data?.department?.en_name}
|
||||||
Salary
|
/>
|
||||||
</Field.Label>
|
</Field.Root>
|
||||||
<Input
|
<Field.Root>
|
||||||
placeholder="Enter the Salary"
|
<Field.Label pt={1} color="black" fontSize="12px">
|
||||||
bgColor="#EEEEEE"
|
Salary
|
||||||
color="black"
|
</Field.Label>
|
||||||
border="none"
|
<Input
|
||||||
pl={1}
|
placeholder="Enter the Salary"
|
||||||
fontSize="12px"
|
bgColor="#EEEEEE"
|
||||||
height="30px"
|
color="black"
|
||||||
/>
|
border="none"
|
||||||
</Field.Root>
|
pl={1}
|
||||||
<Field.Root>
|
fontSize="12px"
|
||||||
<Field.Label pt={1} color="black" fontSize="12px">
|
height="30px"
|
||||||
Experience
|
value={data?.ctc_amount}
|
||||||
</Field.Label>
|
/>
|
||||||
<Input
|
</Field.Root>
|
||||||
placeholder="Enter the Experience"
|
<Field.Root>
|
||||||
bgColor="#EEEEEE"
|
<Field.Label pt={1} color="black" fontSize="12px">
|
||||||
color="black"
|
Experience
|
||||||
border="none"
|
</Field.Label>
|
||||||
pl={1}
|
<Input
|
||||||
fontSize="12px"
|
placeholder="Enter the Experience"
|
||||||
height="30px"
|
bgColor="#EEEEEE"
|
||||||
/>
|
color="black"
|
||||||
</Field.Root>
|
border="none"
|
||||||
<Field.Root>
|
pl={1}
|
||||||
<Field.Label pt={1} color="black" fontSize="12px">
|
fontSize="12px"
|
||||||
Job Location
|
height="30px"
|
||||||
</Field.Label>
|
value={data?.experience}
|
||||||
<Input
|
/>
|
||||||
placeholder="Enter the Job Location"
|
</Field.Root>
|
||||||
bgColor="#EEEEEE"
|
<Field.Root>
|
||||||
color="black"
|
<Field.Label pt={1} color="black" fontSize="12px">
|
||||||
border="none"
|
Job Location
|
||||||
pl={1}
|
</Field.Label>
|
||||||
fontSize="12px"
|
<Input
|
||||||
height="30px"
|
placeholder="Enter the Job Location"
|
||||||
/>
|
bgColor="#EEEEEE"
|
||||||
</Field.Root>
|
color="black"
|
||||||
{/* <Field.Label pt={1} color="black" fontSize="12px">Country Selection</Field.Label>
|
border="none"
|
||||||
<Input placeholder="Enter the Country Selection" /> */}
|
pl={1}
|
||||||
<SelectRoot collection={frameworks} size="sm" w={"100%"}>
|
fontSize="12px"
|
||||||
<SelectLabel pt={1} color="black" fontSize="12px">
|
height="30px"
|
||||||
Country Selection
|
value={data?.job_location}
|
||||||
</SelectLabel>
|
/>
|
||||||
<SelectTrigger
|
</Field.Root>
|
||||||
bgColor="#EEEEEE"
|
|
||||||
color="black"
|
|
||||||
border="none"
|
|
||||||
pl={1}
|
|
||||||
fontSize="12px"
|
|
||||||
height="30px"
|
|
||||||
borderRadius={"5px"}
|
|
||||||
>
|
|
||||||
<SelectValueText
|
|
||||||
placeholder="Enter the Country Selection"
|
|
||||||
pb={"6px"}
|
|
||||||
fontSize={"12px"}
|
|
||||||
/>
|
|
||||||
</SelectTrigger>
|
|
||||||
<SelectContent
|
|
||||||
position={"relative"}
|
|
||||||
zIndex={"9999"}
|
|
||||||
bg={"#fff"}
|
|
||||||
>
|
|
||||||
{frameworks.items.map((movie) => (
|
|
||||||
<SelectItem
|
|
||||||
item={movie}
|
|
||||||
key={movie.value}
|
|
||||||
color={"black"}
|
|
||||||
pl={2}
|
|
||||||
p={1}
|
|
||||||
_hover={{ bg: "#F0F0F0" }} // Light grey background on hover
|
|
||||||
fontSize="12px"
|
|
||||||
>
|
|
||||||
{movie.label}
|
|
||||||
</SelectItem>
|
|
||||||
))}
|
|
||||||
</SelectContent>
|
|
||||||
</SelectRoot>
|
|
||||||
|
|
||||||
<Field.Root>
|
<Field.Root>
|
||||||
<Field.Label pt={1} color="black" fontSize="12px">
|
<Field.Label pt={1} color="black" fontSize="12px">
|
||||||
Job type
|
Country
|
||||||
</Field.Label>
|
</Field.Label>
|
||||||
<Input
|
<Input
|
||||||
placeholder="Enter the Job Type"
|
placeholder="Enter the Country"
|
||||||
bgColor="#EEEEEE"
|
bgColor="#EEEEEE"
|
||||||
color="black"
|
color="black"
|
||||||
border="none"
|
border="none"
|
||||||
pl={1}
|
pl={1}
|
||||||
fontSize="12px"
|
fontSize="12px"
|
||||||
height="30px"
|
height="30px"
|
||||||
/>
|
value={data?.country.en_name}
|
||||||
</Field.Root>
|
/>
|
||||||
<Field.Root>
|
</Field.Root>
|
||||||
<Field.Label pt={1} color="black" fontSize="12px">
|
|
||||||
Skills required
|
|
||||||
</Field.Label>
|
|
||||||
<Input
|
|
||||||
placeholder="Enter the Skills Required"
|
|
||||||
bgColor="#EEEEEE"
|
|
||||||
color="black"
|
|
||||||
border="none"
|
|
||||||
pl={1}
|
|
||||||
fontSize="12px"
|
|
||||||
height="30px"
|
|
||||||
/>
|
|
||||||
</Field.Root>
|
|
||||||
<Field.Root>
|
|
||||||
<Field.Label pt={1} color="black" fontSize="12px">
|
|
||||||
Job Description*
|
|
||||||
</Field.Label>
|
|
||||||
<Input
|
|
||||||
placeholder="Enter the Job Description"
|
|
||||||
bgColor="#EEEEEE"
|
|
||||||
color="black"
|
|
||||||
border="none"
|
|
||||||
pl={1}
|
|
||||||
fontSize="12px"
|
|
||||||
height="30px"
|
|
||||||
/>
|
|
||||||
</Field.Root>
|
|
||||||
<Field.Root>
|
|
||||||
<Field.Label pt={1} color="black" fontSize="12px">
|
|
||||||
Upload Image
|
|
||||||
</Field.Label>
|
|
||||||
<Input
|
|
||||||
placeholder="Upload Image"
|
|
||||||
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"}
|
|
||||||
fontSize="12px"
|
|
||||||
height="30px"
|
|
||||||
>
|
|
||||||
Save
|
|
||||||
</Button>
|
|
||||||
</DialogFooter>
|
|
||||||
|
|
||||||
<DialogCloseTrigger color="black" />
|
{/* <SelectRoot collection={frameworks} size="sm" w={"100%"}>
|
||||||
</DialogContent>
|
<SelectLabel pt={1} color="black" fontSize="12px">
|
||||||
|
Country Selection
|
||||||
|
</SelectLabel>
|
||||||
|
<SelectTrigger
|
||||||
|
bgColor="#EEEEEE"
|
||||||
|
color="black"
|
||||||
|
border="none"
|
||||||
|
pl={1}
|
||||||
|
fontSize="12px"
|
||||||
|
height="30px"
|
||||||
|
borderRadius={"5px"}
|
||||||
|
>
|
||||||
|
<SelectValueText
|
||||||
|
placeholder="Enter the Country Selection"
|
||||||
|
pb={"6px"}
|
||||||
|
fontSize={"12px"}
|
||||||
|
/>
|
||||||
|
</SelectTrigger>
|
||||||
|
<SelectContent
|
||||||
|
position={"relative"}
|
||||||
|
zIndex={"9999"}
|
||||||
|
bg={"#fff"}
|
||||||
|
>
|
||||||
|
{frameworks.items.map((movie) => (
|
||||||
|
<SelectItem
|
||||||
|
item={movie}
|
||||||
|
key={movie.value}
|
||||||
|
color={"black"}
|
||||||
|
pl={2}
|
||||||
|
p={1}
|
||||||
|
_hover={{ bg: "#F0F0F0" }} // Light grey background on hover
|
||||||
|
fontSize="12px"
|
||||||
|
>
|
||||||
|
{movie.label}
|
||||||
|
</SelectItem>
|
||||||
|
))}
|
||||||
|
</SelectContent>
|
||||||
|
</SelectRoot> */}
|
||||||
|
|
||||||
|
<Field.Root>
|
||||||
|
<Field.Label pt={1} color="black" fontSize="12px">
|
||||||
|
Job type
|
||||||
|
</Field.Label>
|
||||||
|
<Input
|
||||||
|
placeholder="Enter the Job Type"
|
||||||
|
bgColor="#EEEEEE"
|
||||||
|
color="black"
|
||||||
|
border="none"
|
||||||
|
pl={1}
|
||||||
|
fontSize="12px"
|
||||||
|
height="30px"
|
||||||
|
value={data?.job_type?.en_name}
|
||||||
|
/>
|
||||||
|
</Field.Root>
|
||||||
|
<Field.Root>
|
||||||
|
<Field.Label pt={1} color="black" fontSize="12px">
|
||||||
|
Skills required
|
||||||
|
</Field.Label>
|
||||||
|
<Input
|
||||||
|
placeholder="Enter the Skills Required"
|
||||||
|
bgColor="#EEEEEE"
|
||||||
|
color="black"
|
||||||
|
border="none"
|
||||||
|
pl={1}
|
||||||
|
fontSize="12px"
|
||||||
|
height="30px"
|
||||||
|
value={data?.skill_description}
|
||||||
|
/>
|
||||||
|
</Field.Root>
|
||||||
|
<Field.Root>
|
||||||
|
<Field.Label pt={1} color="black" fontSize="12px">
|
||||||
|
Job Description*
|
||||||
|
</Field.Label>
|
||||||
|
<Input
|
||||||
|
placeholder="Enter the Job Description"
|
||||||
|
bgColor="#EEEEEE"
|
||||||
|
color="black"
|
||||||
|
border="none"
|
||||||
|
pl={1}
|
||||||
|
fontSize="12px"
|
||||||
|
height="30px"
|
||||||
|
value={data?.job_description}
|
||||||
|
/>
|
||||||
|
</Field.Root>
|
||||||
|
{/* <Field.Root>
|
||||||
|
<Field.Label pt={1} color="black" fontSize="12px">
|
||||||
|
Upload Image
|
||||||
|
</Field.Label>
|
||||||
|
<Input
|
||||||
|
placeholder="Upload Image"
|
||||||
|
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"}
|
||||||
|
fontSize="12px"
|
||||||
|
height="30px"
|
||||||
|
>
|
||||||
|
Save
|
||||||
|
</Button>
|
||||||
|
</DialogFooter> */}
|
||||||
|
|
||||||
|
<DialogCloseTrigger color="black" />
|
||||||
|
</DialogContent>
|
||||||
{/* ))} */}
|
{/* ))} */}
|
||||||
</DialogRoot>
|
</DialogRoot>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -14,9 +14,10 @@ import { Switch } from "../../components/ui/switch";
|
|||||||
import ViewDailog from "./ViewDailog";
|
import ViewDailog from "./ViewDailog";
|
||||||
import { useGetManagePostsQuery, usePostStatusToggleMutation } from "../../Redux/Service/manage.post.service";
|
import { useGetManagePostsQuery, usePostStatusToggleMutation } from "../../Redux/Service/manage.post.service";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { toaster } from "../../components/ui/toaster";
|
import { Toaster, toaster } from "../../components/ui/toaster";
|
||||||
import { FaVideo } from "react-icons/fa";
|
import { FaVideo } from "react-icons/fa";
|
||||||
import SearchComponent from "../../components/SearchComponent";
|
import SearchComponent from "../../components/SearchComponent";
|
||||||
|
import { delay } from "../../components/Utils";
|
||||||
// import Delete from "../../components/ActionIcons/Delete";
|
// import Delete from "../../components/ActionIcons/Delete";
|
||||||
// import ViewDailog from './ViewDailog'
|
// import ViewDailog from './ViewDailog'
|
||||||
|
|
||||||
@@ -71,7 +72,7 @@ const tableHeadRow = [
|
|||||||
|
|
||||||
const ManagePost = () => {
|
const ManagePost = () => {
|
||||||
const [currentPage, setCurrentPage] = useState(1);
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
const { data, refetch } = useGetManagePostsQuery(currentPage)
|
const { data, refetch, isFetching, isError } = useGetManagePostsQuery(currentPage)
|
||||||
const [localData, setLocalData] = useState<any[]>([]);
|
const [localData, setLocalData] = useState<any[]>([]);
|
||||||
const [searchTerm, setSearchTerm] = useState("");
|
const [searchTerm, setSearchTerm] = useState("");
|
||||||
const [postStatusToggle] = usePostStatusToggleMutation()
|
const [postStatusToggle] = usePostStatusToggleMutation()
|
||||||
@@ -96,6 +97,12 @@ const ManagePost = () => {
|
|||||||
);
|
);
|
||||||
try {
|
try {
|
||||||
await postStatusToggle({ id: agencyId, is_active: newStatus }).unwrap();
|
await postStatusToggle({ id: agencyId, is_active: newStatus }).unwrap();
|
||||||
|
toaster.create({
|
||||||
|
title: "Success",
|
||||||
|
description: "Status updated successfully",
|
||||||
|
type: "success",
|
||||||
|
});
|
||||||
|
await delay(500);
|
||||||
refetch()
|
refetch()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error updating:", error);
|
console.error("Error updating:", error);
|
||||||
@@ -149,36 +156,35 @@ const ManagePost = () => {
|
|||||||
h={50}
|
h={50}
|
||||||
src={`${APIURL}${agency.images[0].image_name}`}
|
src={`${APIURL}${agency.images[0].image_name}`}
|
||||||
/>
|
/>
|
||||||
<Text fontSize="xs" color={'lightgray'}>
|
<Text fontSize="xs" color={'lightgray'}>
|
||||||
{`${Number(agency.images.length) > 1 ? '+' + (Number(agency.images.length) - 1) : ''}`}
|
{`${Number(agency.images.length) > 1 ? '+' + (Number(agency.images.length) - 1) : ''}`}
|
||||||
</Text>
|
</Text>
|
||||||
</HStack>
|
</HStack>
|
||||||
) : (
|
) : (
|
||||||
<HStack>
|
<HStack>
|
||||||
<Box
|
<Box
|
||||||
rounded={"lg"}
|
rounded={"lg"}
|
||||||
w={100}
|
w={100}
|
||||||
h={50}
|
h={50}
|
||||||
bg="gray.200"
|
bg="gray.200"
|
||||||
display="flex"
|
display="flex"
|
||||||
alignItems="center"
|
alignItems="center"
|
||||||
justifyContent="center"
|
justifyContent="center"
|
||||||
>
|
>
|
||||||
<Icon as={FaVideo} color="gray.500" />
|
<Icon as={FaVideo} color="gray.500" />
|
||||||
</Box>
|
</Box>
|
||||||
<Text fontSize="xs" color={'lightgray'}>
|
<Text fontSize="xs" color={'lightgray'}>
|
||||||
{`${Number(agency.images.length) > 1 ? '+' + (Number(agency.images.length) - 1) : ''}`}
|
{`${Number(agency.images.length) > 1 ? '+' + (Number(agency.images.length) - 1) : ''}`}
|
||||||
</Text>
|
</Text>
|
||||||
</HStack>
|
</HStack>
|
||||||
) : ''
|
) : ''
|
||||||
// <Image rounded={"lg"} w={100} h={50} src={img} />
|
// <Image rounded={"lg"} w={100} h={50} src={img} />
|
||||||
),
|
),
|
||||||
Description: (
|
Description: (
|
||||||
<Text>
|
<Text>
|
||||||
{`${translation?.content}`.slice(
|
{translation?.content?.length > 30
|
||||||
0,
|
? `${translation.content.slice(0, 30)}...`
|
||||||
30
|
: translation?.content}
|
||||||
) + "..."}
|
|
||||||
</Text>
|
</Text>
|
||||||
),
|
),
|
||||||
"Publish Data": formatAPIDate(agency.created_at),
|
"Publish Data": formatAPIDate(agency.created_at),
|
||||||
@@ -236,8 +242,11 @@ const ManagePost = () => {
|
|||||||
total: data?.data.total || 0
|
total: data?.data.total || 0
|
||||||
}}
|
}}
|
||||||
onPageChange={handlePageChange}
|
onPageChange={handlePageChange}
|
||||||
|
isLoading={isFetching}
|
||||||
|
isError={isError}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
<Toaster />
|
||||||
</MainFrame>
|
</MainFrame>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,12 +1,16 @@
|
|||||||
import { Box, HStack, Input, Text } from "@chakra-ui/react";
|
import { Box, HStack, Text } from "@chakra-ui/react";
|
||||||
import MainFrame from "../../../components/MainFrame";
|
import MainFrame from "../../../components/MainFrame";
|
||||||
import DataTable from "../../../components/DataTable";
|
import DataTable from "../../../components/DataTable";
|
||||||
import { Switch } from "../../../components/ui/switch";
|
import { Switch } from "../../../components/ui/switch";
|
||||||
import { InputGroup } from "../../../components/ui/input-group";
|
// import { InputGroup } from "../../../components/ui/input-group";
|
||||||
import { LuSearch } from "react-icons/lu";
|
// import { LuSearch } from "react-icons/lu";
|
||||||
import { useGetContactQuery } from "../../../Redux/Service/deactivated.account.service";
|
// import { useGetContactQuery } from "../../../Redux/Service/deactivated.account.service";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { Spinner } from "../../../components/Sipnner/Spinner";
|
import { Spinner } from "../../../components/Sipnner/Spinner";
|
||||||
|
import { useGetDeactivateUserQuery, useUserDeactivateToggleMutation } from "../../../Redux/Service/manage.user";
|
||||||
|
import SearchComponent from "../../../components/SearchComponent";
|
||||||
|
import { Toaster, toaster } from "../../../components/ui/toaster";
|
||||||
|
import { delay } from "../../../components/Utils";
|
||||||
|
|
||||||
const tableHeadRow = [
|
const tableHeadRow = [
|
||||||
"Sr. No",
|
"Sr. No",
|
||||||
@@ -17,8 +21,11 @@ const tableHeadRow = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
const DeactivatedAccounts = () => {
|
const DeactivatedAccounts = () => {
|
||||||
const { data ,isLoading} = useGetContactQuery();
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
const [localData, setLocalData] = useState([]);
|
const { data, isLoading, refetch, isError, isFetching } = useGetDeactivateUserQuery(currentPage);
|
||||||
|
const [localData, setLocalData] = useState<any[]>([]);
|
||||||
|
const [searchTerm, setSearchTerm] = useState("");
|
||||||
|
const [userDeactivateToggle] = useUserDeactivateToggleMutation()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (data) {
|
if (data) {
|
||||||
@@ -26,8 +33,47 @@ const DeactivatedAccounts = () => {
|
|||||||
}
|
}
|
||||||
}, [data]);
|
}, [data]);
|
||||||
|
|
||||||
|
const handlePageChange = (page: number) => {
|
||||||
|
setCurrentPage(page);
|
||||||
|
}
|
||||||
|
|
||||||
const manageUser = localData?.map((agency: any, index: number) => ({
|
const filteredData = localData?.filter((agency) => {
|
||||||
|
const searchLower = searchTerm.toLowerCase();
|
||||||
|
const firstName = agency.first_name?.toLowerCase().includes(searchLower);
|
||||||
|
const lastName = agency.last_name?.toLowerCase().includes(searchLower);
|
||||||
|
// const email = agency.capital?.toLowerCase().includes(searchLower);
|
||||||
|
return firstName || lastName;
|
||||||
|
});
|
||||||
|
|
||||||
|
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 userDeactivateToggle({ id: agencyId, is_active: newStatus }).unwrap();
|
||||||
|
toaster.create({
|
||||||
|
title: "Success",
|
||||||
|
description: "Status updated successfully",
|
||||||
|
type: "success",
|
||||||
|
});
|
||||||
|
await delay(500);
|
||||||
|
refetch()
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error updating privacy policy:", error);
|
||||||
|
setLocalData((prevData) =>
|
||||||
|
prevData.map((agency) =>
|
||||||
|
agency.id === agencyId ? { ...agency, is_active: currentStatus } : agency
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const manageUser = filteredData?.map((agency: any, index: number) => ({
|
||||||
"Sr. No": index + 1,
|
"Sr. No": index + 1,
|
||||||
"First Name": agency?.first_name,
|
"First Name": agency?.first_name,
|
||||||
"Last Name": agency?.last_name,
|
"Last Name": agency?.last_name,
|
||||||
@@ -38,13 +84,13 @@ const DeactivatedAccounts = () => {
|
|||||||
size={"sm"}
|
size={"sm"}
|
||||||
colorPalette={"teal"}
|
colorPalette={"teal"}
|
||||||
checked={agency.is_active === true}
|
checked={agency.is_active === true}
|
||||||
// onChange={() => handleToggle(agency.id, agency.is_active ? "1" : "0")}
|
onChange={() => handleToggle(agency.id, agency.is_active ? "1" : "0")}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
),
|
),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
return (
|
return (
|
||||||
<MainFrame>
|
<MainFrame>
|
||||||
<Box
|
<Box
|
||||||
@@ -89,37 +135,32 @@ const DeactivatedAccounts = () => {
|
|||||||
</Text>
|
</Text>
|
||||||
|
|
||||||
<HStack>
|
<HStack>
|
||||||
<InputGroup
|
<SearchComponent
|
||||||
startElement={
|
value={searchTerm}
|
||||||
<LuSearch
|
onChange={(value) => {
|
||||||
fontSize={"xs"}
|
setSearchTerm(value);
|
||||||
style={{ position: "relative", left: "10px" }}
|
// setCurrentPage(1);
|
||||||
/>
|
refetch()
|
||||||
}
|
}}
|
||||||
color={"#000"}
|
/>
|
||||||
>
|
|
||||||
<Input
|
|
||||||
p={4}
|
|
||||||
w={300}
|
|
||||||
bg={"#fff"}
|
|
||||||
colorPalette={"blue"}
|
|
||||||
_focus={{ border: "1px solid #02A0A0" }}
|
|
||||||
rounded={"md"}
|
|
||||||
size={"2xs"}
|
|
||||||
fontSize={"sm"}
|
|
||||||
placeholder="Search..."
|
|
||||||
bgColor={"#EEEEEE"}
|
|
||||||
ps={8}
|
|
||||||
/>
|
|
||||||
</InputGroup>
|
|
||||||
</HStack>
|
</HStack>
|
||||||
</HStack>
|
</HStack>
|
||||||
<DataTable
|
<DataTable
|
||||||
sortableColumns={["Name", "Registration Date "]}
|
sortableColumns={["Name", "Registration Date "]}
|
||||||
tableHeadRow={tableHeadRow}
|
tableHeadRow={tableHeadRow}
|
||||||
data={manageUser}
|
data={manageUser}
|
||||||
|
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}
|
||||||
|
isLoading={isFetching}
|
||||||
|
isError={isError}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
<Toaster />
|
||||||
</MainFrame>
|
</MainFrame>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Field, Input, Stack } from "@chakra-ui/react";
|
import { Box, Field, Input, Stack } from "@chakra-ui/react";
|
||||||
import {
|
import {
|
||||||
DialogActionTrigger,
|
DialogActionTrigger,
|
||||||
DialogBody,
|
DialogBody,
|
||||||
@@ -12,8 +12,32 @@ import {
|
|||||||
} from "../../../components/ui/dialog";
|
} from "../../../components/ui/dialog";
|
||||||
import { Button } from "../../../components/ui/button";
|
import { Button } from "../../../components/ui/button";
|
||||||
import { IoMdAdd } from "react-icons/io";
|
import { IoMdAdd } from "react-icons/io";
|
||||||
|
import { useState } from "react";
|
||||||
|
// import { useCreateUserMutation } from "../../../Redux/Service/manage.user";
|
||||||
|
// import { useState } from "react";
|
||||||
|
|
||||||
function AddRegisterUsers() {
|
function AddRegisterUsers() {
|
||||||
|
// const [createUser] = useCreateUserMutation();
|
||||||
|
const [userType, setUserType] = useState<number | "">("");
|
||||||
|
|
||||||
|
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 (
|
return (
|
||||||
<DialogRoot placement="center">
|
<DialogRoot placement="center">
|
||||||
<DialogTrigger asChild>
|
<DialogTrigger asChild>
|
||||||
@@ -23,13 +47,13 @@ function AddRegisterUsers() {
|
|||||||
</DialogTrigger>
|
</DialogTrigger>
|
||||||
|
|
||||||
<DialogContent
|
<DialogContent
|
||||||
bg={"#fff"}
|
bg={"#fff"}
|
||||||
w={{ base: '90%', md: '400px' }}
|
w={{ base: '90%', md: '400px' }}
|
||||||
height={'80vh'}
|
height={'80vh'}
|
||||||
overflow={'scroll'}
|
overflow={'scroll'}
|
||||||
overflowX="hidden"
|
overflowX="hidden"
|
||||||
p={3} // Reduced padding
|
p={3} // Reduced padding
|
||||||
bgSize={'md'}
|
bgSize={'md'}
|
||||||
>
|
>
|
||||||
<DialogHeader bg="white" >
|
<DialogHeader bg="white" >
|
||||||
<DialogTitle alignSelf="center" color="black" fontSize="14px">
|
<DialogTitle alignSelf="center" color="black" fontSize="14px">
|
||||||
@@ -44,42 +68,110 @@ function AddRegisterUsers() {
|
|||||||
First Name
|
First Name
|
||||||
</Field.Label>
|
</Field.Label>
|
||||||
<Input
|
<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">
|
<Field.Label color="black" pt={1} fontSize="12px">
|
||||||
Last Name
|
Last Name
|
||||||
</Field.Label>
|
</Field.Label>
|
||||||
<Input
|
<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">
|
<Field.Label color="black" pt={1} fontSize="12px">
|
||||||
Gender
|
Gender
|
||||||
</Field.Label>
|
</Field.Label>
|
||||||
<Input
|
<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">
|
<Field.Label color="black" pt={1} fontSize="12px">
|
||||||
DOB
|
DOB
|
||||||
</Field.Label>
|
</Field.Label>
|
||||||
<Input
|
<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"
|
||||||
|
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
|
OTP Verified
|
||||||
</Field.Label>
|
</Field.Label>
|
||||||
<Input
|
<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"
|
||||||
/>
|
/> */}
|
||||||
|
|
||||||
<Field.Label color="black" pt={1} fontSize="12px">
|
<Field.Label color="black" pt={1} fontSize="12px">
|
||||||
Language
|
Language
|
||||||
</Field.Label>
|
</Field.Label>
|
||||||
<Input
|
<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>
|
</Field.Root>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
// import { MdOutlineRemoveRedEye } from "react-icons/md";
|
// import { MdOutlineRemoveRedEye } from "react-icons/md";
|
||||||
import { Field, Input, Span, Stack } from "@chakra-ui/react";
|
import { Box, Field, HStack, Input, Stack } from "@chakra-ui/react";
|
||||||
import {
|
import {
|
||||||
DialogActionTrigger,
|
|
||||||
DialogBody,
|
DialogBody,
|
||||||
DialogCloseTrigger,
|
DialogCloseTrigger,
|
||||||
DialogContent,
|
DialogContent,
|
||||||
@@ -15,118 +14,332 @@ import {
|
|||||||
import { Button } from "../../../components/ui/button";
|
import { Button } from "../../../components/ui/button";
|
||||||
// import { TbEdit } from "react-icons/tb";
|
// import { TbEdit } from "react-icons/tb";
|
||||||
import Edit from "../../../components/ActionIcons/Edit";
|
import Edit from "../../../components/ActionIcons/Edit";
|
||||||
|
import { UserData, useUpdateUserMutation } from "../../../Redux/Service/manage.user";
|
||||||
|
import { useState } from "react";
|
||||||
|
import { Toaster, toaster } from "../../../components/ui/toaster";
|
||||||
|
|
||||||
|
interface UserPayload {
|
||||||
|
id: number;
|
||||||
|
principal_type_xid: number;
|
||||||
|
principal_source_xid: number;
|
||||||
|
first_name: string;
|
||||||
|
last_name: string;
|
||||||
|
gender: string;
|
||||||
|
date_of_birth: string | null;
|
||||||
|
language_xid: number; // ✅ Always an array
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UserFormData {
|
||||||
|
id: number;
|
||||||
|
principal_type_xid: number;
|
||||||
|
first_name: string;
|
||||||
|
last_name: string;
|
||||||
|
phone_number: string;
|
||||||
|
gender: string;
|
||||||
|
date_of_birth: string;
|
||||||
|
is_active: boolean;
|
||||||
|
principal_type: {
|
||||||
|
id: number;
|
||||||
|
principal_type_title: string;
|
||||||
|
};
|
||||||
|
principle_language_linkss: {
|
||||||
|
id?: number;
|
||||||
|
iam_principal_xid?: number;
|
||||||
|
language_xid: number;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function EditRegisterUsers({ data, refetch }: { data: UserData, refetch: () => void }) {
|
||||||
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
|
const transformToFormData = (data: UserData): UserFormData => ({
|
||||||
|
...data,
|
||||||
|
principle_language_linkss: {
|
||||||
|
...data.principle_language_linkss,
|
||||||
|
language_xid: data.principle_language_linkss.language_xid, // wrap in array
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const [formData, setFormData] = useState<UserFormData>(transformToFormData(data));
|
||||||
|
// const [formData, setFormData] = useState<UserData>({
|
||||||
|
// id: data?.id,
|
||||||
|
// first_name: data?.first_name || '',
|
||||||
|
// last_name: data?.last_name || '',
|
||||||
|
// principal_type_xid: data?.principal_type_xid,
|
||||||
|
// phone_number: data?.phone_number || '',
|
||||||
|
// gender: data?.gender || '',
|
||||||
|
// date_of_birth: data?.date_of_birth || '',
|
||||||
|
// principal_type: data?.principal_type,
|
||||||
|
// is_active: data?.is_active ?? true,
|
||||||
|
// principle_language_linkss: {
|
||||||
|
// ...data?.principle_language_linkss,
|
||||||
|
// language_xid: Array.isArray(data?.principle_language_linkss?.language_xid)
|
||||||
|
// ? data.principle_language_linkss.language_xid
|
||||||
|
// : [data?.principle_language_linkss?.language_xid].filter(Boolean),
|
||||||
|
// },
|
||||||
|
// // principle_language_linkss: data?.principle_language_linkss ?? [],
|
||||||
|
// });
|
||||||
|
const [updateUser, { isLoading }] = useUpdateUserMutation();
|
||||||
|
|
||||||
|
const handleOpenModal = () => {
|
||||||
|
setIsOpen(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSubmit = async (event: React.FormEvent) => {
|
||||||
|
event.preventDefault();
|
||||||
|
if (formData.first_name === '' || formData.last_name === '' || formData.phone_number === '' || formData.gender === '' || formData.date_of_birth === '') {
|
||||||
|
toaster.create({
|
||||||
|
title: "Error",
|
||||||
|
description: "Input fields cannot be empty",
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// const languageData = formData?.principle_language_linkss?.language_xid;
|
||||||
|
|
||||||
|
const payload: UserPayload = {
|
||||||
|
id: formData?.id,
|
||||||
|
principal_type_xid: formData?.principal_type_xid,
|
||||||
|
principal_source_xid: formData?.id,
|
||||||
|
first_name: formData?.first_name,
|
||||||
|
last_name: formData?.last_name,
|
||||||
|
gender: formData?.gender,
|
||||||
|
date_of_birth: formData?.date_of_birth,
|
||||||
|
// language_xid: languageData,
|
||||||
|
language_xid: formData.principle_language_linkss?.language_xid
|
||||||
|
? formData.principle_language_linkss.language_xid
|
||||||
|
: formData.principle_language_linkss?.language_xid,
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// console.log('payload', payload)
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await updateUser(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: any) {
|
||||||
|
console.error("Error updating template:", error);
|
||||||
|
// alert("Failed to update template");
|
||||||
|
toaster.create({
|
||||||
|
title: "Error",
|
||||||
|
description: error ? `${error?.data.message}` : "Something went wrong",
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
function EditRegisterUsers() {
|
|
||||||
return (
|
return (
|
||||||
<DialogRoot placement="center">
|
<>
|
||||||
<DialogTrigger asChild>
|
<DialogRoot placement="center" key={formData.id} open={isOpen} onOpenChange={({ open }) => setIsOpen(open)}>
|
||||||
<Span>
|
<DialogTrigger asChild>
|
||||||
|
{/* <Span>
|
||||||
<Edit />
|
<Edit />
|
||||||
</Span>
|
</Span> */}
|
||||||
</DialogTrigger>
|
<Button bg="transparent" color={"black"} h={"18px"} onClick={handleOpenModal}><Edit /></Button>
|
||||||
|
</DialogTrigger>
|
||||||
|
|
||||||
<DialogContent
|
<DialogContent
|
||||||
bg={"#fff"}
|
bg={"#fff"}
|
||||||
w={{ base: "90%", md: "400px" }}
|
w={{ base: "90%", md: "400px" }}
|
||||||
height={"80vh"}
|
height={"80vh"}
|
||||||
overflow={"scroll"}
|
overflow={"scroll"}
|
||||||
overflowX="hidden"
|
overflowX="hidden"
|
||||||
p={3} // Reduced padding
|
p={3} // Reduced padding
|
||||||
bgSize={"md"}
|
bgSize={"md"}
|
||||||
>
|
>
|
||||||
<DialogHeader bg="white" p={0}>
|
<DialogHeader bg="white" p={0}>
|
||||||
<DialogTitle alignSelf="center" color="black" fontSize="14px">
|
<DialogTitle alignSelf="center" color="black" fontSize="14px">
|
||||||
Edit user Accounts
|
Edit user Accounts
|
||||||
</DialogTitle>
|
</DialogTitle>
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
|
|
||||||
<DialogBody bg="white">
|
<DialogBody bg="white">
|
||||||
<Stack py={3}>
|
<Stack py={3}>
|
||||||
<Field.Root>
|
<Field.Root>
|
||||||
<Field.Label color="black" pt={1} fontSize="12px">
|
<Field.Label color="black" pt={1} fontSize="12px">
|
||||||
First Name
|
First Name
|
||||||
</Field.Label>
|
</Field.Label>
|
||||||
<Input
|
<Input
|
||||||
bgColor="#EEEEEE"
|
bgColor="#EEEEEE"
|
||||||
color="black"
|
color="black"
|
||||||
border="none"
|
border="none"
|
||||||
pl={1}
|
pl={1}
|
||||||
fontSize="12px"
|
fontSize="12px"
|
||||||
height="30px"
|
height="30px"
|
||||||
/>
|
value={formData.first_name}
|
||||||
|
onChange={(e) => setFormData({ ...formData, first_name: e.target.value })}
|
||||||
|
/>
|
||||||
|
|
||||||
<Field.Label color="black" pt={1} fontSize="12px">
|
<Field.Label color="black" pt={1} fontSize="12px">
|
||||||
Last Name
|
Last Name
|
||||||
</Field.Label>
|
</Field.Label>
|
||||||
<Input
|
<Input
|
||||||
bgColor="#EEEEEE"
|
bgColor="#EEEEEE"
|
||||||
color="black"
|
color="black"
|
||||||
border="none"
|
border="none"
|
||||||
pl={1}
|
pl={1}
|
||||||
fontSize="12px"
|
fontSize="12px"
|
||||||
height="30px"
|
height="30px"
|
||||||
/>
|
value={formData.last_name}
|
||||||
|
onChange={(e) => setFormData({ ...formData, last_name: e.target.value })}
|
||||||
|
/>
|
||||||
|
|
||||||
<Field.Label color="black" pt={1} fontSize="12px">
|
<Field.Label color="black" pt={1} fontSize="12px">
|
||||||
Gender
|
Gender
|
||||||
</Field.Label>
|
</Field.Label>
|
||||||
<Input
|
<Input
|
||||||
bgColor="#EEEEEE"
|
bgColor="#EEEEEE"
|
||||||
color="black"
|
color="black"
|
||||||
border="none"
|
border="none"
|
||||||
pl={1}
|
pl={1}
|
||||||
fontSize="12px"
|
fontSize="12px"
|
||||||
height="30px"
|
height="30px"
|
||||||
/>
|
value={formData.gender}
|
||||||
|
onChange={(e) => setFormData({ ...formData, gender: e.target.value })}
|
||||||
|
/>
|
||||||
|
|
||||||
<Field.Label color="black" pt={1} fontSize="12px">
|
<Field.Label color="black" pt={1} fontSize="12px">
|
||||||
DOB
|
DOB
|
||||||
</Field.Label>
|
</Field.Label>
|
||||||
<Input
|
<Input
|
||||||
bgColor="#EEEEEE"
|
bgColor="#EEEEEE"
|
||||||
color="black"
|
color="black"
|
||||||
border="none"
|
border="none"
|
||||||
pl={1}
|
pl={1}
|
||||||
fontSize="12px"
|
fontSize="12px"
|
||||||
height="30px"
|
height="30px"
|
||||||
/>
|
value={formData.date_of_birth ? new Date(formData.date_of_birth).toLocaleDateString('en-GB').replace(/\//g, '-') : 'N/A'}
|
||||||
|
onChange={(e) => setFormData({ ...formData, date_of_birth: e.target.value })}
|
||||||
|
disabled={formData.principal_type_xid === 2 ? true : false}
|
||||||
|
/>
|
||||||
|
|
||||||
<Field.Label color="black" pt={1} fontSize="12px">
|
<Field.Label color="black" pt={1} fontSize="12px">
|
||||||
OTP Verified
|
Mobile Number
|
||||||
</Field.Label>
|
</Field.Label>
|
||||||
<Input
|
<Input
|
||||||
bgColor="#EEEEEE"
|
bgColor="#EEEEEE"
|
||||||
color="black"
|
color="black"
|
||||||
border="none"
|
border="none"
|
||||||
pl={1}
|
pl={1}
|
||||||
fontSize="12px"
|
fontSize="12px"
|
||||||
height="30px"
|
height="30px"
|
||||||
/>
|
value={formData.phone_number || ''}
|
||||||
|
onChange={(e) => setFormData({ ...formData, phone_number: e.target.value })}
|
||||||
|
/>
|
||||||
|
|
||||||
<Field.Label color="black" pt={1} fontSize="12px">
|
<Field.Label color="black" pt={1} fontSize="12px">
|
||||||
Language
|
Type Of User
|
||||||
</Field.Label>
|
</Field.Label>
|
||||||
<Input
|
{/* <Input
|
||||||
bgColor="#EEEEEE"
|
bgColor="#EEEEEE"
|
||||||
color="black"
|
color="black"
|
||||||
border="none"
|
border="none"
|
||||||
pl={1}
|
pl={1}
|
||||||
fontSize="12px"
|
fontSize="12px"
|
||||||
height="30px"
|
height="30px"
|
||||||
/>
|
value={formData.principal_type?.principal_type_title || 'N/A'}
|
||||||
</Field.Root>
|
onChange={(e) => setFormData({ ...formData, principal_type: { ...formData.principal_type, principal_type_title: e.target.value } })}
|
||||||
</Stack>
|
/> */}
|
||||||
</DialogBody>
|
|
||||||
<DialogFooter mt={5}>
|
<Box>
|
||||||
<DialogActionTrigger asChild>
|
<select
|
||||||
<Button rounded={"md"} w={"100%"} size={"sm"} bg={"#02A0A0"}>
|
style={{
|
||||||
|
width: "100%",
|
||||||
|
background: "transparent",
|
||||||
|
color: "black",
|
||||||
|
border: "none",
|
||||||
|
fontSize: "12px",
|
||||||
|
height: "30px",
|
||||||
|
outline: "none",
|
||||||
|
}}
|
||||||
|
value={formData.principal_type_xid?.toString() || 'N/A'}
|
||||||
|
onChange={(e) => setFormData({ ...formData, principal_type_xid: Number(e.target.value) })}
|
||||||
|
>
|
||||||
|
{/* <option value="">Select User Type</option> */}
|
||||||
|
<option value="2">Recruiter</option>
|
||||||
|
<option value="3">Jobseeker</option>
|
||||||
|
</select>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
<Field.Label color="black" pt={1} fontSize="12px">
|
||||||
|
Default Language
|
||||||
|
</Field.Label>
|
||||||
|
{/* <Input
|
||||||
|
bgColor="#EEEEEE"
|
||||||
|
color="black"
|
||||||
|
border="none"
|
||||||
|
pl={1}
|
||||||
|
fontSize="12px"
|
||||||
|
height="30px"
|
||||||
|
value={formData?.principle_language_linkss?.language_xid || 'N/A'}
|
||||||
|
onChange={(e) => setFormData({
|
||||||
|
...formData, principle_language_linkss: {
|
||||||
|
...formData?.principle_language_linkss, language_xid: e.target.value
|
||||||
|
.split(",")
|
||||||
|
.map(lang => lang.trim())
|
||||||
|
.filter(Boolean)
|
||||||
|
}
|
||||||
|
})}
|
||||||
|
/> */}
|
||||||
|
|
||||||
|
<HStack>
|
||||||
|
<select
|
||||||
|
style={{
|
||||||
|
width: "100%",
|
||||||
|
background: "transparent",
|
||||||
|
color: "black",
|
||||||
|
border: "none",
|
||||||
|
fontSize: "12px",
|
||||||
|
height: "30px",
|
||||||
|
outline: "none",
|
||||||
|
}}
|
||||||
|
value={formData?.principle_language_linkss?.language_xid || ""}
|
||||||
|
onChange={(e) => {
|
||||||
|
const value = Number(e.target.value);
|
||||||
|
setFormData({
|
||||||
|
...formData,
|
||||||
|
principle_language_linkss: {
|
||||||
|
...formData?.principle_language_linkss,
|
||||||
|
language_xid: value,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<option value="1">English</option>
|
||||||
|
<option value="2">Hindi</option>
|
||||||
|
<option value="3">Marathi</option>
|
||||||
|
<option value="4">Telgu</option>
|
||||||
|
<option value="5">Tamil</option>
|
||||||
|
<option value="6">Bengali</option>
|
||||||
|
<option value="7">Odia</option>
|
||||||
|
</select>
|
||||||
|
</HStack>
|
||||||
|
</Field.Root>
|
||||||
|
</Stack>
|
||||||
|
</DialogBody>
|
||||||
|
<DialogFooter mt={5}>
|
||||||
|
<Button rounded={"md"} w={"100%"} size={"sm"} bg={"#02A0A0"} onClick={handleSubmit} disabled={isLoading}>
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
</DialogActionTrigger>
|
</DialogFooter>
|
||||||
</DialogFooter>
|
<DialogCloseTrigger color="black" />
|
||||||
<DialogCloseTrigger color="black" />
|
</DialogContent>
|
||||||
</DialogContent>
|
</DialogRoot >
|
||||||
</DialogRoot>
|
<Toaster />
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import {
|
import {
|
||||||
Box, HStack,
|
Box, HStack,
|
||||||
|
Image,
|
||||||
// Image,
|
// Image,
|
||||||
Text
|
Text,
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import MainFrame from "../../../components/MainFrame";
|
import MainFrame from "../../../components/MainFrame";
|
||||||
// import AlertDailog from "../../../components/AlertDailog";
|
// import AlertDailog from "../../../components/AlertDailog";
|
||||||
@@ -10,21 +11,26 @@ import DataTable from "../../../components/DataTable";
|
|||||||
import { Switch } from "../../../components/ui/switch";
|
import { Switch } from "../../../components/ui/switch";
|
||||||
import ViewRegisterUsers from "./ViewRegisterUsers";
|
import ViewRegisterUsers from "./ViewRegisterUsers";
|
||||||
import EditRegisterUsers from "./EditRegisterUsers";
|
import EditRegisterUsers from "./EditRegisterUsers";
|
||||||
import AddRegisterUsers from "./AddRegisterUsers";
|
// import AddRegisterUsers from "./AddRegisterUsers";
|
||||||
import { useEffect, useState } from "react";
|
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 SearchComponent from "../../../components/SearchComponent";
|
||||||
|
import AlertDailog from "../../../components/AlertDailog";
|
||||||
|
import { toaster } from "../../../components/ui/toaster";
|
||||||
|
import Delete from "../../../components/ActionIcons/Delete";
|
||||||
|
import { delay } from "../../../components/Utils";
|
||||||
// import Delete from "../../../components/ActionIcons/Delete";
|
// import Delete from "../../../components/ActionIcons/Delete";
|
||||||
|
|
||||||
const tableHeadRow = [
|
const tableHeadRow = [
|
||||||
"Sr. No",
|
"Sr. No",
|
||||||
"First Name",
|
"First Name",
|
||||||
|
"Last Name",
|
||||||
"Mobile Number",
|
"Mobile Number",
|
||||||
"Gender",
|
"Gender",
|
||||||
"DOB",
|
"DOB",
|
||||||
"Type Of User",
|
"Type Of User",
|
||||||
"Language",
|
"Default Language",
|
||||||
"Activate/Deactivate",
|
"Active/Deactive",
|
||||||
"Action",
|
"Action",
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -63,10 +69,14 @@ const tableHeadRow = [
|
|||||||
|
|
||||||
const RegisterUsers = () => {
|
const RegisterUsers = () => {
|
||||||
const [currentPage, setCurrentPage] = useState(1);
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
const { data, refetch } = useGetManageUserQuery(currentPage)
|
const { data, refetch, isFetching, isError } = useGetManageUserQuery(currentPage)
|
||||||
const [localData, setLocalData] = useState<any[]>([]);
|
const [localData, setLocalData] = useState<any[]>([]);
|
||||||
const [searchTerm, setSearchTerm] = useState("");
|
const [searchTerm, setSearchTerm] = useState("");
|
||||||
const [userToggle] = useUserToggleMutation()
|
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);
|
console.log("Register Users Data", data?.data.data);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -97,9 +107,20 @@ const RegisterUsers = () => {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
await userToggle({ id: agencyId, is_active: newStatus }).unwrap();
|
await userToggle({ id: agencyId, is_active: newStatus }).unwrap();
|
||||||
|
toaster.create({
|
||||||
|
title: "Success",
|
||||||
|
description: "Status updated successfully",
|
||||||
|
type: "success",
|
||||||
|
});
|
||||||
|
await delay(500);
|
||||||
refetch()
|
refetch()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error updating privacy policy:", error);
|
console.error("Error updating privacy policy:", error);
|
||||||
|
toaster.create({
|
||||||
|
title: "Error",
|
||||||
|
description: "Someting went wrong.",
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
setLocalData((prevData) =>
|
setLocalData((prevData) =>
|
||||||
prevData.map((agency) =>
|
prevData.map((agency) =>
|
||||||
agency.id === agencyId ? { ...agency, is_active: currentStatus } : agency
|
agency.id === agencyId ? { ...agency, is_active: currentStatus } : agency
|
||||||
@@ -108,21 +129,46 @@ 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) => ({
|
const managepost = filteredData?.flatMap((agency: UserData, index: number) => ({
|
||||||
"Sr. No": (currentPage - 1) * (data?.data.per_page ?? 0) + index + 1,
|
"Sr. No": (currentPage - 1) * (data?.data.per_page ?? 0) + index + 1,
|
||||||
"First Name": agency.first_name,
|
"First Name": agency.first_name,
|
||||||
|
"Last Name": agency.last_name,
|
||||||
"Mobile Number": agency.phone_number,
|
"Mobile Number": agency.phone_number,
|
||||||
"Gender": agency.gender,
|
"Gender": agency.gender,
|
||||||
"DOB": agency.date_of_birth ? new Date(agency.date_of_birth).toLocaleDateString('en-GB').replace(/\//g, '-') : 'N/A',
|
"DOB": agency.date_of_birth ? new Date(agency.date_of_birth).toLocaleDateString('en-GB').replace(/\//g, '-') : 'N/A',
|
||||||
"Type Of User": agency.principal_type?.principal_type_title || 'N/A',
|
"Type Of User": agency.principal_type?.principal_type_title || 'N/A',
|
||||||
// "Language": agency.principle_language_links.map(lang => lang.language_name).join(', ') || 'N/A',
|
"Default Language": agency?.principle_language_linkss?.language?.language_name,
|
||||||
"Action": (
|
"Active/Deactive": agency.is_active === true ? 'Active' : 'Inactive',
|
||||||
|
"Action": (
|
||||||
<HStack justifyContent="center">
|
<HStack justifyContent="center">
|
||||||
<EditRegisterUsers
|
<EditRegisterUsers
|
||||||
// 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 }}
|
data={agency}
|
||||||
// refetch={refetch}
|
refetch={refetch}
|
||||||
/>
|
/>
|
||||||
<ViewRegisterUsers />
|
<ViewRegisterUsers data={agency} />
|
||||||
<Box>
|
<Box>
|
||||||
<Switch
|
<Switch
|
||||||
colorPalette={'teal'}
|
colorPalette={'teal'}
|
||||||
@@ -131,6 +177,24 @@ const RegisterUsers = () => {
|
|||||||
onChange={() => handleToggle(agency.id, agency.is_active ? '1' : '0')}
|
onChange={() => handleToggle(agency.id, agency.is_active ? '1' : '0')}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</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>
|
</HStack>
|
||||||
),
|
),
|
||||||
}))
|
}))
|
||||||
@@ -158,7 +222,7 @@ const RegisterUsers = () => {
|
|||||||
refetch()
|
refetch()
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<AddRegisterUsers />
|
{/* <AddRegisterUsers /> */}
|
||||||
</HStack>
|
</HStack>
|
||||||
</HStack>
|
</HStack>
|
||||||
<DataTable
|
<DataTable
|
||||||
@@ -172,6 +236,8 @@ const RegisterUsers = () => {
|
|||||||
total: data?.data.total || 0
|
total: data?.data.total || 0
|
||||||
}}
|
}}
|
||||||
onPageChange={handlePageChange}
|
onPageChange={handlePageChange}
|
||||||
|
isLoading={isFetching}
|
||||||
|
isError={isError}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
</MainFrame>
|
</MainFrame>
|
||||||
|
|||||||
@@ -9,8 +9,9 @@ import {
|
|||||||
DialogTitle,
|
DialogTitle,
|
||||||
DialogTrigger,
|
DialogTrigger,
|
||||||
} from "../../../components/ui/dialog";
|
} from "../../../components/ui/dialog";
|
||||||
|
import { UserData } from "../../../Redux/Service/manage.user";
|
||||||
|
|
||||||
function ViewRegisterUsers() {
|
function ViewRegisterUsers({ data }: { data: UserData }) {
|
||||||
return (
|
return (
|
||||||
<DialogRoot placement="center">
|
<DialogRoot placement="center">
|
||||||
<DialogTrigger asChild>
|
<DialogTrigger asChild>
|
||||||
@@ -18,13 +19,13 @@ function ViewRegisterUsers() {
|
|||||||
</DialogTrigger>
|
</DialogTrigger>
|
||||||
|
|
||||||
<DialogContent
|
<DialogContent
|
||||||
bg={"#fff"}
|
bg={"#fff"}
|
||||||
w={{ base: '90%', md: '400px' }}
|
w={{ base: '90%', md: '400px' }}
|
||||||
height={'80vh'}
|
height={'80vh'}
|
||||||
overflow={'scroll'}
|
overflow={'scroll'}
|
||||||
overflowX="hidden"
|
overflowX="hidden"
|
||||||
p={3} // Reduced padding
|
p={3} // Reduced padding
|
||||||
bgSize={'md'}
|
bgSize={'md'}
|
||||||
>
|
>
|
||||||
<DialogHeader bg="white">
|
<DialogHeader bg="white">
|
||||||
<DialogTitle alignSelf="center" color="black" fontSize="14px">
|
<DialogTitle alignSelf="center" color="black" fontSize="14px">
|
||||||
@@ -39,14 +40,24 @@ function ViewRegisterUsers() {
|
|||||||
First Name
|
First Name
|
||||||
</Field.Label>
|
</Field.Label>
|
||||||
<Input
|
<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={data?.first_name || ''}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Field.Label color="black" pt={1} fontSize="12px">
|
<Field.Label color="black" pt={1} fontSize="12px">
|
||||||
Last Name
|
Last Name
|
||||||
</Field.Label>
|
</Field.Label>
|
||||||
<Input
|
<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={data?.last_name || ''}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Field.Label color="black" pt={1} fontSize="12px">
|
<Field.Label color="black" pt={1} fontSize="12px">
|
||||||
@@ -54,6 +65,7 @@ function ViewRegisterUsers() {
|
|||||||
</Field.Label>
|
</Field.Label>
|
||||||
<Input
|
<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={data?.gender || ''}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Field.Label color="black" pt={1} fontSize="12px">
|
<Field.Label color="black" pt={1} fontSize="12px">
|
||||||
@@ -61,20 +73,41 @@ function ViewRegisterUsers() {
|
|||||||
</Field.Label>
|
</Field.Label>
|
||||||
<Input
|
<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={data?.date_of_birth ? new Date(data.date_of_birth).toLocaleDateString('en-GB').replace(/\//g, '-') : 'N/A'}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Field.Label color="black" pt={1} fontSize="12px">
|
<Field.Label color="black" pt={1} fontSize="12px">
|
||||||
OTP Verified
|
Mobile Number
|
||||||
</Field.Label>
|
</Field.Label>
|
||||||
<Input
|
<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={data?.phone_number || ''}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Field.Label color="black" pt={1} fontSize="12px">
|
<Field.Label color="black" pt={1} fontSize="12px">
|
||||||
Language
|
Type Of User
|
||||||
|
</Field.Label>
|
||||||
|
<Input
|
||||||
|
bgColor="#EEEEEE"
|
||||||
|
color="black"
|
||||||
|
border="none"
|
||||||
|
pl={1}
|
||||||
|
fontSize="12px"
|
||||||
|
height="30px"
|
||||||
|
value={data?.principal_type?.principal_type_title || 'N/A'}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Field.Label color="black" pt={1} fontSize="12px">
|
||||||
|
Default Language
|
||||||
</Field.Label>
|
</Field.Label>
|
||||||
<Input
|
<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={data?.principle_language_linkss?.language?.language_name || 'N/A'}
|
||||||
/>
|
/>
|
||||||
</Field.Root>
|
</Field.Root>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|||||||
@@ -2,12 +2,15 @@ import { Box, HStack, Text } from "@chakra-ui/react";
|
|||||||
import MainFrame from "../../../components/MainFrame"
|
import MainFrame from "../../../components/MainFrame"
|
||||||
import DataTable from "../../../components/DataTable";
|
import DataTable from "../../../components/DataTable";
|
||||||
import { Switch } from "../../../components/ui/switch";
|
import { Switch } from "../../../components/ui/switch";
|
||||||
// import EditAgencyMaster from "./EditAgencyMaster";
|
import EditAgencyMaster from "./EditAgencyMaster";
|
||||||
// import ViewAgencyAddModel from "./ViewAgencyAddModel";
|
// import ViewAgencyAddModel from "./ViewAgencyAddModel";
|
||||||
import ViewAgencyMaster from "./ViewAgencyMaster";
|
import ViewAgencyMaster from "./ViewAgencyMaster";
|
||||||
import { useAgencyMasterToggleMutation, useGetAgencyMasterQuery } from "../../../Redux/Service/agency.master.module.service";
|
import { useAgencyMasterToggleMutation, useGetAgencyMasterQuery } from "../../../Redux/Service/agency.master.module.service";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import SearchComponent from "../../../components/SearchComponent";
|
import SearchComponent from "../../../components/SearchComponent";
|
||||||
|
import { useDebounce } from "../../../components/Hooks/useDebounce";
|
||||||
|
import { toaster, Toaster } from "../../../components/ui/toaster";
|
||||||
|
import { delay } from "../../../components/Utils";
|
||||||
|
|
||||||
// table data
|
// table data
|
||||||
|
|
||||||
@@ -20,6 +23,7 @@ const tableHeadRow = [
|
|||||||
"Registered Office Address",
|
"Registered Office Address",
|
||||||
"Website/Domain",
|
"Website/Domain",
|
||||||
"GST no.",
|
"GST no.",
|
||||||
|
"Agency Status",
|
||||||
"Action"
|
"Action"
|
||||||
|
|
||||||
];
|
];
|
||||||
@@ -48,10 +52,12 @@ const tableHeadRow = [
|
|||||||
|
|
||||||
const AgencyMaster = () => {
|
const AgencyMaster = () => {
|
||||||
const [currentPage, setCurrentPage] = useState(1);
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
const { data, refetch } = useGetAgencyMasterQuery(currentPage)
|
|
||||||
const [agencyMasterToggle] = useAgencyMasterToggleMutation()
|
const [agencyMasterToggle] = useAgencyMasterToggleMutation()
|
||||||
const [localData, setLocalData] = useState<any[]>([]);
|
const [localData, setLocalData] = useState<any[]>([]);
|
||||||
const [searchTerm, setSearchTerm] = useState("");
|
const [searchTerm, setSearchTerm] = useState("");
|
||||||
|
const debouncedSearchTerm = useDebounce(searchTerm, 500);
|
||||||
|
const queryArgs = debouncedSearchTerm ? { page: currentPage, search: debouncedSearchTerm } : { page: currentPage };
|
||||||
|
const { data, refetch, isError, isFetching } = useGetAgencyMasterQuery(queryArgs)
|
||||||
|
|
||||||
const handleToggle = async (agencyId: string, currentStatus: number) => {
|
const handleToggle = async (agencyId: string, currentStatus: number) => {
|
||||||
const newStatus = currentStatus ? 0 : 1;
|
const newStatus = currentStatus ? 0 : 1;
|
||||||
@@ -62,6 +68,12 @@ const AgencyMaster = () => {
|
|||||||
);
|
);
|
||||||
try {
|
try {
|
||||||
await agencyMasterToggle({ id: agencyId, is_active: newStatus }).unwrap();
|
await agencyMasterToggle({ id: agencyId, is_active: newStatus }).unwrap();
|
||||||
|
toaster.create({
|
||||||
|
title: "Success",
|
||||||
|
description: "Status updated successfully",
|
||||||
|
type: "success",
|
||||||
|
});
|
||||||
|
await delay(500);
|
||||||
refetch()
|
refetch()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error updating privacy policy:", error);
|
console.error("Error updating privacy policy:", error);
|
||||||
@@ -70,6 +82,11 @@ const AgencyMaster = () => {
|
|||||||
agency.id === agencyId ? { ...agency, is_active: currentStatus } : agency
|
agency.id === agencyId ? { ...agency, is_active: currentStatus } : agency
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
toaster.create({
|
||||||
|
title: "Error",
|
||||||
|
description: "Please try again later",
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -77,36 +94,55 @@ const AgencyMaster = () => {
|
|||||||
setCurrentPage(page);
|
setCurrentPage(page);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleSearchChange = (value: string) => {
|
||||||
|
setSearchTerm(value);
|
||||||
|
setCurrentPage(1);
|
||||||
|
};
|
||||||
|
|
||||||
const filteredData = localData?.filter((agency) =>
|
const filteredData = localData?.filter((agency) =>
|
||||||
agency?.name.toLowerCase().includes(searchTerm.toLowerCase())
|
agency?.name.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
||||||
|
agency?.rc_number.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
||||||
|
agency?.state.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
||||||
|
agency?.registered_office.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
||||||
|
agency?.domain_name.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
||||||
|
agency?.gst_number.toLowerCase().includes(searchTerm.toLowerCase())
|
||||||
);
|
);
|
||||||
|
|
||||||
const managepost = filteredData?.map((agency: any, index: number) => ({
|
// const activeCount = filteredData?.filter((a: any) => a.is_active === 1).length ?? 0;
|
||||||
'id': agency.id,
|
|
||||||
"Sr. No": (currentPage - 1) * (data?.data.per_page ?? 0) + index + 1,
|
const managepost = filteredData?.map((agency: any, index: number) => {
|
||||||
"Agency Name": agency.name,
|
// const isOnlyActive = activeCount === 1 && agency.is_active === 1;
|
||||||
"RC no.": agency.rc_number,
|
|
||||||
"State": agency.state,
|
return {
|
||||||
"RC Status": agency.rc_status,
|
id: agency.id,
|
||||||
"Registered Office Address": agency.registered_office,
|
"Sr. No": (currentPage - 1) * (data?.data.per_page ?? 0) + index + 1,
|
||||||
"Website/Domain": agency.domain_name,
|
"Agency Name": agency.name,
|
||||||
"GST no.": agency.gst_number,
|
"RC no.": agency.rc_number,
|
||||||
"is_active": agency.is_active,
|
"State": agency.state,
|
||||||
"Action": (
|
"RC Status": agency.rc_status,
|
||||||
<HStack justifyContent="center">
|
"Registered Office Address": agency.registered_office,
|
||||||
<ViewAgencyMaster agency={localData} id={agency.id} />
|
"Website/Domain": agency.domain_name,
|
||||||
{/* <EditAgencyMaster editData={{ id: agency.id, name: agency.name, domain_name: agency.domain_name, gst_number: agency.gst_number, rc_number: agency.rc_number, rc_status: agency.rc_status, registered_office: agency.registered_office, state: agency.state }} refetch={refetch} /> */}
|
"GST no.": agency.gst_number,
|
||||||
<Box>
|
"Agency Status": agency.is_domain_verified ? "Verified" : "Unverified",
|
||||||
<Switch
|
"is_active": agency.is_active,
|
||||||
colorPalette={"teal"}
|
Action: (
|
||||||
size={"xs"}
|
<HStack justifyContent="center">
|
||||||
onChange={() => handleToggle(agency.id.toString(), Number(agency.is_active))}
|
<ViewAgencyMaster agency={localData} id={agency.id} />
|
||||||
checked={Boolean(Number(agency.is_active))}
|
<EditAgencyMaster editData={agency} refetch={refetch} />
|
||||||
/>
|
<Box>
|
||||||
</Box>
|
<Switch
|
||||||
</HStack>
|
colorPalette={"teal"}
|
||||||
),
|
size={"xs"}
|
||||||
}));
|
onChange={() => handleToggle(agency.id.toString(), Number(agency.is_active))}
|
||||||
|
checked={Boolean(Number(agency.is_active))}
|
||||||
|
// disabled={isOnlyActive}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
</HStack>
|
||||||
|
),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (data?.data?.data) {
|
if (data?.data?.data) {
|
||||||
@@ -158,7 +194,7 @@ const AgencyMaster = () => {
|
|||||||
</InputGroup> */}
|
</InputGroup> */}
|
||||||
<SearchComponent
|
<SearchComponent
|
||||||
value={searchTerm}
|
value={searchTerm}
|
||||||
onChange={setSearchTerm}
|
onChange={handleSearchChange}
|
||||||
/>
|
/>
|
||||||
{/* <ViewAgencyAddModel refetch={refetch} /> */}
|
{/* <ViewAgencyAddModel refetch={refetch} /> */}
|
||||||
</HStack>
|
</HStack>
|
||||||
@@ -174,8 +210,11 @@ const AgencyMaster = () => {
|
|||||||
total: data?.data.total || 0
|
total: data?.data.total || 0
|
||||||
}}
|
}}
|
||||||
onPageChange={handlePageChange}
|
onPageChange={handlePageChange}
|
||||||
|
isLoading={isFetching}
|
||||||
|
isError={isError}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
<Toaster />
|
||||||
</MainFrame>
|
</MainFrame>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,34 +15,47 @@ import { useEffect, useState } from "react";
|
|||||||
import { useUpdateAgencyMasterMutation } from "../../../Redux/Service/agency.master.module.service";
|
import { useUpdateAgencyMasterMutation } from "../../../Redux/Service/agency.master.module.service";
|
||||||
import { Toaster, toaster } from "../../../components/ui/toaster";
|
import { Toaster, toaster } from "../../../components/ui/toaster";
|
||||||
|
|
||||||
interface Organization {
|
// interface Organization {
|
||||||
id: number;
|
// id: number;
|
||||||
raid?: string;
|
// raid?: string;
|
||||||
|
// name: string;
|
||||||
|
// auth_signatory?: string;
|
||||||
|
// state: string;
|
||||||
|
// district?: string;
|
||||||
|
// rc_number: number;
|
||||||
|
// contact_details?: string;
|
||||||
|
// registered_office: string;
|
||||||
|
// branch_office?: string;
|
||||||
|
// registered_email?: string;
|
||||||
|
// other_email?: string;
|
||||||
|
// registered_contact?: string;
|
||||||
|
// website?: string;
|
||||||
|
// domain_name: string;
|
||||||
|
// staff_domain_name?: string;
|
||||||
|
// gst_number: string;
|
||||||
|
// rc_status?: "Active" | "Inactive"; // Assuming it's a status with limited values
|
||||||
|
// }
|
||||||
|
|
||||||
|
type AgencyFormData = {
|
||||||
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
auth_signatory?: string;
|
|
||||||
state: string;
|
state: string;
|
||||||
district?: string;
|
rc_number: string;
|
||||||
rc_number: number;
|
|
||||||
contact_details?: string;
|
|
||||||
registered_office: string;
|
registered_office: string;
|
||||||
branch_office?: string;
|
|
||||||
registered_email?: string;
|
|
||||||
other_email?: string;
|
|
||||||
registered_contact?: string;
|
|
||||||
website?: string;
|
|
||||||
domain_name: string;
|
domain_name: string;
|
||||||
staff_domain_name?: string;
|
|
||||||
gst_number: string;
|
gst_number: string;
|
||||||
rc_status?: "Active" | "Inactive"; // Assuming it's a status with limited values
|
};
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function EditAgencyMaster({ editData, refetch }: { editData: Organization, refetch: VoidFunction }) {
|
|
||||||
|
function EditAgencyMaster<T extends AgencyFormData>({ editData, refetch }: { editData: T, refetch: VoidFunction }) {
|
||||||
|
|
||||||
const [formData, setFormData] = useState(editData);
|
const [formData, setFormData] = useState(editData);
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
const [updateAgencyMaster] = useUpdateAgencyMasterMutation()
|
const [updateAgencyMaster, { isLoading }] = useUpdateAgencyMasterMutation()
|
||||||
|
|
||||||
|
console.log("Edit Data", editData);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setFormData(editData);
|
setFormData(editData);
|
||||||
}, [editData]);
|
}, [editData]);
|
||||||
@@ -104,11 +117,11 @@ function EditAgencyMaster({ editData, refetch }: { editData: Organization, refet
|
|||||||
type: "error",
|
type: "error",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error: any) {
|
||||||
console.error("Error updating template:", error);
|
console.error("Error updating template:", error);
|
||||||
toaster.create({
|
toaster.create({
|
||||||
title: "Error",
|
title: "Error",
|
||||||
description: "Something went wrong.",
|
description: `${error.data.message || "Failed to update"}`,
|
||||||
type: "error",
|
type: "error",
|
||||||
});
|
});
|
||||||
// alert("Failed to update template");
|
// alert("Failed to update template");
|
||||||
@@ -254,6 +267,7 @@ function EditAgencyMaster({ editData, refetch }: { editData: Organization, refet
|
|||||||
fontSize="12px"
|
fontSize="12px"
|
||||||
height="30px"
|
height="30px"
|
||||||
onClick={handleSubmit}
|
onClick={handleSubmit}
|
||||||
|
disabled={isLoading}
|
||||||
>
|
>
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ function ViewAgencyAddModel({ refetch }: { refetch: VoidFunction }) {
|
|||||||
console.error("Error updating template:", error);
|
console.error("Error updating template:", error);
|
||||||
toaster.create({
|
toaster.create({
|
||||||
title: "Error",
|
title: "Error",
|
||||||
description: "Something went wrong",
|
description: "Please try again later",
|
||||||
type: "error",
|
type: "error",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,9 @@ import EditCountryModel from "./EditCountryModel";
|
|||||||
import { CountryData, useCountryToggleMutation, useGetCountryMasterQuery } from "../../../Redux/Service/country.master";
|
import { CountryData, useCountryToggleMutation, useGetCountryMasterQuery } from "../../../Redux/Service/country.master";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import SearchComponent from "../../../components/SearchComponent";
|
import SearchComponent from "../../../components/SearchComponent";
|
||||||
|
import { useDebounce } from "../../../components/Hooks/useDebounce";
|
||||||
|
import { toaster, Toaster } from "../../../components/ui/toaster";
|
||||||
|
import { delay } from "../../../components/Utils";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -36,10 +39,13 @@ const tableHeadRow = [
|
|||||||
|
|
||||||
const Country = () => {
|
const Country = () => {
|
||||||
const [currentPage, setCurrentPage] = useState(1);
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
const { data, refetch } = useGetCountryMasterQuery(currentPage)
|
// const { data, refetch } = useGetCountryMasterQuery(currentPage)
|
||||||
const [countryToggle] = useCountryToggleMutation()
|
const [countryToggle] = useCountryToggleMutation()
|
||||||
const [localData, setLocalData] = useState<any[]>([]);
|
const [localData, setLocalData] = useState<any[]>([]);
|
||||||
const [searchTerm, setSearchTerm] = useState("");
|
const [searchTerm, setSearchTerm] = useState("");
|
||||||
|
const debouncedSearchTerm = useDebounce(searchTerm, 500);
|
||||||
|
const queryArgs = debouncedSearchTerm ? { page: currentPage, search: debouncedSearchTerm } : { page: currentPage };
|
||||||
|
const { data, refetch, isError, isFetching } = useGetCountryMasterQuery(queryArgs);
|
||||||
console.log("Country Data", data?.data.data)
|
console.log("Country Data", data?.data.data)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -52,6 +58,11 @@ const Country = () => {
|
|||||||
setCurrentPage(page);
|
setCurrentPage(page);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleSearchChange = (value: string) => {
|
||||||
|
setSearchTerm(value);
|
||||||
|
setCurrentPage(1);
|
||||||
|
};
|
||||||
|
|
||||||
const filteredData = localData?.filter((agency) => {
|
const filteredData = localData?.filter((agency) => {
|
||||||
const searchLower = searchTerm.toLowerCase();
|
const searchLower = searchTerm.toLowerCase();
|
||||||
const countryName = agency.en_name?.toLowerCase().includes(searchLower);
|
const countryName = agency.en_name?.toLowerCase().includes(searchLower);
|
||||||
@@ -70,9 +81,20 @@ const Country = () => {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
await countryToggle({ id: agencyId, is_active: newStatus }).unwrap();
|
await countryToggle({ id: agencyId, is_active: newStatus }).unwrap();
|
||||||
|
toaster.create({
|
||||||
|
title: "Success",
|
||||||
|
description: "Status updated successfully",
|
||||||
|
type: "success",
|
||||||
|
});
|
||||||
|
await delay(500);
|
||||||
refetch()
|
refetch()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error updating privacy policy:", error);
|
console.error("Error updating privacy policy:", error);
|
||||||
|
toaster.create({
|
||||||
|
title: "Error",
|
||||||
|
description: "Please try again later.",
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
setLocalData((prevData) =>
|
setLocalData((prevData) =>
|
||||||
prevData.map((agency) =>
|
prevData.map((agency) =>
|
||||||
agency.id === agencyId ? { ...agency, is_active: currentStatus } : agency
|
agency.id === agencyId ? { ...agency, is_active: currentStatus } : agency
|
||||||
@@ -99,6 +121,7 @@ const Country = () => {
|
|||||||
),
|
),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
||||||
<MainFrame>
|
<MainFrame>
|
||||||
@@ -137,14 +160,15 @@ const Country = () => {
|
|||||||
</InputGroup> */}
|
</InputGroup> */}
|
||||||
<SearchComponent
|
<SearchComponent
|
||||||
value={searchTerm}
|
value={searchTerm}
|
||||||
onChange={(value) => {
|
// onChange={(value) => {
|
||||||
setSearchTerm(value);
|
// setSearchTerm(value);
|
||||||
// setCurrentPage(1);
|
// // setCurrentPage(1);
|
||||||
refetch()
|
// refetch()
|
||||||
}}
|
// }}
|
||||||
|
onChange={handleSearchChange}
|
||||||
/>
|
/>
|
||||||
{/* <Button bgColor={'#EEEEEE'} pl={3} pr={3}><IoMdAdd /> <Text>Add</Text></Button> */}
|
{/* <Button bgColor={'#EEEEEE'} pl={3} pr={3}><IoMdAdd /> <Text>Add</Text></Button> */}
|
||||||
<CountryAddModel />
|
<CountryAddModel refetch={refetch} />
|
||||||
</HStack>
|
</HStack>
|
||||||
</HStack>
|
</HStack>
|
||||||
<DataTable
|
<DataTable
|
||||||
@@ -158,8 +182,11 @@ const Country = () => {
|
|||||||
total: data?.data.total || 0
|
total: data?.data.total || 0
|
||||||
}}
|
}}
|
||||||
onPageChange={handlePageChange}
|
onPageChange={handlePageChange}
|
||||||
|
isLoading={isFetching}
|
||||||
|
isError={isError}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
<Toaster />
|
||||||
</MainFrame>
|
</MainFrame>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,12 +2,12 @@ import { DialogBody, DialogCloseTrigger, DialogContent, DialogFooter, DialogHead
|
|||||||
import { Field, Input, Stack, Text } from "@chakra-ui/react"
|
import { Field, Input, Stack, Text } from "@chakra-ui/react"
|
||||||
import { IoMdAdd } from "react-icons/io"
|
import { IoMdAdd } from "react-icons/io"
|
||||||
import { Button } from "../../../components/ui/button"
|
import { Button } from "../../../components/ui/button"
|
||||||
import { useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { PostCountry, useCreateCountryPostMutation } from "../../../Redux/Service/country.master";
|
import { PostCountry, useCreateCountryPostMutation } from "../../../Redux/Service/country.master";
|
||||||
import { Toaster, toaster } from "../../../components/ui/toaster";
|
import { Toaster, toaster } from "../../../components/ui/toaster";
|
||||||
|
|
||||||
function CountryAddModel() {
|
function CountryAddModel({refetch}: { refetch: VoidFunction }) {
|
||||||
const [createCountryPost] = useCreateCountryPostMutation()
|
const [createCountryPost, { isLoading }] = useCreateCountryPostMutation()
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
const [countryName, setCountryName] = useState<PostCountry>({
|
const [countryName, setCountryName] = useState<PostCountry>({
|
||||||
en_name: '',
|
en_name: '',
|
||||||
@@ -19,12 +19,26 @@ function CountryAddModel() {
|
|||||||
currency_symbol: '',
|
currency_symbol: '',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!isOpen) {
|
||||||
|
setCountryName({
|
||||||
|
en_name: '',
|
||||||
|
country_code: '',
|
||||||
|
phonecode: '',
|
||||||
|
capital: '',
|
||||||
|
currency: '',
|
||||||
|
currency_name: '',
|
||||||
|
currency_symbol: '',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [isOpen]);
|
||||||
|
|
||||||
const handleOpenModal = () => {
|
const handleOpenModal = () => {
|
||||||
setIsOpen(true); // Open modal when clicking "Add"
|
setIsOpen(true); // Open modal when clicking "Add"
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSubmit = async () => {
|
const handleSubmit = async () => {
|
||||||
if (countryName.en_name === "") {
|
if (countryName.en_name === "" || countryName.country_code === "" || countryName.phonecode === "" || countryName.capital === "" || countryName.currency === "" || countryName.currency_name === "" || countryName.currency_symbol === "") {
|
||||||
toaster.create({
|
toaster.create({
|
||||||
title: "Error",
|
title: "Error",
|
||||||
description: "Input fields cannot be empty",
|
description: "Input fields cannot be empty",
|
||||||
@@ -52,6 +66,7 @@ function CountryAddModel() {
|
|||||||
type: "success",
|
type: "success",
|
||||||
});
|
});
|
||||||
setIsOpen(false);
|
setIsOpen(false);
|
||||||
|
refetch();
|
||||||
} else {
|
} else {
|
||||||
toaster.create({
|
toaster.create({
|
||||||
title: "Error",
|
title: "Error",
|
||||||
@@ -98,7 +113,7 @@ function CountryAddModel() {
|
|||||||
<Field.Root>
|
<Field.Root>
|
||||||
<Field.Label color="black" pt={1} fontSize="12px">Country</Field.Label>
|
<Field.Label color="black" pt={1} fontSize="12px">Country</Field.Label>
|
||||||
<Input
|
<Input
|
||||||
placeholder=""
|
placeholder="Enter Country Name"
|
||||||
bgColor="#EEEEEE"
|
bgColor="#EEEEEE"
|
||||||
color="black"
|
color="black"
|
||||||
border="none"
|
border="none"
|
||||||
@@ -111,7 +126,7 @@ function CountryAddModel() {
|
|||||||
|
|
||||||
<Field.Label color="black" pt={1} fontSize="12px">Country Code</Field.Label>
|
<Field.Label color="black" pt={1} fontSize="12px">Country Code</Field.Label>
|
||||||
<Input
|
<Input
|
||||||
placeholder=""
|
placeholder="Please enter country code ex: IN, US"
|
||||||
bgColor="#EEEEEE"
|
bgColor="#EEEEEE"
|
||||||
color="black"
|
color="black"
|
||||||
border="none"
|
border="none"
|
||||||
@@ -124,7 +139,7 @@ function CountryAddModel() {
|
|||||||
|
|
||||||
<Field.Label color="black" pt={1} fontSize="12px">Phone Code</Field.Label>
|
<Field.Label color="black" pt={1} fontSize="12px">Phone Code</Field.Label>
|
||||||
<Input
|
<Input
|
||||||
placeholder=""
|
placeholder="Please enter phone code ex: +91, +1"
|
||||||
bgColor="#EEEEEE"
|
bgColor="#EEEEEE"
|
||||||
color="black"
|
color="black"
|
||||||
border="none"
|
border="none"
|
||||||
@@ -136,7 +151,7 @@ function CountryAddModel() {
|
|||||||
/>
|
/>
|
||||||
<Field.Label color="black" pt={1} fontSize="12px">Capital</Field.Label>
|
<Field.Label color="black" pt={1} fontSize="12px">Capital</Field.Label>
|
||||||
<Input
|
<Input
|
||||||
placeholder=""
|
placeholder="Enter Capital City"
|
||||||
bgColor="#EEEEEE"
|
bgColor="#EEEEEE"
|
||||||
color="black"
|
color="black"
|
||||||
border="none"
|
border="none"
|
||||||
@@ -148,7 +163,7 @@ function CountryAddModel() {
|
|||||||
/>
|
/>
|
||||||
<Field.Label color="black" pt={1} fontSize="12px">Currency</Field.Label>
|
<Field.Label color="black" pt={1} fontSize="12px">Currency</Field.Label>
|
||||||
<Input
|
<Input
|
||||||
placeholder=""
|
placeholder="Enter Currency"
|
||||||
bgColor="#EEEEEE"
|
bgColor="#EEEEEE"
|
||||||
color="black"
|
color="black"
|
||||||
border="none"
|
border="none"
|
||||||
@@ -160,7 +175,7 @@ function CountryAddModel() {
|
|||||||
/>
|
/>
|
||||||
<Field.Label color="black" pt={1} fontSize="12px">Currency name</Field.Label>
|
<Field.Label color="black" pt={1} fontSize="12px">Currency name</Field.Label>
|
||||||
<Input
|
<Input
|
||||||
placeholder=""
|
placeholder="Enter Currency Name"
|
||||||
bgColor="#EEEEEE"
|
bgColor="#EEEEEE"
|
||||||
color="black"
|
color="black"
|
||||||
border="none"
|
border="none"
|
||||||
@@ -172,7 +187,7 @@ function CountryAddModel() {
|
|||||||
/>
|
/>
|
||||||
<Field.Label color="black" pt={1} fontSize="12px">Currency Symbol</Field.Label>
|
<Field.Label color="black" pt={1} fontSize="12px">Currency Symbol</Field.Label>
|
||||||
<Input
|
<Input
|
||||||
placeholder=""
|
placeholder="Enter Currency Symbol"
|
||||||
bgColor="#EEEEEE"
|
bgColor="#EEEEEE"
|
||||||
color="black"
|
color="black"
|
||||||
border="none"
|
border="none"
|
||||||
@@ -187,7 +202,7 @@ function CountryAddModel() {
|
|||||||
|
|
||||||
</DialogBody>
|
</DialogBody>
|
||||||
<DialogFooter display="flex" justifyContent="center" pt={"2"}>
|
<DialogFooter display="flex" justifyContent="center" pt={"2"}>
|
||||||
<Button w="100%" bg="#02A0A0" color={"#fff"} onClick={handleSubmit}>
|
<Button w="100%" bg="#02A0A0" color={"#fff"} onClick={handleSubmit} disabled={isLoading}>
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
</DialogFooter>
|
</DialogFooter>
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ export interface EditCountryModelProps {
|
|||||||
|
|
||||||
|
|
||||||
function EditCountryModel({ rowData, refetch }: { rowData: EditCountryModelProps, refetch: VoidFunction }) {
|
function EditCountryModel({ rowData, refetch }: { rowData: EditCountryModelProps, refetch: VoidFunction }) {
|
||||||
const [updateCountry] = useUpdateCountryMutation()
|
const [updateCountry, { isLoading }] = useUpdateCountryMutation()
|
||||||
const [editData, setEditData] = useState(rowData)
|
const [editData, setEditData] = useState(rowData)
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
|
|
||||||
@@ -145,7 +145,7 @@ function EditCountryModel({ rowData, refetch }: { rowData: EditCountryModelProps
|
|||||||
</Stack>
|
</Stack>
|
||||||
</DialogBody>
|
</DialogBody>
|
||||||
<DialogFooter display="flex" justifyContent="center" pt={"2"}>
|
<DialogFooter display="flex" justifyContent="center" pt={"2"}>
|
||||||
<Button w="100%" bg="#02A0A0" color={"#fff"} onClick={handleSubmit}>
|
<Button w="100%" bg="#02A0A0" color={"#fff"} onClick={handleSubmit} disabled={isLoading}>
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
</DialogFooter>
|
</DialogFooter>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import { useCreateDepartmentPostMutation, useGetDepartmentMasterDropDownQuery }
|
|||||||
function AddDepartmentMaster({ refetch }: { refetch: VoidFunction }) {
|
function AddDepartmentMaster({ refetch }: { refetch: VoidFunction }) {
|
||||||
const [jobType, setJobType] = useState("");
|
const [jobType, setJobType] = useState("");
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
const [createDepartmentPost] = useCreateDepartmentPostMutation()
|
const [createDepartmentPost, { isLoading }] = useCreateDepartmentPostMutation()
|
||||||
const { data } = useGetDepartmentMasterDropDownQuery()
|
const { data } = useGetDepartmentMasterDropDownQuery()
|
||||||
const [selectdDep, setSelectdDep] = useState<any>({
|
const [selectdDep, setSelectdDep] = useState<any>({
|
||||||
id: '',
|
id: '',
|
||||||
@@ -140,7 +140,7 @@ function AddDepartmentMaster({ refetch }: { refetch: VoidFunction }) {
|
|||||||
|
|
||||||
</DialogBody>
|
</DialogBody>
|
||||||
<DialogFooter display="flex" justifyContent="center" pt={"2"}>
|
<DialogFooter display="flex" justifyContent="center" pt={"2"}>
|
||||||
<Button w="100%" bg="#02A0A0" color={"#fff"} onClick={handleSubmit}>
|
<Button w="100%" bg="#02A0A0" color={"#fff"} onClick={handleSubmit} disabled={isLoading}>
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
</DialogFooter>
|
</DialogFooter>
|
||||||
|
|||||||
@@ -9,6 +9,9 @@ import SearchComponent from "../../../components/SearchComponent";
|
|||||||
import { useDepartmentToggleMutation, useGetDepartmentMasterQuery } from "../../../Redux/Service/department.master";
|
import { useDepartmentToggleMutation, useGetDepartmentMasterQuery } from "../../../Redux/Service/department.master";
|
||||||
import AddDepartmentMaster from "./AddDepartmentMaster";
|
import AddDepartmentMaster from "./AddDepartmentMaster";
|
||||||
import EditDepartmentMaster from "./EditDepartmentMaster";
|
import EditDepartmentMaster from "./EditDepartmentMaster";
|
||||||
|
import { useDebounce } from "../../../components/Hooks/useDebounce";
|
||||||
|
import { Toaster, toaster } from "../../../components/ui/toaster";
|
||||||
|
import { delay } from "../../../components/Utils";
|
||||||
|
|
||||||
|
|
||||||
// table data
|
// table data
|
||||||
@@ -24,12 +27,14 @@ const tableHeadRow = [
|
|||||||
|
|
||||||
const DepartmentMasterList = () => {
|
const DepartmentMasterList = () => {
|
||||||
const [currentPage, setCurrentPage] = useState(1);
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
const { data, refetch } = useGetDepartmentMasterQuery(currentPage)
|
|
||||||
const [departmentToggle] = useDepartmentToggleMutation()
|
const [departmentToggle] = useDepartmentToggleMutation()
|
||||||
const [localData, setLocalData] = useState<any[]>([]);
|
const [localData, setLocalData] = useState<any[]>([]);
|
||||||
const [searchTerm, setSearchTerm] = useState("");
|
const [searchTerm, setSearchTerm] = useState("");
|
||||||
|
const debouncedSearchTerm = useDebounce(searchTerm, 500);
|
||||||
|
const queryArgs = debouncedSearchTerm ? { page: currentPage, search: debouncedSearchTerm } : { page: currentPage };
|
||||||
|
const { data, refetch, isError, isFetching } = useGetDepartmentMasterQuery(queryArgs)
|
||||||
|
|
||||||
console.log("Department Data", data?.data.data)
|
console.log("Department Data", data?.data.data)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (data?.data?.data) {
|
if (data?.data?.data) {
|
||||||
@@ -37,6 +42,11 @@ const DepartmentMasterList = () => {
|
|||||||
}
|
}
|
||||||
}, [data]);
|
}, [data]);
|
||||||
|
|
||||||
|
const handleSearchChange = (value: string) => {
|
||||||
|
setSearchTerm(value);
|
||||||
|
setCurrentPage(1);
|
||||||
|
};
|
||||||
|
|
||||||
const handlePageChange = (page: number) => {
|
const handlePageChange = (page: number) => {
|
||||||
setCurrentPage(page);
|
setCurrentPage(page);
|
||||||
};
|
};
|
||||||
@@ -50,9 +60,20 @@ const DepartmentMasterList = () => {
|
|||||||
);
|
);
|
||||||
try {
|
try {
|
||||||
await departmentToggle({ id: agencyId, is_active: newStatus }).unwrap();
|
await departmentToggle({ id: agencyId, is_active: newStatus }).unwrap();
|
||||||
|
toaster.create({
|
||||||
|
title: "Success",
|
||||||
|
description: "Status updated successfully",
|
||||||
|
type: "success",
|
||||||
|
});
|
||||||
|
await delay(500);
|
||||||
refetch()
|
refetch()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error updating privacy policy:", error);
|
console.error("Error updating privacy policy:", error);
|
||||||
|
toaster.create({
|
||||||
|
title: "Error",
|
||||||
|
description: "Someting went wrong.",
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
setLocalData((prevData) =>
|
setLocalData((prevData) =>
|
||||||
prevData.map((agency) =>
|
prevData.map((agency) =>
|
||||||
agency.id === agencyId ? { ...agency, is_active: currentStatus } : agency
|
agency.id === agencyId ? { ...agency, is_active: currentStatus } : agency
|
||||||
@@ -112,11 +133,7 @@ const DepartmentMasterList = () => {
|
|||||||
<HStack >
|
<HStack >
|
||||||
<SearchComponent
|
<SearchComponent
|
||||||
value={searchTerm}
|
value={searchTerm}
|
||||||
onChange={(value) => {
|
onChange={handleSearchChange}
|
||||||
setSearchTerm(value);
|
|
||||||
// setCurrentPage(1);
|
|
||||||
refetch()
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
{/* <Button bgColor={'#EEEEEE'} pl={3} pr={3}><IoMdAdd /> <Text>Add</Text></Button> */}
|
{/* <Button bgColor={'#EEEEEE'} pl={3} pr={3}><IoMdAdd /> <Text>Add</Text></Button> */}
|
||||||
{/* <ViewAgencyAddModel /> */}
|
{/* <ViewAgencyAddModel /> */}
|
||||||
@@ -134,8 +151,11 @@ const DepartmentMasterList = () => {
|
|||||||
total: data?.data.total || 0
|
total: data?.data.total || 0
|
||||||
}}
|
}}
|
||||||
onPageChange={handlePageChange}
|
onPageChange={handlePageChange}
|
||||||
|
isLoading={isFetching}
|
||||||
|
isError={isError}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
<Toaster />
|
||||||
</MainFrame>
|
</MainFrame>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import { useGetDepartmentMasterDropDownQuery, useUpdateDepartmentMutation } from
|
|||||||
|
|
||||||
function EditDepartmentMaster({ localData, refetch }: { localData: any, refetch: VoidFunction }) {
|
function EditDepartmentMaster({ localData, refetch }: { localData: any, refetch: VoidFunction }) {
|
||||||
const [jobtype, setJobType] = useState("");
|
const [jobtype, setJobType] = useState("");
|
||||||
const [updateDepartment] = useUpdateDepartmentMutation()
|
const [updateDepartment, { isLoading }] = useUpdateDepartmentMutation()
|
||||||
const { data } = useGetDepartmentMasterDropDownQuery()
|
const { data } = useGetDepartmentMasterDropDownQuery()
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
const [selectdDep, setSelectdDep] = useState<any>({
|
const [selectdDep, setSelectdDep] = useState<any>({
|
||||||
@@ -145,7 +145,7 @@ function EditDepartmentMaster({ localData, refetch }: { localData: any, refetch:
|
|||||||
</Stack>
|
</Stack>
|
||||||
</DialogBody>
|
</DialogBody>
|
||||||
<DialogFooter display="flex" justifyContent="center" pt={"2"}>
|
<DialogFooter display="flex" justifyContent="center" pt={"2"}>
|
||||||
<Button w="100%" bg="#02A0A0" color={"#fff"} onClick={handleSubmit}>
|
<Button w="100%" bg="#02A0A0" color={"#fff"} onClick={handleSubmit} disabled={isLoading}>
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
</DialogFooter>
|
</DialogFooter>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import { useCreateIndustryMasterPostMutation } from "../../../Redux/Service/indu
|
|||||||
function AddIndustryMaster({ refetch }: { refetch: VoidFunction }) {
|
function AddIndustryMaster({ refetch }: { refetch: VoidFunction }) {
|
||||||
const [jobType, setJobType] = useState("");
|
const [jobType, setJobType] = useState("");
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
const [createIndustryMasterPost] = useCreateIndustryMasterPostMutation()
|
const [createIndustryMasterPost, { isLoading }] = useCreateIndustryMasterPostMutation()
|
||||||
|
|
||||||
const handleOpenModal = () => {
|
const handleOpenModal = () => {
|
||||||
setIsOpen(true); // Open modal when clicking "Add"
|
setIsOpen(true); // Open modal when clicking "Add"
|
||||||
@@ -88,7 +88,7 @@ function AddIndustryMaster({ refetch }: { refetch: VoidFunction }) {
|
|||||||
|
|
||||||
</DialogBody>
|
</DialogBody>
|
||||||
<DialogFooter display="flex" justifyContent="center" pt={"2"}>
|
<DialogFooter display="flex" justifyContent="center" pt={"2"}>
|
||||||
<Button w="100%" bg="#02A0A0" color={"#fff"} onClick={handleSubmit}>
|
<Button w="100%" bg="#02A0A0" color={"#fff"} onClick={handleSubmit} disabled={isLoading}>
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
</DialogFooter>
|
</DialogFooter>
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import { useUpdateIndustryMasterMutation } from "../../../Redux/Service/industry
|
|||||||
|
|
||||||
function EditIndustryMaster({ id, localData, refetch, categories }: { id: number, localData: any, refetch: VoidFunction, categories: any }) {
|
function EditIndustryMaster({ id, localData, refetch, categories }: { id: number, localData: any, refetch: VoidFunction, categories: any }) {
|
||||||
const [jobtype, setJobType] = useState("");
|
const [jobtype, setJobType] = useState("");
|
||||||
const [updateIndustryMaster] = useUpdateIndustryMasterMutation()
|
const [updateIndustryMaster, { isLoading }] = useUpdateIndustryMasterMutation()
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
|
|
||||||
const handleOpenModal = () => {
|
const handleOpenModal = () => {
|
||||||
@@ -98,7 +98,7 @@ function EditIndustryMaster({ id, localData, refetch, categories }: { id: number
|
|||||||
</Stack>
|
</Stack>
|
||||||
</DialogBody>
|
</DialogBody>
|
||||||
<DialogFooter display="flex" justifyContent="center" pt={"2"}>
|
<DialogFooter display="flex" justifyContent="center" pt={"2"}>
|
||||||
<Button w="100%" bg="#02A0A0" color={"#fff"} onClick={handleSubmit}>
|
<Button w="100%" bg="#02A0A0" color={"#fff"} onClick={handleSubmit} disabled={isLoading}>
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
</DialogFooter>
|
</DialogFooter>
|
||||||
|
|||||||
@@ -9,6 +9,9 @@ import { useGetIndustryMasterQuery, useIndustryMasterToggleMutation } from "../.
|
|||||||
import EditIndustryMaster from "./EditIndustryMaster";
|
import EditIndustryMaster from "./EditIndustryMaster";
|
||||||
import AddIndustryMaster from "./AddIndustryMaster";
|
import AddIndustryMaster from "./AddIndustryMaster";
|
||||||
import SearchComponent from "../../../components/SearchComponent";
|
import SearchComponent from "../../../components/SearchComponent";
|
||||||
|
import { useDebounce } from "../../../components/Hooks/useDebounce";
|
||||||
|
import { Toaster, toaster } from "../../../components/ui/toaster";
|
||||||
|
import { delay } from "../../../components/Utils";
|
||||||
|
|
||||||
|
|
||||||
// table data
|
// table data
|
||||||
@@ -44,10 +47,12 @@ const tableHeadRow = [
|
|||||||
|
|
||||||
const IndustryMasterList = () => {
|
const IndustryMasterList = () => {
|
||||||
const [currentPage, setCurrentPage] = useState(1);
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
const { data, refetch } = useGetIndustryMasterQuery(currentPage)
|
|
||||||
const [industryMasterToggle] = useIndustryMasterToggleMutation()
|
const [industryMasterToggle] = useIndustryMasterToggleMutation()
|
||||||
const [localData, setLocalData] = useState<any[]>([]);
|
const [localData, setLocalData] = useState<any[]>([]);
|
||||||
const [searchTerm, setSearchTerm] = useState("");
|
const [searchTerm, setSearchTerm] = useState("");
|
||||||
|
const debouncedSearchTerm = useDebounce(searchTerm, 500);
|
||||||
|
const queryArgs = debouncedSearchTerm ? { page: currentPage, search: debouncedSearchTerm } : { page: currentPage };
|
||||||
|
const { data, refetch, isError, isFetching } = useGetIndustryMasterQuery(queryArgs)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (data?.data?.data) {
|
if (data?.data?.data) {
|
||||||
@@ -55,6 +60,11 @@ const IndustryMasterList = () => {
|
|||||||
}
|
}
|
||||||
}, [data]);
|
}, [data]);
|
||||||
|
|
||||||
|
const handleSearchChange = (value: string) => {
|
||||||
|
setSearchTerm(value);
|
||||||
|
setCurrentPage(1);
|
||||||
|
};
|
||||||
|
|
||||||
const handlePageChange = (page: number) => {
|
const handlePageChange = (page: number) => {
|
||||||
setCurrentPage(page);
|
setCurrentPage(page);
|
||||||
};
|
};
|
||||||
@@ -68,9 +78,20 @@ const IndustryMasterList = () => {
|
|||||||
);
|
);
|
||||||
try {
|
try {
|
||||||
await industryMasterToggle({ id: agencyId, is_active: newStatus }).unwrap();
|
await industryMasterToggle({ id: agencyId, is_active: newStatus }).unwrap();
|
||||||
|
toaster.create({
|
||||||
|
title: "Success",
|
||||||
|
description: "Status updated successfully",
|
||||||
|
type: "success",
|
||||||
|
});
|
||||||
|
await delay(500);
|
||||||
refetch()
|
refetch()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error updating privacy policy:", error);
|
console.error("Error updating privacy policy:", error);
|
||||||
|
toaster.create({
|
||||||
|
title: "Error",
|
||||||
|
description: "Someting went wrong.",
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
setLocalData((prevData) =>
|
setLocalData((prevData) =>
|
||||||
prevData.map((agency) =>
|
prevData.map((agency) =>
|
||||||
agency.id === agencyId ? { ...agency, is_active: currentStatus } : agency
|
agency.id === agencyId ? { ...agency, is_active: currentStatus } : agency
|
||||||
@@ -130,11 +151,7 @@ const IndustryMasterList = () => {
|
|||||||
<HStack >
|
<HStack >
|
||||||
<SearchComponent
|
<SearchComponent
|
||||||
value={searchTerm}
|
value={searchTerm}
|
||||||
onChange={(value) => {
|
onChange={handleSearchChange}
|
||||||
setSearchTerm(value);
|
|
||||||
// setCurrentPage(1);
|
|
||||||
refetch()
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
{/* <Button bgColor={'#EEEEEE'} pl={3} pr={3}><IoMdAdd /> <Text>Add</Text></Button> */}
|
{/* <Button bgColor={'#EEEEEE'} pl={3} pr={3}><IoMdAdd /> <Text>Add</Text></Button> */}
|
||||||
{/* <ViewAgencyAddModel /> */}
|
{/* <ViewAgencyAddModel /> */}
|
||||||
@@ -152,8 +169,11 @@ const IndustryMasterList = () => {
|
|||||||
total: data?.data.total || 0
|
total: data?.data.total || 0
|
||||||
}}
|
}}
|
||||||
onPageChange={handlePageChange}
|
onPageChange={handlePageChange}
|
||||||
|
isLoading={isFetching}
|
||||||
|
isError={isError}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
<Toaster />
|
||||||
</MainFrame>
|
</MainFrame>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import { Toaster, toaster } from "../../../components/ui/toaster";
|
|||||||
|
|
||||||
|
|
||||||
function EditJobStatusModel({ localData, refetch }: { localData: any, refetch: VoidFunction }) {
|
function EditJobStatusModel({ localData, refetch }: { localData: any, refetch: VoidFunction }) {
|
||||||
const [updateJobStatus] = useUpdateJobStatusMutation()
|
const [updateJobStatus, { isLoading }] = useUpdateJobStatusMutation()
|
||||||
const [title, setTitle] = useState(localData.translation.title);
|
const [title, setTitle] = useState(localData.translation.title);
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
|
|
||||||
@@ -89,7 +89,7 @@ function EditJobStatusModel({ localData, refetch }: { localData: any, refetch: V
|
|||||||
|
|
||||||
</DialogBody>
|
</DialogBody>
|
||||||
<DialogFooter display="flex" justifyContent="center" pt={"2"}>
|
<DialogFooter display="flex" justifyContent="center" pt={"2"}>
|
||||||
<Button w="100%" bg="#02A0A0" color={"#fff"} onClick={handleSubmit}>
|
<Button w="100%" bg="#02A0A0" color={"#fff"} onClick={handleSubmit} disabled={isLoading}>
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
</DialogFooter>
|
</DialogFooter>
|
||||||
|
|||||||
@@ -7,7 +7,9 @@ import EditJobStatusModel from "./EditJobStatusModel";
|
|||||||
import { useGetJobStatusQuery, useJobStatusToggleMutation } from "../../../Redux/Service/job.status";
|
import { useGetJobStatusQuery, useJobStatusToggleMutation } from "../../../Redux/Service/job.status";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import SearchComponent from "../../../components/SearchComponent";
|
import SearchComponent from "../../../components/SearchComponent";
|
||||||
import { toaster } from "../../../components/ui/toaster";
|
import { toaster, Toaster } from "../../../components/ui/toaster";
|
||||||
|
import { useDebounce } from "../../../components/Hooks/useDebounce";
|
||||||
|
import { delay } from "../../../components/Utils";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -37,9 +39,11 @@ const tableHeadRow = [
|
|||||||
|
|
||||||
const JobStatus = () => {
|
const JobStatus = () => {
|
||||||
const [currentPage, setCurrentPage] = useState(1);
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
const { data, refetch } = useGetJobStatusQuery(currentPage)
|
|
||||||
const [localData, setLocalData] = useState<any[]>([]);
|
|
||||||
const [searchTerm, setSearchTerm] = useState("");
|
const [searchTerm, setSearchTerm] = useState("");
|
||||||
|
const debouncedSearchTerm = useDebounce(searchTerm, 500);
|
||||||
|
const queryArgs = debouncedSearchTerm ? { page: currentPage, search: debouncedSearchTerm } : { page: currentPage };
|
||||||
|
const { data, refetch, isError, isFetching } = useGetJobStatusQuery(queryArgs)
|
||||||
|
const [localData, setLocalData] = useState<any[]>([]);
|
||||||
const [jobStatusToggle] = useJobStatusToggleMutation()
|
const [jobStatusToggle] = useJobStatusToggleMutation()
|
||||||
console.log(data?.data.data)
|
console.log(data?.data.data)
|
||||||
|
|
||||||
@@ -53,6 +57,11 @@ const JobStatus = () => {
|
|||||||
setCurrentPage(page);
|
setCurrentPage(page);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleSearchChange = (value: string) => {
|
||||||
|
setSearchTerm(value);
|
||||||
|
setCurrentPage(1);
|
||||||
|
};
|
||||||
|
|
||||||
const handleToggle = async (agencyId: string, currentStatus: number) => {
|
const handleToggle = async (agencyId: string, currentStatus: number) => {
|
||||||
const newStatus = currentStatus ? 0 : 1;
|
const newStatus = currentStatus ? 0 : 1;
|
||||||
setLocalData((prevData) =>
|
setLocalData((prevData) =>
|
||||||
@@ -62,6 +71,12 @@ const JobStatus = () => {
|
|||||||
);
|
);
|
||||||
try {
|
try {
|
||||||
await jobStatusToggle({ id: agencyId, is_active: newStatus }).unwrap();
|
await jobStatusToggle({ id: agencyId, is_active: newStatus }).unwrap();
|
||||||
|
toaster.create({
|
||||||
|
title: "Success",
|
||||||
|
description: "Status updated successfully",
|
||||||
|
type: "success",
|
||||||
|
});
|
||||||
|
await delay(500);
|
||||||
refetch()
|
refetch()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error updating:", error);
|
console.error("Error updating:", error);
|
||||||
@@ -125,11 +140,7 @@ const JobStatus = () => {
|
|||||||
<HStack >
|
<HStack >
|
||||||
<SearchComponent
|
<SearchComponent
|
||||||
value={searchTerm}
|
value={searchTerm}
|
||||||
onChange={(value) => {
|
onChange={handleSearchChange}
|
||||||
setSearchTerm(value);
|
|
||||||
// setCurrentPage(1);
|
|
||||||
refetch()
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
{/* <Button bgColor={'#EEEEEE'} pl={3} pr={3}><IoMdAdd /> <Text>Add</Text></Button> */}
|
{/* <Button bgColor={'#EEEEEE'} pl={3} pr={3}><IoMdAdd /> <Text>Add</Text></Button> */}
|
||||||
<JobStatusAddModel refetch={refetch} />
|
<JobStatusAddModel refetch={refetch} />
|
||||||
@@ -146,8 +157,11 @@ const JobStatus = () => {
|
|||||||
total: data?.data.total || 0
|
total: data?.data.total || 0
|
||||||
}}
|
}}
|
||||||
onPageChange={handlePageChange}
|
onPageChange={handlePageChange}
|
||||||
|
isLoading={isFetching}
|
||||||
|
isError={isError}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
<Toaster />
|
||||||
</MainFrame>
|
</MainFrame>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import { useState } from "react"
|
|||||||
function JobStatusAddModel({ refetch }: { refetch: VoidFunction }) {
|
function JobStatusAddModel({ refetch }: { refetch: VoidFunction }) {
|
||||||
const [title, setTitle] = useState('')
|
const [title, setTitle] = useState('')
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
const [createJobStatusPost] = useCreateJobStatusPostMutation()
|
const [createJobStatusPost, { isLoading }] = useCreateJobStatusPostMutation()
|
||||||
|
|
||||||
const handleOpenModal = () => {
|
const handleOpenModal = () => {
|
||||||
setIsOpen(true);
|
setIsOpen(true);
|
||||||
@@ -88,7 +88,7 @@ function JobStatusAddModel({ refetch }: { refetch: VoidFunction }) {
|
|||||||
|
|
||||||
</DialogBody>
|
</DialogBody>
|
||||||
<DialogFooter display="flex" justifyContent="center" pt={"2"}>
|
<DialogFooter display="flex" justifyContent="center" pt={"2"}>
|
||||||
<Button w="100%" bg="#02A0A0" color={"#fff"} onClick={handleSubmit}>
|
<Button w="100%" bg="#02A0A0" color={"#fff"} onClick={handleSubmit} disabled={isLoading}>
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
</DialogFooter>
|
</DialogFooter>
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import { toaster } from "../../../components/ui/toaster";
|
|||||||
|
|
||||||
function EditJobeModel({ id, localData, refetch }: { id: number, localData: any, refetch: VoidFunction }) {
|
function EditJobeModel({ id, localData, refetch }: { id: number, localData: any, refetch: VoidFunction }) {
|
||||||
const [jobtype, setJobType] = useState("");
|
const [jobtype, setJobType] = useState("");
|
||||||
const [updateJobType] = useUpdateJobTypeMutation()
|
const [updateJobType, { isLoading }] = useUpdateJobTypeMutation()
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
|
|
||||||
const handleOpenModal = () => {
|
const handleOpenModal = () => {
|
||||||
@@ -97,7 +97,7 @@ function EditJobeModel({ id, localData, refetch }: { id: number, localData: any,
|
|||||||
</Stack>
|
</Stack>
|
||||||
</DialogBody>
|
</DialogBody>
|
||||||
<DialogFooter display="flex" justifyContent="center" pt={"2"}>
|
<DialogFooter display="flex" justifyContent="center" pt={"2"}>
|
||||||
<Button w="100%" bg="#02A0A0" color={"#fff"} onClick={handleSubmit}>
|
<Button w="100%" bg="#02A0A0" color={"#fff"} onClick={handleSubmit} disabled={isLoading}>
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
</DialogFooter>
|
</DialogFooter>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import { toaster } from "../../../components/ui/toaster";
|
|||||||
function JobAddModel({ refetch }: { refetch: VoidFunction }) {
|
function JobAddModel({ refetch }: { refetch: VoidFunction }) {
|
||||||
const [jobType, setJobType] = useState("");
|
const [jobType, setJobType] = useState("");
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
const [createJobTypePost] = useCreateJobTypePostMutation()
|
const [createJobTypePost, { isLoading }] = useCreateJobTypePostMutation()
|
||||||
|
|
||||||
const handleOpenModal = () => {
|
const handleOpenModal = () => {
|
||||||
setIsOpen(true); // Open modal when clicking "Add"
|
setIsOpen(true); // Open modal when clicking "Add"
|
||||||
@@ -87,7 +87,7 @@ function JobAddModel({ refetch }: { refetch: VoidFunction }) {
|
|||||||
|
|
||||||
</DialogBody>
|
</DialogBody>
|
||||||
<DialogFooter display="flex" justifyContent="center" pt={"2"}>
|
<DialogFooter display="flex" justifyContent="center" pt={"2"}>
|
||||||
<Button w="100%" bg="#02A0A0" color={"#fff"} onClick={handleSubmit}>
|
<Button w="100%" bg="#02A0A0" color={"#fff"} onClick={handleSubmit} disabled={isLoading}>
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
</DialogFooter>
|
</DialogFooter>
|
||||||
|
|||||||
@@ -6,9 +6,11 @@ import DataTable from "../../../components/DataTable";
|
|||||||
import { Switch } from "../../../components/ui/switch";
|
import { Switch } from "../../../components/ui/switch";
|
||||||
import JobAddModel from "./JobAddModel";
|
import JobAddModel from "./JobAddModel";
|
||||||
import EditJobeModel from "./EditJobModel";
|
import EditJobeModel from "./EditJobModel";
|
||||||
import { JobTypeData, useGetJobTypeQuery } from "../../../Redux/Service/job.type.service";
|
import { JobTypeData, useGetJobTypeQuery, useJobTypeToggleMutation } from "../../../Redux/Service/job.type.service";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import SearchComponent from "../../../components/SearchComponent";
|
import SearchComponent from "../../../components/SearchComponent";
|
||||||
|
import { toaster, Toaster } from "../../../components/ui/toaster";
|
||||||
|
import { delay } from "../../../components/Utils";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -38,10 +40,10 @@ const tableHeadRow = [
|
|||||||
|
|
||||||
const JobType = () => {
|
const JobType = () => {
|
||||||
const [currentPage, setCurrentPage] = useState(1);
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
const { data, refetch } = useGetJobTypeQuery(currentPage)
|
const { data, refetch, isFetching, isError } = useGetJobTypeQuery(currentPage)
|
||||||
const [localData, setLocalData] = useState<any[]>([]);
|
const [localData, setLocalData] = useState<any[]>([]);
|
||||||
const [searchTerm, setSearchTerm] = useState("");
|
const [searchTerm, setSearchTerm] = useState("");
|
||||||
// const [templateMasterToggle] = useTemplateMasterToggleMutation()
|
const [jobTypeToggle] = useJobTypeToggleMutation()
|
||||||
console.log('DATA', data?.data.data);
|
console.log('DATA', data?.data.data);
|
||||||
|
|
||||||
|
|
||||||
@@ -61,25 +63,36 @@ const JobType = () => {
|
|||||||
return title;
|
return title;
|
||||||
});
|
});
|
||||||
|
|
||||||
// const handleToggle = async (agencyId: string, currentStatus: number) => {
|
const handleToggle = async (agencyId: string, currentStatus: number) => {
|
||||||
// const newStatus = currentStatus ? 0 : 1;
|
const newStatus = currentStatus ? 0 : 1;
|
||||||
// setLocalData((prevData) =>
|
setLocalData((prevData) =>
|
||||||
// prevData.map((agency) =>
|
prevData.map((agency) =>
|
||||||
// agency.id === agencyId ? { ...agency, is_active: newStatus } : agency
|
agency.id === agencyId ? { ...agency, is_active: newStatus } : agency
|
||||||
// )
|
)
|
||||||
// );
|
);
|
||||||
// try {
|
try {
|
||||||
// await templateMasterToggle({ id: agencyId, is_active: newStatus }).unwrap();
|
await jobTypeToggle({ id: agencyId, is_active: newStatus }).unwrap();
|
||||||
// refetch()
|
toaster.create({
|
||||||
// } catch (error) {
|
title: "Success",
|
||||||
// console.error("Error updating privacy policy:", error);
|
description: "Status updated successfully",
|
||||||
// setLocalData((prevData) =>
|
type: "success",
|
||||||
// prevData.map((agency) =>
|
});
|
||||||
// agency.id === agencyId ? { ...agency, is_active: currentStatus } : agency
|
await delay(500);
|
||||||
// )
|
refetch()
|
||||||
// );
|
} catch (error) {
|
||||||
// }
|
console.error("Error updating privacy policy:", error);
|
||||||
// };
|
setLocalData((prevData) =>
|
||||||
|
prevData.map((agency) =>
|
||||||
|
agency.id === agencyId ? { ...agency, is_active: currentStatus } : agency
|
||||||
|
)
|
||||||
|
);
|
||||||
|
toaster.create({
|
||||||
|
title: "Error",
|
||||||
|
description: "Please try again later",
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
const managepost = filteredData?.map((agency: JobTypeData, index: number) => ({
|
const managepost = filteredData?.map((agency: JobTypeData, index: number) => ({
|
||||||
@@ -94,7 +107,7 @@ const JobType = () => {
|
|||||||
<Switch
|
<Switch
|
||||||
colorPalette={'teal'}
|
colorPalette={'teal'}
|
||||||
size={"xs"}
|
size={"xs"}
|
||||||
// onChange={() => handleToggle(agency.id, Number(agency.is_active))}
|
onChange={() => handleToggle(agency.id.toString(), Number(agency.is_active))}
|
||||||
checked={Boolean(Number(agency.is_active))}
|
checked={Boolean(Number(agency.is_active))}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
@@ -142,8 +155,11 @@ const JobType = () => {
|
|||||||
total: data?.data.total || 0
|
total: data?.data.total || 0
|
||||||
}}
|
}}
|
||||||
onPageChange={handlePageChange}
|
onPageChange={handlePageChange}
|
||||||
|
isLoading={isFetching}
|
||||||
|
isError={isError}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
<Toaster />
|
||||||
</MainFrame>
|
</MainFrame>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import { useState } from "react";
|
|||||||
// import { FaRegEdit } from "react-icons/fa";
|
// import { FaRegEdit } from "react-icons/fa";
|
||||||
import Edit from "../../../components/ActionIcons/Edit";
|
import Edit from "../../../components/ActionIcons/Edit";
|
||||||
import { Toaster, toaster } from "../../../components/ui/toaster";
|
import { Toaster, toaster } from "../../../components/ui/toaster";
|
||||||
import { Template } from "../../../Redux/Service/template.master.service";
|
// import { Template } from "../../../Redux/Service/template.master.service";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
|
||||||
const IMGURL = import.meta.env.VITE_IMG_TEMPLATES
|
const IMGURL = import.meta.env.VITE_IMG_TEMPLATES
|
||||||
@@ -30,13 +30,14 @@ function EditTemplateModel({ id, localData, refetch }: { id: number, localData:
|
|||||||
const [subTitle, setSubTitle] = useState("");
|
const [subTitle, setSubTitle] = useState("");
|
||||||
const [userType, setUserType] = useState<number | "">("");
|
const [userType, setUserType] = useState<number | "">("");
|
||||||
const [images, setImages] = useState<(File | string)[]>([]);
|
const [images, setImages] = useState<(File | string)[]>([]);
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
// const [objectURLs, setObjectURLs] = useState<string[]>([]); // Store object URLs separately
|
// const [objectURLs, setObjectURLs] = useState<string[]>([]); // Store object URLs separately
|
||||||
// const [updateTemplateMaster] = useUpdateTemplateMasterMutation()
|
// const [updateTemplateMaster] = useUpdateTemplateMasterMutation()
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
const [selectedTemplate, setSelectedTemplate] = useState<Template | null>(null);
|
// const [selectedTemplate, setSelectedTemplate] = useState<Template | null>(null);
|
||||||
const token = localStorage.getItem("token");
|
const token = localStorage.getItem("token");
|
||||||
|
|
||||||
console.log(selectedTemplate);
|
console.log(images);
|
||||||
|
|
||||||
const handleImageChange = async (event: React.ChangeEvent<HTMLInputElement>) => {
|
const handleImageChange = async (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
if (event.target.files) {
|
if (event.target.files) {
|
||||||
@@ -50,14 +51,17 @@ function EditTemplateModel({ id, localData, refetch }: { id: number, localData:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
setImages((prevImages) => [...prevImages, file]);
|
// setImages((prevImages) => [...prevImages, file]);
|
||||||
|
if (file) {
|
||||||
|
setImages([file])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleOpenModal = () => {
|
const handleOpenModal = () => {
|
||||||
const template = localData?.find((item: any) => item.id === id);
|
const template = localData?.find((item: any) => item.id === id);
|
||||||
if (template) {
|
if (template) {
|
||||||
setSelectedTemplate(template);
|
// setSelectedTemplate(template);
|
||||||
setTitle(template.post_template_translate.length > 0 ? template.post_template_translate[0].title : "");
|
setTitle(template.post_template_translate.length > 0 ? template.post_template_translate[0].title : "");
|
||||||
setSubTitle(template.post_template_translate.length > 0 ? template.post_template_translate[0].sub_title : "");
|
setSubTitle(template.post_template_translate.length > 0 ? template.post_template_translate[0].sub_title : "");
|
||||||
setUserType(template.principle_type_xid?.toString() || "");
|
setUserType(template.principle_type_xid?.toString() || "");
|
||||||
@@ -90,9 +94,9 @@ function EditTemplateModel({ id, localData, refetch }: { id: number, localData:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const newImages = images.filter((image) => image instanceof File);
|
// const newImages = images.filter((image) => image instanceof File);
|
||||||
|
|
||||||
if (newImages.length === 0) {
|
if (images.length === 0) {
|
||||||
toaster.create({
|
toaster.create({
|
||||||
title: "Error",
|
title: "Error",
|
||||||
description: "Please upload at least one image.",
|
description: "Please upload at least one image.",
|
||||||
@@ -101,14 +105,18 @@ function EditTemplateModel({ id, localData, refetch }: { id: number, localData:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setLoading(true);
|
||||||
|
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append("id", `${id}`);
|
formData.append("id", `${id}`);
|
||||||
formData.append("principle_type_xid", `${userType}`);
|
formData.append("principle_type_xid", `${userType}`);
|
||||||
formData.append("title", title);
|
formData.append("title", title);
|
||||||
formData.append("sub_title", subTitle);
|
formData.append("sub_title", subTitle);
|
||||||
|
|
||||||
newImages.forEach((image, index) => {
|
images.forEach((image, index) => {
|
||||||
formData.append(`image_name[${index}]`, image, image.name);
|
if (image instanceof File) {
|
||||||
|
formData.append(`image_name[${index}]`, image, image.name);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -123,12 +131,14 @@ function EditTemplateModel({ id, localData, refetch }: { id: number, localData:
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
setIsOpen(false);
|
setIsOpen(false);
|
||||||
|
setLoading(false);
|
||||||
refetch()
|
refetch()
|
||||||
} catch (error) {
|
} catch (error: any) {
|
||||||
console.error("Error updating template:", error);
|
console.error("Error updating template:", error);
|
||||||
|
setLoading(false);
|
||||||
toaster.create({
|
toaster.create({
|
||||||
title: "Error",
|
title: "Error",
|
||||||
description: "Failed to update template. Please try again.",
|
description: `${error.response?.data?.message || "Please try again later."}`,
|
||||||
type: "error",
|
type: "error",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -294,7 +304,7 @@ function EditTemplateModel({ id, localData, refetch }: { id: number, localData:
|
|||||||
|
|
||||||
</DialogBody>
|
</DialogBody>
|
||||||
<DialogFooter display="flex" justifyContent="center" pt={"2"}>
|
<DialogFooter display="flex" justifyContent="center" pt={"2"}>
|
||||||
<Button w="100%" bg="#02A0A0" color={"#fff"} onClick={handleSubmit}>
|
<Button w="100%" bg="#02A0A0" color={"#fff"} onClick={handleSubmit} disabled={loading}>
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
</DialogFooter>
|
</DialogFooter>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { Box, Field, Input, Stack, Text } from "@chakra-ui/react"
|
|||||||
import { IoMdAdd } from "react-icons/io"
|
import { IoMdAdd } from "react-icons/io"
|
||||||
import { Button } from "../../../components/ui/button"
|
import { Button } from "../../../components/ui/button"
|
||||||
import { FiUpload } from "react-icons/fi";
|
import { FiUpload } from "react-icons/fi";
|
||||||
import { useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
// import { useCreateTemplatePostMutation } from "../../../Redux/Service/template.master.service";
|
// import { useCreateTemplatePostMutation } from "../../../Redux/Service/template.master.service";
|
||||||
import { Toaster, toaster } from "../../../components/ui/toaster"
|
import { Toaster, toaster } from "../../../components/ui/toaster"
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
@@ -17,12 +17,23 @@ function TemplateAddModel({ refetch }: { refetch: VoidFunction }) {
|
|||||||
const [images, setImages] = useState<(File | string)[]>([]);
|
const [images, setImages] = useState<(File | string)[]>([]);
|
||||||
// const [createTemplatePost] = useCreateTemplatePostMutation()
|
// const [createTemplatePost] = useCreateTemplatePostMutation()
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
const token = localStorage.getItem("token");
|
const token = localStorage.getItem("token");
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!isOpen) {
|
||||||
|
setTitle("");
|
||||||
|
setSubTitle("");
|
||||||
|
setUserType("");
|
||||||
|
setImages([]);
|
||||||
|
}
|
||||||
|
}, [isOpen]);
|
||||||
|
|
||||||
if (!token) {
|
if (!token) {
|
||||||
console.error("No token found in localStorage!");
|
console.error("No token found in localStorage!");
|
||||||
return;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleOpenModal = () => {
|
const handleOpenModal = () => {
|
||||||
setIsOpen(true); // Open modal when clicking "Add"
|
setIsOpen(true); // Open modal when clicking "Add"
|
||||||
};
|
};
|
||||||
@@ -40,7 +51,10 @@ function TemplateAddModel({ refetch }: { refetch: VoidFunction }) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
setImages((prevImages) => [...prevImages, file]);
|
// setImages((prevImages) => [...prevImages, file]);
|
||||||
|
if(file){
|
||||||
|
setImages([file])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -72,6 +86,7 @@ function TemplateAddModel({ refetch }: { refetch: VoidFunction }) {
|
|||||||
// image_name: images.filter((img) => typeof img === "string"), // Send only Base64 strings
|
// image_name: images.filter((img) => typeof img === "string"), // Send only Base64 strings
|
||||||
// };
|
// };
|
||||||
|
|
||||||
|
setIsLoading(true);
|
||||||
|
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append("principle_type_xid", `${userType}`);
|
formData.append("principle_type_xid", `${userType}`);
|
||||||
@@ -106,13 +121,19 @@ function TemplateAddModel({ refetch }: { refetch: VoidFunction }) {
|
|||||||
setUserType("");
|
setUserType("");
|
||||||
setImages([]);
|
setImages([]);
|
||||||
setIsOpen(false)
|
setIsOpen(false)
|
||||||
} catch (error) {
|
setIsLoading(false);
|
||||||
|
} catch (error: any) {
|
||||||
console.error("Error creating template:", error);
|
console.error("Error creating template:", error);
|
||||||
// alert("Failed to create template");
|
// alert("Failed to create template");
|
||||||
|
toaster.create({
|
||||||
|
title: "Error",
|
||||||
|
description: `${error.response?.data?.message || "Please try again later."}`,
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// console.log("Token stored:", window.localStorage.getItem("token"));
|
// console.log("Token stored:", window.localStorage.getItem("token"))
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -226,7 +247,7 @@ function TemplateAddModel({ refetch }: { refetch: VoidFunction }) {
|
|||||||
|
|
||||||
</DialogBody>
|
</DialogBody>
|
||||||
<DialogFooter display="flex" justifyContent="center" pt={"2"}>
|
<DialogFooter display="flex" justifyContent="center" pt={"2"}>
|
||||||
<Button w="100%" bg="#02A0A0" color={"#fff"} onClick={handleSubmit}>
|
<Button w="100%" bg="#02A0A0" color={"#fff"} onClick={handleSubmit} disabled={isLoading}>
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
</DialogFooter>
|
</DialogFooter>
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ import EditTemplateModel from "./EditTemplateModel";
|
|||||||
import { Template, useGetTemplateMasterQuery, useTemplateMasterToggleMutation } from "../../../Redux/Service/template.master.service";
|
import { Template, useGetTemplateMasterQuery, useTemplateMasterToggleMutation } from "../../../Redux/Service/template.master.service";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import SearchComponent from "../../../components/SearchComponent";
|
import SearchComponent from "../../../components/SearchComponent";
|
||||||
|
import { toaster, Toaster } from "../../../components/ui/toaster";
|
||||||
|
import { delay } from "../../../components/Utils";
|
||||||
|
|
||||||
const APIURL = import.meta.env.VITE_IMG_TEMPLATES
|
const APIURL = import.meta.env.VITE_IMG_TEMPLATES
|
||||||
|
|
||||||
@@ -17,6 +19,7 @@ const APIURL = import.meta.env.VITE_IMG_TEMPLATES
|
|||||||
const tableHeadRow = [
|
const tableHeadRow = [
|
||||||
"Sr. No",
|
"Sr. No",
|
||||||
"Title",
|
"Title",
|
||||||
|
"User Type",
|
||||||
"Images",
|
"Images",
|
||||||
"Action"
|
"Action"
|
||||||
];
|
];
|
||||||
@@ -46,7 +49,7 @@ const tableHeadRow = [
|
|||||||
|
|
||||||
const TemplateMaster = () => {
|
const TemplateMaster = () => {
|
||||||
const [currentPage, setCurrentPage] = useState(1);
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
const { data, refetch } = useGetTemplateMasterQuery(currentPage)
|
const { data, refetch, isFetching, isError } = useGetTemplateMasterQuery(currentPage)
|
||||||
const [localData, setLocalData] = useState<any[]>([]);
|
const [localData, setLocalData] = useState<any[]>([]);
|
||||||
const [templateMasterToggle] = useTemplateMasterToggleMutation();
|
const [templateMasterToggle] = useTemplateMasterToggleMutation();
|
||||||
const [searchTerm, setSearchTerm] = useState("");
|
const [searchTerm, setSearchTerm] = useState("");
|
||||||
@@ -71,6 +74,12 @@ const TemplateMaster = () => {
|
|||||||
);
|
);
|
||||||
try {
|
try {
|
||||||
await templateMasterToggle({ id: agencyId, is_active: newStatus }).unwrap();
|
await templateMasterToggle({ id: agencyId, is_active: newStatus }).unwrap();
|
||||||
|
toaster.create({
|
||||||
|
title: "Success",
|
||||||
|
description: "Status updated successfully",
|
||||||
|
type: "success",
|
||||||
|
});
|
||||||
|
await delay(500);
|
||||||
refetch()
|
refetch()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error updating privacy policy:", error);
|
console.error("Error updating privacy policy:", error);
|
||||||
@@ -79,6 +88,11 @@ const TemplateMaster = () => {
|
|||||||
agency.id === agencyId ? { ...agency, is_active: currentStatus } : agency
|
agency.id === agencyId ? { ...agency, is_active: currentStatus } : agency
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
toaster.create({
|
||||||
|
title: "Error",
|
||||||
|
description: "Please try again later",
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -86,37 +100,45 @@ const TemplateMaster = () => {
|
|||||||
agency.post_template_translate[0].title.toLowerCase().includes(searchTerm.toLowerCase())
|
agency.post_template_translate[0].title.toLowerCase().includes(searchTerm.toLowerCase())
|
||||||
);
|
);
|
||||||
|
|
||||||
const managepost = filteredData?.map((agency: Template, index: number) => ({
|
const activeCount = filteredData?.filter((a: any) => a.is_active === 1).length ?? 0;
|
||||||
'id': agency.id,
|
|
||||||
"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",
|
|
||||||
"Images": (
|
|
||||||
// <Image w={50} src={img} />
|
|
||||||
<HStack key={agency.id}>
|
|
||||||
{agency.post_template_image.map((img) => (
|
|
||||||
<Image rounded={'lg'} w={100} h={50} src={`${APIURL}${img.image_name}`} />
|
|
||||||
))}
|
|
||||||
|
|
||||||
{/* <Image rounded={'lg'} w={100} h={50} src={Templateimg} /> */}
|
const managepost = filteredData?.map((agency: Template, index: number) => {
|
||||||
</HStack>
|
const isOnlyActive = activeCount === 1 && Number(agency.is_active) === 1;
|
||||||
),
|
|
||||||
|
|
||||||
"Action": (
|
return {
|
||||||
<HStack justifyContent="center">
|
'id': agency.id,
|
||||||
<EditTemplateModel id={agency.id} localData={localData} refetch={refetch} />
|
"Sr. No": (currentPage - 1) * (data?.data.per_page ?? 0) + index + 1,
|
||||||
<Box>
|
"Title": agency.post_template_translate.length > 0
|
||||||
<Switch
|
? agency.post_template_translate[0].title
|
||||||
colorPalette={'teal'}
|
: "N/A",
|
||||||
size={"xs"}
|
"User Type": agency.principle_type_xid === 2 ? 'Recruiter' : 'Job Seeker',
|
||||||
onChange={() => handleToggle(agency.id.toString(), Number(agency.is_active ?? 0))}
|
"Images": (
|
||||||
checked={Boolean(Number(agency.is_active))}
|
// <Image w={50} src={img} />
|
||||||
/>
|
<HStack>
|
||||||
</Box>
|
{agency.post_template_image.map((img) => (
|
||||||
</HStack>
|
<Image key={img.id} rounded={'lg'} w={100} h={50} src={`${APIURL}${img.image_name}`} />
|
||||||
),
|
))}
|
||||||
}));
|
|
||||||
|
{/* <Image rounded={'lg'} w={100} h={50} src={Templateimg} /> */}
|
||||||
|
</HStack>
|
||||||
|
),
|
||||||
|
|
||||||
|
"Action": (
|
||||||
|
<HStack justifyContent="center">
|
||||||
|
<EditTemplateModel id={agency.id} localData={localData} refetch={refetch} />
|
||||||
|
<Box>
|
||||||
|
<Switch
|
||||||
|
colorPalette={'teal'}
|
||||||
|
size={"xs"}
|
||||||
|
onChange={() => handleToggle(agency.id.toString(), Number(agency.is_active ?? 0))}
|
||||||
|
checked={Boolean(Number(agency.is_active))}
|
||||||
|
disabled={isOnlyActive}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
</HStack>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
||||||
@@ -172,8 +194,11 @@ const TemplateMaster = () => {
|
|||||||
total: data?.data.total || 0
|
total: data?.data.total || 0
|
||||||
}}
|
}}
|
||||||
onPageChange={handlePageChange}
|
onPageChange={handlePageChange}
|
||||||
|
isLoading={isFetching}
|
||||||
|
isError={isError}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
<Toaster />
|
||||||
</MainFrame>
|
</MainFrame>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ import { useUpdateWorkSpaceMutation } from "../../../Redux/Service/workspace.mod
|
|||||||
function EditWorkModel({ localData, refetch }: {localData: any, refetch: VoidFunction}) {
|
function EditWorkModel({ localData, refetch }: {localData: any, refetch: VoidFunction}) {
|
||||||
const [title, setTitle] = useState(localData?.en_name);
|
const [title, setTitle] = useState(localData?.en_name);
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
const [updateWorkSpace] = useUpdateWorkSpaceMutation()
|
const [updateWorkSpace, { isLoading }] = useUpdateWorkSpaceMutation()
|
||||||
console.log("localData", localData)
|
console.log("localData", localData)
|
||||||
|
|
||||||
const handleOpenModal = () => {
|
const handleOpenModal = () => {
|
||||||
@@ -104,7 +104,7 @@ function EditWorkModel({ localData, refetch }: {localData: any, refetch: VoidFun
|
|||||||
</Stack>
|
</Stack>
|
||||||
</DialogBody>
|
</DialogBody>
|
||||||
<DialogFooter display="flex" justifyContent="center" pt={"2"}>
|
<DialogFooter display="flex" justifyContent="center" pt={"2"}>
|
||||||
<Button w="100%" bg="#02A0A0" color={"#fff"} onClick={handleSubmit}>
|
<Button w="100%" bg="#02A0A0" color={"#fff"} onClick={handleSubmit} disabled={isLoading}>
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
</DialogFooter>
|
</DialogFooter>
|
||||||
|
|||||||
@@ -2,14 +2,14 @@ import { DialogBody, DialogCloseTrigger, DialogContent, DialogFooter, DialogHead
|
|||||||
import { Field, Input, Stack, Text } from "@chakra-ui/react"
|
import { Field, Input, Stack, Text } from "@chakra-ui/react"
|
||||||
import { IoMdAdd } from "react-icons/io"
|
import { IoMdAdd } from "react-icons/io"
|
||||||
import { Button } from "../../../components/ui/button"
|
import { Button } from "../../../components/ui/button"
|
||||||
import { useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { useCreateWorkspacePostMutation } from "../../../Redux/Service/workspace.mode";
|
import { useCreateWorkspacePostMutation } from "../../../Redux/Service/workspace.mode";
|
||||||
import { Toaster, toaster } from "../../../components/ui/toaster";
|
import { Toaster, toaster } from "../../../components/ui/toaster";
|
||||||
|
|
||||||
function WorkAddModel({ refetch }: { refetch: VoidFunction }) {
|
function WorkAddModel({ refetch }: { refetch: VoidFunction }) {
|
||||||
const [title, setTitle] = useState('')
|
const [title, setTitle] = useState('')
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
const [createWorkspacePost] = useCreateWorkspacePostMutation()
|
const [createWorkspacePost, { isLoading }] = useCreateWorkspacePostMutation()
|
||||||
|
|
||||||
const handleOpenModal = () => {
|
const handleOpenModal = () => {
|
||||||
setIsOpen(true);
|
setIsOpen(true);
|
||||||
@@ -40,6 +40,12 @@ function WorkAddModel({ refetch }: { refetch: VoidFunction }) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!isOpen) {
|
||||||
|
setTitle("");
|
||||||
|
}
|
||||||
|
}, [isOpen]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
||||||
<DialogRoot placement="center" open={isOpen}>
|
<DialogRoot placement="center" open={isOpen}>
|
||||||
@@ -88,7 +94,7 @@ function WorkAddModel({ refetch }: { refetch: VoidFunction }) {
|
|||||||
|
|
||||||
</DialogBody>
|
</DialogBody>
|
||||||
<DialogFooter display="flex" justifyContent="center" pt={"2"}>
|
<DialogFooter display="flex" justifyContent="center" pt={"2"}>
|
||||||
<Button w="100%" bg="#02A0A0" color={"#fff"} onClick={handleSubmit}>
|
<Button w="100%" bg="#02A0A0" color={"#fff"} onClick={handleSubmit} disabled={isLoading}>
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
</DialogFooter>
|
</DialogFooter>
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ const tableHeadRow = [
|
|||||||
|
|
||||||
const WorkspaceMode = () => {
|
const WorkspaceMode = () => {
|
||||||
const [currentPage, setCurrentPage] = useState(1);
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
const { data, refetch } = useGetWorkSpaceModeQuery(currentPage)
|
const { data, refetch, isError, isFetching } = useGetWorkSpaceModeQuery(currentPage)
|
||||||
const [localData, setLocalData] = useState<any[]>([]);
|
const [localData, setLocalData] = useState<any[]>([]);
|
||||||
const [searchTerm, setSearchTerm] = useState("");
|
const [searchTerm, setSearchTerm] = useState("");
|
||||||
const [workspaceToggle] = useWorkspaceToggleMutation()
|
const [workspaceToggle] = useWorkspaceToggleMutation()
|
||||||
@@ -63,12 +63,17 @@ const WorkspaceMode = () => {
|
|||||||
);
|
);
|
||||||
try {
|
try {
|
||||||
await workspaceToggle({ id: agencyId, is_active: newStatus }).unwrap();
|
await workspaceToggle({ id: agencyId, is_active: newStatus }).unwrap();
|
||||||
|
toaster.create({
|
||||||
|
title: "Success",
|
||||||
|
description: "Status updated successfully",
|
||||||
|
type: "success",
|
||||||
|
});
|
||||||
refetch()
|
refetch()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error updating privacy policy:", error);
|
console.error("Error updating privacy policy:", error);
|
||||||
toaster.create({
|
toaster.create({
|
||||||
title: "Error",
|
title: "Error",
|
||||||
description: "Someting went wrong.",
|
description: "Please try again later.",
|
||||||
type: "error",
|
type: "error",
|
||||||
});
|
});
|
||||||
setLocalData((prevData) =>
|
setLocalData((prevData) =>
|
||||||
@@ -88,7 +93,9 @@ const WorkspaceMode = () => {
|
|||||||
const managepost = filteredData?.map((agency: any, index: number) => ({
|
const managepost = filteredData?.map((agency: any, index: number) => ({
|
||||||
'id': agency.id,
|
'id': agency.id,
|
||||||
"Sr. No": (currentPage - 1) * (data?.data.per_page ?? 0) + index + 1,
|
"Sr. No": (currentPage - 1) * (data?.data.per_page ?? 0) + index + 1,
|
||||||
"Title": agency.en_name,
|
"Title": agency.en_name.length > 12
|
||||||
|
? agency.en_name.slice(0, 12) + '...'
|
||||||
|
: agency.en_name,
|
||||||
"is_active": agency.is_active,
|
"is_active": agency.is_active,
|
||||||
"Action": (
|
"Action": (
|
||||||
<HStack justifyContent="center">
|
<HStack justifyContent="center">
|
||||||
@@ -131,7 +138,7 @@ const WorkspaceMode = () => {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
{/* <Button bgColor={'#EEEEEE'} pl={3} pr={3}><IoMdAdd /> <Text>Add</Text></Button> */}
|
{/* <Button bgColor={'#EEEEEE'} pl={3} pr={3}><IoMdAdd /> <Text>Add</Text></Button> */}
|
||||||
<WorkAddModel refetch={refetch}/>
|
<WorkAddModel refetch={refetch} />
|
||||||
</HStack>
|
</HStack>
|
||||||
</HStack>
|
</HStack>
|
||||||
<DataTable
|
<DataTable
|
||||||
@@ -145,6 +152,8 @@ const WorkspaceMode = () => {
|
|||||||
total: data?.data.total || 0
|
total: data?.data.total || 0
|
||||||
}}
|
}}
|
||||||
onPageChange={handlePageChange}
|
onPageChange={handlePageChange}
|
||||||
|
isLoading={isFetching}
|
||||||
|
isError={isError}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
<Toaster />
|
<Toaster />
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
|
|
||||||
import { DialogCloseTrigger, Field, IconButton, Input, Stack, Text } from "@chakra-ui/react";
|
import { DialogCloseTrigger, Field, IconButton, Input, Stack, Text } from "@chakra-ui/react";
|
||||||
import { Button } from "../../components/ui/button";
|
import { Button } from "../../components/ui/button";
|
||||||
import { DialogBody, DialogContent, DialogFooter, DialogHeader, DialogRoot, DialogTitle, DialogTrigger } from "../../components/ui/dialog";
|
import { DialogBody, DialogContent, DialogFooter, DialogHeader, DialogRoot, DialogTitle } from "../../components/ui/dialog";
|
||||||
// import EnterPassword from "./EnterPassword";
|
// import EnterPassword from "./EnterPassword";
|
||||||
import { useForm } from "react-hook-form";
|
import { useForm } from "react-hook-form";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { toaster } from "../../components/ui/toaster";
|
import { toaster, Toaster } from "../../components/ui/toaster";
|
||||||
import { useNewPasswordSetMutation } from "../../Redux/Service/profile.password";
|
import { useNewPasswordSetMutation } from "../../Redux/Service/profile.password";
|
||||||
import { LuEye, LuEyeOff } from "react-icons/lu";
|
import { LuEye, LuEyeOff } from "react-icons/lu";
|
||||||
import { InputGroup } from "../../components/ui/input-group";
|
import { InputGroup } from "../../components/ui/input-group";
|
||||||
@@ -114,11 +114,11 @@ function Changepassword({ onClose, isOpen }: EnterPasswordProps) {
|
|||||||
onOpenChange={(open) => !open && onClose()}
|
onOpenChange={(open) => !open && onClose()}
|
||||||
>
|
>
|
||||||
|
|
||||||
<DialogTrigger asChild>
|
{/* <DialogTrigger asChild>
|
||||||
<Button bg="#02A0A0" size={'2xs'} color={"#fff"} px={2} >
|
<Button bg="#02A0A0" size={'2xs'} color={"#fff"} px={2} >
|
||||||
Change Password
|
Change Password
|
||||||
</Button>
|
</Button>
|
||||||
</DialogTrigger>
|
</DialogTrigger> */}
|
||||||
|
|
||||||
<DialogContent
|
<DialogContent
|
||||||
bg={"#fff"}
|
bg={"#fff"}
|
||||||
@@ -203,7 +203,7 @@ function Changepassword({ onClose, isOpen }: EnterPasswordProps) {
|
|||||||
pl={1}
|
pl={1}
|
||||||
fontSize="12px"
|
fontSize="12px"
|
||||||
height="30px"
|
height="30px"
|
||||||
type= {showNewPassword ? "password" : "Text"}
|
type={showNewPassword ? "text" : "password"}
|
||||||
border={errors.confirm_password ? "1px solid red" : "1px solid grey"}
|
border={errors.confirm_password ? "1px solid red" : "1px solid grey"}
|
||||||
{...register("confirm_password", {
|
{...register("confirm_password", {
|
||||||
required: "Please confirm your password",
|
required: "Please confirm your password",
|
||||||
@@ -240,6 +240,7 @@ function Changepassword({ onClose, isOpen }: EnterPasswordProps) {
|
|||||||
<DialogCloseTrigger color="black" />
|
<DialogCloseTrigger color="black" />
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
</DialogRoot >
|
</DialogRoot >
|
||||||
|
<Toaster />
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,9 +6,78 @@ import { Field } from "../../components/ui/field";
|
|||||||
// import Changepassword from "./ChangePassword";
|
// import Changepassword from "./ChangePassword";
|
||||||
import EnterPassword from "./EnterPassword";
|
import EnterPassword from "./EnterPassword";
|
||||||
import { useGetProfileQuery } from "../../Redux/Service/profile.password";
|
import { useGetProfileQuery } from "../../Redux/Service/profile.password";
|
||||||
|
// import { useUpdateImageMutation } from "../../Redux/Service/myprofie.service";
|
||||||
|
import { useEffect, useRef, useState } from "react";
|
||||||
|
import { Toaster, toaster } from "../../components/ui/toaster";
|
||||||
|
import axios from "axios";
|
||||||
|
|
||||||
|
const APIURL = import.meta.env.VITE_API_URL
|
||||||
|
const PROFILEIMGURL = import.meta.env.VITE_IMG_PROFILE
|
||||||
|
|
||||||
const Profile = () => {
|
const Profile = () => {
|
||||||
const { data } = useGetProfileQuery()
|
const { data, refetch } = useGetProfileQuery()
|
||||||
|
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||||
|
const [avatarSrc, setAvatarSrc] = useState<string>("");
|
||||||
|
// const [updateImage] = useUpdateImageMutation();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (data?.data.profile_photo) {
|
||||||
|
setAvatarSrc(data.data.profile_photo);
|
||||||
|
}
|
||||||
|
}, [data?.data.profile_photo]);
|
||||||
|
|
||||||
|
|
||||||
|
const handleClick = () => {
|
||||||
|
fileInputRef.current?.click();
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleFileChange = async (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
const file = e.target.files?.[0];
|
||||||
|
if (!file) return;
|
||||||
|
|
||||||
|
if (file.size > 2 * 1024 * 1024) {
|
||||||
|
alert("File size exceeds 2MB limit.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Preview the image
|
||||||
|
const previewUrl = URL.createObjectURL(file);
|
||||||
|
setAvatarSrc(previewUrl);
|
||||||
|
|
||||||
|
// Prepare FormData
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append("profile_photo", file, file.name);
|
||||||
|
|
||||||
|
const token = localStorage.getItem("token");
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (token) {
|
||||||
|
await axios.post(`${APIURL}/profile-image-edit`, formData, {
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'multipart/form-data',
|
||||||
|
'access-token': `${token}`,
|
||||||
|
},
|
||||||
|
// withCredentials: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
toaster.create({
|
||||||
|
title: "Success",
|
||||||
|
description: "Updated successfully",
|
||||||
|
type: "success",
|
||||||
|
});
|
||||||
|
refetch();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error updating image:", error);
|
||||||
|
toaster.create({
|
||||||
|
title: "Error",
|
||||||
|
description: "Something went wrong",
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
console.log('PROFILE DATA:', data?.data);
|
console.log('PROFILE DATA:', data?.data);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -20,10 +89,11 @@ const Profile = () => {
|
|||||||
<HStack shadow={'md'} rounded={'lg'} justifyContent={'space-between'} alignItems={'flex-end'} w={'100%'} px={3} py={3} >
|
<HStack shadow={'md'} rounded={'lg'} justifyContent={'space-between'} alignItems={'flex-end'} w={'100%'} px={3} py={3} >
|
||||||
<VStack w={'100%'} alignItems={'flex-start'} gap={0}>
|
<VStack w={'100%'} alignItems={'flex-start'} gap={0}>
|
||||||
<Box mb={2} position="relative" width="fit-content"
|
<Box mb={2} position="relative" width="fit-content"
|
||||||
cursor="pointer" onClick={() => alert("Avatar clicked!")}>
|
cursor="pointer" onClick={handleClick}>
|
||||||
<Avatar.Root size={"2xl"} style={{ display: "inline-block", width: "auto" }}>
|
<Avatar.Root size={"2xl"} style={{ display: "flex", width: "50px", height: '50px', justifyContent: 'center' }}>
|
||||||
<Avatar.Fallback />
|
<Avatar.Fallback />
|
||||||
<Avatar.Image src="https://i.pinimg.com/736x/d6/cd/0f/d6cd0ffd4634b0763d3958a7325ce26e.jpg" />
|
{/* <Avatar.Image src="https://i.pinimg.com/736x/d6/cd/0f/d6cd0ffd4634b0763d3958a7325ce26e.jpg" /> */}
|
||||||
|
{avatarSrc && <Avatar.Image src={`${PROFILEIMGURL}${avatarSrc}`} />}
|
||||||
</Avatar.Root>
|
</Avatar.Root>
|
||||||
<Box
|
<Box
|
||||||
position="absolute"
|
position="absolute"
|
||||||
@@ -33,6 +103,13 @@ const Profile = () => {
|
|||||||
>
|
>
|
||||||
<FaCamera color="#ccc" size={16} />
|
<FaCamera color="#ccc" size={16} />
|
||||||
</Box>
|
</Box>
|
||||||
|
<input
|
||||||
|
type="file"
|
||||||
|
accept="image/*"
|
||||||
|
ref={fileInputRef}
|
||||||
|
style={{ display: "none" }}
|
||||||
|
onChange={handleFileChange}
|
||||||
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
<Text color={"black"} as={'span'} fontSize={'sm'} fontWeight={"bold"}>{`${data?.data?.first_name.charAt(0).toUpperCase()}${data?.data.first_name.slice(1)}`}
|
<Text color={"black"} as={'span'} fontSize={'sm'} fontWeight={"bold"}>{`${data?.data?.first_name.charAt(0).toUpperCase()}${data?.data.first_name.slice(1)}`}
|
||||||
</Text>
|
</Text>
|
||||||
@@ -63,7 +140,7 @@ const Profile = () => {
|
|||||||
</VStack>
|
</VStack>
|
||||||
|
|
||||||
</HStack>
|
</HStack>
|
||||||
|
<Toaster />
|
||||||
</MainFrame >
|
</MainFrame >
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ const SetNewPassword = () => {
|
|||||||
height={"fit-content"}
|
height={"fit-content"}
|
||||||
mr={2}
|
mr={2}
|
||||||
>
|
>
|
||||||
{showOldPassword ? <LuEye /> : <LuEyeOff />}
|
{showOldPassword ? <LuEyeOff /> : <LuEye />}
|
||||||
</IconButton>
|
</IconButton>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
@@ -158,7 +158,7 @@ const SetNewPassword = () => {
|
|||||||
color={"#000"}
|
color={"#000"}
|
||||||
mr={2}
|
mr={2}
|
||||||
>
|
>
|
||||||
{showNewPassword ? <LuEye /> : <LuEyeOff />}
|
{showNewPassword ? <LuEyeOff /> : <LuEye />}
|
||||||
</IconButton>
|
</IconButton>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -12,26 +12,54 @@ import {
|
|||||||
import { Field, Grid, Heading, Input, Stack, Text } from "@chakra-ui/react";
|
import { Field, Grid, Heading, Input, Stack, Text } from "@chakra-ui/react";
|
||||||
import { IoMdAdd } from "react-icons/io";
|
import { IoMdAdd } from "react-icons/io";
|
||||||
import { Checkbox } from "../../components/ui/checkbox";
|
import { Checkbox } from "../../components/ui/checkbox";
|
||||||
import { useCreateSubAdminPostMutation } from "../../Redux/Service/manage.subadmin.service";
|
import { PermissionResponse, useCreateSubAdminPostMutation } from "../../Redux/Service/manage.subadmin.service";
|
||||||
import { toaster } from "../../components/ui/toaster";
|
import { toaster, Toaster } from "../../components/ui/toaster";
|
||||||
import { useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
|
|
||||||
function AddModel({ refetch }: { refetch: VoidFunction }) {
|
function AddModel({ refetch, allPermissions }: { refetch: VoidFunction, allPermissions?: PermissionResponse }) {
|
||||||
const [createSubAdminPost] = useCreateSubAdminPostMutation();
|
const [createSubAdminPost, { isLoading }] = useCreateSubAdminPostMutation();
|
||||||
|
|
||||||
// State fields
|
// State fields
|
||||||
const [firstName, setFirstName] = useState("");
|
const [firstName, setFirstName] = useState("");
|
||||||
const [lastName, setLastName] = useState("");
|
const [lastName, setLastName] = useState("");
|
||||||
const [userName, setUserName] = useState("");
|
// const [userName, setUserName] = useState("");
|
||||||
const [dateOfBirth, setDateOfBirth] = useState("");
|
const [dateOfBirth, setDateOfBirth] = useState("");
|
||||||
const [gender, setGender] = useState("");
|
const [gender, setGender] = useState("");
|
||||||
const [ setIsOpen] = useState(false);
|
const [email, setEmail] = useState("");
|
||||||
|
const [phonenumber, setPhonenumber] = useState("");
|
||||||
|
const [permissions, setPermission] = useState<number[]>([]);
|
||||||
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
|
// const [ setIsOpen] = useState(false);
|
||||||
|
|
||||||
|
const handleOpenModal = () => {
|
||||||
|
setIsOpen(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleCheckboxToggle = (permissionId: number) => {
|
||||||
|
setPermission((prevData) =>
|
||||||
|
prevData.includes(permissionId)
|
||||||
|
? prevData.filter((id) => id !== permissionId)
|
||||||
|
: [...prevData, permissionId]
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!isOpen) {
|
||||||
|
setFirstName("");
|
||||||
|
setLastName("");
|
||||||
|
// setUserName("");
|
||||||
|
setDateOfBirth("");
|
||||||
|
setGender("");
|
||||||
|
setEmail("");
|
||||||
|
setPhonenumber("");
|
||||||
|
setPermission([]);
|
||||||
|
}
|
||||||
|
}, [isOpen]);
|
||||||
|
|
||||||
const handleSubmit = async () => {
|
const handleSubmit = async () => {
|
||||||
if (
|
if (
|
||||||
!firstName.trim() ||
|
!firstName.trim() ||
|
||||||
!lastName.trim() ||
|
!lastName.trim() ||
|
||||||
!userName.trim() ||
|
|
||||||
!dateOfBirth.trim() ||
|
!dateOfBirth.trim() ||
|
||||||
!gender.trim()
|
!gender.trim()
|
||||||
) {
|
) {
|
||||||
@@ -43,17 +71,35 @@ function AddModel({ refetch }: { refetch: VoidFunction }) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||||
|
if (!emailRegex.test(email)) {
|
||||||
|
toaster.create({
|
||||||
|
title: "Invalid Email",
|
||||||
|
description: "Please enter a valid email address",
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (phonenumber.length !== 10) {
|
||||||
|
toaster.create({
|
||||||
|
title: "Invalid Phone Number",
|
||||||
|
description: "Phone number must be exactly 10 digits",
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const payload = {
|
const payload = {
|
||||||
principal_type_xid: 4,
|
// user_name: userName,
|
||||||
principal_source_xid: 1,
|
|
||||||
user_name: userName,
|
|
||||||
first_name: firstName,
|
first_name: firstName,
|
||||||
last_name: lastName,
|
last_name: lastName,
|
||||||
date_of_birth: dateOfBirth,
|
date_of_birth: dateOfBirth,
|
||||||
gender: gender,
|
gender: gender,
|
||||||
email_address: "example@yopmail.com", // Hardcoded
|
email_address: email,
|
||||||
phone_number: "9876543210", // Hardcoded
|
phone_number: phonenumber,
|
||||||
created_by: 1,
|
permission: permissions.filter((id) => typeof id === "number"),
|
||||||
|
// created_by: 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -65,27 +111,33 @@ function AddModel({ refetch }: { refetch: VoidFunction }) {
|
|||||||
type: "success",
|
type: "success",
|
||||||
});
|
});
|
||||||
refetch();
|
refetch();
|
||||||
setIsOpen(false);
|
|
||||||
setFirstName("");
|
setFirstName("");
|
||||||
setLastName("");
|
setLastName("");
|
||||||
setUserName("");
|
// setUserName("");
|
||||||
setDateOfBirth("");
|
setDateOfBirth("");
|
||||||
setGender("");
|
setGender("");
|
||||||
|
setIsOpen(false);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error:any) {
|
||||||
console.error("Error creating sub-admin:", error);
|
console.error("Error creating sub-admin:", error);
|
||||||
toaster.create({
|
toaster.create({
|
||||||
title: "Error",
|
title: "Error",
|
||||||
description: "Failed to create sub-admin",
|
description: error ? error.data.message : "Failed to create sub-admin",
|
||||||
type: "error",
|
type: "error",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DialogRoot placement="center">
|
<DialogRoot placement="center" open={isOpen} onOpenChange={({ open }) => setIsOpen(open)}>
|
||||||
<DialogTrigger asChild>
|
<DialogTrigger asChild>
|
||||||
<Button rounded={"md"} px={4} py={2} size={"xs"} bg={"#02A0A0"}>
|
|
||||||
|
<Button
|
||||||
|
rounded={"md"}
|
||||||
|
px={4} py={2}
|
||||||
|
size={"xs"}
|
||||||
|
bg={"#02A0A0"}
|
||||||
|
onClick={handleOpenModal}>
|
||||||
<IoMdAdd /> Add
|
<IoMdAdd /> Add
|
||||||
</Button>
|
</Button>
|
||||||
</DialogTrigger>
|
</DialogTrigger>
|
||||||
@@ -138,7 +190,7 @@ function AddModel({ refetch }: { refetch: VoidFunction }) {
|
|||||||
onChange={(e) => setLastName(e.target.value)}
|
onChange={(e) => setLastName(e.target.value)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Field.Label color="black" pt={1} fontSize="12px">
|
{/* <Field.Label color="black" pt={1} fontSize="12px">
|
||||||
Username
|
Username
|
||||||
</Field.Label>
|
</Field.Label>
|
||||||
<Input
|
<Input
|
||||||
@@ -151,7 +203,7 @@ function AddModel({ refetch }: { refetch: VoidFunction }) {
|
|||||||
height="30px"
|
height="30px"
|
||||||
value={userName}
|
value={userName}
|
||||||
onChange={(e) => setUserName(e.target.value)}
|
onChange={(e) => setUserName(e.target.value)}
|
||||||
/>
|
/> */}
|
||||||
|
|
||||||
<Field.Label color="black" pt={1} fontSize="12px">
|
<Field.Label color="black" pt={1} fontSize="12px">
|
||||||
DOB
|
DOB
|
||||||
@@ -184,30 +236,63 @@ function AddModel({ refetch }: { refetch: VoidFunction }) {
|
|||||||
onChange={(e) => setGender(e.target.value)}
|
onChange={(e) => setGender(e.target.value)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<Field.Label color="black" pt={1} fontSize="12px">
|
||||||
|
Email Address
|
||||||
|
</Field.Label>
|
||||||
|
<Input
|
||||||
|
placeholder="Enter Email address"
|
||||||
|
bgColor="#EEEEEE"
|
||||||
|
color="black"
|
||||||
|
border="none"
|
||||||
|
pl={1}
|
||||||
|
type="email"
|
||||||
|
fontSize="12px"
|
||||||
|
height="30px"
|
||||||
|
value={email}
|
||||||
|
onChange={(e) => setEmail(e.target.value)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Field.Label color="black" pt={1} fontSize="12px">
|
||||||
|
Phone Number
|
||||||
|
</Field.Label>
|
||||||
|
<Input
|
||||||
|
placeholder="Enter phone number"
|
||||||
|
bgColor="#EEEEEE"
|
||||||
|
color="black"
|
||||||
|
border="none"
|
||||||
|
type="tel"
|
||||||
|
pl={1}
|
||||||
|
fontSize="12px"
|
||||||
|
height="30px"
|
||||||
|
value={phonenumber}
|
||||||
|
onChange={(e) => {
|
||||||
|
const value = e.target.value;
|
||||||
|
if (/^\d*$/.test(value)) { // Only allow digits
|
||||||
|
setPhonenumber(value);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
<Heading mt={5} color={"#000"} fontSize={"sm"}>
|
<Heading mt={5} color={"#000"} fontSize={"sm"}>
|
||||||
Permissions
|
Permissions
|
||||||
</Heading>
|
</Heading>
|
||||||
</Field.Root>
|
</Field.Root>
|
||||||
|
|
||||||
<Grid templateColumns="repeat(2, 1fr)" gap={4}>
|
<Grid templateColumns="repeat(2, 1fr)" gap={4}>
|
||||||
{[
|
{Array.isArray(allPermissions?.data?.permission)
|
||||||
"Dashboard",
|
? allPermissions.data.permission.map((permission: any) => (
|
||||||
"Manage contact us",
|
<Checkbox
|
||||||
"manage User",
|
size="sm"
|
||||||
"Manage CMS",
|
color="black"
|
||||||
"Manage Post",
|
key={permission.id}
|
||||||
"Manage Reports",
|
checked={permissions.includes(permission.id)}
|
||||||
"manage Sub-Admin",
|
onChange={() => handleCheckboxToggle(permission.id)}
|
||||||
"My profile",
|
>
|
||||||
"Manage Jobs",
|
<Text fontSize={12}>{permission.app_resource_title}</Text>
|
||||||
"manage feedbacks",
|
</Checkbox>
|
||||||
"Manage community",
|
))
|
||||||
"Notification",
|
: <Text fontSize={12} color="gray.500">Loading permissions...</Text>
|
||||||
].map((permission) => (
|
}
|
||||||
<Checkbox size="sm" color="black" key={permission}>
|
|
||||||
<Text fontSize={12}>{permission}</Text>
|
|
||||||
</Checkbox>
|
|
||||||
))}
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</Stack>
|
</Stack>
|
||||||
</DialogBody>
|
</DialogBody>
|
||||||
@@ -219,13 +304,14 @@ function AddModel({ refetch }: { refetch: VoidFunction }) {
|
|||||||
bg="#02A0A0"
|
bg="#02A0A0"
|
||||||
color={"#fff"}
|
color={"#fff"}
|
||||||
onClick={handleSubmit}
|
onClick={handleSubmit}
|
||||||
|
disabled={isLoading}
|
||||||
>
|
>
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
</DialogFooter>
|
</DialogFooter>
|
||||||
|
<DialogCloseTrigger color="black" onClick={() => setIsOpen(false)} />
|
||||||
<DialogCloseTrigger color="black" />
|
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
|
<Toaster />
|
||||||
</DialogRoot>
|
</DialogRoot>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Field, Grid, Heading, Input, Stack, Text } from "@chakra-ui/react";
|
import { Field, Grid, Heading, Input, Stack, Text } from "@chakra-ui/react";
|
||||||
// import { TbEdit } from "react-icons/tb";
|
// import { TbEdit } from "react-icons/tb";
|
||||||
import { Button } from "./ui/button";
|
import { Button } from "../../components/ui/button";
|
||||||
import { Checkbox } from "./ui/checkbox";
|
import { Checkbox } from "../../components/ui/checkbox";
|
||||||
import {
|
import {
|
||||||
DialogBody,
|
DialogBody,
|
||||||
DialogCloseTrigger,
|
DialogCloseTrigger,
|
||||||
@@ -11,25 +11,23 @@ import {
|
|||||||
DialogRoot,
|
DialogRoot,
|
||||||
DialogTitle,
|
DialogTitle,
|
||||||
DialogTrigger,
|
DialogTrigger,
|
||||||
} from "./ui/dialog";
|
} from "../../components/ui/dialog";
|
||||||
import Edit from "./ActionIcons/Edit";
|
import Edit from "../../components/ActionIcons/Edit";
|
||||||
import { useLazyViewSubAdminQuery, useUpdateSubAdminMutation } from "../Redux/Service/manage.subadmin.service";
|
import { PermissionResponse, useLazyViewSubAdminQuery, useUpdateSubAdminMutation } from "../../Redux/Service/manage.subadmin.service";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { toaster } from "./ui/toaster";
|
import { Toaster, toaster } from "../../components/ui/toaster";
|
||||||
|
|
||||||
const resourceIdToLabel: { [key: number]: string } = {
|
const resourceIdToLabel: { [key: number]: string } = {
|
||||||
1: 'Dashboard',
|
1: 'Dashboard',
|
||||||
2: 'Manage contact us',
|
2: 'Manage User',
|
||||||
3: 'Manage User',
|
3: 'Manage Post',
|
||||||
4: 'Manage CMS',
|
4: 'Manage Subadmin',
|
||||||
5: 'Manage Post',
|
5: 'Manage Jobs',
|
||||||
6: 'Manage Reports',
|
6: 'Manage Groups',
|
||||||
7: 'Manage Sub-Admin',
|
7: 'Manage Contact Us',
|
||||||
8: 'My profile',
|
8: 'Manage CMS',
|
||||||
9: 'Manage Jobs',
|
9: 'My Profile',
|
||||||
10: 'Manage feedbacks',
|
10: 'Master Module',
|
||||||
11: 'Manage community',
|
|
||||||
12: 'Notification',
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -37,11 +35,15 @@ interface ResourceActionLink {
|
|||||||
id: number;
|
id: number;
|
||||||
app_resource_xid: number;
|
app_resource_xid: number;
|
||||||
is_active: boolean;
|
is_active: boolean;
|
||||||
|
app_resource: {
|
||||||
|
id: number,
|
||||||
|
app_resource_title: string
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function EditSubAdmin({ id, refetch }: { id: number, refetch: VoidFunction }) {
|
function EditSubAdmin({ id, refetch, allPermissions }: { id: number, refetch: VoidFunction, allPermissions?: PermissionResponse }) {
|
||||||
const [trigger, { data }] = useLazyViewSubAdminQuery();
|
const [trigger, { data }] = useLazyViewSubAdminQuery();
|
||||||
const [updateSubAdmin] = useUpdateSubAdminMutation()
|
const [updateSubAdmin, {isLoading}] = useUpdateSubAdminMutation()
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
const [editData, setEditData] = useState<{
|
const [editData, setEditData] = useState<{
|
||||||
id: string;
|
id: string;
|
||||||
@@ -62,8 +64,23 @@ function EditSubAdmin({ id, refetch }: { id: number, refetch: VoidFunction }) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (data?.data && data.data.length > 0) {
|
if (data?.data?.length && allPermissions?.data?.permission?.length) {
|
||||||
const subAdmin = data.data[0]; // Extract the first item from the array
|
const subAdmin = data.data[0];
|
||||||
|
|
||||||
|
const activePermissionIds = subAdmin.get_resource_action_link
|
||||||
|
.filter((perm: any) => perm.is_active)
|
||||||
|
.map((perm: any) => perm.app_resource_xid);
|
||||||
|
|
||||||
|
const mergedPermissions: ResourceActionLink[] = allPermissions.data.permission.map((perm) => ({
|
||||||
|
id: perm.id,
|
||||||
|
app_resource_xid: perm.id,
|
||||||
|
is_active: activePermissionIds.includes(perm.id),
|
||||||
|
app_resource: {
|
||||||
|
id: perm.id,
|
||||||
|
app_resource_title: perm.app_resource_title,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
// Map the API response to editData
|
// Map the API response to editData
|
||||||
setEditData({
|
setEditData({
|
||||||
@@ -73,10 +90,10 @@ function EditSubAdmin({ id, refetch }: { id: number, refetch: VoidFunction }) {
|
|||||||
last_name: subAdmin.last_name,
|
last_name: subAdmin.last_name,
|
||||||
date_of_birth: formatDateOfBirth(subAdmin.date_of_birth),
|
date_of_birth: formatDateOfBirth(subAdmin.date_of_birth),
|
||||||
gender: subAdmin.gender,
|
gender: subAdmin.gender,
|
||||||
permission: subAdmin.get_resource_action_link,
|
permission: mergedPermissions,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, [data]);
|
}, [data, allPermissions]);
|
||||||
|
|
||||||
const formatDateOfBirth = (dob: string): string => {
|
const formatDateOfBirth = (dob: string): string => {
|
||||||
// Convert the date to the desired format with slashes
|
// Convert the date to the desired format with slashes
|
||||||
@@ -99,7 +116,7 @@ function EditSubAdmin({ id, refetch }: { id: number, refetch: VoidFunction }) {
|
|||||||
setEditData((prevData) => ({
|
setEditData((prevData) => ({
|
||||||
...prevData,
|
...prevData,
|
||||||
permission: prevData.permission.map((permission) =>
|
permission: prevData.permission.map((permission) =>
|
||||||
permission.id === permissionId
|
permission.app_resource_xid === permissionId
|
||||||
? { ...permission, is_active: !permission.is_active }
|
? { ...permission, is_active: !permission.is_active }
|
||||||
: permission
|
: permission
|
||||||
),
|
),
|
||||||
@@ -113,12 +130,14 @@ function EditSubAdmin({ id, refetch }: { id: number, refetch: VoidFunction }) {
|
|||||||
|
|
||||||
const payload = {
|
const payload = {
|
||||||
id: Number(editData.id),
|
id: Number(editData.id),
|
||||||
unique_id: editData.unique_id,
|
// unique_id: editData.unique_id,
|
||||||
first_name: editData.first_name,
|
first_name: editData.first_name,
|
||||||
last_name: editData.last_name,
|
last_name: editData.last_name,
|
||||||
date_of_birth: editData.date_of_birth,
|
date_of_birth: editData.date_of_birth,
|
||||||
gender: editData.gender,
|
gender: editData.gender,
|
||||||
permission: editData.permission
|
permission: editData.permission
|
||||||
|
.filter((p) => p.is_active)
|
||||||
|
.map((p) => p.app_resource_xid),
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -171,7 +190,7 @@ function EditSubAdmin({ id, refetch }: { id: number, refetch: VoidFunction }) {
|
|||||||
<DialogBody bg="white">
|
<DialogBody bg="white">
|
||||||
<Stack py={3}>
|
<Stack py={3}>
|
||||||
<Field.Root>
|
<Field.Root>
|
||||||
<Field.Label color="black" pt={1} fontSize="12px">
|
{/* <Field.Label color="black" pt={1} fontSize="12px">
|
||||||
ID
|
ID
|
||||||
</Field.Label>
|
</Field.Label>
|
||||||
<Input
|
<Input
|
||||||
@@ -184,7 +203,7 @@ function EditSubAdmin({ id, refetch }: { id: number, refetch: VoidFunction }) {
|
|||||||
height="30px"
|
height="30px"
|
||||||
value={editData.unique_id}
|
value={editData.unique_id}
|
||||||
onChange={(e) => setEditData({ ...editData, unique_id: e.target.value })}
|
onChange={(e) => setEditData({ ...editData, unique_id: e.target.value })}
|
||||||
/>
|
/> */}
|
||||||
|
|
||||||
<Field.Label color="black" pt={1} fontSize="12px">
|
<Field.Label color="black" pt={1} fontSize="12px">
|
||||||
First Name
|
First Name
|
||||||
@@ -248,44 +267,6 @@ function EditSubAdmin({ id, refetch }: { id: number, refetch: VoidFunction }) {
|
|||||||
Permissions
|
Permissions
|
||||||
</Heading>
|
</Heading>
|
||||||
</Field.Root>
|
</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}>
|
<Grid templateColumns="repeat(2, 1fr)" gap={4}>
|
||||||
{editData.permission.map((permission) => {
|
{editData.permission.map((permission) => {
|
||||||
const label = resourceIdToLabel[permission.app_resource_xid];
|
const label = resourceIdToLabel[permission.app_resource_xid];
|
||||||
@@ -295,7 +276,7 @@ function EditSubAdmin({ id, refetch }: { id: number, refetch: VoidFunction }) {
|
|||||||
size="sm"
|
size="sm"
|
||||||
color="black"
|
color="black"
|
||||||
checked={permission.is_active}
|
checked={permission.is_active}
|
||||||
onChange={() => handleCheckboxToggle(permission.id)}
|
onChange={() => handleCheckboxToggle(permission.app_resource_xid)}
|
||||||
cursor={'pointer'}
|
cursor={'pointer'}
|
||||||
>
|
>
|
||||||
<Text fontSize={12}>{label}</Text>
|
<Text fontSize={12}>{label}</Text>
|
||||||
@@ -306,12 +287,13 @@ function EditSubAdmin({ id, refetch }: { id: number, refetch: VoidFunction }) {
|
|||||||
</Stack>
|
</Stack>
|
||||||
</DialogBody>
|
</DialogBody>
|
||||||
<DialogFooter display="flex" justifyContent="center" pt={"2"}>
|
<DialogFooter display="flex" justifyContent="center" pt={"2"}>
|
||||||
<Button size={"xs"} w="100%" bg="#02A0A0" color={"#fff"} onClick={handleSubmit}>
|
<Button size={"xs"} w="100%" bg="#02A0A0" color={"#fff"} onClick={handleSubmit} disabled={isLoading}>
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
</DialogFooter>
|
</DialogFooter>
|
||||||
<DialogCloseTrigger color="black" onClick={() => setIsOpen(false)} />
|
<DialogCloseTrigger color="black" onClick={() => setIsOpen(false)} />
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
|
<Toaster />
|
||||||
</DialogRoot>
|
</DialogRoot>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -1,24 +1,26 @@
|
|||||||
import { Box, HStack, Image, Input, Text } from "@chakra-ui/react"
|
import { Box, HStack, Image, Text } from "@chakra-ui/react"
|
||||||
import MainFrame from "../../components/MainFrame"
|
import MainFrame from "../../components/MainFrame"
|
||||||
import { InputGroup } from "../../components/ui/input-group"
|
// import { InputGroup } from "../../components/ui/input-group"
|
||||||
import { LuSearch } from "react-icons/lu"
|
// import { LuSearch } from "react-icons/lu"
|
||||||
import DataTable from "../../components/DataTable"
|
import DataTable from "../../components/DataTable"
|
||||||
import AlertDailog from "../../components/AlertDailog";
|
import AlertDailog from "../../components/AlertDailog";
|
||||||
// import { RiDeleteBin5Line } from "react-icons/ri";
|
// import { RiDeleteBin5Line } from "react-icons/ri";
|
||||||
import AddModel from "./AddModel"
|
import AddModel from "./AddModel"
|
||||||
import EditSubAdmin from "../../components/EditSubAdmin"
|
import EditSubAdmin from "./EditSubAdmin"
|
||||||
import ViewSubAdmin from "./ViewSubAdmin"
|
import ViewSubAdmin from "./ViewSubAdmin"
|
||||||
import Delete from "../../components/ActionIcons/Delete"
|
import Delete from "../../components/ActionIcons/Delete"
|
||||||
import { useDeleteSubAdminPostMutation, useGetSubAdminQuery } from "../../Redux/Service/manage.subadmin.service"
|
import { PermissionResponse, useDeleteSubAdminPostMutation, useGetPermissionQuery, useGetSubAdminQuery } from "../../Redux/Service/manage.subadmin.service"
|
||||||
import { useEffect, useState } from "react"
|
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"
|
||||||
|
|
||||||
|
|
||||||
// table data
|
// table data
|
||||||
|
|
||||||
const tableHeadRow = [
|
const tableHeadRow = [
|
||||||
"Sr. No",
|
"Sr. No",
|
||||||
"Id",
|
"Emp ID",
|
||||||
"First Name",
|
"First Name",
|
||||||
"last Name",
|
"last Name",
|
||||||
"DOB",
|
"DOB",
|
||||||
@@ -55,37 +57,52 @@ const tableHeadRow = [
|
|||||||
// ];
|
// ];
|
||||||
|
|
||||||
const SubAdmin = () => {
|
const SubAdmin = () => {
|
||||||
const { data, refetch } = useGetSubAdminQuery()
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
|
// const { data, refetch } = useGetSubAdminQuery()
|
||||||
|
const { data: permissions } = useGetPermissionQuery()
|
||||||
const [localData, setLocalData] = useState<any[]>([]);
|
const [localData, setLocalData] = useState<any[]>([]);
|
||||||
|
const [allPermissions, setAllPermissions] = useState<PermissionResponse>();
|
||||||
const [deleteModal, setDeleteModal] = useState(false)
|
const [deleteModal, setDeleteModal] = useState(false)
|
||||||
const [deleteSubAdminPost] = useDeleteSubAdminPostMutation()
|
const [deleteSubAdminPost] = useDeleteSubAdminPostMutation()
|
||||||
|
const [searchTerm, setSearchTerm] = useState("");
|
||||||
console.log("============================",data);
|
const debouncedSearchTerm = useDebounce(searchTerm, 500);
|
||||||
|
const queryArgs = debouncedSearchTerm ? { page: currentPage, search: debouncedSearchTerm } : { page: currentPage };
|
||||||
|
const { data, refetch, isError, isFetching } = useGetSubAdminQuery(queryArgs);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (data?.data.data) {
|
if (data?.data.data) {
|
||||||
setLocalData(data?.data.data);
|
setLocalData(data?.data.data);
|
||||||
|
setAllPermissions(permissions);
|
||||||
}
|
}
|
||||||
}, [data]);
|
}, [data, permissions]);
|
||||||
|
|
||||||
|
console.log("============================", allPermissions);
|
||||||
console.log('localData', localData);
|
console.log('localData', localData);
|
||||||
|
|
||||||
const handleDeleteFaq = async (faqId: number) => {
|
const handlePageChange = (page: number) => {
|
||||||
|
setCurrentPage(page);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSearchChange = (value: string) => {
|
||||||
|
setSearchTerm(value);
|
||||||
|
setCurrentPage(1);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleDeleteAdmin = async (faqId: number) => {
|
||||||
try {
|
try {
|
||||||
const response = await deleteSubAdminPost(faqId).unwrap();
|
const response = await deleteSubAdminPost(faqId).unwrap();
|
||||||
if (response.success) {
|
if (response.success) {
|
||||||
toaster.create({
|
toaster.create({
|
||||||
title: "Success",
|
title: "Success",
|
||||||
description: "FAQ deleted successfully",
|
description: "Sub Admin deleted successfully",
|
||||||
type: "success",
|
type: "success",
|
||||||
});
|
});
|
||||||
refetch()
|
refetch()
|
||||||
console.log("FAQ deleted successfully:", response);
|
console.log("Sub Admin deleted successfully:", response);
|
||||||
}
|
}
|
||||||
// Optionally, refetch data or update state after deletion
|
// Optionally, refetch data or update state after deletion
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error deleting FAQ:", error);
|
console.error("Error deleting Sub Admin:", error);
|
||||||
toaster.create({
|
toaster.create({
|
||||||
title: "Error",
|
title: "Error",
|
||||||
description: "Something went wrong",
|
description: "Something went wrong",
|
||||||
@@ -102,10 +119,18 @@ const SubAdmin = () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const managepost = localData?.map((agency: any, index: number) => ({
|
const filteredData = localData?.filter((agency) => {
|
||||||
|
const searchLower = searchTerm.toLowerCase();
|
||||||
|
const userName = agency.user_name?.toLowerCase().includes(searchLower);
|
||||||
|
const firstName = agency.first_name?.toLowerCase().includes(searchLower);
|
||||||
|
const lastName = agency.last_name?.toLowerCase().includes(searchLower);
|
||||||
|
return userName || firstName || lastName;
|
||||||
|
});
|
||||||
|
|
||||||
|
const managepost = filteredData?.map((agency: any, index: number) => ({
|
||||||
'id': agency.id,
|
'id': agency.id,
|
||||||
"Sr. No": index + 1,
|
"Sr. No": index + 1,
|
||||||
"Id": agency.unique_id,
|
"Emp ID": agency.unique_id,
|
||||||
"First Name": agency.first_name,
|
"First Name": agency.first_name,
|
||||||
"last Name": agency.last_name,
|
"last Name": agency.last_name,
|
||||||
"DOB": formatDateOfBirth(agency.date_of_birth),
|
"DOB": formatDateOfBirth(agency.date_of_birth),
|
||||||
@@ -114,20 +139,20 @@ const SubAdmin = () => {
|
|||||||
"Action": (
|
"Action": (
|
||||||
<HStack justifyContent="center">
|
<HStack justifyContent="center">
|
||||||
{/* <EditDetails rowData={{ id: agency.id, question: agency.question, answer: agency.answer }} refetch={refetch} /> */}
|
{/* <EditDetails rowData={{ id: agency.id, question: agency.question, answer: agency.answer }} refetch={refetch} /> */}
|
||||||
<ViewSubAdmin id={agency.id}/>
|
<ViewSubAdmin id={agency.id} />
|
||||||
<EditSubAdmin id={agency.id} refetch={refetch} />
|
<EditSubAdmin id={agency.id} refetch={refetch} allPermissions={permissions} />
|
||||||
|
|
||||||
<AlertDailog
|
<AlertDailog
|
||||||
isOpen={deleteModal}
|
isOpen={deleteModal}
|
||||||
AltertTiggerIcon={() => <Delete onClick={() => setDeleteModal(prev => !prev)} />}
|
AltertTiggerIcon={() => <Delete onClick={() => setDeleteModal(prev => !prev)} />}
|
||||||
alertText="Delete FAQ"
|
alertText="Delete sub admin"
|
||||||
alertIcon={<Image src={"DeleteIcon"} h={"39px"} />}
|
alertIcon={<Image src={"DeleteIcon"} h={"39px"} />}
|
||||||
alertCaption="are you sure you want to delete ?"
|
alertCaption="are you sure you want to delete ?"
|
||||||
onClose={() => setDeleteModal(false)}
|
onClose={() => setDeleteModal(false)}
|
||||||
onConfirm={() => {
|
onConfirm={() => {
|
||||||
// console.log("User deleted:", index + 1);
|
// console.log("User deleted:", index + 1);
|
||||||
setDeleteModal(false);
|
setDeleteModal(false);
|
||||||
handleDeleteFaq(agency.id)
|
handleDeleteAdmin(agency.id)
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</HStack>
|
</HStack>
|
||||||
@@ -150,38 +175,31 @@ const SubAdmin = () => {
|
|||||||
</Text>
|
</Text>
|
||||||
|
|
||||||
<HStack>
|
<HStack>
|
||||||
<InputGroup
|
<SearchComponent
|
||||||
startElement={
|
value={searchTerm}
|
||||||
<LuSearch fontSize={"xs"} style={{ position: 'relative', left: '10px' }} />
|
onChange={handleSearchChange}
|
||||||
}
|
/>
|
||||||
color={"#000"}
|
|
||||||
>
|
|
||||||
<Input
|
|
||||||
p={3}
|
|
||||||
w={300}
|
|
||||||
bg={"#fff"}
|
|
||||||
colorPalette={"cyan"}
|
|
||||||
_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> */}
|
{/* <Button bgColor={'#EEEEEE'} pl={3} pr={3}><IoMdAdd /> <Text>Add</Text></Button> */}
|
||||||
<AddModel />
|
<AddModel refetch={refetch} allPermissions={permissions} />
|
||||||
</HStack>
|
</HStack>
|
||||||
</HStack>
|
</HStack>
|
||||||
<DataTable
|
<DataTable
|
||||||
sortableColumns={["Name", "Registration Date "]}
|
sortableColumns={["Name", "Registration Date "]}
|
||||||
tableHeadRow={tableHeadRow}
|
tableHeadRow={tableHeadRow}
|
||||||
data={managepost}
|
data={managepost}
|
||||||
// paginationData={data?.data}
|
paginationData={{
|
||||||
// refetch={refetch}
|
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}
|
||||||
|
isLoading={isFetching}
|
||||||
|
isError={isError}
|
||||||
/>
|
/>
|
||||||
</Box> </MainFrame>
|
</Box>
|
||||||
|
<Toaster />
|
||||||
|
</MainFrame>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
export default SubAdmin
|
export default SubAdmin
|
||||||
@@ -22,9 +22,9 @@ import { Checkbox } from "../../components/ui/checkbox";
|
|||||||
// import { FaRegEdit } from "react-icons/fa";
|
// import { FaRegEdit } from "react-icons/fa";
|
||||||
import View from "../../components/ActionIcons/View";
|
import View from "../../components/ActionIcons/View";
|
||||||
import { Button } from "../../components/ui/button";
|
import { Button } from "../../components/ui/button";
|
||||||
import { useLazyViewSubAdminQuery } from "../../Redux/Service/manage.subadmin.service";
|
import {useLazyViewSubAdminQuery } from "../../Redux/Service/manage.subadmin.service";
|
||||||
|
|
||||||
function ViewSubAdmin({ id }: { id: number }) {
|
function ViewSubAdmin({ id, }: { id: number}) {
|
||||||
const [trigger, { data }] = useLazyViewSubAdminQuery();
|
const [trigger, { data }] = useLazyViewSubAdminQuery();
|
||||||
|
|
||||||
const handleView = () => {
|
const handleView = () => {
|
||||||
@@ -64,6 +64,7 @@ function ViewSubAdmin({ id }: { id: number }) {
|
|||||||
overflowX="hidden"
|
overflowX="hidden"
|
||||||
p={3} // Reduced padding
|
p={3} // Reduced padding
|
||||||
bgSize={"md"}
|
bgSize={"md"}
|
||||||
|
key={data.id}
|
||||||
>
|
>
|
||||||
<DialogHeader bg="white">
|
<DialogHeader bg="white">
|
||||||
<DialogTitle alignSelf="center" color="black" fontSize="14px">
|
<DialogTitle alignSelf="center" color="black" fontSize="14px">
|
||||||
@@ -149,8 +150,8 @@ function ViewSubAdmin({ id }: { id: number }) {
|
|||||||
</Field.Root>
|
</Field.Root>
|
||||||
<Grid templateColumns="repeat(2, 1fr)" gap={4}>
|
<Grid templateColumns="repeat(2, 1fr)" gap={4}>
|
||||||
{data.get_resource_action_link.map((check: any) => (
|
{data.get_resource_action_link.map((check: any) => (
|
||||||
<Checkbox size={"sm"} color={"black"} checked={check.is_active}>
|
<Checkbox size={"sm"} color={"black"} checked={check.is_active} key={check.id}>
|
||||||
<Text fontSize={12}>{check.app_resource_xid}</Text>
|
<Text fontSize={12}>{check?.app_resource.app_resource_title}</Text>
|
||||||
</Checkbox>
|
</Checkbox>
|
||||||
// <>
|
// <>
|
||||||
// <Checkbox size={"sm"} color={"black"}>
|
// <Checkbox size={"sm"} color={"black"}>
|
||||||
|
|||||||
@@ -70,8 +70,18 @@ export const agencyMasterModule = createApi({
|
|||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
|
|
||||||
getAgencyMaster: builder.query<AgencyResponse, number>({
|
// getAgencyMaster: builder.query<AgencyResponse, number>({
|
||||||
query: (page = 1) => `/agency-master?page=${page}`
|
// query: (page = 1) => `/agency-master?page=${page}`
|
||||||
|
// }),
|
||||||
|
|
||||||
|
getAgencyMaster: builder.query<AgencyResponse, { page?: number; search?: string }>({
|
||||||
|
query: ({ page, search }) => {
|
||||||
|
const params = new URLSearchParams();
|
||||||
|
if (page) params.append("page", page.toString());
|
||||||
|
if (search) params.append("search", search);
|
||||||
|
|
||||||
|
return `/agency-master?${params.toString()}`;
|
||||||
|
},
|
||||||
}),
|
}),
|
||||||
|
|
||||||
agencyMasterToggle: builder.mutation({
|
agencyMasterToggle: builder.mutation({
|
||||||
|
|||||||
@@ -65,8 +65,18 @@ export const countryMaster = createApi({
|
|||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
// 🔹 GET: Fetch all posts
|
// 🔹 GET: Fetch all posts
|
||||||
getCountryMaster: builder.query<ApiResponse, number>({
|
// getCountryMaster: builder.query<ApiResponse, number>({
|
||||||
query: (page = 1) => `/country-list?page=${page}`,
|
// query: (page = 1) => `/country-list?page=${page}`,
|
||||||
|
// }),
|
||||||
|
|
||||||
|
getCountryMaster: builder.query<ApiResponse, { page?: number; search?: string }>({
|
||||||
|
query: ({ page, search }) => {
|
||||||
|
const params = new URLSearchParams();
|
||||||
|
if (page) params.append("page", page.toString());
|
||||||
|
if (search) params.append("search", search);
|
||||||
|
|
||||||
|
return `/country-list?${params.toString()}`;
|
||||||
|
},
|
||||||
}),
|
}),
|
||||||
|
|
||||||
getCountryMasterEdit: builder.query<CountryEdit, number>({
|
getCountryMasterEdit: builder.query<CountryEdit, number>({
|
||||||
|
|||||||
77
src/Redux/Service/dashBoard.ts
Normal file
77
src/Redux/Service/dashBoard.ts
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
import { createApi } from "@reduxjs/toolkit/query/react";
|
||||||
|
import { baseQueryWithReauth } from "./apiSlice";
|
||||||
|
|
||||||
|
export type TotalUser = {
|
||||||
|
data: {
|
||||||
|
totalRecruiterCount: number;
|
||||||
|
totalCustomerCount: string;
|
||||||
|
totalUserCount: string;
|
||||||
|
recruitersByMonth: Record<string, number>;
|
||||||
|
customersByMonth: Record<string, number>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export type PastUser = {
|
||||||
|
data: {
|
||||||
|
past24hourRecruiterCount: number;
|
||||||
|
past24hourCustomercount: number;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export type NewUser = {
|
||||||
|
data: {
|
||||||
|
newRecuiterCount: number;
|
||||||
|
newCustomerCount: number;
|
||||||
|
newTotalUserCount: number;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export type AgencyList = {
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
created_at: string;
|
||||||
|
is_active: boolean
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
export type FaqList = {
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
id: number;
|
||||||
|
faqs_xid: number;
|
||||||
|
language_master_xid: number;
|
||||||
|
question: string;
|
||||||
|
answer: string;
|
||||||
|
is_active: boolean
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export const dashBoard = createApi({
|
||||||
|
reducerPath: "dashBoard",
|
||||||
|
baseQuery: baseQueryWithReauth, // Use enhanced baseQuery with error handling
|
||||||
|
endpoints: (builder) => ({
|
||||||
|
|
||||||
|
getTotalUser: builder.query<TotalUser, void>({ query: () => "/dashboard-total-user" }),
|
||||||
|
getPastUser: builder.query<PastUser, void>({ query: () => "/dashboard-past-user" }),
|
||||||
|
getNewUser: builder.query<NewUser, void>({ query: () => "/dashboard-new-user" }),
|
||||||
|
getAgencyList: builder.query<AgencyList, void>({ query: () => "/dashboard-agency-list" }),
|
||||||
|
getFaqList: builder.query<FaqList, void>({ query: () => "/dashboard-faq-list" }),
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const {
|
||||||
|
useGetTotalUserQuery,
|
||||||
|
useGetPastUserQuery,
|
||||||
|
useGetNewUserQuery,
|
||||||
|
useGetAgencyListQuery,
|
||||||
|
useGetFaqListQuery,
|
||||||
|
} = dashBoard;
|
||||||
@@ -64,8 +64,18 @@ export const departmentMaster = createApi({
|
|||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
// 🔹 GET: Fetch all posts
|
// 🔹 GET: Fetch all posts
|
||||||
getDepartmentMaster: builder.query<ApiResponse, number>({
|
// getDepartmentMaster: builder.query<ApiResponse, number>({
|
||||||
query: (page = 1) => `/department-master-list?page=${page}`,
|
// query: (page = 1) => `/department-master-list?page=${page}`,
|
||||||
|
// }),
|
||||||
|
|
||||||
|
getDepartmentMaster: builder.query<ApiResponse, { page?: number; search?: string }>({
|
||||||
|
query: ({ page, search }) => {
|
||||||
|
const params = new URLSearchParams();
|
||||||
|
if (page) params.append("page", page.toString());
|
||||||
|
if (search) params.append("search", search);
|
||||||
|
|
||||||
|
return `/department-master-list?${params.toString()}`;
|
||||||
|
},
|
||||||
}),
|
}),
|
||||||
|
|
||||||
getDepartmentMasterDropDown: builder.query<DropDown, void>({
|
getDepartmentMasterDropDown: builder.query<DropDown, void>({
|
||||||
|
|||||||
@@ -61,8 +61,18 @@ export const industryMaster = createApi({
|
|||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
// 🔹 GET: Fetch all posts
|
// 🔹 GET: Fetch all posts
|
||||||
getIndustryMaster: builder.query<IndustryMasterResponse, number>({
|
// getIndustryMaster: builder.query<IndustryMasterResponse, number>({
|
||||||
query: (page = 1) => `/industry-master-list?page=${page}`,
|
// query: (page = 1) => `/industry-master-list?page=${page}`,
|
||||||
|
// }),
|
||||||
|
|
||||||
|
getIndustryMaster: builder.query<IndustryMasterResponse, { page?: number; search?: string }>({
|
||||||
|
query: ({ page, search }) => {
|
||||||
|
const params = new URLSearchParams();
|
||||||
|
if (page) params.append("page", page.toString());
|
||||||
|
if (search) params.append("search", search);
|
||||||
|
|
||||||
|
return `/industry-master-list?${params.toString()}`;
|
||||||
|
},
|
||||||
}),
|
}),
|
||||||
|
|
||||||
updateIndustryMaster: builder.mutation({
|
updateIndustryMaster: builder.mutation({
|
||||||
|
|||||||
@@ -51,8 +51,18 @@ export const jobStatus = createApi({
|
|||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
// 🔹 GET: Fetch all posts
|
// 🔹 GET: Fetch all posts
|
||||||
getJobStatus: builder.query<ApiResponse, number>({
|
// getJobStatus: builder.query<ApiResponse, number>({
|
||||||
query: (page = 1) => `/job-status-list?page=${page}`,
|
// query: (page = 1) => `/job-status-list?page=${page}`,
|
||||||
|
// }),
|
||||||
|
|
||||||
|
getJobStatus: builder.query<ApiResponse, { page?: number; search?: string }>({
|
||||||
|
query: ({ page, search }) => {
|
||||||
|
const params = new URLSearchParams();
|
||||||
|
if (page) params.append("page", page.toString());
|
||||||
|
if (search) params.append("search", search);
|
||||||
|
|
||||||
|
return `/job-status-list?${params.toString()}`;
|
||||||
|
},
|
||||||
}),
|
}),
|
||||||
|
|
||||||
updateJobStatus: builder.mutation({
|
updateJobStatus: builder.mutation({
|
||||||
|
|||||||
@@ -71,9 +71,9 @@ export const jobType = createApi({
|
|||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
|
|
||||||
templateMasterToggle: builder.mutation({
|
jobTypeToggle: builder.mutation({
|
||||||
query: ({ id, is_active }) => ({
|
query: ({ id, is_active }) => ({
|
||||||
url: `/template-status`,
|
url: `/job-type-status`,
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: { id, is_active },
|
body: { id, is_active },
|
||||||
}),
|
}),
|
||||||
@@ -86,5 +86,5 @@ export const {
|
|||||||
useGetJobTypeQuery,
|
useGetJobTypeQuery,
|
||||||
useCreateJobTypePostMutation,
|
useCreateJobTypePostMutation,
|
||||||
useUpdateJobTypeMutation,
|
useUpdateJobTypeMutation,
|
||||||
useTemplateMasterToggleMutation,
|
useJobTypeToggleMutation,
|
||||||
} = jobType;
|
} = jobType;
|
||||||
|
|||||||
@@ -20,14 +20,26 @@ export const manageContactUs = createApi({
|
|||||||
tagTypes: ["Contact"],
|
tagTypes: ["Contact"],
|
||||||
endpoints: (builder) => ({
|
endpoints: (builder) => ({
|
||||||
|
|
||||||
|
|
||||||
getContact: builder.query<ApiResponse, void>({
|
getContact: builder.query<ApiResponse, { page?: number; search?: string }>({
|
||||||
query: () => "/contact-us",
|
query: ({ page, search }) => {
|
||||||
|
const params = new URLSearchParams();
|
||||||
|
if (page) params.append("page", page.toString());
|
||||||
|
if (search) params.append("search", search);
|
||||||
|
return `/contact-us?${params.toString()}`;
|
||||||
|
},
|
||||||
providesTags: ["Contact"],
|
providesTags: ["Contact"],
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
pendingRequest: builder.mutation({
|
||||||
|
query: (body) => ({
|
||||||
|
url: `/contact-us-response`,
|
||||||
|
method: "POST",
|
||||||
|
body,
|
||||||
|
}),
|
||||||
|
invalidatesTags: ["Contact"],
|
||||||
|
}),
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const { useGetContactQuery } = manageContactUs;
|
export const { useGetContactQuery, usePendingRequestMutation } = manageContactUs;
|
||||||
|
|||||||
@@ -66,17 +66,40 @@ export type PostJobStatus = {
|
|||||||
title: string
|
title: string
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type WorkSpace = {
|
||||||
|
id: number;
|
||||||
|
en_name: string;
|
||||||
|
};
|
||||||
|
|
||||||
export const manageJobs = createApi({
|
export const manageJobs = createApi({
|
||||||
reducerPath: "manageJobs",
|
reducerPath: "manageJobs",
|
||||||
baseQuery: baseQueryWithReauth, // Use enhanced baseQuery with error handling
|
baseQuery: baseQueryWithReauth, // Use enhanced baseQuery with error handling
|
||||||
endpoints: (builder) => ({
|
endpoints: (builder) => ({
|
||||||
|
|
||||||
getManageJobs: builder.query<ApiResponse, number>({
|
// getManageJobs: builder.query<ApiResponse, number>({
|
||||||
query: (page = 1) => `/manage-jobs-list?page=${page}`,
|
// query: (page = 1) => `/manage-jobs-list?page=${page}`,
|
||||||
|
// }),
|
||||||
|
|
||||||
|
getManageJobs: builder.query<ApiResponse, { page?: number; search?: string }>({
|
||||||
|
query: ({ page, search }) => {
|
||||||
|
const params = new URLSearchParams();
|
||||||
|
if (page) params.append("page", page.toString());
|
||||||
|
if (search) params.append("search", search);
|
||||||
|
|
||||||
|
return `/manage-jobs-list?${params.toString()}`;
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
|
||||||
|
updateJobs: builder.mutation({
|
||||||
|
query: (updatedData) => ({
|
||||||
|
url: "/manage-jobs-update",
|
||||||
|
method: "POST",
|
||||||
|
body: updatedData,
|
||||||
|
}),
|
||||||
}),
|
}),
|
||||||
|
|
||||||
viewJobs: builder.query<ApiResponse, number>({
|
viewJobs: builder.query<ApiResponse, number>({
|
||||||
query: (id) => `/manage-jobs-list/${id}`,
|
query: () => `/manage-jobs-list`,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
deleteJobsPost: builder.mutation<{ status: string; message: string }, { id: number }>({
|
deleteJobsPost: builder.mutation<{ status: string; message: string }, { id: number }>({
|
||||||
@@ -87,10 +110,38 @@ export const manageJobs = createApi({
|
|||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
// Modes
|
||||||
|
getWorkspaceModes: builder.query({
|
||||||
|
query: () => `/manage-jobs-get-workspace`,
|
||||||
|
}),
|
||||||
|
|
||||||
|
getIndustry: builder.query({
|
||||||
|
query: () => `/manage-jobs-get-industry`,
|
||||||
|
}),
|
||||||
|
|
||||||
|
getDepartment: builder.query({
|
||||||
|
query: () => `/manage-jobs-get-department`,
|
||||||
|
}),
|
||||||
|
|
||||||
|
getCountry: builder.query({
|
||||||
|
query: () => `/manage-jobs-get-country`,
|
||||||
|
}),
|
||||||
|
|
||||||
|
getManageJobType: builder.query({
|
||||||
|
query: () => `/job-type`,
|
||||||
|
}),
|
||||||
|
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const { useGetManageJobsQuery,useLazyViewJobsQuery,useDeleteJobsPostMutation } = manageJobs;
|
export const {
|
||||||
|
useGetManageJobsQuery,
|
||||||
|
useLazyViewJobsQuery,
|
||||||
|
useDeleteJobsPostMutation,
|
||||||
|
useUpdateJobsMutation,
|
||||||
|
useGetWorkspaceModesQuery,
|
||||||
|
useGetIndustryQuery,
|
||||||
|
useGetDepartmentQuery,
|
||||||
|
useGetCountryQuery,
|
||||||
|
useGetManageJobTypeQuery
|
||||||
|
} = manageJobs;
|
||||||
|
|||||||
@@ -40,6 +40,25 @@ interface ApiResponse {
|
|||||||
data: PaginatedData;
|
data: PaginatedData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type Permission = {
|
||||||
|
id: number;
|
||||||
|
app_resource_title: string;
|
||||||
|
is_active: boolean;
|
||||||
|
created_by: string | null;
|
||||||
|
modified_by: string | null;
|
||||||
|
deleted_at: string | null;
|
||||||
|
created_at: string;
|
||||||
|
updated_at: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type PermissionResponse = {
|
||||||
|
status: string;
|
||||||
|
status_code: number;
|
||||||
|
message: string;
|
||||||
|
data: {
|
||||||
|
permission: Permission[];
|
||||||
|
};
|
||||||
|
};
|
||||||
// export type SubAdminPost = {
|
// export type SubAdminPost = {
|
||||||
// id: number;
|
// id: number;
|
||||||
// first_name: string,
|
// first_name: string,
|
||||||
@@ -60,6 +79,10 @@ interface ResourceActionLink {
|
|||||||
deleted_at: string | null;
|
deleted_at: string | null;
|
||||||
created_at: string;
|
created_at: string;
|
||||||
updated_at: string;
|
updated_at: string;
|
||||||
|
app_resource: {
|
||||||
|
id: number;
|
||||||
|
app_resource_title: string
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface SubAdmin {
|
interface SubAdmin {
|
||||||
@@ -80,16 +103,14 @@ interface SubAdminView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface CreateSubAdminPayload {
|
interface CreateSubAdminPayload {
|
||||||
principal_type_xid: number;
|
// user_name: string;
|
||||||
principal_source_xid: number;
|
|
||||||
user_name: string;
|
|
||||||
first_name: string;
|
first_name: string;
|
||||||
last_name: string;
|
last_name: string;
|
||||||
date_of_birth: string;
|
date_of_birth: string;
|
||||||
gender: string;
|
gender: string;
|
||||||
email_address: string;
|
email_address: string;
|
||||||
phone_number: string;
|
phone_number: string;
|
||||||
created_by: number;
|
// created_by: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface CreateSubAdminResponse {
|
interface CreateSubAdminResponse {
|
||||||
@@ -112,9 +133,18 @@ export const manageSubAdmin = createApi({
|
|||||||
body: data,
|
body: data,
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
|
|
||||||
getSubAdmin: builder.query<ApiResponse, void>({
|
getSubAdmin: builder.query<ApiResponse, { page?: number; search?: string }>({
|
||||||
query: () => `/sub-admin`,
|
query: ({ page, search }) => {
|
||||||
|
const params = new URLSearchParams();
|
||||||
|
if (page) params.append("page", page.toString());
|
||||||
|
if (search) params.append("search", search);
|
||||||
|
return `/sub-admin?${params.toString()}`
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
|
||||||
|
getPermission: builder.query<PermissionResponse, void>({
|
||||||
|
query: () => `/resources`,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
viewSubAdmin: builder.query<SubAdminView, number>({
|
viewSubAdmin: builder.query<SubAdminView, number>({
|
||||||
@@ -151,8 +181,9 @@ export const manageSubAdmin = createApi({
|
|||||||
|
|
||||||
deleteSubAdminPost: builder.mutation<{ success: boolean }, number>({
|
deleteSubAdminPost: builder.mutation<{ success: boolean }, number>({
|
||||||
query: (id) => ({
|
query: (id) => ({
|
||||||
url: `/faq-delete/${id}`,
|
url: `/sub-admin-delete`,
|
||||||
method: "DELETE",
|
method: "POST",
|
||||||
|
body: { id },
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
@@ -160,6 +191,7 @@ export const manageSubAdmin = createApi({
|
|||||||
|
|
||||||
export const {
|
export const {
|
||||||
useGetSubAdminQuery,
|
useGetSubAdminQuery,
|
||||||
|
useGetPermissionQuery,
|
||||||
useLazyViewSubAdminQuery,
|
useLazyViewSubAdminQuery,
|
||||||
useUpdateSubAdminMutation,
|
useUpdateSubAdminMutation,
|
||||||
useDeleteSubAdminPostMutation,
|
useDeleteSubAdminPostMutation,
|
||||||
|
|||||||
@@ -10,11 +10,19 @@ export interface UserData {
|
|||||||
gender: string;
|
gender: string;
|
||||||
date_of_birth: string;
|
date_of_birth: string;
|
||||||
is_active: boolean;
|
is_active: boolean;
|
||||||
principal_type:{
|
principal_type: {
|
||||||
id: number;
|
id: number;
|
||||||
principal_type_title: string;
|
principal_type_title: string;
|
||||||
},
|
},
|
||||||
principle_language_links:[]
|
principle_language_linkss: {
|
||||||
|
id: number;
|
||||||
|
language_xid: number;
|
||||||
|
iam_principal_xid: number;
|
||||||
|
language: {
|
||||||
|
id: number,
|
||||||
|
language_name: string;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ApiResponse {
|
interface ApiResponse {
|
||||||
@@ -55,9 +63,9 @@ export const registerUser = createApi({
|
|||||||
reducerPath: "registerUser",
|
reducerPath: "registerUser",
|
||||||
baseQuery: baseQueryWithReauth, // Use enhanced baseQuery with error handling
|
baseQuery: baseQueryWithReauth, // Use enhanced baseQuery with error handling
|
||||||
endpoints: (builder) => ({
|
endpoints: (builder) => ({
|
||||||
createCountryPost: builder.mutation<PostCountry, Partial<PostCountry>>({
|
createUser: builder.mutation<PostCountry, Partial<PostCountry>>({
|
||||||
query: (data) => ({
|
query: (data) => ({
|
||||||
url: "/country-add",
|
url: "/manage-user-store",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: data,
|
body: data,
|
||||||
}),
|
}),
|
||||||
@@ -67,13 +75,13 @@ export const registerUser = createApi({
|
|||||||
query: (page = 1) => `/manage-user-list?page=${page}`,
|
query: (page = 1) => `/manage-user-list?page=${page}`,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
getCountryMasterEdit: builder.query<CountryEdit, number>({
|
getDeactivateUser: builder.query<ApiResponse, number>({
|
||||||
query: (id) => `/country-edit/${id}`,
|
query: (page = 1) => `/manage-user-deactivate-list?page=${page}`,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
updateCountry: builder.mutation({
|
updateUser: builder.mutation({
|
||||||
query: (updatedData) => ({
|
query: (updatedData) => ({
|
||||||
url: "/country-update",
|
url: "/manage-user-update",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: updatedData,
|
body: updatedData,
|
||||||
}),
|
}),
|
||||||
@@ -87,22 +95,31 @@ export const registerUser = createApi({
|
|||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
|
|
||||||
// deleteFaqPost: builder.mutation<{ status: string; message: string }, { id: number }>({
|
userDeactivateToggle: builder.mutation({
|
||||||
// query: ({ id }) => ({
|
query: ({ id, is_active }) => ({
|
||||||
// url: `/faq-delete`,
|
url: `/manage-user-deactivate-status`,
|
||||||
// method: "POST",
|
method: "POST",
|
||||||
// body: { id },
|
body: { id, is_active },
|
||||||
// }),
|
}),
|
||||||
// }),
|
}),
|
||||||
|
|
||||||
|
deleteUser: builder.mutation({
|
||||||
|
query: ({ id }) => ({
|
||||||
|
url: `/manage-user-delete`,
|
||||||
|
method: "POST",
|
||||||
|
body: { id },
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const {
|
export const {
|
||||||
useGetManageUserQuery,
|
useGetManageUserQuery,
|
||||||
useGetCountryMasterEditQuery,
|
useCreateUserMutation,
|
||||||
useCreateCountryPostMutation,
|
useUpdateUserMutation,
|
||||||
useUpdateCountryMutation,
|
|
||||||
useUserToggleMutation,
|
useUserToggleMutation,
|
||||||
// useDeleteFaqPostMutation
|
useGetDeactivateUserQuery,
|
||||||
|
useUserDeactivateToggleMutation,
|
||||||
|
useDeleteUserMutation
|
||||||
} = registerUser;
|
} = registerUser;
|
||||||
@@ -1,26 +1,37 @@
|
|||||||
import { createApi } from "@reduxjs/toolkit/query";
|
import { createApi } from "@reduxjs/toolkit/query/react";
|
||||||
import { baseQueryWithReauth } from "./apiSlice";
|
import { baseQueryWithReauth } from "./apiSlice";
|
||||||
|
|
||||||
export const myProfile = createApi({
|
export const myProfile = createApi({
|
||||||
reducerPath: "myProfile",
|
reducerPath: "myProfile",
|
||||||
baseQuery: baseQueryWithReauth, // Use enhanced baseQuery with error handling
|
baseQuery: baseQueryWithReauth, // Use enhanced baseQuery with error handling
|
||||||
endpoints: (builder) => ({
|
endpoints: (builder) => ({
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
getPosts: builder.query<Post[], void>({ query: () => "/posts" }),
|
// getPosts: builder.query<Post[], void>({ query: () => "/profile-image-edit" }),
|
||||||
|
|
||||||
|
updateImage: builder.mutation({
|
||||||
|
query: (formData: FormData) => {
|
||||||
|
const token = localStorage.getItem("token");
|
||||||
|
|
||||||
}),
|
return {
|
||||||
});
|
url: "/profile-image-edit",
|
||||||
|
method: "POST",
|
||||||
export const { } = myProfile;
|
body: formData,
|
||||||
|
headers: {
|
||||||
export type Post = {
|
"access-token": `${token}`,
|
||||||
id: number;
|
},
|
||||||
title: string;
|
};
|
||||||
body: string;
|
},
|
||||||
};
|
}),
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const {
|
||||||
|
useUpdateImageMutation,
|
||||||
|
} = myProfile;
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ interface PaginationData {
|
|||||||
export interface Template {
|
export interface Template {
|
||||||
id: number;
|
id: number;
|
||||||
is_active: boolean;
|
is_active: boolean;
|
||||||
|
principle_type_xid: number;
|
||||||
post_template_translate: PostTemplateTranslate[];
|
post_template_translate: PostTemplateTranslate[];
|
||||||
post_template_image: PostTemplateImage[];
|
post_template_image: PostTemplateImage[];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ export const workspaceMode = createApi({
|
|||||||
endpoints: (builder) => ({
|
endpoints: (builder) => ({
|
||||||
createWorkspacePost: builder.mutation<PostDepartment, Partial<PostDepartment>>({
|
createWorkspacePost: builder.mutation<PostDepartment, Partial<PostDepartment>>({
|
||||||
query: (data) => ({
|
query: (data) => ({
|
||||||
url: "/department-master-store",
|
url: "/workspace-create",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: data,
|
body: data,
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import { workspaceMode } from "./Service/workspace.mode";
|
|||||||
import { jobStatus } from "./Service/job.status";
|
import { jobStatus } from "./Service/job.status";
|
||||||
import { managePosts } from "./Service/manage.post.service";
|
import { managePosts } from "./Service/manage.post.service";
|
||||||
import { registerUser } from "./Service/manage.user";
|
import { registerUser } from "./Service/manage.user";
|
||||||
|
import { dashBoard } from "./Service/dashBoard";
|
||||||
|
|
||||||
export const store = configureStore({
|
export const store = configureStore({
|
||||||
reducer: {
|
reducer: {
|
||||||
@@ -49,6 +50,7 @@ export const store = configureStore({
|
|||||||
[jobStatus.reducerPath]: jobStatus.reducer,
|
[jobStatus.reducerPath]: jobStatus.reducer,
|
||||||
[managePosts.reducerPath]: managePosts.reducer,
|
[managePosts.reducerPath]: managePosts.reducer,
|
||||||
[registerUser.reducerPath]: registerUser.reducer,
|
[registerUser.reducerPath]: registerUser.reducer,
|
||||||
|
[dashBoard.reducerPath]: dashBoard.reducer,
|
||||||
auth: authReducer,
|
auth: authReducer,
|
||||||
},
|
},
|
||||||
middleware: (getDefaultMiddleware) =>
|
middleware: (getDefaultMiddleware) =>
|
||||||
@@ -76,6 +78,7 @@ export const store = configureStore({
|
|||||||
jobStatus.middleware,
|
jobStatus.middleware,
|
||||||
managePosts.middleware,
|
managePosts.middleware,
|
||||||
registerUser.middleware,
|
registerUser.middleware,
|
||||||
|
dashBoard.middleware,
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { LuBriefcaseBusiness} from "react-icons/lu";
|
import { LuBriefcaseBusiness } from "react-icons/lu";
|
||||||
import { MdHeadsetMic, MdOutlineDashboard} from "react-icons/md";
|
import { MdHeadsetMic, MdOutlineDashboard } from "react-icons/md";
|
||||||
import { GoDotFill } from "react-icons/go";
|
import { GoDotFill } from "react-icons/go";
|
||||||
import { HiOutlinePencilSquare } from "react-icons/hi2";
|
import { HiOutlinePencilSquare } from "react-icons/hi2";
|
||||||
import { BiUser, BiUserPin } from "react-icons/bi";
|
import { BiUser, BiUserPin } from "react-icons/bi";
|
||||||
@@ -8,146 +8,156 @@ import { BsBoxes, BsPersonBadge } from "react-icons/bs";
|
|||||||
import { AiOutlineFileText } from "react-icons/ai";
|
import { AiOutlineFileText } from "react-icons/ai";
|
||||||
|
|
||||||
export const nav = [
|
export const nav = [
|
||||||
|
|
||||||
{
|
{
|
||||||
title: "Dashboard",
|
title: "Dashboard",
|
||||||
path: "/",
|
path: "/",
|
||||||
Icon: MdOutlineDashboard,
|
Icon: MdOutlineDashboard,
|
||||||
type:'single'
|
type: 'single',
|
||||||
},
|
resourceTitle: 'Dashboard'
|
||||||
{
|
},
|
||||||
title: "Manage Users",
|
{
|
||||||
initPath: "/manage-users",
|
title: "Manage Users",
|
||||||
Icon: BiUserPin,
|
initPath: "/manage-users",
|
||||||
type:'multiple',
|
Icon: BiUserPin,
|
||||||
children: [
|
type: 'multiple',
|
||||||
{
|
resourceTitle: 'Manage User',
|
||||||
title: "Register Users",
|
children: [
|
||||||
path: "/manage-users/register-users",
|
{
|
||||||
Icon: GoDotFill,
|
title: "Register Users",
|
||||||
},
|
path: "/manage-users/register-users",
|
||||||
{
|
Icon: GoDotFill,
|
||||||
title: "Deactivated Accounts",
|
},
|
||||||
path: "/manage-users/deactivated-accounts",
|
{
|
||||||
Icon: GoDotFill,
|
title: "Deactivated Accounts",
|
||||||
},
|
path: "/manage-users/deactivated-accounts",
|
||||||
],
|
Icon: GoDotFill,
|
||||||
},
|
},
|
||||||
{
|
],
|
||||||
title: "Manage Post",
|
},
|
||||||
path: "/manage-post",
|
{
|
||||||
Icon: HiOutlinePencilSquare,
|
title: "Manage Post",
|
||||||
type:'single'
|
path: "/manage-post",
|
||||||
},
|
Icon: HiOutlinePencilSquare,
|
||||||
{
|
type: 'single',
|
||||||
title: "Manage Sub-Admin",
|
resourceTitle: 'Manage Post'
|
||||||
path: "/sub-admin",
|
},
|
||||||
Icon: BiUser,
|
{
|
||||||
type:'single'
|
title: "Manage Sub-Admin",
|
||||||
},
|
path: "/sub-admin",
|
||||||
{
|
Icon: BiUser,
|
||||||
title: "Manage Jobs",
|
type: 'single',
|
||||||
path: "/manage-jobs",
|
resourceTitle: 'Manage Subadmin'
|
||||||
Icon: LuBriefcaseBusiness,
|
},
|
||||||
type:'single'
|
{
|
||||||
},
|
title: "Manage Jobs",
|
||||||
{
|
path: "/manage-jobs",
|
||||||
title: "Manage Groups",
|
Icon: LuBriefcaseBusiness,
|
||||||
path: "/manage-groups",
|
type: 'single',
|
||||||
Icon: PiUsersThree,
|
resourceTitle: 'Manage Jobs'
|
||||||
type:'single'
|
},
|
||||||
},
|
{
|
||||||
{
|
title: "Manage Groups",
|
||||||
title: "Manage Contact Us",
|
path: "/manage-groups",
|
||||||
path: "/manage-contact",
|
Icon: PiUsersThree,
|
||||||
Icon: MdHeadsetMic ,
|
type: 'single',
|
||||||
type:'single'
|
resourceTitle: 'Manage Groups'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Manage CMS",
|
title: "Manage Contact Us",
|
||||||
initPath: "/manage-cms",
|
path: "/manage-contact",
|
||||||
Icon: AiOutlineFileText,
|
Icon: MdHeadsetMic,
|
||||||
type:'multiple',
|
type: 'single',
|
||||||
children: [
|
resourceTitle: 'Manage Contact Us'
|
||||||
{
|
},
|
||||||
title: "FAQs",
|
{
|
||||||
path: "/manage-cms/faq",
|
title: "Manage CMS",
|
||||||
Icon: GoDotFill,
|
initPath: "/manage-cms",
|
||||||
},
|
Icon: AiOutlineFileText,
|
||||||
{
|
type: 'multiple',
|
||||||
title: "About Us",
|
resourceTitle: 'Manage CMS',
|
||||||
path: "/manage-cms/about-us",
|
children: [
|
||||||
Icon: GoDotFill,
|
{
|
||||||
},
|
title: "FAQs",
|
||||||
{
|
path: "/manage-cms/faq",
|
||||||
title: "Privacy Policy",
|
Icon: GoDotFill,
|
||||||
path: "/manage-cms/privacy-policy",
|
},
|
||||||
Icon: GoDotFill,
|
{
|
||||||
},
|
title: "About Us",
|
||||||
{
|
path: "/manage-cms/about-us",
|
||||||
title: "Terms And Conditions",
|
Icon: GoDotFill,
|
||||||
path: "/manage-cms/terms-conditions",
|
},
|
||||||
Icon: GoDotFill,
|
{
|
||||||
},
|
title: "Privacy Policy",
|
||||||
// {
|
path: "/manage-cms/privacy-policy",
|
||||||
// title: "Privacy",
|
Icon: GoDotFill,
|
||||||
// path: "/manage-cms/privacy",
|
},
|
||||||
// Icon: GoDotFill,
|
{
|
||||||
// },
|
title: "Terms And Conditions",
|
||||||
],
|
path: "/manage-cms/terms-conditions",
|
||||||
},
|
Icon: GoDotFill,
|
||||||
{
|
},
|
||||||
title: "My Profile",
|
// {
|
||||||
path: "/profile",
|
// title: "Privacy",
|
||||||
Icon: BsPersonBadge,
|
// path: "/manage-cms/privacy",
|
||||||
type:'single'
|
// Icon: GoDotFill,
|
||||||
},
|
// },
|
||||||
{
|
],
|
||||||
title: "Master Module",
|
},
|
||||||
initPath: "/master-module",
|
{
|
||||||
Icon: BsBoxes,
|
title: "My Profile",
|
||||||
type:'multiple',
|
path: "/profile",
|
||||||
children: [
|
Icon: BsPersonBadge,
|
||||||
{
|
type: 'single',
|
||||||
title: "Agency Master",
|
resourceTitle: 'My Profile'
|
||||||
path: "/master-module/agency-master",
|
},
|
||||||
Icon: GoDotFill,
|
{
|
||||||
},
|
title: "Master Module",
|
||||||
{
|
initPath: "/master-module",
|
||||||
title: "Template Master",
|
Icon: BsBoxes,
|
||||||
path: "/master-module/template-master",
|
type: 'multiple',
|
||||||
Icon: GoDotFill,
|
resourceTitle: 'Master Module',
|
||||||
},
|
children: [
|
||||||
{
|
{
|
||||||
title: "Job Type",
|
title: "Agency Master",
|
||||||
path: "/master-module/job-type",
|
path: "/master-module/agency-master",
|
||||||
Icon: GoDotFill,
|
Icon: GoDotFill,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Workspace Mode",
|
title: "Template Master",
|
||||||
path: "/master-module/workspace-mode",
|
path: "/master-module/template-master",
|
||||||
Icon: GoDotFill,
|
Icon: GoDotFill,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Country",
|
title: "Job Type",
|
||||||
path: "/master-module/country",
|
path: "/master-module/job-type",
|
||||||
Icon: GoDotFill,
|
Icon: GoDotFill,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Job Status",
|
title: "Workspace Mode",
|
||||||
path: "/master-module/job-status",
|
path: "/master-module/workspace-mode",
|
||||||
Icon: GoDotFill,
|
Icon: GoDotFill,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Industry Master",
|
title: "Country",
|
||||||
path: "/master-module/industry-master",
|
path: "/master-module/country",
|
||||||
Icon: GoDotFill,
|
Icon: GoDotFill,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Department Master",
|
title: "Job Status",
|
||||||
path: "/master-module/department-master",
|
path: "/master-module/job-status",
|
||||||
Icon: GoDotFill,
|
Icon: GoDotFill,
|
||||||
},
|
},
|
||||||
],
|
{
|
||||||
},
|
title: "Industry Master",
|
||||||
];
|
path: "/master-module/industry-master",
|
||||||
|
Icon: GoDotFill,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Department Master",
|
||||||
|
path: "/master-module/department-master",
|
||||||
|
Icon: GoDotFill,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
@@ -11,19 +11,35 @@ import { FaUser } from "react-icons/fa";
|
|||||||
// ✅ Register required components
|
// ✅ Register required components
|
||||||
ChartJS.register(ArcElement, Tooltip, Legend);
|
ChartJS.register(ArcElement, Tooltip, Legend);
|
||||||
|
|
||||||
const SemiDoughnutChart = () => {
|
const SemiDoughnutChart = ({ totalUser }: { totalUser: any }) => {
|
||||||
|
const dataSource = totalUser ?? {}
|
||||||
|
|
||||||
|
const recruiterCount =
|
||||||
|
dataSource.past24hourRecruiterCount ??
|
||||||
|
dataSource.totalRecruiterCount ??
|
||||||
|
dataSource.newRecuiterCount ??
|
||||||
|
0;
|
||||||
|
|
||||||
|
const customerCount =
|
||||||
|
dataSource.past24hourCustomercount ??
|
||||||
|
dataSource.totalCustomerCount ??
|
||||||
|
dataSource.newCustomerCount ??
|
||||||
|
0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 📊 Chart Data
|
// 📊 Chart Data
|
||||||
const data = {
|
const data = {
|
||||||
labels: ["Recruiter", "Customer"],
|
labels: ["Recruiter", "Customer"],
|
||||||
datasets: [
|
datasets: [
|
||||||
{
|
{
|
||||||
data: [2554, 2800], // Values
|
data: [recruiterCount, customerCount], // Values
|
||||||
backgroundColor: ["#E0E0E0", "#3D5AFE"], // Grey and Blue
|
backgroundColor: ["#E0E0E0", "#3D5AFE"], // Grey and Blue
|
||||||
borderWidth: 0, // No border
|
borderWidth: 0, // No border
|
||||||
cutout: "90%", // Makes it a doughnut shape
|
cutout: "90%", // Makes it a doughnut shape
|
||||||
circumference: 270, // Semi-circle
|
circumference: 270, // Semi-circle
|
||||||
rotation: 225, // Starts from the top
|
rotation: 225, // Starts from the top
|
||||||
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
@@ -50,9 +66,9 @@ const SemiDoughnutChart = () => {
|
|||||||
fontSize: "20px",
|
fontSize: "20px",
|
||||||
fontWeight: "bold",
|
fontWeight: "bold",
|
||||||
color: "#3D5AFE",
|
color: "#3D5AFE",
|
||||||
backgroundColor:'#ECEAF8',
|
backgroundColor: '#ECEAF8',
|
||||||
padding:'15px',
|
padding: '15px',
|
||||||
borderRadius:'50%'
|
borderRadius: '50%'
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<FaUser />
|
<FaUser />
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ interface TableProps {
|
|||||||
total: number;
|
total: number;
|
||||||
};
|
};
|
||||||
onPageChange?: (page: number) => void;
|
onPageChange?: (page: number) => void;
|
||||||
|
isLoading?: boolean;
|
||||||
|
isError?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const DataTable: React.FC<TableProps> = ({
|
const DataTable: React.FC<TableProps> = ({
|
||||||
@@ -33,6 +35,8 @@ const DataTable: React.FC<TableProps> = ({
|
|||||||
sortableColumns = [],
|
sortableColumns = [],
|
||||||
paginationData,
|
paginationData,
|
||||||
onPageChange,
|
onPageChange,
|
||||||
|
isLoading,
|
||||||
|
isError
|
||||||
}: TableProps) => {
|
}: TableProps) => {
|
||||||
const { current_page = 1, last_page = 1 } = paginationData || {};
|
const { current_page = 1, last_page = 1 } = paginationData || {};
|
||||||
const [sortConfig, setSortConfig] = useState<{
|
const [sortConfig, setSortConfig] = useState<{
|
||||||
@@ -103,47 +107,65 @@ const DataTable: React.FC<TableProps> = ({
|
|||||||
))}
|
))}
|
||||||
</Table.Row>
|
</Table.Row>
|
||||||
</Table.Header>
|
</Table.Header>
|
||||||
{data?.length === 0 ? (
|
{isLoading ? (
|
||||||
<Box>
|
<Box textAlign={"center"} py={20} position="absolute" w="84%">
|
||||||
<Box textAlign={"center"} py={20} position={'absolute'} w={'84%'}>
|
<Text fontSize={"18px"} fontWeight={500} mt={2}>
|
||||||
<Image src={EmptyFile} alt="No data" maxW="65px" mx="auto" />
|
Loading...
|
||||||
<Text fontSize={"18px"} fontWeight={500} mt={2}>
|
</Text>
|
||||||
We do not have any records
|
</Box>
|
||||||
</Text>
|
) : isError ? (
|
||||||
</Box>
|
<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 — they’ll appear here if available.
|
||||||
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
) : (
|
) : (
|
||||||
<Table.Body h={"100%"}>
|
<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 — they’ll appear here if available.
|
||||||
|
</Text>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
{data.map((item: any, index) => (
|
{data.map((item: any, index) => (
|
||||||
<Table.Row
|
<Table.Row
|
||||||
key={index}
|
key={index}
|
||||||
bg={index % 2 === 0 ? "#fff" : "#007F3310"}
|
bg={index % 2 === 0 ? "#fff" : "#007F3310"}
|
||||||
>
|
>
|
||||||
{tableHeadRow.map((heading, colIndex) => (
|
{tableHeadRow.map((heading, colIndex) => {
|
||||||
<Table.Cell
|
const cellContent = item[heading];
|
||||||
px={4}
|
const words = typeof cellContent === 'string'
|
||||||
p={2}
|
? cellContent.split(" ")
|
||||||
key={`${index}-${colIndex}`}
|
: cellContent?.toString().split(" ") || [];
|
||||||
fontSize={"xs"}
|
|
||||||
fontWeight={500}
|
const truncated = words.length > 15
|
||||||
border={"none"}
|
? `${words.slice(0, 15).join(" ")}...`
|
||||||
>
|
: cellContent;
|
||||||
{(() => {
|
|
||||||
const words =
|
return (
|
||||||
item[heading]?.toString().split(" ") || [];
|
<Table.Cell
|
||||||
return words.length > 5
|
px={4}
|
||||||
? `${words.slice(0, 5).join(" ")}...`
|
p={2}
|
||||||
: item[heading];
|
key={`${index}-${colIndex}`}
|
||||||
})()}
|
fontSize="xs"
|
||||||
</Table.Cell>
|
fontWeight={500}
|
||||||
))}
|
border="none"
|
||||||
|
>
|
||||||
|
{truncated}
|
||||||
|
</Table.Cell>
|
||||||
|
);
|
||||||
|
})}
|
||||||
</Table.Row>
|
</Table.Row>
|
||||||
))}
|
))}
|
||||||
</Table.Body>
|
</Table.Body>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
</Table.Root>
|
</Table.Root>
|
||||||
</Table.ScrollArea>
|
</Table.ScrollArea>
|
||||||
{last_page > 1 && (
|
{last_page > 1 && !isLoading && !isError && (
|
||||||
<PaginationRoot
|
<PaginationRoot
|
||||||
count={paginationData?.total ?? 0}
|
count={paginationData?.total ?? 0}
|
||||||
pageSize={paginationData?.per_page ?? 0}
|
pageSize={paginationData?.per_page ?? 0}
|
||||||
|
|||||||
16
src/components/Hooks/useDebounce.ts
Normal file
16
src/components/Hooks/useDebounce.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
// hooks/useDebounce.ts
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
|
||||||
|
export function useDebounce<T>(value: T, delay = 500): T {
|
||||||
|
const [debounced, setDebounced] = useState(value);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const handler = setTimeout(() => {
|
||||||
|
setDebounced(value);
|
||||||
|
}, delay);
|
||||||
|
|
||||||
|
return () => clearTimeout(handler); // cleanup on unmount or value change
|
||||||
|
}, [value, delay]);
|
||||||
|
|
||||||
|
return debounced;
|
||||||
|
}
|
||||||
3
src/components/Utils.ts
Normal file
3
src/components/Utils.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
|
||||||
|
|
||||||
|
export const delay = (ms: number) => new Promise(res => setTimeout(res, ms));
|
||||||
@@ -44,7 +44,7 @@ export const DialogCloseTrigger = React.forwardRef<
|
|||||||
{...props}
|
{...props}
|
||||||
asChild
|
asChild
|
||||||
>
|
>
|
||||||
<CloseButton size="sm" ref={ref}>
|
<CloseButton size="sm" ref={ref} _hover={{ color: "gray.200" }}>
|
||||||
{props.children}
|
{props.children}
|
||||||
</CloseButton>
|
</CloseButton>
|
||||||
</ChakraDialog.CloseTrigger>
|
</ChakraDialog.CloseTrigger>
|
||||||
|
|||||||
@@ -183,4 +183,23 @@ input:focus-visible {
|
|||||||
|
|
||||||
.css-1ilznyv {
|
.css-1ilznyv {
|
||||||
border: none;
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-checkbox {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
border: 2px solid black;
|
||||||
|
background-color: white;
|
||||||
|
appearance: none;
|
||||||
|
cursor: pointer;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-checkbox:checked::after {
|
||||||
|
content: "✔";
|
||||||
|
color: black;
|
||||||
|
font-size: 16px;
|
||||||
|
position: absolute;
|
||||||
|
top: -2px;
|
||||||
|
left: 0px;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user