manage department working👷‍♂️

This commit is contained in:
YasinShaikh123
2024-09-11 17:18:36 +05:30
parent f3549fa5b6
commit aa918de8d2
7 changed files with 810 additions and 33 deletions

View File

@@ -628,7 +628,90 @@ const GlobalStateProvider = ({ children }) => {
]
)
const [ employeePermissions, setEmployeePermissions ] = useState([
{
"id": "12451",
"name":"Kartikey Gautam",
"emailID": "kg@wdimails.com",
"department": "Finance",
"role": "Sr. Accountant",
"permissions": "Subadmin",
},
{
"id": "12451",
"name":"Kartikey Gautam",
"emailID": "kg@wdimails.com",
"department": "Finance",
"role": "Sr. Accountant",
"permissions": "Subadmin",
},
{
"id": "12451",
"name":"Kartikey Gautam",
"emailID": "kg@wdimails.com",
"department": "Finance",
"role": "Sr. Accountant",
"permissions": "Subadmin",
},
{
"id": "12451",
"name":"Kartikey Gautam",
"emailID": "kg@wdimails.com",
"department": "Finance",
"role": "Sr. Accountant",
"permissions": "Subadmin",
},
{
"id": "12451",
"name":"Kartikey Gautam",
"emailID": "kg@wdimails.com",
"department": "Finance",
"role": "Sr. Accountant",
"permissions": "Subadmin",
},
{
"id": "12451",
"name":"Kartikey Gautam",
"emailID": "kg@wdimails.com",
"department": "Finance",
"role": "Sr. Accountant",
"permissions": "Subadmin",
},
{
"id": "12451",
"name":"Kartikey Gautam",
"emailID": "kg@wdimails.com",
"department": "Finance",
"role": "Sr. Accountant",
"permissions": "Subadmin",
},
{
"id": "12451",
"name":"Kartikey Gautam",
"emailID": "kg@wdimails.com",
"department": "Finance",
"role": "Sr. Accountant",
"permissions": "Subadmin",
},
{
"id": "12451",
"name":"Kartikey Gautam",
"emailID": "kg@wdimails.com",
"department": "Finance",
"role": "Sr. Accountant",
"permissions": "Subadmin",
},
{
"id": "12451",
"name":"Kartikey Gautam",
"emailID": "kg@wdimails.com",
"department": "Finance",
"role": "Sr. Accountant",
"permissions": "Subadmin",
},
]
)
return (
<GlobalStateContext.Provider
@@ -643,6 +726,8 @@ const GlobalStateProvider = ({ children }) => {
setDepartment,
roles,
setRoles,
employeePermissions,
setEmployeePermissions,
}}
>
{children}

View File

