import React, { createContext, useContext, useState, useRef, useEffect, } from "react"; import { useForm, useFieldArray, FormProvider, useFormContext, Controller, } from "react-hook-form"; import ExpenseList from "../../components/Expenses/ExpenseList"; import ViewExpense from "../../components/Expenses/ViewExpense"; import Breadcrumb from "../../components/common/Breadcrumb"; import GlobalModel from "../../components/common/GlobalModel"; import PreviewDocument from "../../components/Expenses/PreviewDocument"; import ManageExpense from "../../components/Expenses/ManageExpense"; import { useProjectName } from "../../hooks/useProjects"; import { useExpenseStatus } from "../../hooks/masterHook/useMaster"; import { useEmployees, useEmployeesAllOrByProjectId, } from "../../hooks/useEmployees"; import { useSelector } from "react-redux"; import DateRangePicker from "../../components/common/DateRangePicker"; import SelectMultiple from "../../components/common/SelectMultiple"; import { zodResolver } from "@hookform/resolvers/zod"; import { defaultFilter, SearchSchema, } from "../../components/Expenses/ExpenseSchema"; import { useHasUserPermission } from "../../hooks/useHasUserPermission"; import { CREATE_EXEPENSE } from "../../utils/constants"; const SelectDropdown = ({ label, options = [], loading = false, placeholder = "Select...", valueKey = "id", labelKey = "name", selectedValues = [], onChange, isMulti = false, }) => { const handleChange = (e) => { const selected = Array.from( e.target.selectedOptions, (option) => option.value ); onChange && onChange(selected); }; return (
{options.map((option) => { const checked = selectedValues.includes(option[valueKey]); return (
{ let newSelected; if (checked) { newSelected = selectedValues.filter( (val) => val !== option[valueKey] ); } else { newSelected = [...selectedValues, option[valueKey]]; } onChange(newSelected); }} />
); })}
); }; export const ExpenseContext = createContext(); export const useExpenseContext = () => { const context = useContext(ExpenseContext); if (!context) { throw new Error("useExpenseContext must be used within an ExpenseProvider"); } return context; } const ExpensePage = () => { const [isOpen, setIsOpen] = useState(false); const [filters,setFilter] = useState() const IsCreatedAble = useHasUserPermission(CREATE_EXEPENSE) const dropdownRef = useRef(null); const shouldCloseOnOutsideClick = useRef(false); const selectedProjectId = useSelector( (store) => store.localVariables.projectId ); const [ManageExpenseModal, setManageExpenseModal] = useState({ IsOpen: null, expenseId: null, }); const [viewExpense, setViewExpense] = useState({ expenseId: null, view: false, }); const [ViewDocument, setDocumentView] = useState({ IsOpen: false, Image: null, }); const contextValue = { setViewExpense, setManageExpenseModal, setDocumentView, }; const methods = useForm({ resolver: zodResolver(SearchSchema), defaultValues: defaultFilter, }); const { register, handleSubmit, control, getValues, trigger, setValue, watch, reset, formState: { errors }, } = methods; const { projectNames, loading: projectLoading } = useProjectName(); const { ExpenseStatus, loading: statusLoading, error } = useExpenseStatus(); const { employees, loading: empLoading } = useEmployeesAllOrByProjectId( true, selectedProjectId, true ); const onSubmit = (data) => { setFilter(data) }; const isValidDate = (date) => { return 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 toggleDropdown = () => { setIsOpen((prev) => { shouldCloseOnOutsideClick.current = !prev; return !prev; }); }; useEffect(() => { function handleClickOutside(event) { if ( shouldCloseOnOutsideClick.current && dropdownRef.current && dropdownRef.current.contains(event.target) ) { setIsOpen(false); } } document.addEventListener("mousedown", handleClickOutside); return () => { document.removeEventListener("mousedown", handleClickOutside); }; }, []); const clearFilter =()=>{ setFilter( { projectIds: [], statusIds: [], createdByIds: [], paidById: [], startDate: null, endDate: null, }) reset() } return (
setIsOpen((v) => !v)} > {isOpen && (
{ onSubmit(data); setIsOpen(false); })} >
{ExpenseStatus.map((status) => ( (
{ if (e.target.checked) { onChange([...value, status.id]); } else { onChange( value.filter( (v) => v !== status.id ) ); } }} />
)} /> ))}
`${item.firstName} ${item.lastName}` } valueKey="id" IsLoading={empLoading} /> `${item.firstName} ${item.lastName}` } valueKey="id" IsLoading={empLoading} />
)}
{IsCreatedAble && ( )}
{ManageExpenseModal.IsOpen && ( setManageExpenseModal({ IsOpen: null, expenseId: null, }) } > setManageExpenseModal({ IsOpen: null, expenseId: null }) } /> )} {viewExpense.view && ( setViewExpense({ expenseId: null, view: false, }) } > )} {ViewDocument.IsOpen && ( setDocumentView({ IsOpen: false, Image: null })} > )}
); }; export default ExpensePage;