Refactor_Expenses #321
@ -4,9 +4,30 @@ const FabContext = createContext();
|
|||||||
|
|
||||||
export const FabProvider = ({ children }) => {
|
export const FabProvider = ({ children }) => {
|
||||||
const [actions, setActions] = useState([]);
|
const [actions, setActions] = useState([]);
|
||||||
|
const [showTrigger, setShowTrigger] = useState(true);
|
||||||
|
const [isOffcanvasOpen, setIsOffcanvasOpen] = useState(false);
|
||||||
|
const [offcanvas, setOffcanvas] = useState({
|
||||||
|
isOpen: false,
|
||||||
|
title: "",
|
||||||
|
content: null,
|
||||||
|
});
|
||||||
|
|
||||||
|
const openOffcanvas = (title, content) => {
|
||||||
|
setOffcanvas({ isOpen: true, title, content });
|
||||||
|
setTimeout(() => {
|
||||||
|
const offcanvasElement = document.getElementById("globalOffcanvas");
|
||||||
|
if (offcanvasElement) {
|
||||||
|
const bsOffcanvas = new window.bootstrap.Offcanvas(offcanvasElement);
|
||||||
|
bsOffcanvas.show();
|
||||||
|
}
|
||||||
|
}, 100);
|
||||||
|
};
|
||||||
|
const setOffcanvasContent = (title, content) => {
|
||||||
|
setOffcanvas(prev => ({ ...prev, title, content }));
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FabContext.Provider value={{ actions, setActions }}>
|
<FabContext.Provider value={{ actions, setActions, offcanvas, openOffcanvas, showTrigger, setShowTrigger,isOffcanvasOpen, setIsOffcanvasOpen, setOffcanvasContent, }}>
|
||||||
{children}
|
{children}
|
||||||
</FabContext.Provider>
|
</FabContext.Provider>
|
||||||
);
|
);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React from "react";
|
import React,{useEffect} from "react";
|
||||||
import { useSelector } from "react-redux";
|
import { useSelector } from "react-redux";
|
||||||
import {
|
import {
|
||||||
useDashboardProjectsCardData,
|
useDashboardProjectsCardData,
|
||||||
@ -14,16 +14,25 @@ import ProjectCompletionChart from "./ProjectCompletionChart";
|
|||||||
import ProjectProgressChart from "./ProjectProgressChart";
|
import ProjectProgressChart from "./ProjectProgressChart";
|
||||||
import ProjectOverview from "../Project/ProjectOverview";
|
import ProjectOverview from "../Project/ProjectOverview";
|
||||||
import AttendanceOverview from "./AttendanceChart";
|
import AttendanceOverview from "./AttendanceChart";
|
||||||
|
import { useFab } from "../../Context/FabContext";
|
||||||
|
|
||||||
const Dashboard = () => {
|
const Dashboard = () => {
|
||||||
const { projectsCardData } = useDashboardProjectsCardData();
|
const { projectsCardData } = useDashboardProjectsCardData();
|
||||||
const { teamsCardData } = useDashboardTeamsCardData();
|
const { teamsCardData } = useDashboardTeamsCardData();
|
||||||
const { tasksCardData } = useDashboardTasksCardData();
|
const { tasksCardData } = useDashboardTasksCardData();
|
||||||
|
const {setShowTrigger} = useFab()
|
||||||
|
|
||||||
// Get the selected project ID from Redux store
|
// Get the selected project ID from Redux store
|
||||||
const projectId = useSelector((store) => store.localVariables.projectId);
|
const projectId = useSelector((store) => store.localVariables.projectId);
|
||||||
const isAllProjectsSelected = projectId === null;
|
const isAllProjectsSelected = projectId === null;
|
||||||
|
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setShowTrigger(false);
|
||||||
|
console.log("OffCanvas")
|
||||||
|
return () => setShowTrigger(true);
|
||||||
|
}, [setShowTrigger])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="container-fluid mt-5">
|
<div className="container-fluid mt-5">
|
||||||
<div className="row gy-4">
|
<div className="row gy-4">
|
||||||
|
152
src/components/Expenses/ExpenseFilterPanel.jsx
Normal file
152
src/components/Expenses/ExpenseFilterPanel.jsx
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
// components/Expense/ExpenseFilterPanel.jsx
|
||||||
|
import React, { useEffect } from "react";
|
||||||
|
import { FormProvider, useForm, Controller } from "react-hook-form";
|
||||||
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
|
import {
|
||||||
|
defaultFilter,
|
||||||
|
SearchSchema,
|
||||||
|
} from "./ExpenseSchema";
|
||||||
|
|
||||||
|
import DateRangePicker from "../common/DateRangePicker";
|
||||||
|
import SelectMultiple from "../common/SelectMultiple";
|
||||||
|
|
||||||
|
import { useProjectName } from "../../hooks/useProjects";
|
||||||
|
import { useExpenseStatus } from "../../hooks/masterHook/useMaster";
|
||||||
|
import { useEmployeesAllOrByProjectId } from "../../hooks/useEmployees";
|
||||||
|
import { useSelector } from "react-redux";
|
||||||
|
|
||||||
|
const ExpenseFilterPanel = ({ onApply }) => {
|
||||||
|
const selectedProjectId = useSelector((store) => store.localVariables.projectId);
|
||||||
|
|
||||||
|
const { projectNames, loading: projectLoading } = useProjectName();
|
||||||
|
const { ExpenseStatus = [] } = useExpenseStatus();
|
||||||
|
const { employees, loading: empLoading } = useEmployeesAllOrByProjectId(
|
||||||
|
true,
|
||||||
|
selectedProjectId,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
const methods = useForm({
|
||||||
|
resolver: zodResolver(SearchSchema),
|
||||||
|
defaultValues: defaultFilter,
|
||||||
|
});
|
||||||
|
|
||||||
|
const { control, handleSubmit, setValue, reset } = methods;
|
||||||
|
|
||||||
|
const isValidDate = (date) => date instanceof Date && !isNaN(date);
|
||||||
|
const setDateRange = ({ startDate, endDate }) => {
|
||||||
|
const parsedStart = new Date(startDate);
|
||||||
|
const parsedEnd = new Date(endDate);
|
||||||
|
setValue(
|
||||||
|
"startDate",
|
||||||
|
isValidDate(parsedStart) ? parsedStart.toISOString().split("T")[0] : null
|
||||||
|
);
|
||||||
|
setValue(
|
||||||
|
"endDate",
|
||||||
|
isValidDate(parsedEnd) ? parsedEnd.toISOString().split("T")[0] : null
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const closePanel = () => {
|
||||||
|
document.querySelector(".offcanvas.show .btn-close")?.click();
|
||||||
|
};
|
||||||
|
|
||||||
|
const onSubmit = (data) => {
|
||||||
|
onApply(data);
|
||||||
|
closePanel();
|
||||||
|
};
|
||||||
|
|
||||||
|
const onClear = () => {
|
||||||
|
reset(defaultFilter);
|
||||||
|
onApply(defaultFilter);
|
||||||
|
closePanel();
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FormProvider {...methods}>
|
||||||
|
<form onSubmit={handleSubmit(onSubmit)} className="p-2 text-start">
|
||||||
|
|
||||||
|
<div className="mb-3 w-100">
|
||||||
|
<DateRangePicker
|
||||||
|
onRangeChange={setDateRange}
|
||||||
|
endDateMode="today"
|
||||||
|
DateDifference="6"
|
||||||
|
dateFormat="DD-MM-YYYY"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div className="row g-2">
|
||||||
|
<SelectMultiple
|
||||||
|
name="projectIds"
|
||||||
|
label="Select Projects"
|
||||||
|
options={projectNames}
|
||||||
|
labelKey="name"
|
||||||
|
valueKey="id"
|
||||||
|
IsLoading={projectLoading}
|
||||||
|
/>
|
||||||
|
<SelectMultiple
|
||||||
|
name="createdByIds"
|
||||||
|
label="Select Creator"
|
||||||
|
options={employees}
|
||||||
|
labelKey={(item) => `${item.firstName} ${item.lastName}`}
|
||||||
|
valueKey="id"
|
||||||
|
IsLoading={empLoading}
|
||||||
|
/>
|
||||||
|
<SelectMultiple
|
||||||
|
name="paidById"
|
||||||
|
label="Select Paid By"
|
||||||
|
options={employees}
|
||||||
|
labelKey={(item) => `${item.firstName} ${item.lastName}`}
|
||||||
|
valueKey="id"
|
||||||
|
IsLoading={empLoading}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div className="mb-3">
|
||||||
|
<label className="form-label ">Select Status</label>
|
||||||
|
<div className="d-flex flex-wrap">
|
||||||
|
{ExpenseStatus.map((status) => (
|
||||||
|
<Controller
|
||||||
|
key={status.id}
|
||||||
|
control={control}
|
||||||
|
name="statusIds"
|
||||||
|
render={({ field: { value = [], onChange } }) => (
|
||||||
|
<div className="d-flex align-items-center me-3 mb-2">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
className="form-check-input"
|
||||||
|
value={status.id}
|
||||||
|
checked={value.includes(status.id)}
|
||||||
|
onChange={(e) => {
|
||||||
|
const checked = e.target.checked;
|
||||||
|
onChange(
|
||||||
|
checked
|
||||||
|
? [...value, status.id]
|
||||||
|
: value.filter((v) => v !== status.id)
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<label className="ms-2 mb-0">{status.displayName}</label>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="d-flex justify-content-end py-3 gap-2">
|
||||||
|
<button type="button" className="btn btn-secondary btn-xs" onClick={onClear}>
|
||||||
|
Clear
|
||||||
|
</button>
|
||||||
|
<button type="submit" className="btn btn-primary btn-xs">
|
||||||
|
Apply
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</FormProvider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ExpenseFilterPanel;
|
@ -28,9 +28,9 @@ const DateRangePicker = ({
|
|||||||
altFormat: "d-m-Y",
|
altFormat: "d-m-Y",
|
||||||
defaultDate: [startDate, endDate],
|
defaultDate: [startDate, endDate],
|
||||||
static: false,
|
static: false,
|
||||||
appendTo: document.body,
|
// appendTo: document.body,
|
||||||
clickOpens: true,
|
clickOpens: true,
|
||||||
maxDate: endDate, // ✅ Disable future dates
|
maxDate: endDate,
|
||||||
onChange: (selectedDates, dateStr) => {
|
onChange: (selectedDates, dateStr) => {
|
||||||
const [startDateString, endDateString] = dateStr.split(" To ");
|
const [startDateString, endDateString] = dateStr.split(" To ");
|
||||||
onRangeChange?.({ startDate: startDateString, endDate: endDateString });
|
onRangeChange?.({ startDate: startDateString, endDate: endDateString });
|
||||||
@ -51,23 +51,15 @@ const DateRangePicker = ({
|
|||||||
<div className={`col-${sm} col-sm-${md} px-1 position-relative`}>
|
<div className={`col-${sm} col-sm-${md} px-1 position-relative`}>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
className="form-control form-control-sm ps-2 pe-5 "
|
className="form-control form-control-sm ps-2 pe-5 me-4"
|
||||||
placeholder="From to End"
|
placeholder="From to End"
|
||||||
id="flatpickr-range"
|
id="flatpickr-range"
|
||||||
ref={inputRef}
|
ref={inputRef}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<i
|
<i
|
||||||
className="bx bx-calendar calendar-icon cursor-pointer"
|
className="bx bx-calendar calendar-icon cursor-pointer position-absolute top-50 translate-middle-y "
|
||||||
style={{
|
style={{right:"12px"}}
|
||||||
position: "absolute",
|
|
||||||
top: "50%",
|
|
||||||
right: "12px",
|
|
||||||
transform: "translateY(-50%)",
|
|
||||||
color: "#6c757d",
|
|
||||||
fontSize: "1.1rem",
|
|
||||||
|
|
||||||
}}
|
|
||||||
></i>
|
></i>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
52
src/components/common/GlobalOffcanvas .jsx
Normal file
52
src/components/common/GlobalOffcanvas .jsx
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
import React, { useEffect, useRef } from "react";
|
||||||
|
import { useFab } from "../../Context/FabContext";
|
||||||
|
|
||||||
|
const GlobalOffcanvas = () => {
|
||||||
|
const { offcanvas, setIsOffcanvasOpen } = useFab();
|
||||||
|
const offcanvasRef = useRef();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const el = offcanvasRef.current;
|
||||||
|
const bsOffcanvas = new bootstrap.Offcanvas(el);
|
||||||
|
|
||||||
|
const handleShow = () => setIsOffcanvasOpen(true);
|
||||||
|
const handleHide = () => setIsOffcanvasOpen(false);
|
||||||
|
|
||||||
|
el.addEventListener("show.bs.offcanvas", handleShow);
|
||||||
|
el.addEventListener("hidden.bs.offcanvas", handleHide);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
el.removeEventListener("show.bs.offcanvas", handleShow);
|
||||||
|
el.removeEventListener("hidden.bs.offcanvas", handleHide);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="offcanvas offcanvas-end"
|
||||||
|
tabIndex="-1"
|
||||||
|
id="globalOffcanvas"
|
||||||
|
ref={offcanvasRef}
|
||||||
|
aria-labelledby="offcanvasLabel"
|
||||||
|
data-bs-backdrop="false"
|
||||||
|
data-bs-scroll="true"
|
||||||
|
>
|
||||||
|
<div className="offcanvas-header">
|
||||||
|
<h5 className="offcanvas-title" id="offcanvasLabel">
|
||||||
|
{offcanvas.title}
|
||||||
|
</h5>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn-close text-reset"
|
||||||
|
data-bs-dismiss="offcanvas"
|
||||||
|
aria-label="Close"
|
||||||
|
></button>
|
||||||
|
</div>
|
||||||
|
<div className="offcanvas-body mx-0 flex-grow-0">
|
||||||
|
{offcanvas.content || <p>No content</p>}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default GlobalOffcanvas;
|
26
src/components/common/OffcanvasTrigger.jsx
Normal file
26
src/components/common/OffcanvasTrigger.jsx
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import { createPortal } from "react-dom";
|
||||||
|
import { useFab } from "../../Context/FabContext";
|
||||||
|
|
||||||
|
const OffcanvasTrigger = () => {
|
||||||
|
const { openOffcanvas, offcanvas, showTrigger } = useFab();
|
||||||
|
|
||||||
|
if (!showTrigger || !offcanvas.content) return null;
|
||||||
|
|
||||||
|
const btn = (
|
||||||
|
<i
|
||||||
|
className="bx bx-slider-alt position-fixed p-2 bg-primary text-white rounded-start"
|
||||||
|
onClick={() => openOffcanvas(offcanvas.title, offcanvas.content)}
|
||||||
|
role="button"
|
||||||
|
style={{
|
||||||
|
top: "25%",
|
||||||
|
right: "0%",
|
||||||
|
cursor: "pointer",
|
||||||
|
zIndex: 1056,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
return createPortal(btn, document.body);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default OffcanvasTrigger;
|
@ -7,6 +7,8 @@ import Footer from "../components/Layout/Footer";
|
|||||||
import FloatingMenu from "../components/common/FloatingMenu";
|
import FloatingMenu from "../components/common/FloatingMenu";
|
||||||
import { FabProvider } from "../Context/FabContext";
|
import { FabProvider } from "../Context/FabContext";
|
||||||
import { useSelector } from "react-redux";
|
import { useSelector } from "react-redux";
|
||||||
|
import OffcanvasTrigger from "../components/common/OffcanvasTrigger";
|
||||||
|
import GlobalOffcanvas from "../components/common/GlobalOffcanvas ";
|
||||||
|
|
||||||
const HomeLayout = () => {
|
const HomeLayout = () => {
|
||||||
const loggedUser = useSelector((store) => store.globalVariables.loginUser);
|
const loggedUser = useSelector((store) => store.globalVariables.loginUser);
|
||||||
@ -34,9 +36,11 @@ const HomeLayout = () => {
|
|||||||
<Footer />
|
<Footer />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<OffcanvasTrigger />
|
||||||
<FloatingMenu />
|
<FloatingMenu />
|
||||||
<div className="layout-overlay layout-menu-toggle"></div>
|
<div className="layout-overlay layout-menu-toggle"></div>
|
||||||
</div>
|
</div>
|
||||||
|
<GlobalOffcanvas />
|
||||||
</div>
|
</div>
|
||||||
</FabProvider>
|
</FabProvider>
|
||||||
);
|
);
|
||||||
|
@ -8,24 +8,19 @@ import {
|
|||||||
import Breadcrumb from "../../components/common/Breadcrumb";
|
import Breadcrumb from "../../components/common/Breadcrumb";
|
||||||
import AttendanceLog from "../../components/Activities/AttendcesLogs";
|
import AttendanceLog from "../../components/Activities/AttendcesLogs";
|
||||||
import Attendance from "../../components/Activities/Attendance";
|
import Attendance from "../../components/Activities/Attendance";
|
||||||
// import AttendanceModel from "../../components/Activities/AttendanceModel";
|
|
||||||
import showToast from "../../services/toastService";
|
import showToast from "../../services/toastService";
|
||||||
// import { useProjects } from "../../hooks/useProjects";
|
|
||||||
import Regularization from "../../components/Activities/Regularization";
|
import Regularization from "../../components/Activities/Regularization";
|
||||||
import { useAttendance } from "../../hooks/useAttendance";
|
import { useAttendance } from "../../hooks/useAttendance";
|
||||||
import { useDispatch, useSelector } from "react-redux";
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
import { setProjectId } from "../../slices/localVariablesSlice";
|
import { setProjectId } from "../../slices/localVariablesSlice";
|
||||||
// import { markCurrentAttendance } from "../../slices/apiSlice/attendanceAllSlice";
|
|
||||||
import { hasUserPermission } from "../../utils/authUtils";
|
import { hasUserPermission } from "../../utils/authUtils";
|
||||||
import { useHasUserPermission } from "../../hooks/useHasUserPermission";
|
import { useHasUserPermission } from "../../hooks/useHasUserPermission";
|
||||||
import { REGULARIZE_ATTENDANCE } from "../../utils/constants";
|
import { REGULARIZE_ATTENDANCE } from "../../utils/constants";
|
||||||
import eventBus from "../../services/eventBus";
|
import eventBus from "../../services/eventBus";
|
||||||
// import AttendanceRepository from "../../repositories/AttendanceRepository";
|
|
||||||
import { useProjectName } from "../../hooks/useProjects";
|
import { useProjectName } from "../../hooks/useProjects";
|
||||||
import GlobalModel from "../../components/common/GlobalModel";
|
import GlobalModel from "../../components/common/GlobalModel";
|
||||||
import CheckCheckOutmodel from "../../components/Activities/CheckCheckOutForm";
|
import CheckCheckOutmodel from "../../components/Activities/CheckCheckOutForm";
|
||||||
import AttendLogs from "../../components/Activities/AttendLogs";
|
import AttendLogs from "../../components/Activities/AttendLogs";
|
||||||
// import Confirmation from "../../components/Activities/Confirmation";
|
|
||||||
import { useQueryClient } from "@tanstack/react-query";
|
import { useQueryClient } from "@tanstack/react-query";
|
||||||
|
|
||||||
const AttendancePage = () => {
|
const AttendancePage = () => {
|
||||||
@ -35,11 +30,7 @@ const AttendancePage = () => {
|
|||||||
const loginUser = getCachedProfileData();
|
const loginUser = getCachedProfileData();
|
||||||
var selectedProject = useSelector((store) => store.localVariables.projectId);
|
var selectedProject = useSelector((store) => store.localVariables.projectId);
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
// const {
|
|
||||||
// attendance,
|
|
||||||
// loading: attLoading,
|
|
||||||
// recall: attrecall,
|
|
||||||
// } = useAttendance(selectedProject);
|
|
||||||
const [attendances, setAttendances] = useState();
|
const [attendances, setAttendances] = useState();
|
||||||
const [empRoles, setEmpRoles] = useState(null);
|
const [empRoles, setEmpRoles] = useState(null);
|
||||||
const [isCreateModalOpen, setIsCreateModalOpen] = useState(false);
|
const [isCreateModalOpen, setIsCreateModalOpen] = useState(false);
|
||||||
@ -53,33 +44,6 @@ const AttendancePage = () => {
|
|||||||
date: new Date().toLocaleDateString(),
|
date: new Date().toLocaleDateString(),
|
||||||
});
|
});
|
||||||
|
|
||||||
// const handler = useCallback(
|
|
||||||
// (msg) => {
|
|
||||||
// if (selectedProject == msg.projectId) {
|
|
||||||
// const updatedAttendance = attendances.map((item) =>
|
|
||||||
// item.employeeId === msg.response.employeeId
|
|
||||||
// ? { ...item, ...msg.response }
|
|
||||||
// : item
|
|
||||||
// );
|
|
||||||
// queryClient.setQueryData(["attendance", selectedProject], (oldData) => {
|
|
||||||
// if (!oldData) return oldData;
|
|
||||||
// return oldData.map((emp) =>
|
|
||||||
// emp.employeeId === data.employeeId ? { ...emp, ...data } : emp
|
|
||||||
// );
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// [selectedProject, attrecall]
|
|
||||||
// );
|
|
||||||
|
|
||||||
// const employeeHandler = useCallback(
|
|
||||||
// (msg) => {
|
|
||||||
// if (attendances.some((item) => item.employeeId == msg.employeeId)) {
|
|
||||||
// attrecall();
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// [selectedProject, attendances]
|
|
||||||
// );
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (selectedProject == null) {
|
if (selectedProject == null) {
|
||||||
dispatch(setProjectId(projectNames[0]?.id));
|
dispatch(setProjectId(projectNames[0]?.id));
|
||||||
@ -117,32 +81,9 @@ const AttendancePage = () => {
|
|||||||
}
|
}
|
||||||
}, [modelConfig, isCreateModalOpen]);
|
}, [modelConfig, isCreateModalOpen]);
|
||||||
|
|
||||||
// useEffect(() => {
|
|
||||||
// eventBus.on("attendance", handler);
|
|
||||||
// return () => eventBus.off("attendance", handler);
|
|
||||||
// }, [handler]);
|
|
||||||
|
|
||||||
// useEffect(() => {
|
|
||||||
// eventBus.on("employee", employeeHandler);
|
|
||||||
// return () => eventBus.off("employee", employeeHandler);
|
|
||||||
// }, [employeeHandler]);
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{/* {isCreateModalOpen && modelConfig && (
|
|
||||||
<div
|
|
||||||
className="modal fade show"
|
|
||||||
style={{ display: "block" }}
|
|
||||||
id="check-Out-modalg"
|
|
||||||
tabIndex="-1"
|
|
||||||
aria-hidden="true"
|
|
||||||
>
|
|
||||||
<AttendanceModel
|
|
||||||
modelConfig={modelConfig}
|
|
||||||
closeModal={closeModal}
|
|
||||||
handleSubmitForm={handleSubmit}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)} */}
|
|
||||||
{isCreateModalOpen && modelConfig && (
|
{isCreateModalOpen && modelConfig && (
|
||||||
<GlobalModel
|
<GlobalModel
|
||||||
isOpen={isCreateModalOpen}
|
isOpen={isCreateModalOpen}
|
||||||
|
@ -38,6 +38,8 @@ import {
|
|||||||
VIEW_ALL_EXPNESE,
|
VIEW_ALL_EXPNESE,
|
||||||
VIEW_SELF_EXPENSE,
|
VIEW_SELF_EXPENSE,
|
||||||
} from "../../utils/constants";
|
} from "../../utils/constants";
|
||||||
|
import { useFab } from "../../Context/FabContext";
|
||||||
|
import ExpenseFilterPanel from "../../components/Expenses/ExpenseFilterPanel";
|
||||||
|
|
||||||
const SelectDropdown = ({
|
const SelectDropdown = ({
|
||||||
label,
|
label,
|
||||||
@ -215,6 +217,22 @@ const ExpensePage = () => {
|
|||||||
reset();
|
reset();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const { setOffcanvasContent, setShowTrigger } = useFab();
|
||||||
|
useEffect(() => {
|
||||||
|
setShowTrigger(true);
|
||||||
|
|
||||||
|
setOffcanvasContent(
|
||||||
|
"Expense Filters",
|
||||||
|
<ExpenseFilterPanel
|
||||||
|
onApply={(data) => setFilter(data)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
return () => {
|
||||||
|
setOffcanvasContent("", null);
|
||||||
|
setShowTrigger(false);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ExpenseContext.Provider value={contextValue}>
|
<ExpenseContext.Provider value={contextValue}>
|
||||||
<div className="container-fluid">
|
<div className="container-fluid">
|
||||||
@ -235,7 +253,7 @@ const ExpensePage = () => {
|
|||||||
ref={dropdownRef}
|
ref={dropdownRef}
|
||||||
>
|
>
|
||||||
<i
|
<i
|
||||||
className="bx bx-slider-alt ms-2"
|
className="bx bx-slider-alt ms-2 d-none"
|
||||||
role="button"
|
role="button"
|
||||||
aria-expanded={isOpen}
|
aria-expanded={isOpen}
|
||||||
style={{ cursor: "pointer" }}
|
style={{ cursor: "pointer" }}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user