@@ -0,0 +1,236 @@
import {
Box,
Button,
Checkbox,
CheckboxGroup,
FormControl,
FormErrorMessage,
FormLabel,
Input,
Modal,
ModalBody,
ModalCloseButton,
ModalContent,
ModalFooter,
ModalHeader,
ModalOverlay,
Select,
Stack,
Text,
useDisclosure,
} from "@chakra-ui/react";
import * as yup from "yup";
import React, { useContext } from "react";
import { Controller, useForm } from "react-hook-form";
import { yupResolver } from "@hookform/resolvers/yup";
import GlobalStateContext from "../../../Contexts/GlobalStateContext";
import { IoSettingsOutline } from "react-icons/io5";
import PrimaryButton from "../../../Components/Buttons/PrimaryButton";
import AddRoleModalAdvance from "./AddRoleModalAdvance";
// Validation schema using Yup
const cashDetails = yup.object().shape({
role: yup.string().required("Role is required"),
department_xid: yup.number().required("Artifact name is required"),
});
const AddRoleModal = ({ isOpen, onClose }) => {
// ======================[ Cotext Api ]
const { roleDepartments } = useContext(GlobalStateContext);
// const { isOpenAdvance, onOpenAdvance, onCloseAdvance } = useDisclosure();
const {
isOpen: isOpenAdvance,
onOpen: onOpenAdvance,
onClose: onCloseAdvance,
} = useDisclosure();
const {
control,
handleSubmit,
reset,
formState: { errors },
} = useForm({
resolver: yupResolver(cashDetails),
});
// Define the onSubmit function
const onSubmit = (data) => {
console.log(data);
// You can add any further logic you need after form submission
reset(); // Reset the form after submission
onClose(); // Close the modal after submission
};
return (
<Modal isOpen={isOpen} onClose={onClose} isCentered>
<ModalOverlay />
<ModalContent height={"550px"} overflow={"scroll"}>
<ModalHeader fontSize={"sm"}>Add Role</ModalHeader>
<ModalCloseButton />
<Box as="form" onSubmit={handleSubmit(onSubmit)}>
<ModalBody>
<Stack spacing={4}>
{/* FormControl for role input */}
<FormControl isInvalid={errors.role} isRequired>
<FormLabel fontSize={"sm"} mb={0}>
Role
</FormLabel>
<Controller
name="role"
control={control}
render={({ field }) => (
<Input
rounded={"md"}
{...field}
fontSize={"sm"}
type="text"
size={"sm"}
placeholder="Enter role"
/>
)}
/>
<FormErrorMessage fontSize={"xs"} fontWeight={500}>
{errors.role?.message}
</FormErrorMessage>
</FormControl>
<FormControl isInvalid={errors.department} isRequired>
<FormLabel fontSize={"sm"} mb={0}>
Department
</FormLabel>
<Controller
name="department"
control={control}
render={({ field }) => (
<Select
rounded={"md"}
{...field}
placeholder="Select department"
fontSize={"sm"}
size={"sm"}
>
{roleDepartments?.roleDepartment?.map(
({ id, department }) => (
<option key={id} value={id}>
{department}
</option>
)
)}
</Select>
)}
/>
<FormErrorMessage fontSize={"xs"} fontWeight={500}>
{errors.department_xid?.message}
</FormErrorMessage>
</FormControl>
<FormControl isInvalid={errors.gradeLevel} isRequired>
<FormLabel fontSize={"sm"} mb={0}>
Grade/level
</FormLabel>
<Controller
name="gradeLevel"
control={control}
render={({ field }) => (
<Select
rounded={"md"}
{...field}
placeholder="Select grade/level"
fontSize={"sm"}
size={"sm"}
>
{roleDepartments?.roleDepartment?.map(
({ id, gradeLevel }) => (
<option key={id} value={id}>
{gradeLevel}
</option>
)
)}
</Select>
)}
/>
<FormErrorMessage fontSize={"xs"} fontWeight={500}>
{errors.department_xid?.message}
</FormErrorMessage>
</FormControl>
<FormControl isRequired>
<Text mt={2} mb={2} fontSize={"sm"}>
Will this role be an Wallet Approver as well? If yes select
category.
</Text>
<CheckboxGroup colorScheme="purple">
<Checkbox value="naruto">
<Text as={"span"} fontSize={"xs"}>
Expense wallet approver
</Text>
</Checkbox>
<br />
<Checkbox value="sasuke">
<Text as={"span"} fontSize={"xs"}>
Benefit wallet approver
</Text>
</Checkbox>
<br />
<Checkbox value="kakashi">
<Text as={"span"} fontSize={"xs"}>
Withdraw funds approver
</Text>
</Checkbox>
</CheckboxGroup>
</FormControl>
<Box backgroundColor={"#6311CB14"} p={4} rounded={"md"}>
<Text
display={"flex"}
alignItems={"center"}
fontSize={"sm"}
me={2}
color={"#000"}
mb={2}
>
<Text mb={0} me={2} fontSize={"md"}>
<IoSettingsOutline color="#6311CB" />
</Text>{" "}
Advance Setting
</Text>
<Text color={"#878787"} fontSize={"xs"}>
Enable this to provide Corporate dashboard access to this
role.
</Text>
<PrimaryButton onClick={onOpenAdvance} title={"Give Access"} />
</Box>
</Stack>
</ModalBody>
<ModalFooter>
{/* Cancel Button */}
<Button
colorScheme="gray"
mr={3}
onClick={onClose}
fontSize={"sm"}
size={"sm"}
w={"50%"}
>
Save as draft
</Button>
{/* Submit Button */}
<Button
colorScheme="customPurple"
size={"sm"}
fontSize={"sm"}
fontWeight={500}
w={"50%"}
type="submit"
>
Save & proceed
</Button>
</ModalFooter>
</Box>
</ModalContent>
<AddRoleModalAdvance isOpen={isOpenAdvance} onClose={onCloseAdvance} />
</Modal>
);
};
export default AddRoleModal;

