This commit is contained in:
2024-09-27 20:21:20 +05:30
5 changed files with 1191 additions and 334 deletions

View File

@@ -9,30 +9,36 @@ import {
Tr,
Skeleton,
TableCaption,
Tfoot,
Radio,
RadioGroup,
CheckboxGroup,
Checkbox,
} from "@chakra-ui/react";
import EmptySearchList from "../EmptySearchList";
import { TABLE_PAGINATION } from "../../Constants/Paginations";
const DataTable = ({
const NormalTable = ({
data,
isLoading,
tableHeadRow,
emptyMessage,
centered,
total,
showRadioButton, // New prop for showing the radio button
selectedRadio,
setSelectedRadio, // State for managing radio button selection
}) => {
console.log(data);
const columnWidth =
data && data[0]
? `${(100 / Object.keys(data[0]).length).toFixed(2)}%`
: "auto";
const handleRadioChange = (value) => {
setSelectedRadio(value);
};
return (
<TableContainer
overflowX={"auto"}
className="h-auto w-100 table-scroll"
>
<TableContainer overflowX={"auto"} className="h-auto w-100 table-scroll">
{data?.length === 0 ? (
<EmptySearchList message={emptyMessage} />
) : (
@@ -40,15 +46,11 @@ const DataTable = ({
<TableCaption p={total ? 0 : null}>
{total ? total : "OptiFii v1.0.0"}
</TableCaption>
<Thead
// bgGradient="linear(to-r, gray.50, gray.50)"
bg="#6311cb37"
>
<Thead bg="#6311cb37">
<Tr>
{tableHeadRow.map((heading, index) => (
<Th
color={"purple.900"}
// fontSize={'sm'}
textAlign={
tableHeadRow.length - 1 === index || centered
? "center"
@@ -56,15 +58,19 @@ const DataTable = ({
}
key={index}
p={4}
// width="20px" // Adjust width as needed
// color={"#fff"}
whiteSpace="normal" // Allow text to wrap
wordBreak="normal" // Ensure long words break properly
overflowWrap="normal" // Break long words if necessary
whiteSpace="normal"
wordBreak="normal"
overflowWrap="normal"
textTransform={"none"}
>
{isLoading ? <Skeleton height="20px" /> : heading}
{/* {heading} */}
{/* Conditionally render radio button in the heading */}
{showRadioButton && heading === "Select" ? (
<CheckboxGroup value={selectedRadio}>
<Checkbox isDisabled /> {/* Disabled radio button in header */}
</CheckboxGroup>
) : (
isLoading ? <Skeleton height="20px" /> : heading
)}
</Th>
))}
</Tr>
@@ -76,15 +82,12 @@ const DataTable = ({
<Tr bg={index % 2 === 0 ? "" : "#6311cb14"} key={index}>
{tableHeadRow.map((_, i) => (
<Td
// width={"fit-content"}
key={i}
style={{
whiteSpace: "nowrap",
textOverflow: "ellipsis",
}}
className="web-text-small"
// w={columnWidth}
>
<Skeleton height="20px" mb={1} mt={1} />
</Td>
@@ -93,7 +96,10 @@ const DataTable = ({
)
)
: data?.map((item, index) => (
<Tr bg={index % 2 === 0 ? "" : "#6311cb14"} key={index}>
<Tr cursor={'pointer'}
transition={'0.2s all'}
_hover={{ shadow: "lg" }}
h={12} bg={index % 2 === 0 ? "" : "#6311cb14"} key={index}>
{tableHeadRow.map((heading, i) => (
<Td
textAlign={
@@ -110,7 +116,17 @@ const DataTable = ({
}}
className="web-text-small"
>
{item[heading]}
{/* Conditionally render radio button in the table body */}
{showRadioButton && heading === "Select" ? (
<CheckboxGroup
value={selectedRadio}
onChange={handleRadioChange}
>
<Checkbox bg={'#fff'} value={item.id} /> {/* Dynamic radio buttons */}
</CheckboxGroup>
) : (
item[heading]
)}
</Td>
))}
</Tr>
@@ -122,4 +138,4 @@ const DataTable = ({
);
};
export default DataTable;
export default NormalTable;

File diff suppressed because it is too large Load Diff

View File

@@ -1,15 +1,464 @@
import { Box } from "@chakra-ui/react";
import React from "react";
import {
Avatar,
Box,
Button,
Checkbox,
Divider,
Flex,
HStack,
Icon,
Image,
Input,
InputGroup,
InputLeftElement,
Menu,
MenuButton,
MenuItem,
MenuList,
Radio,
Select,
Tag,
TagLabel,
Text,
VStack,
} from "@chakra-ui/react";
import {
Tabs,
TabList,
Tab,
TabIndicator,
TabPanels,
TabPanel,
} 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 womenpfp from "../../assets/womenpfp1.png";
import {
AddIcon,
CalendarIcon,
ChevronDownIcon,
EmailIcon,
SearchIcon,
ViewIcon,
} from "@chakra-ui/icons";
import {
MdFilterList,
MdNotificationsNone,
MdOutlineHeadsetMic,
} from "react-icons/md";
import { OPACITY_ON_LOAD } from "../../Layout/animations";
import { Link, NavLink, useNavigate } from "react-router-dom";
import { FaArrowUpFromBracket } from "react-icons/fa6";
import { LuListFilter } from "react-icons/lu";
import { BsFilterRight } from "react-icons/bs";
import pdfIcon from "../../assets/pdfIcon.svg";
import ExcelIcon from "../../assets/ExcelIcon.svg";
const AdvanceExpenseRequest = () => {
return (
<Box h={"100%"} p={6}>
<MiniHeader
title={"My Requests"}
subTitle={"Lorem ipsum dolor sit amet, consectetur adipiscing elit."}
backButton={true}
const { AdvanceExpenseRequest } = useContext(GlobalStateContext);
const [isLoading, setIsLoading] = useState(false);
const [searchTerm, setSearchTerm] = useState("");
const [users, setusers] = useState(50);
const navigate = useNavigate();
useEffect(() => {
// Set isLoading to true
setIsLoading(true);
// Simulate a 3-second delay
const timer = setTimeout(() => {
setIsLoading(false);
}, 500);
return () => clearTimeout(timer);
}, []);
// ===============================[ Table Header ]
const tableHeadRow = [
"Sr. no",
"Report name",
"Report by",
"Report amount",
"Date & time",
"Approver",
"Disburser",
"Action",
];
const pendingTable = AdvanceExpenseRequest.map((item, index) => ({
"Sr. no": (
<Checkbox colorScheme="purple">
<Text
as={"span"}
display={"flex"}
gap={2}
alignItems={"center"}
fontSize={"xs"}
>
{/* <Icon
as={PiReceipt}
boxSize={8}
p={1.5}
bg={index % 2 === 0 ? "#6311cb14" : "#fff"}
rounded={"full"}
/> */}
{item?.id}
</Text>
</Checkbox>
),
"Report name": (
<Text
as={"span"}
display={"flex"}
gap={2}
alignItems={"center"}
fontSize={"xs"}
color="#3725EA"
>
{item?.ReportName}
</Text>
),
"Report by": (
<Flex align={'center'} gap={2}>
<Avatar size={'sm'} name={item?.ReportBy?.profName} src={item?.ReportBy?.profImage} />
<Text as={'span'}>{item?.ReportBy?.profName}</Text>
</Flex>
),
"Report amount": item?.ReportAmount,
"Date & time": item?.DateTime,
"Approver": item?.Approver,
"Disburser": item?.Disburser,
"Action": (
<Text
as={"button"}
onClick={() => navigate('/advance-expense-request-view')}
fontSize={"xs"}
color="#fff"
bg={'#6311CB'}
py={1.5} px={5}
borderRadius={5}
>{item?.Action}</Text>
),
}));
const completedTable = AdvanceExpenseRequest.map((item, index) => ({
"Sr. no": (
<Checkbox colorScheme="purple">
<Text
as={"span"}
display={"flex"}
gap={2}
alignItems={"center"}
fontSize={"xs"}
>
{/* <Icon
as={PiReceipt}
boxSize={8}
p={1.5}
bg={index % 2 === 0 ? "#6311cb14" : "#fff"}
rounded={"full"}
/> */}
{item?.id}
</Text>
</Checkbox>
),
"Report name": (
<Text
as={"span"}
display={"flex"}
gap={2}
alignItems={"center"}
fontSize={"xs"}
color="#3725EA"
>
{item?.ReportName}
</Text>
),
"Report by": (
<Flex align={'center'} gap={2}>
<Avatar size={'sm'} name={item?.ReportBy?.profName} src={item?.ReportBy?.profImage} />
<Text as={'span'}>{item?.ReportBy?.profName}</Text>
</Flex>
),
"Report amount": item?.ReportAmount,
"Date & time": item?.DateTime,
"Approver": item?.Approver,
"Disburser": item?.Disburser,
"Action": (
<Text
as={"button"}
fontSize={"xs"}
color="#fff"
bg={'#6311CB'}
py={1.5} px={5}
borderRadius={5}
>{item?.Action}</Text>
),
}));
const rejectedTable = AdvanceExpenseRequest.map((item, index) => ({
"Sr. no": (
<Checkbox colorScheme="purple">
<Text
as={"span"}
display={"flex"}
gap={2}
alignItems={"center"}
fontSize={"xs"}
>
{/* <Icon
as={PiReceipt}
boxSize={8}
p={1.5}
bg={index % 2 === 0 ? "#6311cb14" : "#fff"}
rounded={"full"}
/> */}
{item?.id}
</Text>
</Checkbox>
),
"Report name": (
<Text
as={"span"}
display={"flex"}
gap={2}
alignItems={"center"}
fontSize={"xs"}
color="#3725EA"
>
{item?.ReportName}
</Text>
),
"Report by": (
<Flex align={'center'} gap={2}>
<Avatar size={'sm'} name={item?.ReportBy?.profName} src={item?.ReportBy?.profImage} />
<Text as={'span'}>{item?.ReportBy?.profName}</Text>
</Flex>
),
"Report amount": item?.ReportAmount,
"Date & time": item?.DateTime,
"Approver": item?.Approver,
"Disburser": item?.Disburser,
"Action": (
<Text
as={"button"}
fontSize={"xs"}
color="#fff"
bg={'#6311CB'}
py={1.5} px={5}
borderRadius={5}
>{item?.Action}</Text>
),
}));
const tabsData = [
{
label: 'Pending',
num: 50,
content: <NormalTable
emptyMessage={`We don't have any Sponers `}
tableHeadRow={tableHeadRow}
data={pendingTable}
isLoading={isLoading}
/>
},
{
label: 'Completed',
content: <NormalTable
emptyMessage={`We don't have any Sponers `}
tableHeadRow={tableHeadRow}
data={completedTable}
isLoading={isLoading}
/>
},
{
label: 'Rejected',
content: <NormalTable
emptyMessage={`We don't have any Sponers `}
tableHeadRow={tableHeadRow}
data={rejectedTable}
isLoading={isLoading}
/>
}
];
return (
<Box {...OPACITY_ON_LOAD} p={4} overflowX={"scroll"}>
<Box
rounded={"xl"}
py={3}
// pb={0}
display={"flex"}
flexDirection={"column"}
bg={"#fff"}
shadow={"md"}
minH={"100%"}
>
<VStack mb={0} px={3} alignItems={"start"} gap={0}>
<Box
display={"flex"}
justifyContent={"space-between"}
alignItems={"center"}
w={"100%"}
>
<InputGroup width={300} size="sm" >
<InputLeftElement pointerEvents="none">
<SearchIcon color="gray.300" />
</InputLeftElement>
<Input
type="search"
placeholder="Type to search..."
rounded="md"
focusBorderColor="#3725EA"
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
/>
</InputGroup>
</Box>
<Divider />
<HStack w={"100%"} justifyContent={"space-between"} mb={4}>
<Flex align={'center'} gap={5}>
<Menu>
<MenuButton
as={Button}
leftIcon={<BsFilterRight fontSize={"16px"} />}
rightIcon={<ChevronDownIcon />}
fontSize={"xs"}
color={"gray.700"}
variant="outline"
size={"sm"}
me={2}
>
Sort
</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>
<Flex align={'center'} gap={2}>
<Text as={'span'} fontSize={'xs'}>Show</Text>
<Select borderRadius={5} size={"sm"}>
<option value='10'>10</option>
<option value='30'>30</option>
<option value='50'>50</option>
<option value='80'>80</option>
</Select>
<Text as={'span'} fontSize={'xs'}>entries</Text>
</Flex>
</Flex>
<Box>
<Link to={"#"} style={{ marginRight: "8px" }}>
{/* <SecondaryButton
leftIcon={<Image me={2} src={backFund} w={"17px"} />}
title={"Pull back funds"}
/> */}
</Link>
<Menu>
<MenuButton
as={Button}
leftIcon={<FaArrowUpFromBracket />}
rightIcon={<ChevronDownIcon />}
fontSize={"xs"}
colorScheme="gray"
color={"gray.700"}
variant="outline"
size={"sm"}
me={2}
>
Export
</MenuButton>
<MenuList>
<MenuItem fontSize={"sm"}>
<Image src={pdfIcon} me={2} /> Export as PDF
</MenuItem>
<MenuItem fontSize={"sm"}>
<Image src={ExcelIcon} me={2} /> Export as Excel
</MenuItem>
</MenuList>
</Menu>
<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>
</HStack>
</VStack>
<Tabs position="relative" variant="unstyled">
<TabList color="#B0B0B0">
{tabsData?.map((tab, index) => (
<Tab
key={index}
fontSize="small"
_selected={{
color: "#6311CB",
fontWeight: "medium",
}}
display={'flex'}
alignItems={'center'}
gap={2}
>
{tab?.label}
{tab?.label == "Pending" &&
<Text
as={"span"}
fontSize={"xs"}
color="#fff"
bg={'#6311CB'}
py={1} px={2}
borderRadius={5}
>{tab?.num}</Text>}
</Tab>
))}
</TabList>
<TabIndicator
mt="-1.5px"
height="2px"
bg="blue.500"
borderRadius="1px"
color="red"
/>
<TabPanels>
{tabsData?.map((tabCont, index) => (
<TabPanel key={index}>
{tabCont?.content}
</TabPanel>
))}
</TabPanels>
</Tabs>
</Box>
</Box>
);
};

View File

@@ -0,0 +1,275 @@
import {
Box,
Button,
HStack,
VStack,
Icon,
Checkbox,
Tag,
TagLabel,
Text,
Image,
useDisclosure,
Alert,
CloseButton,
AlertDescription,
Flex,
} 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 { RiDeleteBin5Line } from "react-icons/ri";
import { AiOutlineEdit } from "react-icons/ai";
import { LiaFileInvoiceSolid } from "react-icons/lia";
import { PiReceipt } from "react-icons/pi";
import { MdOutlineNoFood } from "react-icons/md";
import { OPACITY_ON_LOAD } from "../../Layout/animations";
import { IoMdCheckmark } from "react-icons/io";
import { RxCross2 } from "react-icons/rx";
import PrimaryButton from "../../Components/Buttons/PrimaryButton"
import SecondaryButton from "../../Components/Buttons/SecondaryButton"
import { FaCheck } from "react-icons/fa";
const AdvanceExpenseRequestView = () => {
const [alertStatus, setAlertStatus] = useState(null);
const handleApprove = () => {
setAlertStatus('success');
};
const handleReject = () => {
setAlertStatus('error');
};
const { AdvanceExpenseRequestView } = useContext(GlobalStateContext);
const [isLoading, setIsLoading] = useState(false);
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 = [
"Date & time",
"Merchant",
"Category",
"Payment mode",
"Reimburse Amount",
"Bills",
"Action",
];
// const extractedArray = reportsHistory.map((item)=>({ }))
const extractedArray = AdvanceExpenseRequestView.map((item, index) => ({
"Date & time": item?.DateTime,
"Merchant": item?.Merchant,
"Category": item?.Category,
"Payment mode": item?.Paymentmode,
"Reimburse Amount": item?.ReimburseAmount,
"Bills": (
<HStack
>
<Box p={2} bg={"#ebe0f8"} rounded={"full"}>
<LiaFileInvoiceSolid color="#6311CB" fontSize={"18px"} />
</Box>
<Text color={"#3725EA"} fontSize={"xs"} fontWeight={500} mb={0}>
Invoice243
</Text>
</HStack>
),
"Action": (
<Flex align={'center'} gap={3}>
<Text
as={'span'}
py={2} px={3} borderRadius={5} border={'1px solid #00A438'} color={'#00A438'} bg={'#dbf2e3'}
display={'flex'}
align={'center'}
justifyContent={'center'}
gap={1.5}
>
<Flex align={'center'} as="span">
<FaCheck />
</Flex>
Approve
</Text>
<Text
as={'span'}
py={2} px={3} borderRadius={5} border={'1px solid #EE1B24'} color={'#EE1B24'} bg={'#fee9ea'}
display={'flex'}
align={'center'}
justifyContent={'center'}
gap={1.5}
>
<Flex align={'center'} as="span">
<RxCross2 />
</Flex>
Reject
</Text>
</Flex>
)
}));
return (
<Box h={"100%"} p={4} {...OPACITY_ON_LOAD} overflowX={"scroll"}>
{/* <MiniHeader
title={"My Requests"}
subTitle={"Lorem ipsum dolor sit amet, consectetur adipiscing elit."}
backButton={true}
/> */}
{alertStatus === 'success' && (
<Alert status="success" bg="#6311CB" color="#fff" rounded={"md"} mb={4}>
<Box>
<HStack>
<IoMdCheckmark size={16} />
<Text fontSize="xs" mb={0} fontWeight={500}>
Approved by giftryt
</Text>
</HStack>
</Box>
</Alert>
)}
{alertStatus === 'error' && (
<Alert status="error" bg="#EE1B24" color="#fff" rounded={"md"} mb={4}>
<Box>
<HStack>
<RxCross2 size={16} />
<Text fontSize="xs" mb={0} fontWeight={500}>
Rejected by giftryt
</Text>
</HStack>
</Box>
</Alert>
)}
<Box bg={"#fff"} p={4} rounded={"md"} boxShadow={"md"}>
<HStack width={"100%"} mb={8}>
<Box bg={"#e5f6eb"} border={"1px solid #00A438"} px={4} py={1} rounded={"md"} h={14} flex={1}>
<HStack>
<IoMdCheckmark color="#00A438" />
<Text color={"#00A438"} fontSize={"sm"} mb={1} fontWeight={500}>
Approved
</Text>
</HStack>
<Text color={"#667085"} fontSize={"xs"} fontWeight={400} mb={0}>
By Sr. Manager
</Text>
</Box>
<HStack bg={"#00A438"} px={4} py={1} rounded={"md"} h={14} justifyContent={"start"} flex={1}>
<Text color={"#fff"} fontSize={"sm"} mb={0} fontWeight={400}>
In progress
</Text>
</HStack>
<VStack bg={"#f9f9f9"} px={4} py={1} rounded={"md"} h={14} spacing={1} alignItems={"start"} flex={1}>
<Text color={"#79797B"} fontSize={"sm"} mb={0} fontWeight={400}>
Pending
</Text>
<Text color={"#79797B"} fontSize={"xs"} mb={0} fontWeight={400}>
By Sr. Manager
</Text>
</VStack>
<VStack bg={"#f9f9f9"} px={4} py={1} rounded={"md"} h={14} spacing={1} alignItems={"start"} flex={1}>
<Text color={"#79797B"} fontSize={"sm"} mb={0} fontWeight={400}>
Pending
</Text>
<Text color={"#79797B"} fontSize={"xs"} mb={0} fontWeight={400}>
By Sr. Manager
</Text>
</VStack>
<VStack bg={"#f9f9f9"} px={4} py={1} rounded={"md"} h={14} spacing={1} alignItems={"start"} flex={1}>
<Text color={"#79797B"} fontSize={"sm"} mb={0} fontWeight={400}>
Pending
</Text>
<Text color={"#79797B"} fontSize={"xs"} mb={0} fontWeight={400}>
By Sr. Manager
</Text>
</VStack>
</HStack>
<HStack justifyContent={"space-between"} mb={6}>
<Box>
<Text color={"#667085"} fontSize={"xs"} mb={1}>
Report number : 1254587841
</Text>
<Text color={"#252C32"} fontSize={"sm"} mb={0} fontWeight={500}>
Reimbursement report 2024
</Text>
</Box>
<Box >
<Text color={"#667085"} fontSize={"xs"} mb={1}>
Amount to be reimbursed
</Text>
<Text color={"#252C32"} textAlign={'right'} fontSize={"sm"} fontWeight={500} mb={0}>
50,000
</Text>
</Box>
</HStack>
<HStack justifyContent={"space-between"} mb={6}>
<Box>
<Text color={"#667085"} fontSize={"xs"} fontWeight={500} mb={2}>
Submitted by
</Text>
<HStack mb={4} alignItems={"start"}>
<Image
borderRadius='full'
boxSize='40px'
src='https://bit.ly/dan-abramov'
alt='Dan Abramov'
/>
<Box>
<Text color={"#000000"} fontSize={"sm"} mb={0} fontWeight={500}>
Pooja Shah
</Text>
<Text color={"#667085"} fontSize={"xs"} mb={0} fontWeight={400}>
poojashah @wdipl.com
</Text>
</Box>
</HStack>
<Text color={"#252C32"} fontSize={"xs"} mb={0} fontWeight={400}>
Duration - 10 June - 28 June
</Text>
</Box>
</HStack>
<NormalTable
emptyMessage={`We don't have any Sponers `}
tableHeadRow={tableHeadRow}
data={extractedArray}
isLoading={isLoading}
showRadioButton={true}
/>
<HStack justifyContent={"end"} my={4} spacing={4}>
<SecondaryButton title="Reject" onClick={handleReject} />
<PrimaryButton title="Approve" onClick={handleApprove} />
</HStack>
</Box>
</Box>
);
};
export default AdvanceExpenseRequestView;

View File

@@ -19,6 +19,7 @@ import OptiFiiExpenseDashboard from "../Pages/OptiFiiExpense/OptiFiiExpenseDashb
import GiftCard from "../Pages/OptiFiiGifsAndVouchers/GiftCard";
import ApplicationStatus from "../Pages/OptiFiiGifsAndVouchers/id/ApplicationStatus";
import GiftDashboard from "../Pages/OptiFiiGifsAndVouchers/GiftDashboard";
import AdvanceExpenseRequestView from "../Pages/OptiFiiExpense/AdvanceExpenseRequestView";
export const RouteLink = [
{ path: "/", Component: Dashbaord },
{ path: "/expenses", Component: Expenses },
@@ -30,6 +31,7 @@ export const RouteLink = [
{ path: "/wallet-program", Component: WalletProgram },
{ path: "/reimbursement-request", Component: ReimbursementRequest },
{ path: "/advance-expense-request", Component: AdvanceExpenseRequest },
{ path: "/advance-expense-request-view", Component: AdvanceExpenseRequestView },
{ path: "/optiFii-benefit", Component: OptiFiiTaxBenefit },
{ path: "/optiFii-vouchers", Component: OptiFiiGifsAndVouchers },
{ path: "/reports", Component: Report },