From 7882095294babe8ee79c1da539fb96ce41c0d853 Mon Sep 17 00:00:00 2001 From: priyanshuvish Date: Tue, 1 Oct 2024 19:44:47 +0530 Subject: [PATCH] update --- src/Components/DataTable/AccordianTable.jsx | 192 +++++++ src/Components/PayCard.jsx | 96 ++++ src/Components/SuccessModal/SuccessModal.jsx | 104 ++++ src/Contexts/GlobalStateProvider.jsx | 414 +++++++++----- src/Pages/ManageHumanResource/Employees.jsx | 207 ++++--- .../ManageHumanResource/EmployeesAddModal.jsx | 101 ++++ .../EmployeesAddMultipleModal.jsx | 91 +++ .../EmployeesEditModal.jsx | 101 ++++ .../EmployeesPullBackFunds.jsx | 52 ++ .../ManageHumanResource/EmployeesView.jsx | 518 ++++++++++++++++++ .../EmployeesViewRecentReports.jsx | 240 ++++++++ .../EmployeesViewRecentReportsView.jsx | 219 ++++++++ .../EmployeesViewRecentTransaction.jsx | 201 +++++++ .../PullBackFundsBenefit.jsx | 216 ++++++++ .../PullBackFundsExpense.jsx | 182 ++++++ .../PullBackFundsGifts.jsx | 179 ++++++ .../OnboardingAddCompanyDetails.jsx | 312 +++++------ src/Routes/Routes.js | 10 + src/assets/TRANSCORP_LOGO.svg | 13 + src/assets/logo_card.svg | 13 + src/assets/rupayImg.png | Bin 0 -> 8181 bytes 21 files changed, 3082 insertions(+), 379 deletions(-) create mode 100644 src/Components/DataTable/AccordianTable.jsx create mode 100644 src/Components/PayCard.jsx create mode 100644 src/Components/SuccessModal/SuccessModal.jsx create mode 100644 src/Pages/ManageHumanResource/EmployeesAddModal.jsx create mode 100644 src/Pages/ManageHumanResource/EmployeesAddMultipleModal.jsx create mode 100644 src/Pages/ManageHumanResource/EmployeesEditModal.jsx create mode 100644 src/Pages/ManageHumanResource/EmployeesPullBackFunds.jsx create mode 100644 src/Pages/ManageHumanResource/EmployeesView.jsx create mode 100644 src/Pages/ManageHumanResource/EmployeesViewRecentReports.jsx create mode 100644 src/Pages/ManageHumanResource/EmployeesViewRecentReportsView.jsx create mode 100644 src/Pages/ManageHumanResource/EmployeesViewRecentTransaction.jsx create mode 100644 src/Pages/ManageHumanResource/PullBackFundsBenefit.jsx create mode 100644 src/Pages/ManageHumanResource/PullBackFundsExpense.jsx create mode 100644 src/Pages/ManageHumanResource/PullBackFundsGifts.jsx create mode 100644 src/assets/TRANSCORP_LOGO.svg create mode 100644 src/assets/logo_card.svg create mode 100644 src/assets/rupayImg.png diff --git a/src/Components/DataTable/AccordianTable.jsx b/src/Components/DataTable/AccordianTable.jsx new file mode 100644 index 0000000..ad84d8b --- /dev/null +++ b/src/Components/DataTable/AccordianTable.jsx @@ -0,0 +1,192 @@ +import React, { useState } from "react"; +import { + Table, + TableContainer, + Tbody, + Td, + Th, + Thead, + Tr, + Skeleton, + TableCaption, + Checkbox, + CheckboxGroup, + Collapse, + HStack, + Text, + Box, // Import Collapse from Chakra UI +} from "@chakra-ui/react"; +import EmptySearchList from "../EmptySearchList"; +import { TABLE_PAGINATION } from "../../Constants/Paginations"; + +const AccordionTable = ({ + data, + isLoading, + tableHeadRow, + emptyMessage, + centered, + total, + showRadioButton, + selectedRadio, + setSelectedRadio, +}) => { + const [expandedRow, setExpandedRow] = useState(null); // Track the expanded row + + console.log(data); + + + const columnWidth = + data && data[0] + ? `${(100 / Object.keys(data[0]).length).toFixed(2)}%` + : "auto"; + + const handleRadioChange = (value) => { + setSelectedRadio(value); + }; + + const toggleRow = (index) => { + setExpandedRow(expandedRow === index ? null : index); // Toggle row expansion + }; + + return ( + + {data?.length === 0 ? ( + + ) : ( + + + {total ? total : "OptiFii v1.0.0"} + + + + {tableHeadRow.map((heading, index) => ( + + ))} + + + + {isLoading + ? Array.from({ length: TABLE_PAGINATION?.size }).map( + (_, index) => ( + + {tableHeadRow.map((_, i) => ( + + ))} + + ) + ) + : data?.map((item, index) => ( + + toggleRow(index)} // Handle row click + > + {tableHeadRow.map((heading, i) => ( + + ))} + + + {/* Conditionally render the expanded content with transition */} + + + + + ))} + +
+ {showRadioButton && heading === "Select" ? ( + + + + ) : isLoading ? ( + + ) : ( + heading + )} +
+ +
+ {showRadioButton && heading === "Select" ? ( + + + + ) : ( + item[heading] + )} +
+ + {item?.subMenu?.map(({ wallet, walBal }, index) =>
+ + + Hide contetnt + + + + + + {wallet} + + + + {walBal} + + +
)} +
+
+ )} +
+ ); +}; + +export default AccordionTable; diff --git a/src/Components/PayCard.jsx b/src/Components/PayCard.jsx new file mode 100644 index 0000000..83b77ae --- /dev/null +++ b/src/Components/PayCard.jsx @@ -0,0 +1,96 @@ +import React, { useEffect, useRef } from 'react' +import logo_card from "../assets/logo_card.svg"; +import TRANSCORP_LOGO from "../assets/TRANSCORP_LOGO.svg"; +import RuPay from "../assets/rupayImg.png"; +// import VanillaTilt from 'vanilla-tilt'; +import { Box, Text, VStack } from '@chakra-ui/layout'; +import { Image } from '@chakra-ui/image'; +import { Button } from '@chakra-ui/button'; + +const PayCard = () => { + // const tiltRef = useRef(null); useEffect(() => { + // const node = tiltRef.current; + // if (node) { + // VanillaTilt.init(node, { + // max: 5, + // speed: 400, + // glare: true, + // "max-glare": 0.5, + // }); + // } + // return () => { + // if (node && node.vanillaTilt) { + // node.vanillaTilt.destroy(); + // } + // }; + // }, []); + + + return ( + + + + + + + + + 1234 5678 1234 5678 + + + + + + {/* */} + + + + + Valid in india + + + ) +} + +export default PayCard \ No newline at end of file diff --git a/src/Components/SuccessModal/SuccessModal.jsx b/src/Components/SuccessModal/SuccessModal.jsx new file mode 100644 index 0000000..b80eb68 --- /dev/null +++ b/src/Components/SuccessModal/SuccessModal.jsx @@ -0,0 +1,104 @@ +import React from 'react'; +import { + Box, HStack, Text, Modal, ModalOverlay, ModalHeader, ModalCloseButton, ModalBody, ModalContent, Button +} from '@chakra-ui/react'; +import { motion } from 'framer-motion'; +import SecondaryButton from '../Buttons/SecondaryButton'; +import PrimaryButton from '../Buttons/PrimaryButton'; + +// Define motion components +const MotionBox = motion(Box); +const MotionSvg = motion("svg"); +const MotionCircle = motion.circle; +const MotionPolyline = motion.polyline; + +const SuccessModal = ({isOpen,onClose}) => { + + return ( + <> + + + + + + + + {/* svg with Framer Motion animation */} + + + + + + + + + Your employee list has been submitted + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. + + + + + + + + + + + + + ); +} + +export default SuccessModal; diff --git a/src/Contexts/GlobalStateProvider.jsx b/src/Contexts/GlobalStateProvider.jsx index 45ff9ab..9bfc221 100644 --- a/src/Contexts/GlobalStateProvider.jsx +++ b/src/Contexts/GlobalStateProvider.jsx @@ -63,6 +63,20 @@ const GlobalStateProvider = ({ children }) => { Department: "Sales", Role: "Sr. Manager", status: "Active", + subMenu: [ + { + wallet: "Food", + walBal: "₹ 5000", + + }, { + wallet: "Travel", + walBal: "₹ 7000", + + }, { + wallet: "Toor", + walBal: "₹ 3000", + + },] }, { id: 2, @@ -74,6 +88,21 @@ const GlobalStateProvider = ({ children }) => { Department: "Sales", Role: "Sr. Manager", status: "Active", + subMenu: [ + { + wallet: "Food", + walBal: "₹ 5000", + + }, { + wallet: "Travel", + walBal: "₹ 7000", + + }, { + wallet: "Toor", + walBal: "₹ 3000", + + },] + }, { id: 3, @@ -85,6 +114,21 @@ const GlobalStateProvider = ({ children }) => { Department: "Sales", Role: "Sr. Manager", status: "Active", + subMenu: [ + { + wallet: "Food", + walBal: "₹ 5000", + + }, { + wallet: "Travel", + walBal: "₹ 7000", + + }, { + wallet: "Toor", + walBal: "₹ 3000", + + },] + }, { id: 4, @@ -96,6 +140,21 @@ const GlobalStateProvider = ({ children }) => { Department: "Sales", Role: "Sr. Manager", status: "Active", + subMenu: [ + { + wallet: "Food", + walBal: "₹ 5000", + + }, { + wallet: "Travel", + walBal: "₹ 7000", + + }, { + wallet: "Toor", + walBal: "₹ 3000", + + },] + }, { id: 5, @@ -107,6 +166,21 @@ const GlobalStateProvider = ({ children }) => { Department: "Sales", Role: "Sr. Manager", status: "Inactive", + subMenu: [ + { + wallet: "Food", + walBal: "₹ 5000", + + }, { + wallet: "Travel", + walBal: "₹ 7000", + + }, { + wallet: "Toor", + walBal: "₹ 3000", + + },] + }, { id: 6, @@ -118,6 +192,21 @@ const GlobalStateProvider = ({ children }) => { Department: "Sales", Role: "Sr. Manager", status: "Inactive", + subMenu: [ + { + wallet: "Food", + walBal: "₹ 5000", + + }, { + wallet: "Travel", + walBal: "₹ 7000", + + }, { + wallet: "Toor", + walBal: "₹ 3000", + + },] + }, { id: 7, @@ -129,6 +218,7 @@ const GlobalStateProvider = ({ children }) => { Department: "Sales", Role: "Sr. Manager", status: "Active", + }, { id: 8, @@ -140,6 +230,21 @@ const GlobalStateProvider = ({ children }) => { Department: "Sales", Role: "Sr. Manager", status: "Inactive", + subMenu: [ + { + wallet: "Food", + walBal: "₹ 5000", + + }, { + wallet: "Travel", + walBal: "₹ 7000", + + }, { + wallet: "Toor", + walBal: "₹ 3000", + + },] + }, { id: 9, @@ -151,61 +256,7 @@ const GlobalStateProvider = ({ children }) => { Department: "Sales", Role: "Sr. Manager", status: "Active", - }, - { - id: 10, - EmpID: "124589", - Name: "Status", - emailAddress: "in***@wdimails.com", - mobileNumber: "+91 ***8451254", - Grade: "L1", - Department: "Sales", - Role: "Sr. Manager", - status: "Active", - }, - { - id: 11, - EmpID: "124589", - Name: "Status", - emailAddress: "in***@wdimails.com", - mobileNumber: "+91 ***8451254", - Grade: "L1", - Department: "Sales", - Role: "Sr. Manager", - status: "Inactive", - }, - { - id: 7, - EmpID: "124589", - Name: "Status", - emailAddress: "in***@wdimails.com", - mobileNumber: "+91 ***8451254", - Grade: "L1", - Department: "Sales", - Role: "Sr. Manager", - status: "Active", - }, - { - id: 8, - EmpID: "124589", - Name: "Status", - emailAddress: "in***@wdimails.com", - mobileNumber: "+91 ***8451254", - Grade: "L1", - Department: "Sales", - Role: "Sr. Manager", - status: "Active", - }, - { - id: 9, - EmpID: "124589", - Name: "Status", - emailAddress: "in***@wdimails.com", - mobileNumber: "+91 ***8451254", - Grade: "L1", - Department: "Sales", - Role: "Sr. Manager", - status: "Active", + }, { id: 10, @@ -218,50 +269,6 @@ const GlobalStateProvider = ({ children }) => { Role: "Sr. Manager", status: "Inactive", }, - { - id: 11, - EmpID: "124589", - Name: "Status", - emailAddress: "in***@wdimails.com", - mobileNumber: "+91 ***8451254", - Grade: "L1", - Department: "Sales", - Role: "Sr. Manager", - status: "Active", - }, - { - id: 7, - EmpID: "124589", - Name: "Status", - emailAddress: "in***@wdimails.com", - mobileNumber: "+91 ***8451254", - Grade: "L1", - Department: "Sales", - Role: "Sr. Manager", - status: "Active", - }, - { - id: 8, - EmpID: "124589", - Name: "Status", - emailAddress: "in***@wdimails.com", - mobileNumber: "+91 ***8451254", - Grade: "L1", - Department: "Sales", - Role: "Sr. Manager", - status: "Active", - }, - { - id: 9, - EmpID: "124589", - Name: "Status", - emailAddress: "in***@wdimails.com", - mobileNumber: "+91 ***8451254", - Grade: "L1", - Department: "Sales", - Role: "Sr. Manager", - status: "Active", - }, { id: 10, EmpID: "124589", @@ -1267,15 +1274,6 @@ const GlobalStateProvider = ({ children }) => { approver: "Sales", disburser: "Sales", }, - { - reportName: "Jan 12, 2022", - reportBy: "in***@wdimails.com", - reportAmount: "+91 ***8451254", - dateTime: "Sales", - orderStatus: "Fully reimbursed", - approver: "Sales", - disburser: "Sales", - }, ]); // const [advanceStatus, setAdvanceStatus] = useState([ @@ -1563,7 +1561,7 @@ const GlobalStateProvider = ({ children }) => { }, ]) -// supprt and ticket + // supprt and ticket const [SupportAndTicket, setSupportAndTicket] = useState([ { @@ -1947,42 +1945,168 @@ const GlobalStateProvider = ({ children }) => { }, ] -); + ); -return ( - - {children} - -); + // Recent report + const [recentReports, setRecentReports] = useState([ + { + reportName: "Food for June 30", + reportAmount: "₹ 5000", + dateTime: "Jun 10, 2024", + status: "Fully Reimbursed", + approver: "Reethik Thota", + disburser: "Reethik Thota L1", + }, + { + reportName: "Food for June 30", + reportAmount: "₹ 5000", + dateTime: "Jun 10, 2024", + status: "Approved", + approver: "Reethik Thota", + disburser: "Reethik Thota L1", + }, + { + reportName: "Food for June 30", + reportAmount: "₹ 5000", + dateTime: "Jun 10, 2024", + status: "Approved", + approver: "Reethik Thota", + disburser: "Reethik Thota L1", + }, + { + reportName: "Food for June 30", + reportAmount: "₹ 5000", + dateTime: "Jun 10, 2024", + status: "Approved", + approver: "Reethik Thota", + disburser: "Reethik Thota L1", + }, + { + reportName: "Food for June 30", + reportAmount: "₹ 5000", + dateTime: "Jun 10, 2024", + status: "Fully Reimbursed", + approver: "Reethik Thota", + disburser: "Reethik Thota L1", + }, + { + reportName: "Food for June 30", + reportAmount: "₹ 5000", + dateTime: "Jun 10, 2024", + status: "Fully Reimbursed", + approver: "Reethik Thota", + disburser: "Reethik Thota L1", + }, + { + reportName: "Food for June 30", + reportAmount: "₹ 5000", + dateTime: "Jun 10, 2024", + status: "Fully Reimbursed", + approver: "Reethik Thota", + disburser: "Reethik Thota L1", + }, + { + reportName: "Food for June 30", + reportAmount: "₹ 5000", + dateTime: "Jun 10, 2024", + status: "Fully Reimbursed", + approver: "Reethik Thota", + disburser: "Reethik Thota L1", + }, + ]); + + // Recent transaction + + const [recentTransaction, setRecentTransaction] = useState([ + { + walletName: "Food", + Card: "Visa card **** 4831", + dateTime: "Jun 10, 2024", + Amount: "₹ 5000", + Merchant: "Dine in", + }, + { + walletName: "Food", + Card: "Visa card **** 4831", + dateTime: "Jun 10, 2024", + Amount: "₹ 5000", + Merchant: "Dine in", + }, + { + walletName: "Food", + Card: "Visa card **** 4831", + dateTime: "Jun 10, 2024", + Amount: "₹ 5000", + Merchant: "Dine in", + }, + { + walletName: "Food", + Card: "Visa card **** 4831", + dateTime: "Jun 10, 2024", + Amount: "₹ 5000", + Merchant: "Dine in", + }, + { + walletName: "Food", + Card: "Visa card **** 4831", + dateTime: "Jun 10, 2024", + Amount: "₹ 5000", + Merchant: "Dine in", + }, + { + walletName: "Food", + Card: "Visa card **** 4831", + dateTime: "Jun 10, 2024", + Amount: "₹ 5000", + Merchant: "Dine in", + }, + { + walletName: "Food", + Card: "Visa card **** 4831", + dateTime: "Jun 10, 2024", + Amount: "₹ 5000", + Merchant: "Dine in", + }, + ]); + + return ( + + {children} + + ); }; export default GlobalStateProvider; diff --git a/src/Pages/ManageHumanResource/Employees.jsx b/src/Pages/ManageHumanResource/Employees.jsx index a53fd44..3683346 100644 --- a/src/Pages/ManageHumanResource/Employees.jsx +++ b/src/Pages/ManageHumanResource/Employees.jsx @@ -1,9 +1,11 @@ import { Box, Button, + Checkbox, Divider, HStack, Icon, + IconButton, Image, Input, InputGroup, @@ -16,6 +18,7 @@ import { Tag, TagLabel, Text, + useDisclosure, VStack, } from "@chakra-ui/react"; import React, { useContext, useEffect, useState } from "react"; @@ -24,32 +27,49 @@ import GlobalStateContext from "../../Contexts/GlobalStateContext"; import NormalTable from "../../Components/DataTable/NormalTable"; import { AddIcon, - CalendarIcon, ChevronDownIcon, - EmailIcon, SearchIcon, - ViewIcon, } from "@chakra-ui/icons"; -import { MdFilterList, MdNotificationsNone, MdOutlineHeadsetMic } from "react-icons/md"; -import { RiDeleteBin5Line, RiWallet3Line } from "react-icons/ri"; -import { AiOutlineEdit } from "react-icons/ai"; -import { FaRegEye } from "react-icons/fa"; -import { PiReceipt } from "react-icons/pi"; +import { MdOutlineDeleteOutline, MdOutlineModeEdit } from "react-icons/md"; +import { FaRegUser } from "react-icons/fa"; import { OPACITY_ON_LOAD } from "../../Layout/animations"; -import { Link } from "react-router-dom"; +import { Link, useNavigate } from "react-router-dom"; import backFund from "../../assets/backfund.svg"; import PrimaryButton from "../../Components/Buttons/PrimaryButton"; import { FaArrowUpFromBracket } from "react-icons/fa6"; import SecondaryButton from "../../Components/Buttons/SecondaryButton"; -import { LuListFilter } from "react-icons/lu"; -import { BsFilterRight } from "react-icons/bs"; +import { LuEye, LuListFilter } from "react-icons/lu"; +import { BsFilterRight, BsThreeDotsVertical } from "react-icons/bs"; import pdfIcon from "../../assets/pdfIcon.svg"; import ExcelIcon from "../../assets/ExcelIcon.svg" +import { HiOutlineUserGroup } from "react-icons/hi"; +import EmployeesAddModal from "./EmployeesAddModal"; +import EmployeesEditModal from "./EmployeesEditModal"; +import EmployeesAddMultipleModal from "./EmployeesAddMultipleModal"; const Employees = () => { const { employees } = useContext(GlobalStateContext); const [isLoading, setIsLoading] = useState(false); const [searchTerm, setSearchTerm] = useState(""); + const navigate = useNavigate(); + + const { + isOpen: isAddOpen, + onOpen: onAddOpen, + onClose: onAddClose, + } = useDisclosure(); // For EmployeesAddModal + + const { + isOpen: isEditOpen, + onOpen: onEditOpen, + onClose: onEditClose, + } = useDisclosure(); // For EmployeesEditModal + + const { + isOpen: isMultipleOpen, + onOpen: onMultipleOpen, + onClose: onMultipleClose, + } = useDisclosure(); // For EmployeesAddMultipleModal useEffect(() => { // Set isLoading to true @@ -81,26 +101,28 @@ const Employees = () => { const extractedArray = employees.map((item, index) => ({ "Emp ID": ( - + - {item?.EmpID} - + + ), + "Name": ( + + Dan Abramov + + {item?.Name} + + ), - Name: item?.Name, "Email Address": item?.emailAddress, "Mobile number": item?.mobileNumber, Grade: item?.Grade, @@ -115,16 +137,15 @@ const Employees = () => { item?.status === "Active" ? "green" : item?.status === "Inactive" - ? "red" - : "gray" + ? "red" + : "gray" } - border={`1px solid ${ - item?.status === "Active" - ? "green" - : item?.status === "Inactive" + border={`1px solid ${item?.status === "Active" + ? "green" + : item?.status === "Inactive" ? "red" : "gray" // default border color if status doesn't match any condition - }`} + }`} p={1} px={3} > @@ -132,42 +153,42 @@ const Employees = () => { ), Action: ( - - - - + + + } + bg={"transparent"} + /> + + } + fontSize={"sm"} + fontWeight={500} + color={"#4D4D4D"} + > + Edit + + } + fontSize={"sm"} + fontWeight={500} + color={"#4D4D4D"} + > + Delete + + } + fontSize={"sm"} + fontWeight={500} + color={"#4D4D4D"} + onClick={()=>navigate("/employees/view")} + > + View + + + ), })); @@ -224,13 +245,35 @@ const Employees = () => { Export as Excel - } title={"Add Employee"} /> + + } title={"Add Employee"} /> + + } + fontSize={"xs"} + fontWeight={500} + color={"#4D4D4D"} + onClick={onAddOpen} + > + Add single employee + + } + fontSize={"xs"} + fontWeight={500} + color={"#4D4D4D"} + onClick={onMultipleOpen} + > + Add multiple employee + + + - + } @@ -244,20 +287,19 @@ const Employees = () => { Sort - Ascending + Ascending Descending Recently Viewed Recently Added - - - } - title={"Pull back funds"} - /> - + + navigate("/employees/pull-back-funds")} + leftIcon={} + title={"Pull back funds"} + /> { Recently Added - + { isLoading={isLoading} /> + {/* Call EmployeesAddModal */} + + + {/* Call EmployeesEditModal */} + + + {/* Call EmployeesEditModal */} + + ); }; diff --git a/src/Pages/ManageHumanResource/EmployeesAddModal.jsx b/src/Pages/ManageHumanResource/EmployeesAddModal.jsx new file mode 100644 index 0000000..076ba00 --- /dev/null +++ b/src/Pages/ManageHumanResource/EmployeesAddModal.jsx @@ -0,0 +1,101 @@ +import { Box, HStack, Input, Modal, ModalBody, ModalCloseButton, ModalContent, ModalHeader, ModalOverlay, Select, Text } from '@chakra-ui/react' +import React, { useState } from 'react' +import SecondaryButton from '../../Components/Buttons/SecondaryButton' +import PrimaryButton from '../../Components/Buttons/PrimaryButton' +import PhoneInput from "react-phone-input-2"; +import "react-phone-input-2/lib/style.css"; + +const EmployeesAddModal = ({ isOpen, onClose }) => { + + const [phone, setPhone] = useState(""); + + return ( + + {/* modal */} + + + + Add employee + + + + + + Employee name + + + + + + Email address + + + + + + + + Phone number + + {/* */} + + + + + Employee code + + + + + + + + Department + + + + + + Designation + + + + + + + + + + + + + + + ) +} + +export default EmployeesAddModal \ No newline at end of file diff --git a/src/Pages/ManageHumanResource/EmployeesAddMultipleModal.jsx b/src/Pages/ManageHumanResource/EmployeesAddMultipleModal.jsx new file mode 100644 index 0000000..2b1bb3c --- /dev/null +++ b/src/Pages/ManageHumanResource/EmployeesAddMultipleModal.jsx @@ -0,0 +1,91 @@ +import { Box, HStack, Modal, ModalBody, ModalCloseButton, ModalContent, ModalHeader, ModalOverlay, Text } from '@chakra-ui/react' +import React, { useState } from 'react' +import PrimaryButton from '../../Components/Buttons/PrimaryButton' +import FileUploader from '../../Components/FileUploader/FileUploader' +import SuccessModal from '../../Components/SuccessModal/SuccessModal' +import { useDisclosure } from '@chakra-ui/react' + +const EmployeesAddMultipleModal = ({ isOpen, onClose }) => { + const { isOpen: isSuccessOpen, onOpen: onSuccessOpen, onClose: onSuccessClose } = useDisclosure(); + const [isLoading, setIsLoading] = useState(false); + + const handleFileUploadMultipleEmp = async (file, setPreview) => { + setIsLoading(true); + const formData = new FormData(); + formData.append("document", file); // Append file + + const code = sessionStorage?.getItem("codeCorporate"); + try { + const res = await sendFile({ data: formData, code }); // Upload file to server + console.log(res); + if (res?.data?.data) { + setCorpData({ ...corpData, gst_file_path_name: res?.data?.data }); + setValue("gst_file_path_name", res?.data?.data); + setPreview(res?.data?.data); + toast({ + render: () => , + }); + setIsLoading(false); + } else if (res?.error?.data?.message) { + toast({ + render: () => , + }); + } else if (res?.error) { + toast({ + render: () => , + }); + } + setIsLoading(false); + } catch (error) { + console.error("File upload failed", error); + setIsLoading(false); + } + }; + + const handleNextClick = () => { + // Trigger success modal here + onSuccessOpen(); + }; + + return ( + + {/* modal */} + + + + Get your sheet from excel + + + + + Need help getting started? + + + Read and learn + about importing to OptiFii + + + Download + a sample Excel file + + + + + + + + + + + + + {/* success modal*/} + + + ); +} + +export default EmployeesAddMultipleModal; diff --git a/src/Pages/ManageHumanResource/EmployeesEditModal.jsx b/src/Pages/ManageHumanResource/EmployeesEditModal.jsx new file mode 100644 index 0000000..63f1893 --- /dev/null +++ b/src/Pages/ManageHumanResource/EmployeesEditModal.jsx @@ -0,0 +1,101 @@ +import { Box, HStack, Input, Modal, ModalBody, ModalCloseButton, ModalContent, ModalHeader, ModalOverlay, Select, Text } from '@chakra-ui/react' +import React, { useState } from 'react' +import SecondaryButton from '../../Components/Buttons/SecondaryButton' +import PrimaryButton from '../../Components/Buttons/PrimaryButton' +import PhoneInput from "react-phone-input-2"; +import "react-phone-input-2/lib/style.css"; + +const EmployeesEditModal = ({ isOpen, onClose }) => { + + const [phone, setPhone] = useState(""); + + return ( + + {/* modal */} + + + + Edit employee + + + + + + Employee name + + + + + + Email address + + + + + + + + Phone number + + {/* */} + + + + + Employee code + + + + + + + + Department + + + + + + Designation + + + + + + + + + + + + + + + ) +} + +export default EmployeesEditModal \ No newline at end of file diff --git a/src/Pages/ManageHumanResource/EmployeesPullBackFunds.jsx b/src/Pages/ManageHumanResource/EmployeesPullBackFunds.jsx new file mode 100644 index 0000000..34e4db1 --- /dev/null +++ b/src/Pages/ManageHumanResource/EmployeesPullBackFunds.jsx @@ -0,0 +1,52 @@ +import { Box, Tab, TabIndicator, TabList, TabPanel, TabPanels, Tabs } from "@chakra-ui/react"; +import React from "react"; +import PullBackFundsExpense from "./PullBackFundsExpense"; +import PullBackFundsBenefit from "./PullBackFundsBenefit"; +import PullBackFundsGifts from "./PullBackFundsGifts"; + +const EmployeesPullBackFunds = () => { + return ( + + + + Expense + Benefit + Gifts + + + + + + + + + + + + + + + + + ); +}; + +export default EmployeesPullBackFunds; diff --git a/src/Pages/ManageHumanResource/EmployeesView.jsx b/src/Pages/ManageHumanResource/EmployeesView.jsx new file mode 100644 index 0000000..55df01c --- /dev/null +++ b/src/Pages/ManageHumanResource/EmployeesView.jsx @@ -0,0 +1,518 @@ +import { + Badge, Box, HStack, Image, Tab, TabIndicator, TabList, TabPanel, TabPanels, Tabs, Text, + Heading, Menu, MenuButton, MenuItem, MenuList, VStack, Button, + Tag, +} from '@chakra-ui/react' +import React, { useContext, useEffect, useState } from 'react' +import { OPACITY_ON_LOAD } from '../../Layout/animations' +import MiniHeader from '../../Components/MiniHeader' +import { GoDotFill } from 'react-icons/go' +import PayCard from '../../Components/PayCard' +import PrimaryButton from '../../Components/Buttons/PrimaryButton' +import { BsPrinter } from 'react-icons/bs' +import { LuListFilter, LuScrollText } from "react-icons/lu"; +import NormalTable from "../../Components/DataTable/NormalTable"; +import { FaArrowUpFromBracket } from "react-icons/fa6"; +import pdfIcon from "../../assets/pdfIcon.svg"; +import ExcelIcon from "../../assets/ExcelIcon.svg"; +import { AiOutlineCalendar } from "react-icons/ai"; +import { IoMdArrowDropdown } from "react-icons/io"; +import { BsArrowsAngleExpand, BsFilterRight } from "react-icons/bs"; +import { ChevronDownIcon, SearchIcon } from "@chakra-ui/icons"; +import GlobalStateContext from '../../Contexts/GlobalStateContext' +import { MdDeleteOutline, MdNoFood, MdOutlineModeEdit } from 'react-icons/md' +import SecondaryButton from '../../Components/Buttons/SecondaryButton' +import { useNavigate } from 'react-router-dom' + + + +const EmployeesView = () => { + + const { reimbursementStatus } = useContext(GlobalStateContext); + const { advanceStatus } = useContext(GlobalStateContext); + const [isLoading, setIsLoading] = useState(false); + const [searchTerm, setSearchTerm] = useState(""); + + const navigate = useNavigate(); + + 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 = [ + "Report name", + "Report amount", + "Date & time", + "Order Status", + "Approver", + "Disburser", + "", + ]; + + const tableHeadRowAdvance = [ + "Wallet Name", + "Card", + "Date & time", + "Amount", + "Merchant", + ]; + + // const extractedArray = reportsHistory.map((item)=>({ })) + + const extractedArray = reimbursementStatus.map((item, index) => ({ + "Report name": ( + + + + + + Food for June 30 + + + ), + "Report amount": ( + + ₹ 5000 + + ), + "Date & time": ( + + Jun 10, 2024, + + ), + + "Order Status": ( + + {item?.orderStatus} + + ), + Approver: ( + + Reethik Thota + + ), + + Disburser: ( + + Reethik Thota L1 + + ), + "": ( + + View Reports + + ), + + })); + + const extractedArrayAdvance = advanceStatus.map((item, index) => ({ + "Wallet Name": ( + + + + + + Food + + + ), + "Card": ( + + Visa card **** 4831 + + ), + "Date & time": ( + + Jun 10, 2024, + + ), + + "Amount": ( + + ₹ 5000 + + ), + + "Merchant": ( + + Dine in + + ), + })); + + return ( + + + + + + Employee Details + + + } + title={"Edit"} /> + } + title={"Delete"} /> + + + + + + Dan Abramov + + + Pooja Shah + + Design - UI/UX Designer + + Employee ID : WD-0067 + + Member Since : 1st Jan 2022 + + + + + + Active + + + + + + Phone : + + +91 4578451245 + + + + Email : + + poojashah@wdipl.com + + + + Grade : + + A01 + + + + + + + + + + Card Details + + + + + + + + + Card ID + + 0067445 + + + + Card limit + + ₹ 10,000 + + + + Card type + + Reloadable + + + + + + + + + + + + Wallets + + } + title={"Pull back funds"} + /> + + + + + + Expense + + Benefit + Gifts + + + + + + + + + + + + + + + + + + + + {/* dhbfdbf */} + + + + + + Recent Reports + + + + + Time Period : + + + + Feb 20 - Jan 30, 2024{" "} + + + + + + } + rightIcon={} + fontSize={"xs"} + colorScheme="gray" + color={"gray.700"} + variant="outline" + size={"sm"} + > + Export + + + + Export as PDF + + + Export as Excel + + + + navigate("/employees/view/recent-reports")} + as={Button} + color={"#6311CB"} + size={18} + cursor={"pointer"} + /> + + + + + + + + + + + + Recent Transaction + + + + + Time Period : + + + + Feb 20 - Jan 30, 2024{" "} + + + + + navigate("/employees/view/recent-transaction")} + as={Button} + color={"#6311CB"} + size={18} + cursor={"pointer"} + /> + + + + + + + + ) +} + +export default EmployeesView + + diff --git a/src/Pages/ManageHumanResource/EmployeesViewRecentReports.jsx b/src/Pages/ManageHumanResource/EmployeesViewRecentReports.jsx new file mode 100644 index 0000000..dc76ec9 --- /dev/null +++ b/src/Pages/ManageHumanResource/EmployeesViewRecentReports.jsx @@ -0,0 +1,240 @@ +import { + Box, HStack, Text, Tag, + Image, + VStack, + InputGroup, + InputLeftElement, + Input, + Menu, + MenuButton, + MenuList, + MenuItem, + Divider, + Button +} from '@chakra-ui/react' +import React, { useContext, useEffect, useState } from 'react' +import { OPACITY_ON_LOAD } from '../../Layout/animations' +import MiniHeader from '../../Components/MiniHeader' +import { LuListFilter, LuScrollText } from "react-icons/lu"; +import NormalTable from "../../Components/DataTable/NormalTable"; +import GlobalStateContext from '../../Contexts/GlobalStateContext' +import { ChevronDownIcon, SearchIcon } from '@chakra-ui/icons'; +import { FaArrowUpFromBracket } from 'react-icons/fa6'; +import { BsFilterRight } from 'react-icons/bs'; +import pdfIcon from "../../assets/pdfIcon.svg"; +import ExcelIcon from "../../assets/ExcelIcon.svg" +import { GoDotFill } from 'react-icons/go'; +import { useNavigate } from 'react-router-dom'; + +const EmployeesViewRecentReports = () => { + + const { recentReports } = useContext(GlobalStateContext); + const [isLoading, setIsLoading] = useState(false); + const [searchTerm, setSearchTerm] = useState(""); + const navigate = useNavigate(); + + useEffect(() => { + setIsLoading(true); + + const timer = setTimeout(() => { + setIsLoading(false); + }, 500); + + return () => clearTimeout(timer); + }, []); + + // ===============================[ Table Header ] + const tableHeadRow = [ + "Report name", + "Report amount", + "Date & time", + "Order Status", + "Approver", + "Disburser", + "", + ]; + + // Dynamically map the reports to the table + const extractedArray = recentReports.map((item, index) => ({ + "Report name": ( + + + + + + {item?.reportName || "N/A"} + + + ), + "Report amount": ( + + {item?.reportAmount || "N/A"} + + ), + "Date & time": ( + + {item?.dateTime || "N/A"} + + ), + "Order Status": ( + + + + + {item?.status || "N/A"} + + + + + ), + Approver: ( + + {item?.approver || "N/A"} + + ), + Disburser: ( + + {item?.disburser || "N/A"} + + ), + "": ( + navigate("/employees/view/recent-reports/view")} + > + View Reports + + ), + })); + + return ( + + + + + + Dan Abramov + + + Pooja Shah + + Design - UI/UX Designer + + + + + + + + + setSearchTerm(e.target.value)} + /> + + + + + + + + } + rightIcon={} + fontSize={"xs"} + color={"gray.700"} + variant="outline" + size={"sm"} + me={2} + > + Sort + + + Ascending + Descending + Recently Viewed + Recently Added + + + + + + } + rightIcon={} + fontSize={"xs"} + colorScheme="gray" + color={"gray.700"} + variant="outline" + size={"sm"} + me={2} + > + Export + + + Export as PDF + Export as Excel + + + + } + rightIcon={} + fontSize={"xs"} + color={"gray.700"} + variant="outline" + size={"sm"} + me={2} + > + Filter + + + Ascending + Descending + Recently Viewed + Recently Added + + + + + + + + ); +}; + +export default EmployeesViewRecentReports; diff --git a/src/Pages/ManageHumanResource/EmployeesViewRecentReportsView.jsx b/src/Pages/ManageHumanResource/EmployeesViewRecentReportsView.jsx new file mode 100644 index 0000000..da81701 --- /dev/null +++ b/src/Pages/ManageHumanResource/EmployeesViewRecentReportsView.jsx @@ -0,0 +1,219 @@ +import { + Badge, Box, HStack, Image, Tab, TabIndicator, TabList, TabPanel, TabPanels, Tabs, Text, + Heading, Menu, MenuButton, MenuItem, MenuList, VStack, Button, + Tag, + Divider, +} from '@chakra-ui/react' +import React, { useContext, useEffect, useState } from 'react' +import { OPACITY_ON_LOAD } from '../../Layout/animations' +import MiniHeader from '../../Components/MiniHeader' +import { GoDotFill } from 'react-icons/go' +import PayCard from '../../Components/PayCard' +import PrimaryButton from '../../Components/Buttons/PrimaryButton' +import { BsPrinter } from 'react-icons/bs' +import { LuListFilter, LuScrollText } from "react-icons/lu"; +import NormalTable from "../../Components/DataTable/NormalTable"; +import { FaArrowUpFromBracket } from "react-icons/fa6"; +import pdfIcon from "../../assets/pdfIcon.svg"; +import ExcelIcon from "../../assets/ExcelIcon.svg"; +import { AiOutlineCalendar } from "react-icons/ai"; +import { IoMdArrowDropdown } from "react-icons/io"; +import { BsArrowsAngleExpand, BsFilterRight } from "react-icons/bs"; +import { ChevronDownIcon, SearchIcon } from "@chakra-ui/icons"; +import GlobalStateContext from '../../Contexts/GlobalStateContext' +import { MdDeleteOutline, MdNoFood, MdOutlineModeEdit } from 'react-icons/md' +import SecondaryButton from '../../Components/Buttons/SecondaryButton' +import { useNavigate } from 'react-router-dom' + + + +const EmployeesViewRecentReportsView = () => { + + const { reimbursementStatus } = useContext(GlobalStateContext); + const { advanceStatus } = useContext(GlobalStateContext); + const [isLoading, setIsLoading] = useState(false); + const [searchTerm, setSearchTerm] = useState(""); + + const navigate = useNavigate(); + + 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 = [ + "Report name", + "Report amount", + "Date & time", + "Order Status", + "Approver", + "Disburser", + "", + ]; + + const tableHeadRowAdvance = [ + "Wallet Name", + "Card", + "Date & time", + "Amount", + "Merchant", + ]; + + // const extractedArray = reportsHistory.map((item)=>({ })) + + const extractedArray = reimbursementStatus.map((item, index) => ({ + "Report name": ( + + + + + + Food for June 30 + + + ), + "Report amount": ( + + ₹ 5000 + + ), + "Date & time": ( + + Jun 10, 2024, + + ), + + "Order Status": ( + + {item?.orderStatus} + + ), + Approver: ( + + Reethik Thota + + ), + + Disburser: ( + + Reethik Thota L1 + + ), + "": ( + + View Reports + + ), + + })); + + const extractedArrayAdvance = advanceStatus.map((item, index) => ({ + "Wallet Name": ( + + + + + + Food + + + ), + "Card": ( + + Visa card **** 4831 + + ), + "Date & time": ( + + Jun 10, 2024, + + ), + + "Amount": ( + + ₹ 5000 + + ), + + "Merchant": ( + + Dine in + + ), + })); + + return ( + + + + + + + Food expense June 2024 + + + + + + + + Fully Reimbursed + + + + + + + + + + + + Report by + + + Kartikey Gautam + + + + + {/* */} + + + ) +} + +export default EmployeesViewRecentReportsView + + diff --git a/src/Pages/ManageHumanResource/EmployeesViewRecentTransaction.jsx b/src/Pages/ManageHumanResource/EmployeesViewRecentTransaction.jsx new file mode 100644 index 0000000..8d262cb --- /dev/null +++ b/src/Pages/ManageHumanResource/EmployeesViewRecentTransaction.jsx @@ -0,0 +1,201 @@ +import { + Box, HStack, Text, Tag, + Image, + VStack, + InputGroup, + InputLeftElement, + Input, + Menu, + MenuButton, + MenuList, + MenuItem, + Divider, + Button +} from '@chakra-ui/react' +import React, { useContext, useEffect, useState } from 'react' +import { OPACITY_ON_LOAD } from '../../Layout/animations' +import MiniHeader from '../../Components/MiniHeader' +import { LuListFilter, LuScrollText } from "react-icons/lu"; +import NormalTable from "../../Components/DataTable/NormalTable"; +import GlobalStateContext from '../../Contexts/GlobalStateContext' +import { ChevronDownIcon, SearchIcon } from '@chakra-ui/icons'; +import { FaArrowUpFromBracket } from 'react-icons/fa6'; +import { BsFilterRight } from 'react-icons/bs'; +import pdfIcon from "../../assets/pdfIcon.svg"; +import ExcelIcon from "../../assets/ExcelIcon.svg" +import { MdNoFood } from 'react-icons/md'; + +const EmployeesViewRecentTransaction = () => { + + const { recentTransaction } = useContext(GlobalStateContext); + const [isLoading, setIsLoading] = useState(false); + const [searchTerm, setSearchTerm] = useState(""); + + useEffect(() => { + setIsLoading(true); + + const timer = setTimeout(() => { + setIsLoading(false); + }, 500); + + return () => clearTimeout(timer); + }, []); + + // ===============================[ Table Header ] + const tableHeadRow = [ + "Wallet Name", + "Card", + "Date & time", + "Amount", + "Merchant", + ]; + + // Dynamically map the reports to the table + const extractedArrayTransaction = recentTransaction.map((item, index) => ({ + "Wallet Name": ( + + + + + + {item?.walletName || "N/A"} + + + ), + "Card": ( + + {item?.Card || "N/A"} + + ), + "Date & time": ( + + {item?.dateTime || "N/A"} + + ), + "Amount": ( + + {item?.Amount || "N/A"} + + ), + "Merchant": ( + + {item?.Merchant || "N/A"} + + ), + })); + + + return ( + + + + + + Dan Abramov + + + Pooja Shah + + Design - UI/UX Designer + + + + + + + + + setSearchTerm(e.target.value)} + /> + + + + + + + + } + rightIcon={} + fontSize={"xs"} + color={"gray.700"} + variant="outline" + size={"sm"} + me={2} + > + Sort + + + Ascending + Descending + Recently Viewed + Recently Added + + + + + + } + rightIcon={} + fontSize={"xs"} + colorScheme="gray" + color={"gray.700"} + variant="outline" + size={"sm"} + me={2} + > + Export + + + Export as PDF + Export as Excel + + + + } + rightIcon={} + fontSize={"xs"} + color={"gray.700"} + variant="outline" + size={"sm"} + me={2} + > + Filter + + + Ascending + Descending + Recently Viewed + Recently Added + + + + + + + + ); +}; + +export default EmployeesViewRecentTransaction; diff --git a/src/Pages/ManageHumanResource/PullBackFundsBenefit.jsx b/src/Pages/ManageHumanResource/PullBackFundsBenefit.jsx new file mode 100644 index 0000000..0def9b1 --- /dev/null +++ b/src/Pages/ManageHumanResource/PullBackFundsBenefit.jsx @@ -0,0 +1,216 @@ +import { + Accordion, + AccordionButton, + AccordionItem, + AccordionPanel, + Box, + Button, + Checkbox, + HStack, + Image, + Input, + InputGroup, + InputLeftElement, + Menu, + MenuButton, + MenuItem, + MenuList, + Text, + VStack, +} from "@chakra-ui/react"; +import React, { useContext, useEffect, useState } from "react"; +import MiniHeader from "../../Components/MiniHeader"; +import GlobalStateContext from "../../Contexts/GlobalStateContext"; +import NormalTable from "../../Components/DataTable/NormalTable"; +import { + ChevronDownIcon, + SearchIcon, +} from "@chakra-ui/icons"; + +import { OPACITY_ON_LOAD } from "../../Layout/animations"; +import { LuEye, LuListFilter } from "react-icons/lu"; +import AccordianTable from "../../Components/DataTable/AccordianTable"; + + + +const PullBackFundsBenefit = () => { + const { employees } = useContext(GlobalStateContext); + const [isLoading, setIsLoading] = useState(false); + const [searchTerm, setSearchTerm] = useState(""); + + 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 = [ + "Emp ID", + "Name", + "Email Address", + "Mobile number", + "Wallet", + "Wallet balance", + ]; + + // const extractedArray = reportsHistory.map((item)=>({ })) + + const extractedArray = employees.map((item, index) => ({ + "Emp ID": ( + + + + {item?.EmpID} + + + + ), + "Name": ( + + Dan Abramov + + {item?.Name} + + + ), + "Email Address": item?.emailAddress, + "Mobile number": item?.mobileNumber, + "Wallet": ( + + + + Food + + + Fuel + + + Travel + + + + ), + "Wallet balance": ( + + ₹ 5000 + + ), + "subMenu": item.subMenu + })); + + return ( + + + + + + + + + setSearchTerm(e.target.value)} + /> + + + + } + rightIcon={} + fontSize={"xs"} + color={"gray.700"} + variant="outline" + size={"sm"} + me={2} + > + Filter + + + Ascending + Descending + Recently Viewed + Recently Added + + + + + + + + + ); +}; + +export default PullBackFundsBenefit; diff --git a/src/Pages/ManageHumanResource/PullBackFundsExpense.jsx b/src/Pages/ManageHumanResource/PullBackFundsExpense.jsx new file mode 100644 index 0000000..e651411 --- /dev/null +++ b/src/Pages/ManageHumanResource/PullBackFundsExpense.jsx @@ -0,0 +1,182 @@ +import { + Accordion, + AccordionButton, + AccordionItem, + AccordionPanel, + Box, + Button, + Checkbox, + HStack, + Image, + Input, + InputGroup, + InputLeftElement, + Menu, + MenuButton, + MenuItem, + MenuList, + Text, + VStack, +} from "@chakra-ui/react"; +import React, { useContext, useEffect, useState } from "react"; +import MiniHeader from "../../Components/MiniHeader"; +import GlobalStateContext from "../../Contexts/GlobalStateContext"; +import NormalTable from "../../Components/DataTable/NormalTable"; +import { + ChevronDownIcon, + SearchIcon, +} from "@chakra-ui/icons"; + +import { OPACITY_ON_LOAD } from "../../Layout/animations"; +import { LuEye, LuListFilter } from "react-icons/lu"; +import { RiArrowDropDownLine, RiArrowDropRightLine } from "react-icons/ri"; +import AccordianTable from "../../Components/DataTable/AccordianTable"; + + + +const PullBackFundsExpense = () => { + const { employees } = useContext(GlobalStateContext); + const [isLoading, setIsLoading] = useState(false); + const [searchTerm, setSearchTerm] = useState(""); + + 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 = [ + "Emp ID", + "Name", + "Email Address", + "Mobile number", + "Wallet", + "Wallet balance", + ]; + + // const extractedArray = reportsHistory.map((item)=>({ })) + + const extractedArray = employees.map((item, index) => ({ + "Emp ID": ( + + + + {item?.EmpID} + + + + ), + "Name": ( + + Dan Abramov + + {item?.Name} + + + ), + "Email Address": item?.emailAddress, + "Mobile number": item?.mobileNumber, + "Wallet": ( + + + Food + + + ), + "Wallet balance": ( + + ₹ 5000 + + ), + "subMenu": item.subMenu + })); + + return ( + + + + + + + + + setSearchTerm(e.target.value)} + /> + + + + } + rightIcon={} + fontSize={"xs"} + color={"gray.700"} + variant="outline" + size={"sm"} + me={2} + > + Filter + + + Ascending + Descending + Recently Viewed + Recently Added + + + + + + + + + ); +}; + +export default PullBackFundsExpense; diff --git a/src/Pages/ManageHumanResource/PullBackFundsGifts.jsx b/src/Pages/ManageHumanResource/PullBackFundsGifts.jsx new file mode 100644 index 0000000..62ed34f --- /dev/null +++ b/src/Pages/ManageHumanResource/PullBackFundsGifts.jsx @@ -0,0 +1,179 @@ +import { + Accordion, + AccordionButton, + AccordionItem, + AccordionPanel, + Box, + Button, + Checkbox, + HStack, + Image, + Input, + InputGroup, + InputLeftElement, + Menu, + MenuButton, + MenuItem, + MenuList, + Text, + VStack, +} from "@chakra-ui/react"; +import React, { useContext, useEffect, useState } from "react"; +import MiniHeader from "../../Components/MiniHeader"; +import GlobalStateContext from "../../Contexts/GlobalStateContext"; +import NormalTable from "../../Components/DataTable/NormalTable"; +import { + ChevronDownIcon, + SearchIcon, +} from "@chakra-ui/icons"; + +import { OPACITY_ON_LOAD } from "../../Layout/animations"; +import { LuEye, LuListFilter } from "react-icons/lu"; +import AccordianTable from "../../Components/DataTable/AccordianTable"; + + + +const PullBackFundsGifts = () => { + const { employees } = useContext(GlobalStateContext); + const [isLoading, setIsLoading] = useState(false); + const [searchTerm, setSearchTerm] = useState(""); + + 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 = [ + "Emp ID", + "Name", + "Email Address", + "Mobile number", + "Card number", + "Wallet balance", + ]; + + // const extractedArray = reportsHistory.map((item)=>({ })) + + const extractedArray = employees.map((item, index) => ({ + "Emp ID": ( + + + + {item?.EmpID} + + + + ), + "Name": ( + + Dan Abramov + + {item?.Name} + + + ), + "Email Address": item?.emailAddress, + "Mobile number": item?.mobileNumber, + "Card number": ( + + 3446 **** **** **** + + ), + "Wallet balance": ( + + ₹ 5000 + + ), + "subMenu": item.subMenu + })); + + return ( + + + + + + + + + setSearchTerm(e.target.value)} + /> + + + + } + rightIcon={} + fontSize={"xs"} + color={"gray.700"} + variant="outline" + size={"sm"} + me={2} + > + Filter + + + Ascending + Descending + Recently Viewed + Recently Added + + + + + + + + + ); +}; + +export default PullBackFundsGifts; diff --git a/src/Pages/Onboarding/OnboardingAddCompanyDetails.jsx b/src/Pages/Onboarding/OnboardingAddCompanyDetails.jsx index d571bef..0cc639a 100644 --- a/src/Pages/Onboarding/OnboardingAddCompanyDetails.jsx +++ b/src/Pages/Onboarding/OnboardingAddCompanyDetails.jsx @@ -12,20 +12,20 @@ import ToastBox from '../../Components/ToastBox'; // Yup validation schema const schema = yup.object().shape({ - cin_number: yup - .string() - .required('CIN is required') - .matches(/^[A-Za-z0-9]{21}$/, 'CIN must be exactly 21 characters long'), - pancard_number: yup - .string() - .required('Company PAN is required') - .matches(/[A-Z]{5}[0-9]{4}[A-Z]{1}$/, 'Invalid PAN format'), - gst_number: yup - .string() - .required('GST number is required') - .matches(/\d{2}[A-Z]{5}\d{4}[A-Z]{1}[A-Z\d]{1}[Z]{1}[A-Z\d]{1}/, 'Invalid GST number format'), - gst_file_path_name: yup.mixed().required('GST certificate is required'), - pancard_file_path_name: yup.mixed().required('PAN card is required'), + cin_number: yup + .string() + .required('CIN is required') + .matches(/^[A-Za-z0-9]{21}$/, 'CIN must be exactly 21 characters long'), + pancard_number: yup + .string() + .required('Company PAN is required') + .matches(/[A-Z]{5}[0-9]{4}[A-Z]{1}$/, 'Invalid PAN format'), + gst_number: yup + .string() + .required('GST number is required') + .matches(/\d{2}[A-Z]{5}\d{4}[A-Z]{1}[A-Z\d]{1}[Z]{1}[A-Z\d]{1}/, 'Invalid GST number format'), + gst_file_path_name: yup.mixed().required('GST certificate is required'), + pancard_file_path_name: yup.mixed().required('PAN card is required'), }); const OnboardingAddCompanyDetails = ({ @@ -36,21 +36,21 @@ const OnboardingAddCompanyDetails = ({ steps, handleNext, }) => { - const { register, handleSubmit, setValue, formState: { errors } } = useForm({ - resolver: yupResolver(schema), - }); + const { register, handleSubmit, setValue, formState: { errors } } = useForm({ + resolver: yupResolver(schema), + }); const [fileName, setFileName] = useState(""); - const [ sendFile ] = useSentFileMutation() - const [ isLoading, setIsLoading ] = useState() + const [sendFile] = useSentFileMutation() + const [isLoading, setIsLoading] = useState() const toast = useToast() - const onSubmit = (data) => { - console.log('Form Data:', data); + const onSubmit = (data) => { + console.log('Form Data:', data); setCorpData({ ...corpData, ...data }); handleNext(); - }; + }; @@ -64,25 +64,25 @@ const OnboardingAddCompanyDetails = ({ console.log(files); const formData = new FormData(); - formData.append("document", files[0]); // Append file + formData.append("document", files[0]); // Append file const code = localStorage?.getItem("codeCorporate"); try { - const res = await sendFile({data:formData, code}); // Upload file to server - + const res = await sendFile({ data: formData, code }); // Upload file to server + if (res?.data?.data) { - console.log(res?.data?.data); + console.log(res?.data?.data); // Assuming res.data.data contains the file URL or some ID setValue("gst_file_path_name", res?.data?.data); // Set value with server response - // setCorpData({ ...corpData, ...data }); + // setCorpData({ ...corpData, ...data }); setIsLoading(false) } } catch (error) { console.error("File upload failed", error); } - - + + // setValue("logo_path_file_name", files); // Update react-hook-form state } @@ -96,14 +96,14 @@ const OnboardingAddCompanyDetails = ({ // Assuming only one file is allowed setFileName(files.name); const formData = new FormData(); - formData.append("document", files[0]); // Append file + formData.append("document", files[0]); // Append file const code = localStorage?.getItem("codeCorporate"); try { - const res = await sendFile({data:formData, code}); // Upload file to server + const res = await sendFile({ data: formData, code }); // Upload file to server if (res?.data?.data) { // Assuming res.data.data contains the file URL or some ID setValue("pancard_file_path_name", res?.data?.data); // Set value with server response - // setCorpData({ ...corpData, ...data }); + // setCorpData({ ...corpData, ...data }); setIsLoading(false) } } catch (error) { @@ -124,23 +124,23 @@ const OnboardingAddCompanyDetails = ({ const code = localStorage?.getItem("codeCorporate"); try { const res = await sendFile({ data: formData, code }); // Upload file to server - console.log(res); + console.log(res); if (res?.data?.data) { // Assuming res.data.data contains the file URL or some ID - setCorpData({ ...corpData, gst_file_path_name:res?.data?.data }); + setCorpData({ ...corpData, gst_file_path_name: res?.data?.data }); setValue("gst_file_path_name", res?.data?.data); - console.log(errors); + console.log(errors); setPreview(res?.data?.data) toast({ render: () => , }); setIsLoading(false); - } else if (res?.error?.data?.message){ + } else if (res?.error?.data?.message) { toast({ render: () => , }); - - } else if(res?.error){ + + } else if (res?.error) { toast({ render: () => , }); @@ -163,23 +163,23 @@ const OnboardingAddCompanyDetails = ({ const code = localStorage?.getItem("codeCorporate"); try { const res = await sendFile({ data: formData, code }); // Upload file to server - console.log(res); + console.log(res); if (res?.data?.data) { // Assuming res.data.data contains the file URL or some ID - setCorpData({ ...corpData, pancard_file_path_name:res?.data?.data }); + setCorpData({ ...corpData, pancard_file_path_name: res?.data?.data }); setValue("pancard_file_path_name", res?.data?.data); - console.log(errors); + console.log(errors); setPreview(res?.data?.data) toast({ render: () => , }); setIsLoading(false); - } else if (res?.error?.data?.message){ + } else if (res?.error?.data?.message) { toast({ render: () => , }); - - } else if(res?.error){ + + } else if (res?.error) { toast({ render: () => , }); @@ -197,66 +197,66 @@ const OnboardingAddCompanyDetails = ({ - return ( + return ( - - Add company details - - - Lorem ipsum dolor sit amet, adipiscing elit. - + + Add company details + + + Lorem ipsum dolor sit amet, adipiscing elit. + - - {/* CIN Field */} - - - CIN - - - {errors.cin_number && {errors.cin_number.message}} - + + {/* CIN Field */} + + + CIN + + + {errors.cin_number && {errors.cin_number.message}} + - {/* Company PAN Field */} - - - Company PAN - - - {errors.pancard_number && {errors.pancard_number.message}} - + {/* Company PAN Field */} + + + Company PAN + + + {errors.pancard_number && {errors.pancard_number.message}} + - {/* Company GST Number */} - - - Company GST number - - - {errors.gst_number && {errors.gst_number.message}} - + {/* Company GST Number */} + + + Company GST number + + + {errors.gst_number && {errors.gst_number.message}} + - {/* Upload GST Certificate */} - {/* + {/* Upload GST Certificate */} + {/* Upload GST Certificate @@ -313,37 +313,37 @@ const OnboardingAddCompanyDetails = ({ - {errors.gst_file_path_name?.message && ( - - {errors.gst_file_path_name?.message} - - )} + > {errors.gst_file_path_name?.message && ( + + {errors.gst_file_path_name?.message} + + )} - + - {errors.pancard_file_path_name?.message && ( - - {errors.pancard_file_path_name?.message} - - )} + > {errors.pancard_file_path_name?.message && ( + + {errors.pancard_file_path_name?.message} + + )} - + - {/* Upload PAN Card */} - {/* + {/* Upload PAN Card */} + {/* Upload PAN Card @@ -398,8 +398,8 @@ const OnboardingAddCompanyDetails = ({ */} - {/* Submit Button */} - {/* + {/* Submit Button */} + {/* - } - variant="outline" - size="sm" - px={8} - _hover={{ opacity: 0.8 }} - color={"#d0b8ef"} - border={"1px solid #d0b8ef"} - isDisabled={activeStep === 0} - onClick={() => setActiveStep(activeStep - 1)} - /> + + } + variant="outline" + size="sm" + px={8} + _hover={{ opacity: 0.8 }} + color={"#d0b8ef"} + border={"1px solid #d0b8ef"} + isDisabled={activeStep === 0} + onClick={() => setActiveStep(activeStep - 1)} + /> - - - + + + - {/* Display the loading spinner */} - {isLoading && ( - + {/* Display the loading spinner */} + {isLoading && ( + Uploading please wait... )} - - ); + + ); }; export default OnboardingAddCompanyDetails; diff --git a/src/Routes/Routes.js b/src/Routes/Routes.js index d1d4cb0..b85e19b 100644 --- a/src/Routes/Routes.js +++ b/src/Routes/Routes.js @@ -23,6 +23,11 @@ import CreateWallet from "../Pages/OptiFiiExpense/wallet/CreateWallet"; import GiftDashboard from "../Pages/OptiFiiGifsAndVouchers/GiftDashboard"; import AdvanceExpenseRequestView from "../Pages/OptiFiiExpense/AdvanceExpenseRequestView"; import ReimbursementRequestView from "../Pages/OptiFiiExpense/ReimbursementRequestView"; +import EmployeesPullBackFunds from "../Pages/ManageHumanResource/EmployeesPullBackFunds"; +import EmployeesView from "../Pages/ManageHumanResource/EmployeesView"; +import EmployeesViewRecentReports from "../Pages/ManageHumanResource/EmployeesViewRecentReports"; +import EmployeesViewRecentTransaction from "../Pages/ManageHumanResource/EmployeesViewRecentTransaction"; +import EmployeesViewRecentReportsView from "../Pages/ManageHumanResource/EmployeesViewRecentReportsView"; export const RouteLink = [ { path: "/", Component: Dashbaord }, { path: "/expenses", Component: Expenses }, @@ -48,6 +53,11 @@ export const RouteLink = [ { path: "/gift-card/application-status", Component: ApplicationStatus }, { path: "/gift-card/digital-application-status", Component: DigitalApplicationStatus }, {path:"/wallet-program/create-wallet" , Component : CreateWallet}, + { path: "/employees/pull-back-funds", Component: EmployeesPullBackFunds }, + { path: "/employees/view", Component: EmployeesView }, + { path: "/employees/view/recent-reports", Component: EmployeesViewRecentReports }, + // { path: "/employees/view/recent-reports/view", Component: EmployeesViewRecentReportsView }, + { path: "/employees/view/recent-transaction", Component: EmployeesViewRecentTransaction }, diff --git a/src/assets/TRANSCORP_LOGO.svg b/src/assets/TRANSCORP_LOGO.svg new file mode 100644 index 0000000..35ab6d7 --- /dev/null +++ b/src/assets/TRANSCORP_LOGO.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/src/assets/logo_card.svg b/src/assets/logo_card.svg new file mode 100644 index 0000000..443ef88 --- /dev/null +++ b/src/assets/logo_card.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/src/assets/rupayImg.png b/src/assets/rupayImg.png new file mode 100644 index 0000000000000000000000000000000000000000..9112fe6035fd19cc910204fc0531f73d7fb4f820 GIT binary patch literal 8181 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 literal 0 HcmV?d00001