View File

@@ -0,0 +1,296 @@
import {
Box,
Button,
Checkbox,
CheckboxGroup,
FormControl,
FormErrorMessage,
FormLabel,
Input,
Modal,
ModalBody,
ModalCloseButton,
ModalContent,
ModalFooter,
ModalHeader,
ModalOverlay,
Select,
Stack,
Table,
Tbody,
Td,
Text,
Th,
Thead,
Tr,
} from "@chakra-ui/react";
import * as yup from "yup";
import React, { useContext } from "react";
import { Controller, useForm } from "react-hook-form";
import { yupResolver } from "@hookform/resolvers/yup";
import GlobalStateContext from "../../../Contexts/GlobalStateContext";
import { IoSettingsOutline } from "react-icons/io5";
import PrimaryButton from "../../../Components/Buttons/PrimaryButton";
// Validation schema using Yup
const cashDetails = yup.object().shape({
role: yup.string().required("Role is required"),
department_xid: yup.number().required("Artifact name is required"),
});
const AddRoleModalAdvance = ({ isOpen, onClose }) => {
// ======================[ Cotext Api ]
const { roleDepartments } = useContext(GlobalStateContext);
const {
control,
handleSubmit,
reset,
formState: { errors },
} = useForm({
resolver: yupResolver(cashDetails),
});
// Define the onSubmit function
const onSubmit = (data) => {
console.log(data);
// You can add any further logic you need after form submission
reset(); // Reset the form after submission
onClose(); // Close the modal after submission
};
const data = [
{
action: "Dashboard",
all: "John Doe",
view: 28,
add: "Text",
edit: "Text",
delete: "Text",
},
{
action: "Dashboard",
all: "John Doe",
view: 28,
add: "Text",
edit: "Text",
delete: "Text",
},
{
action: "Dashboard",
all: "John Doe",
view: 28,
add: "Text",
edit: "Text",
delete: "Text",
},
{
action: "Dashboard",
all: "John Doe",
view: 28,
add: "Text",
edit: "Text",
delete: "Text",
},
];
return (
<Modal isOpen={isOpen} onClose={onClose} isCentered>
<ModalOverlay />
<ModalContent height={"600px"} overflow={"scroll"}>
<ModalHeader fontSize={"sm"}>Add Role Advance</ModalHeader>
<ModalCloseButton />
<Box as="form" onSubmit={handleSubmit(onSubmit)}>
<ModalBody>
<Stack spacing={4}>
{/* FormControl for role input */}
<FormControl isInvalid={errors.role} isRequired>
<FormLabel fontSize={"sm"} mb={0}>
Role
</FormLabel>
<Controller
name="role"
control={control}
render={({ field }) => (
<Input
rounded={"md"}
{...field}
fontSize={"sm"}
type="text"
size={"sm"}
placeholder="Enter role"
/>
)}
/>
<FormErrorMessage fontSize={"xs"} fontWeight={500}>
{errors.role?.message}
</FormErrorMessage>
</FormControl>
<FormControl isInvalid={errors.department} isRequired>
<FormLabel fontSize={"sm"} mb={0}>
Department
</FormLabel>
<Controller
name="department"
control={control}
render={({ field }) => (
<Select
rounded={"md"}
{...field}
placeholder="Select department"
fontSize={"sm"}
size={"sm"}
>
{roleDepartments?.roleDepartment?.map(
({ id, department }) => (
<option key={id} value={id}>
{department}
</option>
)
)}
</Select>
)}
/>
<FormErrorMessage fontSize={"xs"} fontWeight={500}>
{errors.department_xid?.message}
</FormErrorMessage>
</FormControl>
<FormControl isInvalid={errors.gradeLevel} isRequired>
<FormLabel fontSize={"sm"} mb={0}>
Grade/level
</FormLabel>
<Controller
name="gradeLevel"
control={control}
render={({ field }) => (
<Select
rounded={"md"}
{...field}
placeholder="Select grade/level"
fontSize={"sm"}
size={"sm"}
>
{roleDepartments?.roleDepartment?.map(
({ id, gradeLevel }) => (
<option key={id} value={id}>
{gradeLevel}
</option>
)
)}
</Select>
)}
/>
<FormErrorMessage fontSize={"xs"} fontWeight={500}>
{errors.department_xid?.message}
</FormErrorMessage>
</FormControl>
<FormControl isRequired>
<Text mt={2} mb={2} fontSize={"sm"}>
Will this role be an Wallet Approver as well? If yes select
category.
</Text>
<CheckboxGroup colorScheme="purple">
<Checkbox value="naruto">
<Text as={"span"} fontSize={"xs"}>
Expense wallet approver
</Text>
</Checkbox>
<br />
<Checkbox value="sasuke">
<Text as={"span"} fontSize={"xs"}>
Benefit wallet approver
</Text>
</Checkbox>
<br />
<Checkbox value="kakashi">
<Text as={"span"} fontSize={"xs"}>
Withdraw funds approver
</Text>
</Checkbox>
</CheckboxGroup>
</FormControl>
<Box backgroundColor={"#6311CB14"} p={4} rounded={"md"}>
<Text
display={"flex"}
alignItems={"center"}
fontSize={"sm"}
me={2}
color={"#000"}
mb={2}
>
<Text mb={0} me={2} fontSize={"md"}>
<IoSettingsOutline color="#6311CB" />
</Text>{" "}
Advance Setting
</Text>
<Text color={"#878787"} fontSize={"xs"}>
Enable this to provide Corporate dashboard access to this
role.
</Text>
<PrimaryButton title={"Give Access"} />
</Box>
<Box margin="auto" mt={5} overflow={"scroll"}>
<Table variant="striped">
{/* <TableCaption>Employee Details</TableCaption> */}
<Thead>
<Tr>
<Th>Actions</Th>
<Th>All</Th>
<Th>View</Th>
<Th>Add</Th>
<Th>Edit</Th>
<Th>Delete</Th>
</Tr>
</Thead>
<Tbody>
{data.map((row) => (
<Tr key={row.id}>
<Td fontSize={"xs"}>{row.action}</Td>
<Td fontSize={"xs"}>{row.all}</Td>
<Td fontSize={"xs"}>{row.view}</Td>
<Td fontSize={"xs"}>{row.add}</Td>
<Td fontSize={"xs"}>{row.edit}</Td>
<Td fontSize={"xs"}>{row.delete}</Td>
</Tr>
))}
</Tbody>
</Table>
</Box>
</Stack>
</ModalBody>
<ModalFooter>
{/* Cancel Button */}
<Button
colorScheme="gray"
mr={3}
onClick={onClose}
fontSize={"sm"}
size={"sm"}
w={"50%"}
>
Save as draft
</Button>
{/* Submit Button */}
<Button
colorScheme="customPurple"
size={"sm"}
fontSize={"sm"}
fontWeight={500}
w={"50%"}
type="submit"
>
Save & proceed
</Button>
</ModalFooter>
</Box>
</ModalContent>
</Modal>
);
};
export default AddRoleModalAdvance;

