import React, { useState } from "react"; import { EXPENSE_DRAFT, EXPENSE_REJECTEDBY, ITEMS_PER_PAGE, } from "../../utils/constants"; import { formatCurrency, getColorNameFromHex, useDebounce, } from "../../utils/appUtils"; import { usePaymentRequestList } from "../../hooks/useExpense"; import { formatDate, formatUTCToLocalTime } from "../../utils/dateUtils"; import Avatar from "../../components/common/Avatar"; import { usePaymentRequestContext } from "../../pages/PaymentRequest/PaymentRequestPage"; import { ExpenseTableSkeleton } from "../Expenses/ExpenseSkeleton"; import ConfirmModal from "../common/ConfirmModal"; import { useNavigate } from "react-router-dom"; import { useSelector } from "react-redux"; import Error from "../common/Error"; const PaymentRequestList = ({ filters, groupBy = "submittedBy", search }) => { const { setManageRequest, setVieRequest } = usePaymentRequestContext(); const navigate = useNavigate(); const [IsDeleteModalOpen, setIsDeleteModalOpen] = useState(false); const [deletingId, setDeletingId] = useState(null); const SelfId = useSelector( (store) => store?.globalVariables?.loginUser?.employeeInfo?.id ); const groupByField = (items, field) => { return items.reduce((acc, item) => { let key; let displayField; switch (field) { case "transactionDate": key = item?.transactionDate?.split("T")[0]; displayField = "Transaction Date"; break; case "status": key = item?.status?.displayName || "Unknown"; displayField = "Status"; break; case "submittedBy": key = `${item?.createdBy?.firstName ?? ""} ${ item.createdBy?.lastName ?? "" }`.trim(); displayField = "Submitted By"; break; case "project": key = item?.project?.name || "Unknown Project"; displayField = "Project"; break; case "paymentMode": key = item?.paymentMode?.name || "Unknown Mode"; displayField = "Payment Mode"; break; case "expensesType": key = item?.expensesType?.name || "Unknown Type"; displayField = "Expense Category"; break; case "createdAt": key = item?.createdAt?.split("T")[0] || "Unknown Date"; displayField = "Created Date"; break; default: key = "Others"; displayField = "Others"; } const groupKey = `${field}_${key}`; // unique key for object property if (!acc[groupKey]) { acc[groupKey] = { key, displayField, items: [] }; } acc[groupKey].items.push(item); return acc; }, {}); }; const paymentRequestColumns = [ { key: "paymentRequestUID", label: "Request ID", align: "text-start mx-2", getValue: (e) => e.paymentRequestUID || "N/A", }, { key: "title", label: "Request Title", align: "text-start", getValue: (e) => e.title || "N/A", }, // { key: "payee", label: "Payee", align: "text-start" }, { key: "SubmittedBy", label: "Submitted By", align: "text-start", getValue: (e) => `${e.createdBy?.firstName ?? ""} ${ e.createdBy?.lastName ?? "" }`.trim() || "N/A", customRender: (e) => (
navigate(`/employee/${e.createdBy?.id}`)} > {`${e.createdBy?.firstName ?? ""} ${ e.createdBy?.lastName ?? "" }`.trim() || "N/A"}
), }, { key: "createdAt", label: "Submitted On", align: "text-start", getValue: (e) => formatUTCToLocalTime(e?.createdAt), }, { key: "amount", label: " Amount", align: "text-start", getValue: (e) => ( <> {formatCurrency(e?.amount)} {e.currency.currencyCode} ), align: "text-end px-3", }, { key: "expenseStatus", label: "Status", align: "text-center", getValue: (e) => ( {e?.expenseStatus?.name || "Unknown"} ), }, ]; const [currentPage, setCurrentPage] = useState(1); const debouncedSearch = useDebounce(search, 500); const { data, isLoading, isError, error, isRefetching, refetch } = usePaymentRequestList( ITEMS_PER_PAGE, currentPage, filters, true, debouncedSearch ); const paymentRequestData = data?.data || []; const totalPages = data?.data?.totalPages || 1; if (isError) { return ; } const header = [ "Request ID", "Request Title", "Submitted By", "Submitted On", "Amount", "Status", "Action", ]; if (isLoading) return ; const grouped = groupBy ? groupByField(data?.data ?? [], groupBy) : { All: data?.data ?? [] }; const IsGroupedByDate = [ { key: "transactionDate", displayField: "Transaction Date" }, { key: "createdAt", displayField: "created Date" }, ]?.includes(groupBy); const canEditExpense = (paymentRequest) => { return ( (paymentRequest?.expenseStatus?.id === EXPENSE_DRAFT || EXPENSE_REJECTEDBY.includes(paymentRequest?.expenseStatus.id)) && paymentRequest?.createdBy?.id === SelfId ); }; const canDetetExpense = (request) => { return ( request?.expenseStatus?.id === EXPENSE_DRAFT && request?.createdBy?.id === SelfId ); }; const handleDelete = (id) => { setDeletingId(id); DeleteExpense( { id }, { onSettled: () => { setDeletingId(null); setIsDeleteModalOpen(false); }, } ); }; return ( <> {IsDeleteModalOpen && ( setIsDeleteModalOpen(false)} // loading={isPending} paramData={deletingId} /> )}
{paymentRequestColumns.map((col) => ( ))} {Object.keys(grouped).length > 0 ? ( Object.values(grouped).map(({ key, displayField, items }) => ( {items?.map((paymentRequest) => ( {paymentRequestColumns.map( (col) => (col.isAlwaysVisible || groupBy !== col.key) && ( ) )} ))} )) ) : ( )}
{col.label} Action
{" "} {displayField} :{" "} {" "} {IsGroupedByDate ? formatUTCToLocalTime(key) : key}
{col?.customRender ? col?.customRender(paymentRequest) : col?.getValue(paymentRequest)}
setVieRequest({ requestId: paymentRequest.id, view: true, }) } > {canEditExpense(paymentRequest) && (
  • setManageRequest({ IsOpen: true, RequestId: paymentRequest.id, }) } > Modify
  • {canDetetExpense(paymentRequest) && (
  • { setIsDeleteModalOpen(true); setDeletingId(paymentRequest.id); }} > Delete
  • )}
)}

No Request Found

{/* Pagination */} {totalPages > 1 && (
)}
); }; export default PaymentRequestList;