View File

@@ -0,0 +1,166 @@
import {
Box,
Button,
Checkbox,
Icon,
Input,
InputGroup,
InputLeftElement,
Menu,
MenuButton,
MenuItem,
MenuList,
Radio,
Text,
useDisclosure,
VStack,
} from "@chakra-ui/react";
import React, { useContext, useEffect, useState } from "react";
import { AddIcon, ChevronDownIcon, SearchIcon } from "@chakra-ui/icons";
import { LuListFilter } from "react-icons/lu";
import GlobalStateContext from "../../../Contexts/GlobalStateContext";
import { OPACITY_ON_LOAD } from "../../../Layout/animations";
import PrimaryButton from "../../../Components/Buttons/PrimaryButton";
import NormalTable from "../../../Components/DataTable/NormalTable";
import SwitchButton from "../../../Components/SwitchButton";
import AddDepartment from "./AddDepartmentModal";
import { PiReceipt } from "react-icons/pi";
const EmployeePermissions = () => {
const { employeePermissions } = useContext(GlobalStateContext);
const [isLoading, setIsLoading] = useState(false);
const [searchTerm, setSearchTerm] = useState("");
const [isSwitchOn, setIsSwitchOn] = useState(true);
const { isOpen, onOpen, onClose } = useDisclosure();
useEffect(() => {
// Set isLoading to true
setIsLoading(true);
// Simulate a 3-second delay
const timer = setTimeout(() => {
setIsLoading(false); // Set isLoading to false after 3 seconds
}, 500);
// Cleanup the timer when the component unmounts or when the useEffect re-runs
return () => clearTimeout(timer);
}, []); // Empty dependency array means this effect runs once after the component mounts
// ===============================[ Table Header ]
const tableHeadRow = [
"Employee ID",
"Name",
"Email ID",
"Department",
"Role",
"Permissions",
"Action",
];
// const extractedArray = reportsHistory.map((item)=>({ }))
const extractedArray = employeePermissions.map((item, index) => ({
"Employee ID": (
<Checkbox colorScheme="purple" value="1">
<Text
as={"span"}
display={"flex"}
gap={2}
alignItems={"center"}
fontSize={"xs"}
>
{item?.id}
</Text>
</Checkbox>
),
"Name": item?.name,
"Email ID": item?.emailID,
"Department": item?.department,
"Role": item?.role,
"Permissions":(
<Box bg='#dfdfdf' display={"inline-block"} p={1} rounded={4}>
{item?.permissions}
</Box>
),
"Action": (
<Box
display={"flex"}
gap={1}
alignItems={"center"}
justifyContent={"center"}
>
<SwitchButton isSwitchOn={isSwitchOn} setIsSwitchOn={setIsSwitchOn} />
</Box>
),
}));
return (
<Box {...OPACITY_ON_LOAD} overflowX={"scroll"}>
<Box
rounded={"xl"}
py={3}
// pb={0}
display={"flex"}
flexDirection={"column"}
bg={"#fff"}
shadow={"md"}
minH={"100%"}
>
<VStack mb={3} px={3} alignItems={"start"} gap={0}>
<Box
display={"flex"}
justifyContent={"space-between"}
alignItems={"center"}
w={"100%"}
>
<InputGroup width={300} size="sm" ml={5}>
<InputLeftElement pointerEvents="none">
<SearchIcon color="gray.300" />
</InputLeftElement>
<Input
type="search"
placeholder="Search"
rounded="md"
focusBorderColor="#3725EA"
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
/>
</InputGroup>
<Box>
<Menu>
<MenuButton
as={Button}
leftIcon={<LuListFilter fontSize={"16px"} />}
rightIcon={<ChevronDownIcon />}
fontSize={"xs"}
color={"gray.700"}
variant="outline"
size={"sm"}
me={2}
>
Filter
</MenuButton>
<MenuList>
<MenuItem fontSize={"sm"}>Ascending</MenuItem>
<MenuItem fontSize={"sm"}>Descending</MenuItem>
<MenuItem fontSize={"sm"}>Recently Viewed</MenuItem>
<MenuItem fontSize={"sm"}>Recently Added</MenuItem>
</MenuList>
</Menu>
</Box>
</Box>
</VStack>
<NormalTable
emptyMessage={`We don't have any Sponers `}
tableHeadRow={tableHeadRow}
data={extractedArray}
isLoading={isLoading}
/>
</Box>
<AddDepartment isOpen={isOpen} onClose={onClose} />
</Box>
);
};
export default EmployeePermissions;

View File

@@ -3,6 +3,7 @@ import React from "react";
import MiniHeader from "../../../Components/MiniHeader";
import Department from "./Department";
import Roles from "./Roles";
import EmployeePermissions from "./EmployeePermissions";
const ManageDepartmentAndRoles = () => {
return (
@@ -21,8 +22,8 @@ const ManageDepartmentAndRoles = () => {
<TabPanel px={0}>
<Roles />
</TabPanel>
<TabPanel>
<p>three!</p>
<TabPanel px={0}>
<EmployeePermissions />
</TabPanel>
</TabPanels>
</Tabs>

View File

@@ -25,6 +25,7 @@ import NormalTable from "../../../Components/DataTable/NormalTable";
import SwitchButton from "../../../Components/SwitchButton";
import AddDepartment from "./AddDepartmentModal";
import { PiReceipt } from "react-icons/pi";
import AddRoleModal from "./AddRoleModal";
const Roles = () => {
const { roles } = useContext(GlobalStateContext);
@@ -135,7 +136,7 @@ const Roles = () => {
alignItems={"center"}
w={"100%"}
>
<InputGroup width={300} size="sm" ml={5}>
<InputGroup width={300} size="sm" ml={5}>
<InputLeftElement pointerEvents="none">
<SearchIcon color="gray.300" />
</InputLeftElement>
@@ -184,7 +185,7 @@ const Roles = () => {
isLoading={isLoading}
/>
</Box>
<AddDepartment isOpen={isOpen} onClose={onClose} />
<AddRoleModal isOpen={isOpen} onClose={onClose} />
</Box>
);
};

View File

@@ -1,19 +1,11 @@
import { HiOutlineNewspaper } from "react-icons/hi";
import { TbBrandMedium, TbSquareRoundedFilled } from "react-icons/tb";
import {
RiMoneyDollarBoxLine,
} from "react-icons/ri";
import { RiExchangeBoxLine } from "react-icons/ri";
import { VscSymbolClass } from "react-icons/vsc";
import { FiHome, FiUsers } from "react-icons/fi";
import {MdOutlineEditCalendar, MdOutlinePolicy, MdOutlineTaskAlt, MdWorkspacesOutline } from "react-icons/md";
import { GrNotification } from "react-icons/gr";
import HomeIcon from "../assets/homeIcon.png"
import { PiReceiptBold } from "react-icons/pi";
import { PiCopySimple } from "react-icons/pi";
import { GoGift } from "react-icons/go";
import { MdOutlineLiveHelp } from "react-icons/md";
import { TbSquareRoundedFilled } from "react-icons/tb";
import { FaRegAddressCard } from "react-icons/fa6";
import { RiMoneyDollarBoxLine } from "react-icons/ri";
import { LuMousePointerClick } from "react-icons/lu";
import { TbAlignBoxBottomCenter } from "react-icons/tb";
import { MdOutlineNotifications } from "react-icons/md";
import { AiOutlineHome } from "react-icons/ai";
import { IoSettingsOutline } from "react-icons/io5";
export const nav = [
@@ -29,7 +21,7 @@ export const nav = [
},
{
title: "Manage Human Resource",
Icon: FiHome,
Icon: FaRegAddressCard,
path: "/home",
submenu: [
{
@@ -69,9 +61,15 @@ export const nav = [
},
{
title: "OptiFii Expense",
Icon: FiHome,
Icon: RiMoneyDollarBoxLine,
path: "/home",
submenu: [
{
title: "Dashboard",
path: "/dashboard",
icon: TbSquareRoundedFilled,
colorCode:"#70a1ff"
},
{
title: "Wallet program",
path: "/wallet-program",
@@ -93,23 +91,17 @@ export const nav = [
],
type: "accordion",
},
{
title: "OptiFii Expense",
type: "single",
path: "/optiFii-expense",
Icon: PiReceiptBold,
},
{
title: "OptiFii Tax Benefit",
type: "single",
path: "/optiFii-benefit",
Icon: PiReceiptBold,
Icon: LuMousePointerClick,
},
{
title: "OptiFii Gifs & Vouchers",
type: "single",
path: "/optiFii-vouchers",
Icon: PiReceiptBold,
Icon: LuMousePointerClick,
},
{
title: "Shop",
@@ -119,13 +111,13 @@ export const nav = [
title: "Reports",
type: "single",
path: "/reports",
Icon: PiReceiptBold,
Icon: TbAlignBoxBottomCenter,
},
{
title: "Support & Ticket",
type: "single",
path: "/support-ticket",
Icon: PiReceiptBold,
Icon: MdOutlineNotifications,
},
{
title: "Settings",
@@ -135,7 +127,7 @@ export const nav = [
title: "Settings",
type: "single",
path: "/settings",
Icon: PiReceiptBold,
Icon: IoSettingsOutline,
},
];